mirror of
https://github.com/mfontanini/libtins
synced 2026-01-27 12:14:26 +01:00
Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfe9f9f4a5 | ||
|
|
c082dfad67 | ||
|
|
331bc57b44 | ||
|
|
b7e20f550e | ||
|
|
e15ef0d837 | ||
|
|
08fd9e2d69 | ||
|
|
3a99213c0b | ||
|
|
ad71158268 | ||
|
|
186d23c920 | ||
|
|
cfbf88bb5f | ||
|
|
1681981fe8 | ||
|
|
3e84b07a01 | ||
|
|
b087c964d4 | ||
|
|
bf70a94921 | ||
|
|
e5282f8a3c | ||
|
|
5920185288 | ||
|
|
92f0249d2b | ||
|
|
016cfeecc6 | ||
|
|
8bf0c355f4 | ||
|
|
fa4178de09 | ||
|
|
04578b109f | ||
|
|
9dabb6f570 | ||
|
|
8812153491 | ||
|
|
17da10d76e | ||
|
|
dae25b3381 | ||
|
|
745071af65 | ||
|
|
f3448f1797 | ||
|
|
dad6091706 | ||
|
|
6d6eb9c5d7 | ||
|
|
64b84fa91d | ||
|
|
bac8388cec | ||
|
|
e69d0d7ce9 | ||
|
|
b326546229 | ||
|
|
5c22cc7985 | ||
|
|
bd31b3648f | ||
|
|
3c595e6225 | ||
|
|
ed40dd423d | ||
|
|
0e5d7d7ae0 | ||
|
|
9ef6f7a612 | ||
|
|
da923aa63c | ||
|
|
f88d94cbaa | ||
|
|
6403d1908d | ||
|
|
423dbf2404 | ||
|
|
af6b0fdbb2 | ||
|
|
8e7eb25558 | ||
|
|
91a724fe2d | ||
|
|
eb1c43d293 | ||
|
|
4123764a48 | ||
|
|
abe94ece52 | ||
|
|
2498ebf7d6 | ||
|
|
f8445c2e5c | ||
|
|
116eb9f1c1 | ||
|
|
48c068b84a | ||
|
|
20a3868e82 | ||
|
|
85d7401520 | ||
|
|
3b848060aa | ||
|
|
69fc5ff54b | ||
|
|
8db6032303 | ||
|
|
549c0e97d0 | ||
|
|
c3861cf54e | ||
|
|
7c1453662f | ||
|
|
5b60b79fd8 | ||
|
|
07b5d74179 | ||
|
|
76b0c919b9 | ||
|
|
785ee7b47b | ||
|
|
64b267c7ea | ||
|
|
0832184896 | ||
|
|
5d41316b9a | ||
|
|
602ead5de5 | ||
|
|
72e038b9bf |
@@ -15,6 +15,7 @@ addons:
|
|||||||
packages:
|
packages:
|
||||||
- libpcap-dev
|
- libpcap-dev
|
||||||
- libssl-dev
|
- libssl-dev
|
||||||
|
- libboost-all-dev
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- mkdir build
|
- mkdir build
|
||||||
|
|||||||
52
CHANGES
52
CHANGES
@@ -1,3 +1,55 @@
|
|||||||
|
v3.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
|
v3.3 - Sun Jan 31 21:06:04 PST 2016
|
||||||
|
|
||||||
- Add TCP connection close example
|
- Add TCP connection close example
|
||||||
|
|||||||
103
CMakeLists.txt
103
CMakeLists.txt
@@ -21,6 +21,11 @@ ELSE()
|
|||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
IF(APPLE)
|
||||||
|
# This is set to ON as of policy CMP0042
|
||||||
|
SET(CMAKE_MACOSX_RPATH ON)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
# Build output checks
|
# Build output checks
|
||||||
OPTION(LIBTINS_BUILD_SHARED "Build libtins as a shared library." ON)
|
OPTION(LIBTINS_BUILD_SHARED "Build libtins as a shared library." ON)
|
||||||
IF(LIBTINS_BUILD_SHARED)
|
IF(LIBTINS_BUILD_SHARED)
|
||||||
@@ -38,7 +43,7 @@ ENDIF(LIBTINS_BUILD_SHARED)
|
|||||||
|
|
||||||
# The version number.
|
# The version number.
|
||||||
SET(LIBTINS_VERSION_MAJOR 3)
|
SET(LIBTINS_VERSION_MAJOR 3)
|
||||||
SET(LIBTINS_VERSION_MINOR 3)
|
SET(LIBTINS_VERSION_MINOR 4)
|
||||||
SET(LIBTINS_VERSION "${LIBTINS_VERSION_MAJOR}.${LIBTINS_VERSION_MINOR}")
|
SET(LIBTINS_VERSION "${LIBTINS_VERSION_MAJOR}.${LIBTINS_VERSION_MINOR}")
|
||||||
|
|
||||||
# Required Packages
|
# Required Packages
|
||||||
@@ -56,21 +61,33 @@ IF(WIN32)
|
|||||||
ADD_DEFINITIONS(-DNOMINMAX)
|
ADD_DEFINITIONS(-DNOMINMAX)
|
||||||
ENDIF(WIN32)
|
ENDIF(WIN32)
|
||||||
|
|
||||||
|
INCLUDE(ExternalProject)
|
||||||
|
|
||||||
# *******************
|
# *******************
|
||||||
# Compilation options
|
# 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
|
# C++11 support
|
||||||
OPTION(LIBTINS_ENABLE_CXX11 "Compile libtins with c++11 features" OFF)
|
OPTION(LIBTINS_ENABLE_CXX11 "Compile libtins with c++11 features" ON)
|
||||||
IF(LIBTINS_ENABLE_CXX11)
|
IF(LIBTINS_ENABLE_CXX11)
|
||||||
SET(HAVE_CXX11 ON)
|
# We only use declval and decltype on gcc/clang as VC fails to build that code,
|
||||||
INCLUDE(CheckCXX11Features)
|
# at least on VC2013
|
||||||
IF(HAS_CXX11_NULLPTR AND HAS_CXX11_RVALUE_REFERENCES)
|
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")
|
MESSAGE(STATUS "Enabling C++11 features")
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_COMPILER_FLAGS}")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_COMPILER_FLAGS}")
|
||||||
ELSE(HAS_CXX11_NULLPTR AND HAS_CXX11_RVALUE_REFERENCES)
|
ELSE()
|
||||||
MESSAGE(FATAL_ERROR "C++11 features requested but the compiler does not support them.")
|
MESSAGE(WARNING "The compiler doesn't support the necessary C++11 features. "
|
||||||
ENDIF(HAS_CXX11_NULLPTR AND HAS_CXX11_RVALUE_REFERENCES)
|
"Disabling C++11 on this build")
|
||||||
|
ENDIF()
|
||||||
ELSE(LIBTINS_ENABLE_CXX11)
|
ELSE(LIBTINS_ENABLE_CXX11)
|
||||||
MESSAGE(
|
MESSAGE(
|
||||||
WARNING
|
WARNING
|
||||||
@@ -83,17 +100,46 @@ ENDIF(LIBTINS_ENABLE_CXX11)
|
|||||||
OPTION(LIBTINS_ENABLE_DOT11 "Compile libtins with IEEE 802.11 support" ON)
|
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)
|
OPTION(LIBTINS_ENABLE_WPA2 "Compile libtins with WPA2 decryption features (requires OpenSSL)" ON)
|
||||||
IF(LIBTINS_ENABLE_DOT11)
|
IF(LIBTINS_ENABLE_DOT11)
|
||||||
SET(HAVE_DOT11 ON)
|
SET(TINS_HAVE_DOT11 ON)
|
||||||
MESSAGE(STATUS "Enabling IEEE 802.11 support.")
|
MESSAGE(STATUS "Enabling IEEE 802.11 support.")
|
||||||
IF(LIBTINS_ENABLE_WPA2)
|
IF(LIBTINS_ENABLE_WPA2)
|
||||||
FIND_PACKAGE(OpenSSL REQUIRED)
|
FIND_PACKAGE(OpenSSL)
|
||||||
SET(HAVE_WPA2_DECRYPTION ON)
|
IF(OPENSSL_FOUND)
|
||||||
MESSAGE(STATUS "Enabling WPA2 decryption support.")
|
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)
|
ELSE(LIBTINS_ENABLE_WPA2)
|
||||||
MESSAGE(STATUS "Disabling WPA2 decryption support.")
|
MESSAGE(STATUS "Disabling WPA2 decryption support.")
|
||||||
ENDIF(LIBTINS_ENABLE_WPA2)
|
ENDIF(LIBTINS_ENABLE_WPA2)
|
||||||
ENDIF(LIBTINS_ENABLE_DOT11)
|
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
|
# Use pcap_sendpacket to send l2 packets rather than raw sockets
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
SET(USE_PCAP_SENDPACKET_DEFAULT ON)
|
SET(USE_PCAP_SENDPACKET_DEFAULT ON)
|
||||||
@@ -104,7 +150,7 @@ ENDIF(WIN32)
|
|||||||
OPTION(LIBTINS_USE_PCAP_SENDPACKET "Use pcap_sendpacket to send l2 packets"
|
OPTION(LIBTINS_USE_PCAP_SENDPACKET "Use pcap_sendpacket to send l2 packets"
|
||||||
${USE_PCAP_SENDPACKET_DEFAULT})
|
${USE_PCAP_SENDPACKET_DEFAULT})
|
||||||
IF(LIBTINS_USE_PCAP_SENDPACKET)
|
IF(LIBTINS_USE_PCAP_SENDPACKET)
|
||||||
SET(HAVE_PACKET_SENDER_PCAP_SENDPACKET ON)
|
SET(TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET ON)
|
||||||
MESSAGE(STATUS "Using pcap_sendpacket to send l2 packets.")
|
MESSAGE(STATUS "Using pcap_sendpacket to send l2 packets.")
|
||||||
ENDIF(LIBTINS_USE_PCAP_SENDPACKET)
|
ENDIF(LIBTINS_USE_PCAP_SENDPACKET)
|
||||||
|
|
||||||
@@ -149,6 +195,17 @@ INSTALL(
|
|||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
|
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 subdirectories
|
||||||
# ******************
|
# ******************
|
||||||
@@ -160,11 +217,23 @@ ADD_SUBDIRECTORY(src)
|
|||||||
IF(EXISTS "${CMAKE_SOURCE_DIR}/googletest/CMakeLists.txt")
|
IF(EXISTS "${CMAKE_SOURCE_DIR}/googletest/CMakeLists.txt")
|
||||||
# Enable tests and add the test directory
|
# Enable tests and add the test directory
|
||||||
MESSAGE(STATUS "Tests have been enabled")
|
MESSAGE(STATUS "Tests have been enabled")
|
||||||
SET(gtest_force_shared_crt ON CACHE BOOL "Always use /MD")
|
SET(GOOGLETEST_ROOT ${CMAKE_SOURCE_DIR}/googletest)
|
||||||
SET(BUILD_GMOCK OFF)
|
SET(GOOGLETEST_INCLUDE ${GOOGLETEST_ROOT}/googletest/include)
|
||||||
SET(BUILD_GTEST ON)
|
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()
|
ENABLE_TESTING()
|
||||||
ADD_SUBDIRECTORY(googletest)
|
|
||||||
ADD_SUBDIRECTORY(tests)
|
ADD_SUBDIRECTORY(tests)
|
||||||
ELSE()
|
ELSE()
|
||||||
MESSAGE(STATUS "googletest git submodule is absent. Run `git submodule init && git submodule update` to get it")
|
MESSAGE(STATUS "googletest git submodule is absent. Run `git submodule init && git submodule update` to get it")
|
||||||
|
|||||||
30
CONTRIBUTING.md
Normal file
30
CONTRIBUTING.md
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# 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.
|
||||||
26
README.md
26
README.md
@@ -36,6 +36,7 @@ cmake ../
|
|||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Static/shared build
|
||||||
Note that by default, only the shared object is compiled. If you would
|
Note that by default, only the shared object is compiled. If you would
|
||||||
like to generate a static library file, run:
|
like to generate a static library file, run:
|
||||||
|
|
||||||
@@ -46,6 +47,8 @@ cmake ../ -DLIBTINS_BUILD_SHARED=0
|
|||||||
The generated static/shared library files will be located in the
|
The generated static/shared library files will be located in the
|
||||||
_build/lib_ directory.
|
_build/lib_ directory.
|
||||||
|
|
||||||
|
### C++11 support
|
||||||
|
|
||||||
libtins is noticeable faster if you enable _C++11_ support. Therefore,
|
libtins is noticeable faster if you enable _C++11_ support. Therefore,
|
||||||
if your compiler supports this standard, then you should enable it.
|
if your compiler supports this standard, then you should enable it.
|
||||||
In order to do so, use the _LIBTINS_ENABLE_CXX11_ switch:
|
In order to do so, use the _LIBTINS_ENABLE_CXX11_ switch:
|
||||||
@@ -54,6 +57,22 @@ In order to do so, use the _LIBTINS_ENABLE_CXX11_ switch:
|
|||||||
cmake ../ -DLIBTINS_ENABLE_CXX11=1
|
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
|
If you want to disable _WPA2_ decryption support, which will remove
|
||||||
openssl as a dependency for compilation, use the
|
openssl as a dependency for compilation, use the
|
||||||
_LIBTINS_ENABLE_WPA2_ switch:
|
_LIBTINS_ENABLE_WPA2_ switch:
|
||||||
@@ -62,6 +81,8 @@ _LIBTINS_ENABLE_WPA2_ switch:
|
|||||||
cmake ../ -DLIBTINS_ENABLE_WPA2=0
|
cmake ../ -DLIBTINS_ENABLE_WPA2=0
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### IEEE 802.11 support
|
||||||
|
|
||||||
If you want to disable IEEE 802.11 support(this will also disable
|
If you want to disable IEEE 802.11 support(this will also disable
|
||||||
RadioTap and WPA2 decryption), which will reduce the size of the
|
RadioTap and WPA2 decryption), which will reduce the size of the
|
||||||
resulting library in around 20%, use the _LIBTINS_ENABLE_DOT11_ switch:
|
resulting library in around 20%, use the _LIBTINS_ENABLE_DOT11_ switch:
|
||||||
@@ -119,3 +140,8 @@ You might want to have a look at the examples located in the "examples"
|
|||||||
directory. The same samples can be found online at:
|
directory. The same samples can be found online at:
|
||||||
|
|
||||||
http://libtins.github.io/examples/
|
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.
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
# HAS_CXX11_CONSTEXPR - constexpr keyword
|
# HAS_CXX11_CONSTEXPR - constexpr keyword
|
||||||
# HAS_CXX11_CSTDINT_H - cstdint header
|
# HAS_CXX11_CSTDINT_H - cstdint header
|
||||||
# HAS_CXX11_DECLTYPE - decltype keyword
|
# HAS_CXX11_DECLTYPE - decltype keyword
|
||||||
|
# HAS_CXX11_DECLVAL - declval feature
|
||||||
# HAS_CXX11_FUNC - __func__ preprocessor constant
|
# HAS_CXX11_FUNC - __func__ preprocessor constant
|
||||||
# HAS_CXX11_INITIALIZER_LIST - initializer list
|
# HAS_CXX11_INITIALIZER_LIST - initializer list
|
||||||
# HAS_CXX11_LAMBDA - lambdas
|
# HAS_CXX11_LAMBDA - lambdas
|
||||||
@@ -68,11 +69,11 @@ endif ()
|
|||||||
|
|
||||||
function(cxx11_check_feature FEATURE_NAME RESULT_VAR)
|
function(cxx11_check_feature FEATURE_NAME RESULT_VAR)
|
||||||
if (NOT DEFINED ${RESULT_VAR})
|
if (NOT DEFINED ${RESULT_VAR})
|
||||||
set(_bindir "${CMAKE_CURRENT_BINARY_DIR}/cxx11_${FEATURE_NAME}")
|
set(_bindir "${CMAKE_CURRENT_BINARY_DIR}/cxx_${FEATURE_NAME}")
|
||||||
|
|
||||||
set(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/CheckCXX11Features/cxx11-test-${FEATURE_NAME})
|
set(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/CheckCXXFeatures/cxx-test-${FEATURE_NAME})
|
||||||
set(_LOG_NAME "\"${FEATURE_NAME}\"")
|
set(_LOG_NAME "\"${FEATURE_NAME}\"")
|
||||||
message(STATUS "Checking C++11 support for ${_LOG_NAME}")
|
message(STATUS "Checking C++ support for ${_LOG_NAME}")
|
||||||
|
|
||||||
set(_SRCFILE "${_SRCFILE_BASE}.cpp")
|
set(_SRCFILE "${_SRCFILE_BASE}.cpp")
|
||||||
set(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.cpp")
|
set(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.cpp")
|
||||||
@@ -116,27 +117,31 @@ function(cxx11_check_feature FEATURE_NAME RESULT_VAR)
|
|||||||
endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
|
endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
|
||||||
|
|
||||||
if (${RESULT_VAR})
|
if (${RESULT_VAR})
|
||||||
message(STATUS "Checking C++11 support for ${_LOG_NAME}: works")
|
message(STATUS "Checking C++ support for ${_LOG_NAME}: works")
|
||||||
else (${RESULT_VAR})
|
else (${RESULT_VAR})
|
||||||
message(STATUS "Checking C++11 support for ${_LOG_NAME}: not supported")
|
message(STATUS "Checking C++ support for ${_LOG_NAME}: not supported")
|
||||||
endif (${RESULT_VAR})
|
endif (${RESULT_VAR})
|
||||||
set(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "C++11 support for ${_LOG_NAME}")
|
set(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "C++ support for ${_LOG_NAME}")
|
||||||
endif (NOT DEFINED ${RESULT_VAR})
|
endif (NOT DEFINED ${RESULT_VAR})
|
||||||
endfunction(cxx11_check_feature)
|
endfunction(cxx11_check_feature)
|
||||||
|
|
||||||
cxx11_check_feature("__func__" HAS_CXX11_FUNC)
|
#cxx11_check_feature("regex" HAS_CXX11_LIB_REGEX)
|
||||||
cxx11_check_feature("auto" HAS_CXX11_AUTO)
|
#cxx11_check_feature("__func__" HAS_CXX11_FUNC)
|
||||||
cxx11_check_feature("auto_ret_type" HAS_CXX11_AUTO_RET_TYPE)
|
#cxx11_check_feature("auto" HAS_CXX11_AUTO)
|
||||||
cxx11_check_feature("class_override_final" HAS_CXX11_CLASS_OVERRIDE)
|
#cxx11_check_feature("auto_ret_type" HAS_CXX11_AUTO_RET_TYPE)
|
||||||
cxx11_check_feature("constexpr" HAS_CXX11_CONSTEXPR)
|
#cxx11_check_feature("class_override_final" HAS_CXX11_CLASS_OVERRIDE)
|
||||||
cxx11_check_feature("cstdint" HAS_CXX11_CSTDINT_H)
|
#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("decltype" HAS_CXX11_DECLTYPE)
|
||||||
|
cxx11_check_feature("declval" HAS_CXX11_DECLVAL)
|
||||||
cxx11_check_feature("initializer_list" HAS_CXX11_INITIALIZER_LIST)
|
cxx11_check_feature("initializer_list" HAS_CXX11_INITIALIZER_LIST)
|
||||||
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("regex" HAS_CXX11_LIB_REGEX)
|
|
||||||
cxx11_check_feature("rvalue-references" HAS_CXX11_RVALUE_REFERENCES)
|
cxx11_check_feature("rvalue-references" HAS_CXX11_RVALUE_REFERENCES)
|
||||||
cxx11_check_feature("sizeof_member" HAS_CXX11_SIZEOF_MEMBER)
|
cxx11_check_feature("functional" HAS_CXX11_FUNCTIONAL)
|
||||||
cxx11_check_feature("static_assert" HAS_CXX11_STATIC_ASSERT)
|
cxx11_check_feature("chrono" HAS_CXX11_CHRONO)
|
||||||
cxx11_check_feature("variadic_templates" HAS_CXX11_VARIADIC_TEMPLATES)
|
cxx11_check_feature("builtin-swap" HAS_GCC_BUILTIN_SWAP)
|
||||||
8
cmake/Modules/CheckCXXFeatures/cxx-test-builtin-swap.cpp
Normal file
8
cmake/Modules/CheckCXXFeatures/cxx-test-builtin-swap.cpp
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
9
cmake/Modules/CheckCXXFeatures/cxx-test-chrono.cpp
Normal file
9
cmake/Modules/CheckCXXFeatures/cxx-test-chrono.cpp
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
using namespace std::chrono;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
system_clock::time_point tp = system_clock::now();
|
||||||
|
milliseconds ms = duration_cast<milliseconds>(tp.time_since_epoch());
|
||||||
|
return (ms.count() > 0) ? 0 : 1;
|
||||||
|
}
|
||||||
19
cmake/Modules/CheckCXXFeatures/cxx-test-declval.cpp
Normal file
19
cmake/Modules/CheckCXXFeatures/cxx-test-declval.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
// Example code taken from http://en.cppreference.com/w/cpp/utility/declval
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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<NonDefault>().foo()) n2 = n1; // type of n2 is int
|
||||||
|
return (n1 == 1 && n2 == 1) ? 0 : 1;
|
||||||
|
}
|
||||||
11
cmake/Modules/CheckCXXFeatures/cxx-test-functional.cpp
Normal file
11
cmake/Modules/CheckCXXFeatures/cxx-test-functional.cpp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#include <functional>
|
||||||
|
|
||||||
|
int add(int x, int y) {
|
||||||
|
return x + y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::function<int(int, int)> func;
|
||||||
|
func = std::bind(&add, std::placeholders::_1, std::placeholders::_2);
|
||||||
|
return (func(2, 2) == 4) ? 0 : 1;
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@ before_build:
|
|||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- if "%platform%"=="x64" ( set GENERATOR="Visual Studio 12 Win64" ) else ( set GENERATOR="Visual Studio 12" )
|
- 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 -DLIBTINS_ENABLE_CXX11=1
|
- cmake .. -G %GENERATOR% -DPCAP_ROOT_DIR=c:\WpdPack -DLIBTINS_BUILD_SHARED=0 -DLIBTINS_ENABLE_WPA2=0
|
||||||
build:
|
build:
|
||||||
project: C:/projects/libtins/build/libtins.sln
|
project: C:/projects/libtins/build/libtins.sln
|
||||||
verbosity: minimal
|
verbosity: minimal
|
||||||
@@ -37,7 +37,7 @@ after_build:
|
|||||||
- 7z a libtins-%platform%-%Configuration%.zip libtins
|
- 7z a libtins-%platform%-%Configuration%.zip libtins
|
||||||
test_script:
|
test_script:
|
||||||
- cd c:\projects\libtins\build
|
- cd c:\projects\libtins\build
|
||||||
- ctest -C %Configuration%
|
- ctest -C %Configuration% -V
|
||||||
deploy_script:
|
deploy_script:
|
||||||
- ps: Push-AppveyorArtifact "install\libtins-$env:Platform-$env:Configuration.zip"
|
- ps: Push-AppveyorArtifact "install\libtins-$env:Platform-$env:Configuration.zip"
|
||||||
skip_commits:
|
skip_commits:
|
||||||
|
|||||||
23
cmake/cmake_uninstall.cmake.in
Normal file
23
cmake/cmake_uninstall.cmake.in
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# 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)
|
||||||
@@ -1365,7 +1365,8 @@ INCLUDE_FILE_PATTERNS =
|
|||||||
# undefined via #undef or recursively expanded use the := operator
|
# undefined via #undef or recursively expanded use the := operator
|
||||||
# instead of the = operator.
|
# instead of the = operator.
|
||||||
|
|
||||||
PREDEFINED =
|
PREDEFINED = "TINS_IS_CXX11=1" \
|
||||||
|
"TINS_HAVE_WPA2_CALLBACKS=1"
|
||||||
|
|
||||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
|
# 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.
|
# this tag can be used to specify a list of macro names that should be expanded.
|
||||||
|
|||||||
@@ -1,73 +1,81 @@
|
|||||||
FIND_PACKAGE(libtins QUIET)
|
|
||||||
FIND_PACKAGE(Threads QUIET)
|
FIND_PACKAGE(Threads QUIET)
|
||||||
|
FIND_PACKAGE(Boost COMPONENTS regex)
|
||||||
|
|
||||||
IF(libtins_FOUND)
|
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/examples)
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/examples)
|
INCLUDE_DIRECTORIES(
|
||||||
INCLUDE_DIRECTORIES(
|
${CMAKE_CURRENT_SOURCE_DIR}/../include
|
||||||
${LIBTINS_INCLUDE_DIRS}
|
${PCAP_INCLUDE_DIR}
|
||||||
${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
|
||||||
)
|
)
|
||||||
LINK_LIBRARIES(${LIBTINS_LIBRARIES})
|
IF(Boost_REGEX_FOUND)
|
||||||
|
SET(LIBTINS_CXX11_EXAMPLES ${LIBTINS_CXX11_EXAMPLES} http_requests)
|
||||||
IF(HAVE_CXX11)
|
|
||||||
SET(LIBTINS_CXX11_EXAMPLES
|
|
||||||
arpmonitor
|
|
||||||
dns_queries
|
|
||||||
dns_spoof
|
|
||||||
dns_stats
|
|
||||||
icmp_responses
|
|
||||||
interfaces_info
|
|
||||||
tcp_connection_close
|
|
||||||
traceroute
|
|
||||||
wps_detect
|
|
||||||
)
|
|
||||||
ELSE(HAVE_CXX11)
|
|
||||||
MESSAGE(WARNING "Disabling some examples since C++11 support is disabled.")
|
|
||||||
ENDIF(HAVE_CXX11)
|
|
||||||
|
|
||||||
ADD_CUSTOM_TARGET(
|
|
||||||
examples DEPENDS
|
|
||||||
arpspoofing
|
|
||||||
${LIBTINS_CXX11_EXAMPLES}
|
|
||||||
beacon_display
|
|
||||||
portscan
|
|
||||||
route_table
|
|
||||||
)
|
|
||||||
|
|
||||||
ADD_EXECUTABLE(arpspoofing EXCLUDE_FROM_ALL arpspoofing.cpp)
|
|
||||||
ADD_EXECUTABLE(route_table EXCLUDE_FROM_ALL route_table.cpp)
|
|
||||||
IF(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(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)
|
|
||||||
ENDIF(HAVE_CXX11)
|
|
||||||
|
|
||||||
ADD_EXECUTABLE(beacon_display EXCLUDE_FROM_ALL beacon_display.cpp)
|
|
||||||
|
|
||||||
if(THREADS_FOUND)
|
|
||||||
IF(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(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()
|
ELSE()
|
||||||
MESSAGE(WARNING "Disabling portscan and traceroute examples since pthreads library was not found.")
|
MESSAGE(WARNING "Disabling HTTP requests example since boost.regex was not found")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ELSE(libtins_FOUND)
|
ELSE(TINS_HAVE_CXX11)
|
||||||
MESSAGE(
|
MESSAGE(WARNING "Disabling some examples since C++11 support is disabled.")
|
||||||
WARNING
|
ENDIF(TINS_HAVE_CXX11)
|
||||||
"Disabling examples since libtins is not installed. "
|
|
||||||
"Run cmake again once it is installed in order to compile them."
|
ADD_CUSTOM_TARGET(
|
||||||
)
|
examples DEPENDS
|
||||||
ENDIF(libtins_FOUND)
|
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()
|
||||||
|
|||||||
118
examples/defragmenter.cpp
Normal file
118
examples/defragmenter.cpp
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* 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 <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
|
#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] << " <input-file> <output-file>" << 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -31,6 +31,9 @@
|
|||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
// Fix for gcc 4.6
|
||||||
|
#define _GLIBCXX_USE_NANOSLEEP
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
@@ -65,8 +68,8 @@ using namespace Tins;
|
|||||||
template<typename Duration>
|
template<typename Duration>
|
||||||
class statistics {
|
class statistics {
|
||||||
public:
|
public:
|
||||||
using duration_type = Duration;
|
typedef Duration duration_type;
|
||||||
using locker_type = lock_guard<mutex>;
|
typedef lock_guard<mutex> locker_type;
|
||||||
|
|
||||||
struct information {
|
struct information {
|
||||||
duration_type average, worst;
|
duration_type average, worst;
|
||||||
@@ -108,18 +111,18 @@ private:
|
|||||||
class dns_monitor {
|
class dns_monitor {
|
||||||
public:
|
public:
|
||||||
// The response times are measured in milliseconds
|
// The response times are measured in milliseconds
|
||||||
using duration_type = milliseconds;
|
typedef milliseconds duration_type;
|
||||||
// The statistics type used.
|
// The statistics type used.
|
||||||
using statistics_type = statistics<duration_type>;
|
typedef statistics<duration_type> statistics_type;
|
||||||
|
|
||||||
void run(BaseSniffer& sniffer);
|
void run(BaseSniffer& sniffer);
|
||||||
const statistics_type& stats() const {
|
const statistics_type& stats() const {
|
||||||
return m_stats;
|
return m_stats;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
using packet_info = tuple<IPv4Address, IPv4Address, uint16_t>;
|
typedef tuple<IPv4Address, IPv4Address, uint16_t> packet_info;
|
||||||
using clock_type = system_clock;
|
typedef system_clock clock_type;
|
||||||
using time_point_type = clock_type::time_point;
|
typedef clock_type::time_point time_point_type;
|
||||||
|
|
||||||
bool callback(const PDU& pdu);
|
bool callback(const PDU& pdu);
|
||||||
static packet_info make_packet_info(const PDU& pdu, const DNS& dns);
|
static packet_info make_packet_info(const PDU& pdu, const DNS& dns);
|
||||||
|
|||||||
147
examples/http_requests.cpp
Normal file
147
examples/http_requests.cpp
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* 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 <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <boost/regex.hpp>
|
||||||
|
#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<Stream::payload_type::const_iterator> client_match;
|
||||||
|
match_results<Stream::payload_type::const_iterator> 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] << " <interface>" << 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,11 +29,14 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
#include <tins/network_interface.h>
|
#include <tins/network_interface.h>
|
||||||
|
|
||||||
using std::cout;
|
using std::cout;
|
||||||
|
using std::wcout;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
using std::ostringstream;
|
||||||
|
|
||||||
using namespace Tins;
|
using namespace Tins;
|
||||||
|
|
||||||
@@ -50,12 +53,35 @@ int main() {
|
|||||||
NetworkInterface::Info info = iface.info();
|
NetworkInterface::Info info = iface.info();
|
||||||
|
|
||||||
// Now print all of this info.
|
// Now print all of this info.
|
||||||
cout << name << ": " << endl;
|
cout << name;
|
||||||
cout << " HW address: " << info.hw_addr << endl
|
|
||||||
<< " IP address: " << info.ip_addr << endl
|
#ifdef _WIN32
|
||||||
<< " Netmask: " << info.netmask << endl
|
// If this is running on Windows, also print the friendly name
|
||||||
<< " Broadcast: " << info.bcast_addr << endl
|
wcout << " (" << iface.friendly_name() << ")";
|
||||||
<< " Iface index: " << iface.id() << endl
|
#endif // _WIN32
|
||||||
<< " Status: " << "interface " << status << endl << endl;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
162
examples/stream_dump.cpp
Normal file
162
examples/stream_dump.cpp
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* 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 <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#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] << " <interface> <port>" << 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
#include <tins/tins.h>
|
#include <tins/tins.h>
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|||||||
@@ -31,6 +31,9 @@
|
|||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
// Fix for gcc 4.6
|
||||||
|
#define _GLIBCXX_USE_NANOSLEEP
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@@ -128,7 +131,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
sender.send(ip);
|
sender.send(ip);
|
||||||
// Give him a little time
|
// Give it a little time
|
||||||
sleep_for(milliseconds(100));
|
sleep_for(milliseconds(100));
|
||||||
}
|
}
|
||||||
running = false;
|
running = false;
|
||||||
|
|||||||
@@ -5,3 +5,4 @@ INSTALL(
|
|||||||
COMPONENT Headers
|
COMPONENT Headers
|
||||||
)
|
)
|
||||||
ADD_SUBDIRECTORY(dot11)
|
ADD_SUBDIRECTORY(dot11)
|
||||||
|
ADD_SUBDIRECTORY(tcp_ip)
|
||||||
|
|||||||
@@ -72,6 +72,14 @@ public:
|
|||||||
REPLY = 0x0002
|
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.
|
* \brief Constructs an ARP object using the provided addresses.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -333,7 +333,7 @@ protected:
|
|||||||
vend_type& vend() { return vend_; }
|
vend_type& vend() { return vend_; }
|
||||||
|
|
||||||
void write_serialization(uint8_t* buffer, uint32_t total_sz, const PDU* parent);
|
void write_serialization(uint8_t* buffer, uint32_t total_sz, const PDU* parent);
|
||||||
private:
|
|
||||||
/**
|
/**
|
||||||
* Struct that represents the Bootp datagram.
|
* Struct that represents the Bootp datagram.
|
||||||
*/
|
*/
|
||||||
@@ -355,6 +355,7 @@ private:
|
|||||||
uint8_t file[128];
|
uint8_t file[128];
|
||||||
} TINS_END_PACK;
|
} TINS_END_PACK;
|
||||||
|
|
||||||
|
private:
|
||||||
bootp_header bootp_;
|
bootp_header bootp_;
|
||||||
vend_type vend_;
|
vend_type vend_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,15 +2,24 @@
|
|||||||
#define TINS_CONFIG_H
|
#define TINS_CONFIG_H
|
||||||
|
|
||||||
/* Define if the compiler supports basic C++11 syntax */
|
/* Define if the compiler supports basic C++11 syntax */
|
||||||
#cmakedefine HAVE_CXX11
|
#cmakedefine TINS_HAVE_CXX11
|
||||||
|
|
||||||
/* Have IEEE 802.11 support */
|
/* Have IEEE 802.11 support */
|
||||||
#cmakedefine HAVE_DOT11
|
#cmakedefine TINS_HAVE_DOT11
|
||||||
|
|
||||||
/* Have WPA2 decryption library */
|
/* Have WPA2 decryption library */
|
||||||
#cmakedefine HAVE_WPA2_DECRYPTION
|
#cmakedefine TINS_HAVE_WPA2_DECRYPTION
|
||||||
|
|
||||||
/* Use pcap_sendpacket to send l2 packets */
|
/* Use pcap_sendpacket to send l2 packets */
|
||||||
#cmakedefine HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
#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
|
#endif // TINS_CONFIG_H
|
||||||
|
|||||||
@@ -29,13 +29,16 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#if !defined(TINS_CRYPTO_H) && defined(HAVE_DOT11)
|
#if !defined(TINS_CRYPTO_H) && defined(TINS_HAVE_DOT11)
|
||||||
#define TINS_CRYPTO_H
|
#define TINS_CRYPTO_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#ifdef TINS_HAVE_WPA2_CALLBACKS
|
||||||
|
#include <functional>
|
||||||
|
#endif // TINS_HAVE_WPA2_CALLBACKS
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "snap.h"
|
#include "snap.h"
|
||||||
#include "rawpdu.h"
|
#include "rawpdu.h"
|
||||||
@@ -52,7 +55,7 @@ namespace Crypto {
|
|||||||
|
|
||||||
struct RC4Key;
|
struct RC4Key;
|
||||||
|
|
||||||
#ifdef HAVE_WPA2_DECRYPTION
|
#ifdef TINS_HAVE_WPA2_DECRYPTION
|
||||||
namespace WPA2 {
|
namespace WPA2 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -160,12 +163,19 @@ public:
|
|||||||
* \return The generated PMK.
|
* \return The generated PMK.
|
||||||
*/
|
*/
|
||||||
const pmk_type& pmk() const;
|
const pmk_type& pmk() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Getter for the SSID
|
||||||
|
* \return The access point's SSID
|
||||||
|
*/
|
||||||
|
const std::string& ssid() const;
|
||||||
private:
|
private:
|
||||||
pmk_type pmk_;
|
pmk_type pmk_;
|
||||||
|
std::string ssid_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // WPA2
|
} // WPA2
|
||||||
#endif // HAVE_WPA2_DECRYPTION
|
#endif // TINS_HAVE_WPA2_DECRYPTION
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief RC4 Key abstraction.
|
* \brief RC4 Key abstraction.
|
||||||
@@ -240,7 +250,7 @@ private:
|
|||||||
std::vector<uint8_t> key_buffer_;
|
std::vector<uint8_t> key_buffer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_WPA2_DECRYPTION
|
#ifdef TINS_HAVE_WPA2_DECRYPTION
|
||||||
/**
|
/**
|
||||||
* \brief Decrypts WPA2-encrypted traffic.
|
* \brief Decrypts WPA2-encrypted traffic.
|
||||||
*
|
*
|
||||||
@@ -275,6 +285,32 @@ public:
|
|||||||
*/
|
*/
|
||||||
typedef std::map<addr_pair, WPA2::SessionKeys> keys_map;
|
typedef std::map<addr_pair, WPA2::SessionKeys> 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<void(const std::string&,
|
||||||
|
const address_type&)> 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<void(const std::string&,
|
||||||
|
const address_type&,
|
||||||
|
const address_type&)> handshake_captured_callback_type;
|
||||||
|
|
||||||
|
#endif // TINS_HAVE_WPA2_CALLBACKS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Adds an access points's information.
|
* \brief Adds an access points's information.
|
||||||
*
|
*
|
||||||
@@ -353,6 +389,30 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool decrypt(PDU& pdu);
|
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
|
* \brief Getter for the keys on this decrypter
|
||||||
*
|
*
|
||||||
@@ -381,8 +441,12 @@ private:
|
|||||||
pmks_map pmks_;
|
pmks_map pmks_;
|
||||||
bssids_map aps_;
|
bssids_map aps_;
|
||||||
keys_map keys_;
|
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 // HAVE_WPA2_DECRYPTION
|
#endif // TINS_HAVE_WPA2_DECRYPTION
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Pluggable decrypter object which can be used to decrypt
|
* \brief Pluggable decrypter object which can be used to decrypt
|
||||||
@@ -459,7 +523,7 @@ void rc4(ForwardIterator start, ForwardIterator end, RC4Key& key, OutputIterator
|
|||||||
template<typename Functor>
|
template<typename Functor>
|
||||||
DecrypterProxy<Functor, WEPDecrypter> make_wep_decrypter_proxy(const Functor& functor);
|
DecrypterProxy<Functor, WEPDecrypter> make_wep_decrypter_proxy(const Functor& functor);
|
||||||
|
|
||||||
#ifdef HAVE_WPA2_DECRYPTION
|
#ifdef TINS_HAVE_WPA2_DECRYPTION
|
||||||
/**
|
/**
|
||||||
* \brief Wrapper function to create a DecrypterProxy using a
|
* \brief Wrapper function to create a DecrypterProxy using a
|
||||||
* WPA2Decrypter as the Decrypter template parameter.
|
* WPA2Decrypter as the Decrypter template parameter.
|
||||||
@@ -471,7 +535,7 @@ template<typename Functor>
|
|||||||
DecrypterProxy<Functor, WPA2Decrypter> make_wpa2_decrypter_proxy(const Functor& functor) {
|
DecrypterProxy<Functor, WPA2Decrypter> make_wpa2_decrypter_proxy(const Functor& functor) {
|
||||||
return DecrypterProxy<Functor, WPA2Decrypter>(functor);
|
return DecrypterProxy<Functor, WPA2Decrypter>(functor);
|
||||||
}
|
}
|
||||||
#endif // HAVE_WPA2_DECRYPTION
|
#endif // TINS_HAVE_WPA2_DECRYPTION
|
||||||
|
|
||||||
// Implementation section
|
// Implementation section
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
#define TINS_CXXSTD_GCC_FIX 0
|
#define TINS_CXXSTD_GCC_FIX 0
|
||||||
#endif // __GXX_EXPERIMENTAL_CXX0X__
|
#endif // __GXX_EXPERIMENTAL_CXX0X__
|
||||||
|
|
||||||
#if !defined(TINS_IS_CXX11) && defined(HAVE_CXX11)
|
#if !defined(TINS_IS_CXX11) && defined(TINS_HAVE_CXX11)
|
||||||
#define TINS_IS_CXX11 (__cplusplus > 199711L || TINS_CXXSTD_GCC_FIX == 1 || _MSC_VER >= 1800)
|
#define TINS_IS_CXX11 (__cplusplus > 199711L || TINS_CXXSTD_GCC_FIX == 1 || _MSC_VER >= 1800)
|
||||||
#elif !defined(TINS_IS_CXX11)
|
#elif !defined(TINS_IS_CXX11)
|
||||||
#define TINS_IS_CXX11 0
|
#define TINS_IS_CXX11 0
|
||||||
|
|||||||
@@ -172,6 +172,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
typedef std::list<option> options_type;
|
typedef std::list<option> options_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 Creates an instance of DHCP.
|
* \brief Creates an instance of DHCP.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -412,6 +412,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
typedef std::vector<uint8_t> interface_id_type;
|
typedef std::vector<uint8_t> interface_id_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
*/
|
*/
|
||||||
@@ -854,7 +862,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. \sa PDU::header_size
|
* This method overrides PDU::header_size. \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
|
|
||||||
|
|||||||
@@ -589,6 +589,14 @@ public:
|
|||||||
typedef IPv4Address address_type;
|
typedef IPv4Address address_type;
|
||||||
typedef IPv6Address address_v6_type;
|
typedef IPv6Address address_v6_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 Default constructor.
|
* \brief Default constructor.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#if !defined(TINS_DOT_11) && defined(HAVE_DOT11)
|
#if !defined(TINS_DOT_11) && defined(TINS_HAVE_DOT11)
|
||||||
#define TINS_DOT_11
|
#define TINS_DOT_11
|
||||||
|
|
||||||
#include "dot11/dot11_base.h"
|
#include "dot11/dot11_base.h"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
|
||||||
#if !defined(TINS_DOT11_DOT11_ASSOC_H) && defined(HAVE_DOT11)
|
#if !defined(TINS_DOT11_DOT11_ASSOC_H) && defined(TINS_HAVE_DOT11)
|
||||||
#define TINS_DOT11_DOT11_ASSOC_H
|
#define TINS_DOT11_DOT11_ASSOC_H
|
||||||
|
|
||||||
#include "../dot11/dot11_mgmt.h"
|
#include "../dot11/dot11_mgmt.h"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
|
||||||
#if !defined(TINS_DOT11_DOT11_AUTH_H) && defined(HAVE_DOT11)
|
#if !defined(TINS_DOT11_DOT11_AUTH_H) && defined(TINS_HAVE_DOT11)
|
||||||
#define TINS_DOT11_DOT11_AUTH_H
|
#define TINS_DOT11_DOT11_AUTH_H
|
||||||
|
|
||||||
#include "../dot11/dot11_mgmt.h"
|
#include "../dot11/dot11_mgmt.h"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
|
||||||
#if !defined(TINS_DOT11_DOT11_H) && defined(HAVE_DOT11)
|
#if !defined(TINS_DOT11_DOT11_H) && defined(TINS_HAVE_DOT11)
|
||||||
#define TINS_DOT11_DOT11_H
|
#define TINS_DOT11_DOT11_H
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
|
||||||
#if !defined(TINS_DOT11_DOT11_BEACON_H) && defined(HAVE_DOT11)
|
#if !defined(TINS_DOT11_DOT11_BEACON_H) && defined(TINS_HAVE_DOT11)
|
||||||
#define TINS_DOT11_DOT11_BEACON_H
|
#define TINS_DOT11_DOT11_BEACON_H
|
||||||
|
|
||||||
#include "../dot11/dot11_mgmt.h"
|
#include "../dot11/dot11_mgmt.h"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
|
||||||
#if !defined(TINS_DOT11_DOT11_CONTROL_H) && defined(HAVE_DOT11)
|
#if !defined(TINS_DOT11_DOT11_CONTROL_H) && defined(TINS_HAVE_DOT11)
|
||||||
|
|
||||||
#define TINS_DOT11_DOT11_CONTROL_H
|
#define TINS_DOT11_DOT11_CONTROL_H
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
|
||||||
#if !defined(TINS_DOT11_DOT11_DATA_H) && defined(HAVE_DOT11)
|
#if !defined(TINS_DOT11_DOT11_DATA_H) && defined(TINS_HAVE_DOT11)
|
||||||
#define TINS_DOT11_DOT11_DATA_H
|
#define TINS_DOT11_DOT11_DATA_H
|
||||||
|
|
||||||
#include "../dot11/dot11_base.h"
|
#include "../dot11/dot11_base.h"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
|
||||||
#if !defined(TINS_DOT11_DOT11_MGMT_H) && defined(HAVE_DOT11)
|
#if !defined(TINS_DOT11_DOT11_MGMT_H) && defined(TINS_HAVE_DOT11)
|
||||||
|
|
||||||
#define TINS_DOT11_DOT11_MGMT_H
|
#define TINS_DOT11_DOT11_MGMT_H
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
|
||||||
#if !defined(TINS_DOT11_DOT11_PROBE_H) && defined(HAVE_DOT11)
|
#if !defined(TINS_DOT11_DOT11_PROBE_H) && defined(TINS_HAVE_DOT11)
|
||||||
|
|
||||||
#define TINS_DOT11_DOT11_PROBE_H
|
#define TINS_DOT11_DOT11_PROBE_H
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
static const PDU::PDUType pdu_flag = PDU::DOT1Q;
|
static const PDU::PDUType pdu_flag = PDU::DOT1Q;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
*/
|
*/
|
||||||
@@ -73,7 +81,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. \sa PDU::header_size
|
* This method overrides PDU::header_size. \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
|
|
||||||
@@ -192,7 +200,7 @@ private:
|
|||||||
void write_serialization(uint8_t* buffer, uint32_t total_sz, const PDU* parent);
|
void write_serialization(uint8_t* buffer, uint32_t total_sz, const PDU* parent);
|
||||||
|
|
||||||
TINS_BEGIN_PACK
|
TINS_BEGIN_PACK
|
||||||
struct dot1q_hdr {
|
struct dot1q_header {
|
||||||
#if TINS_IS_BIG_ENDIAN
|
#if TINS_IS_BIG_ENDIAN
|
||||||
uint16_t priority:3,
|
uint16_t priority:3,
|
||||||
cfi:1,
|
cfi:1,
|
||||||
@@ -207,9 +215,9 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
} TINS_END_PACK;
|
} TINS_END_PACK;
|
||||||
|
|
||||||
static uint16_t get_id(const dot1q_hdr* hdr);
|
static uint16_t get_id(const dot1q_header* hdr);
|
||||||
|
|
||||||
dot1q_hdr header_;
|
dot1q_header header_;
|
||||||
bool append_padding_;
|
bool append_padding_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
static const address_type BROADCAST;
|
static const address_type BROADCAST;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 Constructor for creating an Dot3 PDU
|
* \brief Constructor for creating an Dot3 PDU
|
||||||
*
|
*
|
||||||
@@ -71,7 +79,7 @@ public:
|
|||||||
* \param child The PDU which will be set as the inner PDU.
|
* \param child The PDU which will be set as the inner PDU.
|
||||||
*/
|
*/
|
||||||
Dot3(const address_type& dst_hw_addr = address_type(),
|
Dot3(const address_type& dst_hw_addr = address_type(),
|
||||||
const address_type& src_hw_addr = address_type());
|
const address_type& src_hw_addr = address_type());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Constructs a Dot3 object from a buffer and adds a
|
* \brief Constructs a Dot3 object from a buffer and adds a
|
||||||
@@ -145,12 +153,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
|
|
||||||
#if !defined(_WIN32) || defined(HAVE_PACKET_SENDER_PCAP_SENDPACKET)
|
#if !defined(_WIN32) || defined(TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET)
|
||||||
/**
|
/**
|
||||||
* \sa PDU::send()
|
* \sa PDU::send()
|
||||||
*/
|
*/
|
||||||
void send(PacketSender& sender, const NetworkInterface& iface);
|
void send(PacketSender& sender, const NetworkInterface& iface);
|
||||||
#endif // !_WIN32 || HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
#endif // !_WIN32 || TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Check whether ptr points to a valid response for this PDU.
|
* \brief Check whether ptr points to a valid response for this PDU.
|
||||||
|
|||||||
@@ -69,6 +69,14 @@ public:
|
|||||||
EAPOL_WPA = 254
|
EAPOL_WPA = 254
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 Static method to instantiate the correct EAPOL subclass
|
* \brief Static method to instantiate the correct EAPOL subclass
|
||||||
* based on a raw buffer.
|
* based on a raw buffer.
|
||||||
@@ -338,7 +346,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. This size includes the
|
* This method overrides PDU::header_size. This size includes the
|
||||||
* payload and options size.
|
* payload and options size.
|
||||||
*
|
*
|
||||||
* \sa PDU::header_size
|
* \sa PDU::header_size
|
||||||
@@ -603,7 +611,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. This size includes the
|
* This method overrides PDU::header_size. This size includes the
|
||||||
* payload and options size.
|
* payload and options size.
|
||||||
*
|
*
|
||||||
* \sa PDU::header_size
|
* \sa PDU::header_size
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#define TINS_IS_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN)
|
#define TINS_IS_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN)
|
||||||
#define TINS_IS_BIG_ENDIAN (_BYTE_ORDER == _BIG_ENDIAN)
|
#define TINS_IS_BIG_ENDIAN (_BYTE_ORDER == _BIG_ENDIAN)
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
|
#include <cstdlib>
|
||||||
// Assume windows == little endian. fixme later
|
// Assume windows == little endian. fixme later
|
||||||
#define TINS_IS_LITTLE_ENDIAN 1
|
#define TINS_IS_LITTLE_ENDIAN 1
|
||||||
#define TINS_IS_BIG_ENDIAN 0
|
#define TINS_IS_BIG_ENDIAN 0
|
||||||
@@ -51,6 +52,19 @@
|
|||||||
#define TINS_IS_BIG_ENDIAN (__BYTE_ORDER == __BIG_ENDIAN)
|
#define TINS_IS_BIG_ENDIAN (__BYTE_ORDER == __BIG_ENDIAN)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Define macros to swap bytes using compiler intrinsics when possible
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define TINS_BYTE_SWAP_16(data) _byteswap_ushort(data)
|
||||||
|
#define TINS_BYTE_SWAP_32(data) _byteswap_ulong(data)
|
||||||
|
#define TINS_BYTE_SWAP_64(data) _byteswap_uint64(data)
|
||||||
|
#elif defined(TINS_HAVE_GCC_BUILTIN_SWAP)
|
||||||
|
#define TINS_BYTE_SWAP_16(data) __builtin_bswap16(data)
|
||||||
|
#define TINS_BYTE_SWAP_32(data) __builtin_bswap32(data)
|
||||||
|
#define TINS_BYTE_SWAP_64(data) __builtin_bswap64(data)
|
||||||
|
#else
|
||||||
|
#define TINS_NO_BYTE_SWAP_INTRINSICS
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Tins {
|
namespace Tins {
|
||||||
namespace Endian {
|
namespace Endian {
|
||||||
|
|
||||||
@@ -70,7 +84,11 @@ inline uint8_t do_change_endian(uint8_t data) {
|
|||||||
* \param data The data to convert.
|
* \param data The data to convert.
|
||||||
*/
|
*/
|
||||||
inline uint16_t do_change_endian(uint16_t data) {
|
inline uint16_t do_change_endian(uint16_t data) {
|
||||||
return ((data & 0xff00) >> 8) | ((data & 0x00ff) << 8);
|
#ifdef TINS_NO_BYTE_SWAP_INTRINSICS
|
||||||
|
return ((data & 0xff00) >> 8) | ((data & 0x00ff) << 8);
|
||||||
|
#else
|
||||||
|
return TINS_BYTE_SWAP_16(data);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,8 +97,12 @@ inline uint16_t do_change_endian(uint16_t data) {
|
|||||||
* \param data The data to convert.
|
* \param data The data to convert.
|
||||||
*/
|
*/
|
||||||
inline uint32_t do_change_endian(uint32_t data) {
|
inline uint32_t do_change_endian(uint32_t data) {
|
||||||
return (((data & 0xff000000) >> 24) | ((data & 0x00ff0000) >> 8) |
|
#ifdef TINS_NO_BYTE_SWAP_INTRINSICS
|
||||||
((data & 0x0000ff00) << 8) | ((data & 0x000000ff) << 24));
|
return (((data & 0xff000000) >> 24) | ((data & 0x00ff0000) >> 8) |
|
||||||
|
((data & 0x0000ff00) << 8) | ((data & 0x000000ff) << 24));
|
||||||
|
#else
|
||||||
|
return TINS_BYTE_SWAP_32(data);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,8 +111,12 @@ inline uint32_t do_change_endian(uint32_t data) {
|
|||||||
* \param data The data to convert.
|
* \param data The data to convert.
|
||||||
*/
|
*/
|
||||||
inline uint64_t do_change_endian(uint64_t data) {
|
inline uint64_t do_change_endian(uint64_t data) {
|
||||||
return (((uint64_t)(do_change_endian((uint32_t)(data & 0xffffffff))) << 32) |
|
#ifdef TINS_NO_BYTE_SWAP_INTRINSICS
|
||||||
(do_change_endian(((uint32_t)(data >> 32)))));
|
return (((uint64_t)(do_change_endian((uint32_t)(data & 0xffffffff))) << 32) |
|
||||||
|
(do_change_endian(((uint32_t)(data >> 32)))));
|
||||||
|
#else
|
||||||
|
return TINS_BYTE_SWAP_64(data);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -60,6 +60,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
static const address_type BROADCAST;
|
static const address_type BROADCAST;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 ethernet II PDU.
|
* \brief Constructs an ethernet II PDU.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -200,6 +200,17 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Exception thrown when a feature has been disabled
|
||||||
|
* at compile time.
|
||||||
|
*/
|
||||||
|
class feature_disabled : public exception_base {
|
||||||
|
public:
|
||||||
|
const char* what() const throw() {
|
||||||
|
return "Feature disabled";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Exception thrown when a payload is too large to fit
|
* \brief Exception thrown when a payload is too large to fit
|
||||||
* into a PDUOption.
|
* into a PDUOption.
|
||||||
@@ -273,6 +284,36 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Exception thrown when a stream is not found
|
||||||
|
*/
|
||||||
|
class stream_not_found : public exception_base {
|
||||||
|
public:
|
||||||
|
const char* what() const throw() {
|
||||||
|
return "Stream not found";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Exception thrown when a required callback for an object is not set
|
||||||
|
*/
|
||||||
|
class callback_not_set : public exception_base {
|
||||||
|
public:
|
||||||
|
const char* what() const throw() {
|
||||||
|
return "Callback not set";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Exception thrown when an invalid packet is provided to some function
|
||||||
|
*/
|
||||||
|
class invalid_packet : public exception_base {
|
||||||
|
public:
|
||||||
|
const char* what() const throw() {
|
||||||
|
return "Invalid packet";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
namespace Crypto {
|
namespace Crypto {
|
||||||
namespace WPA2 {
|
namespace WPA2 {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#if !defined(TINS_HANDSHAKE_CAPTURER_H) && defined(HAVE_DOT11)
|
#if !defined(TINS_HANDSHAKE_CAPTURER_H) && defined(TINS_HAVE_DOT11)
|
||||||
#define TINS_HANDSHAKE_CAPTURER_H
|
#define TINS_HANDSHAKE_CAPTURER_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|||||||
@@ -92,6 +92,14 @@ public:
|
|||||||
ADDRESS_MASK_REPLY = 18
|
ADDRESS_MASK_REPLY = 18
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 Creates an instance of ICMP.
|
* \brief Creates an instance of ICMP.
|
||||||
*
|
*
|
||||||
@@ -379,7 +387,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. This size includes the
|
* This method overrides PDU::header_size. This size includes the
|
||||||
* payload and options size.
|
* payload and options size.
|
||||||
*
|
*
|
||||||
* \sa PDU::header_size
|
* \sa PDU::header_size
|
||||||
@@ -389,7 +397,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the trailer size.
|
* \brief Returns the trailer size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::trailer_size. This size will hold the extensions size
|
* This method overrides PDU::trailer_size. This size will hold the extensions size
|
||||||
*
|
*
|
||||||
* \sa PDU::header_size
|
* \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -80,14 +80,20 @@ public:
|
|||||||
NEIGHBOUR_SOLICIT = 135,
|
NEIGHBOUR_SOLICIT = 135,
|
||||||
NEIGHBOUR_ADVERT = 136,
|
NEIGHBOUR_ADVERT = 136,
|
||||||
REDIRECT = 137,
|
REDIRECT = 137,
|
||||||
ROUTER_RENUMBER = 137,
|
ROUTER_RENUMBER = 138,
|
||||||
NI_QUERY = 139,
|
NI_QUERY = 139,
|
||||||
NI_REPLY = 140,
|
NI_REPLY = 140,
|
||||||
MLD2_REPORT = 143,
|
MLD2_REPORT = 143,
|
||||||
DHAAD_REQUEST = 144,
|
DHAAD_REQUEST = 144,
|
||||||
DHAAD_REPLY = 145,
|
DHAAD_REPLY = 145,
|
||||||
MOBILE_PREFIX_SOL = 146,
|
MOBILE_PREFIX_SOLICIT = 146,
|
||||||
MOBILE_PREFIX_ADV = 147
|
MOBILE_PREFIX_ADVERT = 147,
|
||||||
|
CERT_PATH_SOLICIT = 148,
|
||||||
|
CERT_PATH_ADVERT = 149,
|
||||||
|
MULTICAST_ROUTER_ADVERT = 151,
|
||||||
|
MULTICAST_ROUTER_SOLICIT = 152,
|
||||||
|
MULTICAST_ROUTER_TERMINATE = 153,
|
||||||
|
RPL_CONTROL_MSG = 155
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1027,7 +1033,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. This size includes the
|
* This method overrides PDU::header_size. This size includes the
|
||||||
* payload and options size. \sa PDU::header_size
|
* payload and options size. \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
@@ -1035,7 +1041,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the trailer size.
|
* \brief Returns the trailer size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::trailer_size. This size will hold the extensions size
|
* This method overrides PDU::trailer_size. This size will hold the extensions size
|
||||||
*
|
*
|
||||||
* \sa PDU::header_size
|
* \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -128,7 +128,9 @@ PDU* pdu_from_dlt_flag(int flag, const uint8_t* buffer,
|
|||||||
PDU* pdu_from_flag(PDU::PDUType type, const uint8_t* buffer, uint32_t size);
|
PDU* pdu_from_flag(PDU::PDUType type, const uint8_t* buffer, uint32_t size);
|
||||||
|
|
||||||
Constants::Ethernet::e pdu_flag_to_ether_type(PDU::PDUType flag);
|
Constants::Ethernet::e pdu_flag_to_ether_type(PDU::PDUType flag);
|
||||||
|
PDU::PDUType ether_type_to_pdu_flag(Constants::Ethernet::e flag);
|
||||||
Constants::IP::e pdu_flag_to_ip_type(PDU::PDUType flag);
|
Constants::IP::e pdu_flag_to_ip_type(PDU::PDUType flag);
|
||||||
|
PDU::PDUType ip_type_to_pdu_flag(Constants::IP::e flag);
|
||||||
|
|
||||||
uint32_t get_padded_icmp_inner_pdu_size(const PDU* inner_pdu, uint32_t pad_alignment);
|
uint32_t get_padded_icmp_inner_pdu_size(const PDU* inner_pdu, uint32_t pad_alignment);
|
||||||
void try_parse_icmp_extensions(Memory::InputMemoryStream& stream,
|
void try_parse_icmp_extensions(Memory::InputMemoryStream& stream,
|
||||||
@@ -177,6 +179,9 @@ bool decrement(HWAddress<n>& addr) {
|
|||||||
return decrement_buffer(addr);
|
return decrement_buffer(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compares sequence numbers as defined by RFC 1982.
|
||||||
|
int seq_compare(uint32_t seq1, uint32_t seq2);
|
||||||
|
|
||||||
IPv4Address last_address_from_mask(IPv4Address addr, IPv4Address mask);
|
IPv4Address last_address_from_mask(IPv4Address addr, IPv4Address mask);
|
||||||
IPv6Address last_address_from_mask(IPv6Address addr, const IPv6Address& mask);
|
IPv6Address last_address_from_mask(IPv6Address addr, const IPv6Address& mask);
|
||||||
template<size_t n>
|
template<size_t n>
|
||||||
|
|||||||
@@ -246,6 +246,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
typedef std::list<option> options_type;
|
typedef std::list<option> options_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 Constructor for building the IP PDU.
|
* \brief Constructor for building the IP PDU.
|
||||||
*
|
*
|
||||||
@@ -280,7 +288,7 @@ public:
|
|||||||
* \return The number of dwords the header occupies in an uin8_t.
|
* \return The number of dwords the header occupies in an uin8_t.
|
||||||
*/
|
*/
|
||||||
small_uint<4> head_len() const {
|
small_uint<4> head_len() const {
|
||||||
return this->ip_.ihl;
|
return this->header_.ihl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -289,7 +297,7 @@ public:
|
|||||||
* \return The this IP PDU's type of service.
|
* \return The this IP PDU's type of service.
|
||||||
*/
|
*/
|
||||||
uint8_t tos() const {
|
uint8_t tos() const {
|
||||||
return ip_.tos;
|
return header_.tos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -298,7 +306,7 @@ public:
|
|||||||
* \return The total length of this IP PDU.
|
* \return The total length of this IP PDU.
|
||||||
*/
|
*/
|
||||||
uint16_t tot_len() const {
|
uint16_t tot_len() const {
|
||||||
return Endian::be_to_host(ip_.tot_len);
|
return Endian::be_to_host(header_.tot_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -307,7 +315,7 @@ public:
|
|||||||
* \return The id for this IP PDU.
|
* \return The id for this IP PDU.
|
||||||
*/
|
*/
|
||||||
uint16_t id() const {
|
uint16_t id() const {
|
||||||
return Endian::be_to_host(ip_.id);
|
return Endian::be_to_host(header_.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -321,7 +329,7 @@ public:
|
|||||||
* \sa IP::flags
|
* \sa IP::flags
|
||||||
*/
|
*/
|
||||||
TINS_DEPRECATED(uint16_t frag_off() const) {
|
TINS_DEPRECATED(uint16_t frag_off() const) {
|
||||||
return Endian::be_to_host(ip_.frag_off);
|
return Endian::be_to_host(header_.frag_off);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -333,7 +341,7 @@ public:
|
|||||||
* \return The fragment offset, measured in units of 8 byte blocks
|
* \return The fragment offset, measured in units of 8 byte blocks
|
||||||
*/
|
*/
|
||||||
small_uint<13> fragment_offset() const {
|
small_uint<13> fragment_offset() const {
|
||||||
return Endian::be_to_host(ip_.frag_off) & 0x1fff;
|
return Endian::be_to_host(header_.frag_off) & 0x1fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -342,7 +350,7 @@ public:
|
|||||||
* \return The IP flags field
|
* \return The IP flags field
|
||||||
*/
|
*/
|
||||||
Flags flags() const {
|
Flags flags() const {
|
||||||
return static_cast<Flags>(Endian::be_to_host(ip_.frag_off) >> 13);
|
return static_cast<Flags>(Endian::be_to_host(header_.frag_off) >> 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -351,7 +359,7 @@ public:
|
|||||||
* \return The time to live for this IP PDU.
|
* \return The time to live for this IP PDU.
|
||||||
*/
|
*/
|
||||||
uint8_t ttl() const {
|
uint8_t ttl() const {
|
||||||
return ip_.ttl;
|
return header_.ttl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -360,7 +368,7 @@ public:
|
|||||||
* \return The protocol for this IP PDU.
|
* \return The protocol for this IP PDU.
|
||||||
*/
|
*/
|
||||||
uint8_t protocol() const {
|
uint8_t protocol() const {
|
||||||
return ip_.protocol;
|
return header_.protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -369,7 +377,7 @@ public:
|
|||||||
* \return The checksum for this IP PDU.
|
* \return The checksum for this IP PDU.
|
||||||
*/
|
*/
|
||||||
uint16_t checksum() const {
|
uint16_t checksum() const {
|
||||||
return Endian::be_to_host(ip_.check);
|
return Endian::be_to_host(header_.check);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -378,7 +386,7 @@ public:
|
|||||||
* \return The source address for this IP PDU.
|
* \return The source address for this IP PDU.
|
||||||
*/
|
*/
|
||||||
address_type src_addr() const {
|
address_type src_addr() const {
|
||||||
return address_type(ip_.saddr);
|
return address_type(header_.saddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -386,7 +394,7 @@ public:
|
|||||||
* \return The destination address for this IP PDU.
|
* \return The destination address for this IP PDU.
|
||||||
*/
|
*/
|
||||||
address_type dst_addr() const {
|
address_type dst_addr() const {
|
||||||
return address_type(ip_.daddr);
|
return address_type(header_.daddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -394,7 +402,7 @@ public:
|
|||||||
* \return The version for this IP PDU.
|
* \return The version for this IP PDU.
|
||||||
*/
|
*/
|
||||||
small_uint<4> version() const {
|
small_uint<4> version() const {
|
||||||
return ip_.version;
|
return header_.version;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -675,7 +683,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. \sa PDU::header_size
|
* This method overrides PDU::header_size. \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
|
|
||||||
@@ -760,7 +768,7 @@ private:
|
|||||||
options_type::iterator search_option_iterator(option_identifier id);
|
options_type::iterator search_option_iterator(option_identifier id);
|
||||||
void update_padded_options_size();
|
void update_padded_options_size();
|
||||||
|
|
||||||
ip_header ip_;
|
ip_header header_;
|
||||||
uint16_t options_size_, padded_options_size_;
|
uint16_t options_size_, padded_options_size_;
|
||||||
options_type ip_options_;
|
options_type ip_options_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -93,32 +93,61 @@ private:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Reassembles fragmented IP packets.
|
* \brief Reassembles fragmented IP packets.
|
||||||
|
*
|
||||||
|
* This class is fairly simple: just feed packets into it using IPv4Reassembler::process.
|
||||||
|
* If the return value is IPv4Reassembler::FRAGMENTED, then the packet is fragmented
|
||||||
|
* and we haven't yet seen the missing fragments, hence we can't reassemble it.
|
||||||
|
* If the function returns either IPv4Reassembler::NOT_FRAGMENTED (meaning the
|
||||||
|
* packet wasn't fragmented) or IPv4Reassembler::REASSEMBLED (meaning the packet was
|
||||||
|
* fragmented but it's now reassembled), then you can process the packet normally.
|
||||||
|
*
|
||||||
|
* Simple example:
|
||||||
|
*
|
||||||
|
* \code
|
||||||
|
* IPv4Reassembler reassembler;
|
||||||
|
* Sniffer sniffer = ...;
|
||||||
|
* sniffer.sniff_loop([&](PDU& pdu) {
|
||||||
|
* // Process it in any case, unless it's fragmented (and can't be reassembled yet)
|
||||||
|
* if (reassembler.process(pdu) != IPv4Reassembler::FRAGMENTED) {
|
||||||
|
* // Now actually process the packet
|
||||||
|
* process_packet(pdu);
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
* \endcode
|
||||||
*/
|
*/
|
||||||
class TINS_API IPv4Reassembler {
|
class TINS_API IPv4Reassembler {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* The status of each processed packet.
|
* The status of each processed packet.
|
||||||
*/
|
*/
|
||||||
enum packet_status {
|
enum PacketStatus {
|
||||||
NOT_FRAGMENTED,
|
NOT_FRAGMENTED, ///< The given packet is not fragmented
|
||||||
FRAGMENTED,
|
FRAGMENTED, ///< The given packet is fragmented and can't be reassembled yet
|
||||||
REASSEMBLED
|
REASSEMBLED ///< The given packet was fragmented but is now reassembled
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TINS_DEPRECATED(typedef PacketStatus packet_status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type used to represent the overlapped segment
|
* The type used to represent the overlapped segment reassembly
|
||||||
* reassembly technique to be used.
|
* technique to be used.
|
||||||
*/
|
*/
|
||||||
enum overlapping_technique {
|
enum OverlappingTechnique {
|
||||||
NONE
|
NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
|
IPv4Reassembler();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an IPV4Reassembler.
|
* Constructs an IPV4Reassembler.
|
||||||
|
*
|
||||||
* \param technique The technique to be used for reassembling
|
* \param technique The technique to be used for reassembling
|
||||||
* overlapped fragments.
|
* overlapped fragments.
|
||||||
*/
|
*/
|
||||||
IPv4Reassembler(overlapping_technique technique = NONE);
|
IPv4Reassembler(OverlappingTechnique technique);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Processes a PDU and tries to reassemble it.
|
* \brief Processes a PDU and tries to reassemble it.
|
||||||
@@ -134,7 +163,7 @@ public:
|
|||||||
* fragmented or REASSEMBLED if the packet was fragmented
|
* fragmented or REASSEMBLED if the packet was fragmented
|
||||||
* but has now been reassembled.
|
* but has now been reassembled.
|
||||||
*/
|
*/
|
||||||
packet_status process(PDU& pdu);
|
PacketStatus process(PDU& pdu);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all of the packets and data stored.
|
* Removes all of the packets and data stored.
|
||||||
@@ -161,7 +190,7 @@ private:
|
|||||||
address_pair make_address_pair(IPv4Address addr1, IPv4Address addr2) const;
|
address_pair make_address_pair(IPv4Address addr1, IPv4Address addr2) const;
|
||||||
|
|
||||||
streams_type streams_;
|
streams_type streams_;
|
||||||
overlapping_technique technique_;
|
OverlappingTechnique technique_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -190,10 +219,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool operator()(PDU& pdu) {
|
bool operator()(PDU& pdu) {
|
||||||
// Forward it unless it's fragmented.
|
// Forward it unless it's fragmented.
|
||||||
if(reassembler_.process(pdu) != IPv4Reassembler::FRAGMENTED)
|
if (reassembler_.process(pdu) != IPv4Reassembler::FRAGMENTED) {
|
||||||
return functor_(pdu);
|
return functor_(pdu);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
IPv4Reassembler reassembler_;
|
IPv4Reassembler reassembler_;
|
||||||
@@ -210,7 +241,7 @@ template<typename Functor>
|
|||||||
IPv4ReassemblerProxy<Functor> make_ipv4_reassembler_proxy(Functor func) {
|
IPv4ReassemblerProxy<Functor> make_ipv4_reassembler_proxy(Functor func) {
|
||||||
return IPv4ReassemblerProxy<Functor>(func);
|
return IPv4ReassemblerProxy<Functor>(func);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
} // Tins
|
||||||
|
|
||||||
#endif // TINS_IP_REASSEMBLER_H
|
#endif // TINS_IP_REASSEMBLER_H
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. \sa PDU::header_size
|
* This method overrides PDU::header_size. \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
|
|
||||||
@@ -237,7 +237,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. \sa PDU::header_size
|
* This method overrides PDU::header_size. \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,14 @@ public:
|
|||||||
NO_NEXT_HEADER = 59
|
NO_NEXT_HEADER = 59
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 IPv6 object.
|
* \brief Constructs an IPv6 object.
|
||||||
*
|
*
|
||||||
@@ -251,7 +259,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. \sa PDU::header_size
|
* This method overrides PDU::header_size. \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace Tins {
|
|||||||
*/
|
*/
|
||||||
namespace Memory {
|
namespace Memory {
|
||||||
|
|
||||||
inline void read_data(const uint8_t* buffer, uint8_t* output_buffer, uint32_t size) {
|
inline void read_data(const uint8_t* buffer, uint8_t* output_buffer, size_t size) {
|
||||||
std::memcpy(output_buffer, buffer, size);
|
std::memcpy(output_buffer, buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ void read_value(const uint8_t* buffer, T& value) {
|
|||||||
std::memcpy(&value, buffer, sizeof(value));
|
std::memcpy(&value, buffer, sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void write_data(uint8_t* buffer, const uint8_t* ptr, uint32_t size) {
|
inline void write_data(uint8_t* buffer, const uint8_t* ptr, size_t size) {
|
||||||
std::memcpy(buffer, ptr, size);
|
std::memcpy(buffer, ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ void write_value(uint8_t* buffer, const T& value) {
|
|||||||
|
|
||||||
class InputMemoryStream {
|
class InputMemoryStream {
|
||||||
public:
|
public:
|
||||||
InputMemoryStream(const uint8_t* buffer, uint32_t total_sz)
|
InputMemoryStream(const uint8_t* buffer, size_t total_sz)
|
||||||
: buffer_(buffer), size_(total_sz) {
|
: buffer_(buffer), size_(total_sz) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ public:
|
|||||||
: buffer_(&data[0]), size_(data.size()) {
|
: buffer_(&data[0]), size_(data.size()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void skip(uint32_t size) {
|
void skip(size_t size) {
|
||||||
if (TINS_UNLIKELY(size > size_)) {
|
if (TINS_UNLIKELY(size > size_)) {
|
||||||
throw malformed_packet();
|
throw malformed_packet();
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ public:
|
|||||||
size_ -= size;
|
size_ -= size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool can_read(uint32_t byte_count) const {
|
bool can_read(size_t byte_count) const {
|
||||||
return TINS_LIKELY(size_ >= byte_count);
|
return TINS_LIKELY(size_ >= byte_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ public:
|
|||||||
skip(HWAddress<n>::address_size);
|
skip(HWAddress<n>::address_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void read(void* output_buffer, uint32_t output_buffer_size) {
|
void read(void* output_buffer, size_t output_buffer_size) {
|
||||||
if (!can_read(output_buffer_size)) {
|
if (!can_read(output_buffer_size)) {
|
||||||
throw malformed_packet();
|
throw malformed_packet();
|
||||||
}
|
}
|
||||||
@@ -154,11 +154,11 @@ public:
|
|||||||
return buffer_;
|
return buffer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t size() const {
|
size_t size() const {
|
||||||
return size_;
|
return size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void size(uint32_t new_size) {
|
void size(size_t new_size) {
|
||||||
size_ = new_size;
|
size_ = new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,12 +167,12 @@ public:
|
|||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
const uint8_t* buffer_;
|
const uint8_t* buffer_;
|
||||||
uint32_t size_;
|
size_t size_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OutputMemoryStream {
|
class OutputMemoryStream {
|
||||||
public:
|
public:
|
||||||
OutputMemoryStream(uint8_t* buffer, uint32_t total_sz)
|
OutputMemoryStream(uint8_t* buffer, size_t total_sz)
|
||||||
: buffer_(buffer), size_(total_sz) {
|
: buffer_(buffer), size_(total_sz) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ public:
|
|||||||
: buffer_(&buffer[0]), size_(buffer.size()) {
|
: buffer_(&buffer[0]), size_(buffer.size()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void skip(uint32_t size) {
|
void skip(size_t size) {
|
||||||
if (TINS_UNLIKELY(size > size_)) {
|
if (TINS_UNLIKELY(size > size_)) {
|
||||||
throw malformed_packet();
|
throw malformed_packet();
|
||||||
}
|
}
|
||||||
@@ -209,7 +209,7 @@ public:
|
|||||||
|
|
||||||
template <typename ForwardIterator>
|
template <typename ForwardIterator>
|
||||||
void write(ForwardIterator start, ForwardIterator end) {
|
void write(ForwardIterator start, ForwardIterator end) {
|
||||||
const uint32_t length = std::distance(start, end);
|
const size_t length = std::distance(start, end);
|
||||||
if (TINS_UNLIKELY(size_ < length)) {
|
if (TINS_UNLIKELY(size_ < length)) {
|
||||||
throw serialization_error();
|
throw serialization_error();
|
||||||
}
|
}
|
||||||
@@ -217,7 +217,7 @@ public:
|
|||||||
skip(length);
|
skip(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(const uint8_t* ptr, uint32_t length) {
|
void write(const uint8_t* ptr, size_t length) {
|
||||||
write(ptr, ptr + length);
|
write(ptr, ptr + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ public:
|
|||||||
write(address.begin(), address.end());
|
write(address.begin(), address.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill(uint32_t size, uint8_t value) {
|
void fill(size_t size, uint8_t value) {
|
||||||
if (TINS_UNLIKELY(size_ < size)) {
|
if (TINS_UNLIKELY(size_ < size)) {
|
||||||
throw serialization_error();
|
throw serialization_error();
|
||||||
}
|
}
|
||||||
@@ -246,12 +246,12 @@ public:
|
|||||||
return buffer_;
|
return buffer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t size() const {
|
size_t size() const {
|
||||||
return size_;
|
return size_;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
uint8_t* buffer_;
|
uint8_t* buffer_;
|
||||||
uint32_t size_;
|
size_t size_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -40,9 +40,10 @@ namespace Tins {
|
|||||||
class ICMPExtension;
|
class ICMPExtension;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* \class MPLS
|
||||||
* \brief Represents an MPLS PDU
|
* \brief Represents an MPLS PDU
|
||||||
*/
|
*/
|
||||||
class MPLS : public PDU {
|
class TINS_API MPLS : public PDU {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* \brief This PDU's flag.
|
* \brief This PDU's flag.
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "hw_address.h"
|
#include "hw_address.h"
|
||||||
#include "ip_address.h"
|
#include "ip_address.h"
|
||||||
|
#include "ipv6_address.h"
|
||||||
|
|
||||||
namespace Tins {
|
namespace Tins {
|
||||||
|
|
||||||
@@ -55,11 +56,20 @@ public:
|
|||||||
*/
|
*/
|
||||||
typedef HWAddress<6> address_type;
|
typedef HWAddress<6> address_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct IPv6Prefix {
|
||||||
|
IPv6Address address;
|
||||||
|
uint32_t prefix_length;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Struct that holds an interface's addresses.
|
* \brief Struct that holds an interface's addresses.
|
||||||
*/
|
*/
|
||||||
struct Info {
|
struct Info {
|
||||||
IPv4Address ip_addr, netmask, bcast_addr;
|
IPv4Address ip_addr, netmask, bcast_addr;
|
||||||
|
std::vector<IPv6Prefix> ipv6_addrs;
|
||||||
address_type hw_addr;
|
address_type hw_addr;
|
||||||
bool is_up;
|
bool is_up;
|
||||||
};
|
};
|
||||||
@@ -191,6 +201,31 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool is_up() const;
|
bool is_up() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the hardware address for this interface.
|
||||||
|
*/
|
||||||
|
address_type hw_address() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the IPv4 address for this interface.
|
||||||
|
*/
|
||||||
|
IPv4Address ipv4_address() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the IPv4 netmask for this interface.
|
||||||
|
*/
|
||||||
|
IPv4Address ipv4_mask() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the broadcast IPv4 address for this interface.
|
||||||
|
*/
|
||||||
|
IPv4Address ipv4_broadcast() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the IPv6 addresses for this interface.
|
||||||
|
*/
|
||||||
|
std::vector<IPv6Prefix> ipv6_addresses() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Compares this interface for equality.
|
* \brief Compares this interface for equality.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -148,11 +148,19 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Constructs a Packet from a PDU* and a Timestamp.
|
* \brief Constructs a Packet from a PDU* and a Timestamp.
|
||||||
*
|
*
|
||||||
* The PDU* is cloned using PDU::clone.
|
* The PDU is cloned using PDU::clone.
|
||||||
*/
|
*/
|
||||||
Packet(const PDU* apdu, const Timestamp& tstamp)
|
Packet(const PDU* apdu, const Timestamp& tstamp)
|
||||||
: pdu_(apdu->clone()), ts_(tstamp) { }
|
: pdu_(apdu->clone()), ts_(tstamp) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Constructs a Packet from a PDU& and a Timestamp.
|
||||||
|
*
|
||||||
|
* The PDU is cloned using PDU::clone.
|
||||||
|
*/
|
||||||
|
Packet(const PDU& apdu, const Timestamp& tstamp)
|
||||||
|
: pdu_(apdu.clone()), ts_(tstamp) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Constructs a Packet from a PDU* and a Timestamp.
|
* \brief Constructs a Packet from a PDU* and a Timestamp.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -37,9 +37,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#ifdef HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
#ifdef TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
||||||
#include <pcap.h>
|
#include <pcap.h>
|
||||||
#endif // HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
#endif // TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
||||||
#include "network_interface.h"
|
#include "network_interface.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "cxxstd.h"
|
#include "cxxstd.h"
|
||||||
@@ -184,14 +184,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
~PacketSender();
|
~PacketSender();
|
||||||
|
|
||||||
#if !defined(_WIN32) || defined(HAVE_PACKET_SENDER_PCAP_SENDPACKET)
|
#if !defined(_WIN32) || defined(TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET)
|
||||||
/**
|
/**
|
||||||
* \brief Opens a layer 2 socket.
|
* \brief Opens a layer 2 socket.
|
||||||
*
|
*
|
||||||
* If this operation fails, then a socket_open_error will be thrown.
|
* If this operation fails, then a socket_open_error will be thrown.
|
||||||
*/
|
*/
|
||||||
void open_l2_socket(const NetworkInterface& iface = NetworkInterface());
|
void open_l2_socket(const NetworkInterface& iface = NetworkInterface());
|
||||||
#endif // !_WIN32 || defined(HAVE_PACKET_SENDER_PCAP_SENDPACKET)
|
#endif // !_WIN32 || defined(TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Opens a layer 3 socket, using the corresponding protocol
|
* \brief Opens a layer 3 socket, using the corresponding protocol
|
||||||
@@ -324,7 +324,7 @@ public:
|
|||||||
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
#if !defined(_WIN32) || defined(HAVE_PACKET_SENDER_PCAP_SENDPACKET)
|
#if !defined(_WIN32) || defined(TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET)
|
||||||
/**
|
/**
|
||||||
* \brief Sends a level 2 PDU.
|
* \brief Sends a level 2 PDU.
|
||||||
*
|
*
|
||||||
@@ -342,7 +342,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
void send_l2(PDU& pdu, struct sockaddr* link_addr, uint32_t len_addr,
|
void send_l2(PDU& pdu, struct sockaddr* link_addr, uint32_t len_addr,
|
||||||
const NetworkInterface& iface = NetworkInterface());
|
const NetworkInterface& iface = NetworkInterface());
|
||||||
#endif // !_WIN32 || HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
#endif // !_WIN32 || TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Receives a layer 3 PDU response to a previously sent PDU.
|
* \brief Receives a layer 3 PDU response to a previously sent PDU.
|
||||||
@@ -384,18 +384,17 @@ private:
|
|||||||
PacketSender(const PacketSender&);
|
PacketSender(const PacketSender&);
|
||||||
PacketSender& operator=(const PacketSender&);
|
PacketSender& operator=(const PacketSender&);
|
||||||
int find_type(SocketType type);
|
int find_type(SocketType type);
|
||||||
int timeval_subtract (struct timeval* result, struct timeval* x, struct timeval* y);
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
bool ether_socket_initialized(const NetworkInterface& iface = NetworkInterface()) const;
|
bool ether_socket_initialized(const NetworkInterface& iface = NetworkInterface()) const;
|
||||||
int getether_socket_(const NetworkInterface& iface = NetworkInterface());
|
int get_ether_socket(const NetworkInterface& iface = NetworkInterface());
|
||||||
#endif
|
#endif
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void send(PDU& pdu, const NetworkInterface& iface) {
|
void send(PDU& pdu, const NetworkInterface& iface) {
|
||||||
static_cast<T&>(pdu).send(*this, iface);
|
static_cast<T&>(pdu).send(*this, iface);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
#ifdef TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
||||||
pcap_t* make_pcap_handle(const NetworkInterface& iface) const;
|
pcap_t* make_pcap_handle(const NetworkInterface& iface) const;
|
||||||
#endif // HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
#endif // TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
||||||
|
|
||||||
PDU* recv_match_loop(const std::vector<int>& sockets,
|
PDU* recv_match_loop(const std::vector<int>& sockets,
|
||||||
PDU& pdu,
|
PDU& pdu,
|
||||||
@@ -418,10 +417,10 @@ private:
|
|||||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||||
int buffer_size_;
|
int buffer_size_;
|
||||||
#endif // BSD
|
#endif // BSD
|
||||||
#ifdef HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
#ifdef TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
||||||
typedef std::map<NetworkInterface, pcap_t*> PcapHandleMap;
|
typedef std::map<NetworkInterface, pcap_t*> PcapHandleMap;
|
||||||
PcapHandleMap pcap_handles_;
|
PcapHandleMap pcap_handles_;
|
||||||
#endif // HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
#endif // TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Tins
|
} // Tins
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ public:
|
|||||||
IPSEC_ESP,
|
IPSEC_ESP,
|
||||||
PKTAP,
|
PKTAP,
|
||||||
MPLS,
|
MPLS,
|
||||||
|
UNKNOWN = 999,
|
||||||
USER_DEFINED_PDU = 1000
|
USER_DEFINED_PDU = 1000
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -188,6 +189,37 @@ public:
|
|||||||
*/
|
*/
|
||||||
static const endian_type endianness = BE;
|
static const endian_type endianness = BE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Type used to store a PDU header's data.
|
||||||
|
*/
|
||||||
|
struct metadata {
|
||||||
|
/**
|
||||||
|
* \brief Default constructor
|
||||||
|
*/
|
||||||
|
metadata();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Constructs an instance of metadata using the given values
|
||||||
|
|
||||||
|
*/
|
||||||
|
metadata(uint32_t header_size, PDUType current_type, PDUType next_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The total header size for the current protocol
|
||||||
|
*/
|
||||||
|
uint32_t header_size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current PDU type
|
||||||
|
*/
|
||||||
|
PDUType current_pdu_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The next PDU type
|
||||||
|
*/
|
||||||
|
PDUType next_pdu_type;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Default constructor.
|
* \brief Default constructor.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -368,7 +368,7 @@ public:
|
|||||||
}
|
}
|
||||||
real_size_ = rhs.real_size_;
|
real_size_ = rhs.real_size_;
|
||||||
if (real_size_ > small_buffer_size) {
|
if (real_size_ > small_buffer_size) {
|
||||||
payload_.big_buffer_ptr = nullptr;
|
payload_.big_buffer_ptr = 0;
|
||||||
std::swap(payload_.big_buffer_ptr, rhs.payload_.big_buffer_ptr);
|
std::swap(payload_.big_buffer_ptr, rhs.payload_.big_buffer_ptr);
|
||||||
rhs.real_size_ = 0;
|
rhs.real_size_ = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size.
|
* This method overrides PDU::header_size.
|
||||||
* \sa PDU::header_size
|
* \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. \sa PDU::header_size
|
* This method overrides PDU::header_size. \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
|
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. \sa PDU::header_size
|
* This method overrides PDU::header_size. \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#if !defined(TINS_RADIOTAP_H) && defined(HAVE_DOT11)
|
#if !defined(TINS_RADIOTAP_H) && defined(TINS_HAVE_DOT11)
|
||||||
#define TINS_RADIOTAP_H
|
#define TINS_RADIOTAP_H
|
||||||
|
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ public:
|
|||||||
*
|
*
|
||||||
* This returns the same as RawPDU::payload_size().
|
* This returns the same as RawPDU::payload_size().
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. \sa PDU::header_size
|
* This method overrides PDU::header_size. \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#if !defined(TINS_RSN_INFORMATION) && defined(HAVE_DOT11)
|
#if !defined(TINS_RSN_INFORMATION) && defined(TINS_HAVE_DOT11)
|
||||||
#define TINS_RSN_INFORMATION
|
#define TINS_RSN_INFORMATION
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. \sa PDU::header_size
|
* This method overrides PDU::header_size. \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public:
|
|||||||
* This constructor is available only in C++11.
|
* This constructor is available only in C++11.
|
||||||
*/
|
*/
|
||||||
BaseSniffer(BaseSniffer &&rhs) TINS_NOEXCEPT
|
BaseSniffer(BaseSniffer &&rhs) TINS_NOEXCEPT
|
||||||
: handle_(nullptr), mask_(), extract_raw_(false) {
|
: handle_(0), mask_(), extract_raw_(false) {
|
||||||
*this = std::move(rhs);
|
*this = std::move(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,7 +596,7 @@ protected:
|
|||||||
RFMON = 4,
|
RFMON = 4,
|
||||||
PACKET_FILTER = 8,
|
PACKET_FILTER = 8,
|
||||||
IMMEDIATE_MODE = 16,
|
IMMEDIATE_MODE = 16,
|
||||||
DIRECTION = 16
|
DIRECTION = 32
|
||||||
};
|
};
|
||||||
|
|
||||||
void configure_sniffer_pre_activation(Sniffer& sniffer) const;
|
void configure_sniffer_pre_activation(Sniffer& sniffer) const;
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. \sa PDU::header_size
|
* This method overrides PDU::header_size. \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
typedef std::vector<uint32_t> sack_type;
|
typedef std::vector<uint32_t> sack_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 TCP constructor.
|
* \brief TCP constructor.
|
||||||
*
|
*
|
||||||
@@ -503,7 +511,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. This size includes the
|
* This method overrides PDU::header_size. This size includes the
|
||||||
* payload and options size.
|
* payload and options size.
|
||||||
*
|
*
|
||||||
* \sa PDU::header_size
|
* \sa PDU::header_size
|
||||||
|
|||||||
6
include/tins/tcp_ip/CMakeLists.txt
Normal file
6
include/tins/tcp_ip/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
FILE(GLOB INCLUDE_FILES "*.h")
|
||||||
|
INSTALL(
|
||||||
|
FILES ${INCLUDE_FILES}
|
||||||
|
DESTINATION include/tins/tcp_ip
|
||||||
|
COMPONENT Headers
|
||||||
|
)
|
||||||
155
include/tins/tcp_ip/ack_tracker.h
Normal file
155
include/tins/tcp_ip/ack_tracker.h
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* 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_TCP_IP_ACK_TRACKER_H
|
||||||
|
#define TINS_TCP_IP_ACK_TRACKER_H
|
||||||
|
|
||||||
|
#include "../config.h"
|
||||||
|
|
||||||
|
#ifdef TINS_HAVE_ACK_TRACKER
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/icl/interval_set.hpp>
|
||||||
|
|
||||||
|
namespace Tins {
|
||||||
|
|
||||||
|
class PDU;
|
||||||
|
|
||||||
|
namespace TCPIP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Represents an acknowledged segment range
|
||||||
|
*
|
||||||
|
* The interval represented by this range is a closed interval [first, last].
|
||||||
|
*/
|
||||||
|
class AckedRange {
|
||||||
|
public:
|
||||||
|
typedef boost::icl::discrete_interval<uint32_t> interval_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Constructs an acked range
|
||||||
|
*
|
||||||
|
* \param first The first acked byte
|
||||||
|
* \param last The last acked byte (inclusive)
|
||||||
|
*/
|
||||||
|
AckedRange(uint32_t first, uint32_t last);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Gets the next acked interval in this range
|
||||||
|
*
|
||||||
|
* If has_next() == false, then this returns an empty interval
|
||||||
|
*/
|
||||||
|
interval_type next();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether there is still some non-consumed acked-interval in this
|
||||||
|
* range
|
||||||
|
*/
|
||||||
|
bool has_next() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the first index acked by this range
|
||||||
|
*/
|
||||||
|
uint32_t first() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the last index acked by this range
|
||||||
|
*/
|
||||||
|
uint32_t last() const;
|
||||||
|
private:
|
||||||
|
uint32_t first_;
|
||||||
|
uint32_t last_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Allows tracking acknowledged intervals in a TCP stream
|
||||||
|
*/
|
||||||
|
class AckTracker {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* The type used to store ACKed intervals
|
||||||
|
*/
|
||||||
|
typedef boost::icl::interval_set<uint32_t> interval_set_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
|
AckTracker();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Construct an instance using some attributes
|
||||||
|
*
|
||||||
|
* \param intial_ack The initial ACK number to use
|
||||||
|
* \param use_sack Indicate whether to use Selective ACKs to track ACK numbers
|
||||||
|
*/
|
||||||
|
AckTracker(uint32_t initial_ack, bool use_sack = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Process a packet
|
||||||
|
*/
|
||||||
|
void process_packet(const PDU& packet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Indicates whether Selective ACKs should be processed
|
||||||
|
*/
|
||||||
|
void use_sack();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the current ACK number in this tracker
|
||||||
|
*/
|
||||||
|
uint32_t ack_number() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves all acked intervals by Selective ACKs
|
||||||
|
*/
|
||||||
|
const interval_set_type& acked_intervals() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Indicates whether the given segment has been already ACKed
|
||||||
|
*
|
||||||
|
* \param sequence_number The segment's sequence number
|
||||||
|
* \param length The segment's length
|
||||||
|
*/
|
||||||
|
bool is_segment_acked(uint32_t sequence_number, uint32_t length) const;
|
||||||
|
private:
|
||||||
|
void process_sack(const std::vector<uint32_t>& sack);
|
||||||
|
void cleanup_sacked_intervals(uint32_t old_ack, uint32_t new_ack);
|
||||||
|
|
||||||
|
interval_set_type acked_intervals_;
|
||||||
|
uint32_t ack_number_;
|
||||||
|
bool use_sack_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // TCPIP
|
||||||
|
} // Tins
|
||||||
|
|
||||||
|
#endif // TINS_HAVE_ACK_TRACKER
|
||||||
|
|
||||||
|
#endif // TINS_TCP_IP_ACK_TRACKER_H
|
||||||
|
|
||||||
336
include/tins/tcp_ip/flow.h
Normal file
336
include/tins/tcp_ip/flow.h
Normal file
@@ -0,0 +1,336 @@
|
|||||||
|
/*
|
||||||
|
* 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_TCP_IP_FLOW_H
|
||||||
|
#define TINS_TCP_IP_FLOW_H
|
||||||
|
|
||||||
|
#include "../cxxstd.h"
|
||||||
|
|
||||||
|
// This classes use C++11 features
|
||||||
|
#if TINS_IS_CXX11
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <array>
|
||||||
|
#include <map>
|
||||||
|
#include <functional>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "../macros.h"
|
||||||
|
#include "ack_tracker.h"
|
||||||
|
#include "../hw_address.h"
|
||||||
|
|
||||||
|
namespace Tins {
|
||||||
|
|
||||||
|
class PDU;
|
||||||
|
class TCP;
|
||||||
|
class IPv4Address;
|
||||||
|
class IPv6Address;
|
||||||
|
|
||||||
|
namespace TCPIP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Represents an unidirectional TCP flow between 2 endpoints
|
||||||
|
*
|
||||||
|
* This class will keep the state for all the traffic sent by
|
||||||
|
* one of the peers in a TCP connection. This contains the sequence number,
|
||||||
|
* payload ready to be read and buffered payload, along with some other
|
||||||
|
* properties of the flow.
|
||||||
|
*
|
||||||
|
* A TCP stream (see class Stream) is made out of 2 Flows, so you should
|
||||||
|
* probably have a look at that class first.
|
||||||
|
*
|
||||||
|
* You shouldn't normally need to interact with this class. Stream already
|
||||||
|
* provides proxys to most of its Flow's attributes.
|
||||||
|
*/
|
||||||
|
class TINS_API Flow {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* \brief Enum that indicates the state of this flow.
|
||||||
|
*
|
||||||
|
* Note that although similar, this is not mapped to a TCP state-machine
|
||||||
|
* state. This is mostly used internally to know which packets the flow is
|
||||||
|
* expecting and to know when it's done sending data.
|
||||||
|
*/
|
||||||
|
enum State {
|
||||||
|
UNKNOWN,
|
||||||
|
SYN_SENT,
|
||||||
|
ESTABLISHED,
|
||||||
|
FIN_SENT,
|
||||||
|
RST_SENT
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type used to store the payload
|
||||||
|
*/
|
||||||
|
typedef std::vector<uint8_t> payload_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type used to store the buffered payload
|
||||||
|
*/
|
||||||
|
typedef std::map<uint32_t, payload_type> buffered_payload_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type used to store the callback called when new data is available
|
||||||
|
*/
|
||||||
|
typedef std::function<void(Flow&)> data_available_callback_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief The type used to store the callback called when data is buffered
|
||||||
|
*
|
||||||
|
* The arguments are the flow, the sequence number and payload that will
|
||||||
|
* be buffered.
|
||||||
|
*/
|
||||||
|
typedef std::function<void(Flow&,
|
||||||
|
uint32_t,
|
||||||
|
const payload_type&)> flow_packet_callback_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a Flow from an IPv4 address
|
||||||
|
*
|
||||||
|
* \param dst_address This flow's destination address
|
||||||
|
* \param dst_port This flow's destination port
|
||||||
|
* \param sequence_number The initial sequence number to be used
|
||||||
|
*/
|
||||||
|
Flow(const IPv4Address& dst_address, uint16_t dst_port,
|
||||||
|
uint32_t sequence_number);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a Flow from an IPv6 address
|
||||||
|
*
|
||||||
|
* \param dst_address This flow's destination address
|
||||||
|
* \param dst_port This flow's destination port
|
||||||
|
* \param sequence_number The initial sequence number to be used
|
||||||
|
*/
|
||||||
|
Flow(const IPv6Address& dst_address, uint16_t dst_port,
|
||||||
|
uint32_t sequence_number);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sets the callback that will be executed when data is readable
|
||||||
|
*
|
||||||
|
* Whenever this flow has readable data, this callback will be executed.
|
||||||
|
* By readable, this means that there's non-out-of-order data captured.
|
||||||
|
*
|
||||||
|
* \param callback The callback to be executed
|
||||||
|
*/
|
||||||
|
void data_callback(const data_available_callback_type& callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sets the callback that will be executed when out of order data arrives
|
||||||
|
*
|
||||||
|
* Whenever this flow receives out-of-order data, this callback will be
|
||||||
|
* executed.
|
||||||
|
*
|
||||||
|
* \param callback The callback to be executed
|
||||||
|
*/
|
||||||
|
void out_of_order_callback(const flow_packet_callback_type& callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Processes a packet.
|
||||||
|
*
|
||||||
|
* If this packet contains data and starts or overlaps with the current
|
||||||
|
* sequence number, then the data will be appended to this flow's payload
|
||||||
|
* and the data_callback will be executed.
|
||||||
|
*
|
||||||
|
* If this packet contains out-of-order data, it will be buffered and the
|
||||||
|
* buffering_callback will be executed.
|
||||||
|
*
|
||||||
|
* \param pdu The packet to be processed
|
||||||
|
* \sa Flow::data_callback
|
||||||
|
* \sa Flow::buffering_callback
|
||||||
|
*/
|
||||||
|
void process_packet(PDU& pdu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this flow uses IPv6 addresses
|
||||||
|
*/
|
||||||
|
bool is_v6() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Indicates whether this flow is finished
|
||||||
|
*
|
||||||
|
* A finished is considered to be finished if either it sent a
|
||||||
|
* packet with the FIN or RST flags on.
|
||||||
|
*/
|
||||||
|
bool is_finished() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Indicates whether a packet belongs to this flow
|
||||||
|
*
|
||||||
|
* Since Flow represents a unidirectional stream, this will only check
|
||||||
|
* the destination endpoint and not the source one.
|
||||||
|
*
|
||||||
|
* \param packet The packet to be checked
|
||||||
|
*/
|
||||||
|
bool packet_belongs(const PDU& packet) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the IPv4 destination address
|
||||||
|
*
|
||||||
|
* Note that it's only safe to execute this method if is_v6() == false
|
||||||
|
*/
|
||||||
|
IPv4Address dst_addr_v4() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the IPv6 destination address
|
||||||
|
*
|
||||||
|
* Note that it's only safe to execute this method if is_v6() == true
|
||||||
|
*/
|
||||||
|
IPv6Address dst_addr_v6() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves this flow's destination port
|
||||||
|
*/
|
||||||
|
uint16_t dport() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves this flow's payload (const)
|
||||||
|
*/
|
||||||
|
const payload_type& payload() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves this flow's destination port
|
||||||
|
*/
|
||||||
|
payload_type& payload();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves this flow's state
|
||||||
|
*/
|
||||||
|
State state() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves this flow's sequence number
|
||||||
|
*/
|
||||||
|
uint32_t sequence_number() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves this flow's buffered payload (const)
|
||||||
|
*/
|
||||||
|
const buffered_payload_type& buffered_payload() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves this flow's buffered payload
|
||||||
|
*/
|
||||||
|
buffered_payload_type& buffered_payload();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves this flow's total buffered bytes
|
||||||
|
*/
|
||||||
|
uint32_t total_buffered_bytes() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the state of this flow
|
||||||
|
*
|
||||||
|
* \param new_state The new state of this flow
|
||||||
|
*/
|
||||||
|
void state(State new_state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sets whether this flow should ignore data packets
|
||||||
|
*
|
||||||
|
* If the data packets are ignored then the flow will just be
|
||||||
|
* followed to keep track of its state.
|
||||||
|
*/
|
||||||
|
void ignore_data_packets();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Returns the MSS for this Flow.
|
||||||
|
*
|
||||||
|
* If the MSS option wasn't provided by the peer, -1 is returned
|
||||||
|
*/
|
||||||
|
int mss() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Indicates whether this Flow supports selective acknowledgements
|
||||||
|
*/
|
||||||
|
bool sack_permitted() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Enables tracking of ACK numbers
|
||||||
|
*
|
||||||
|
* This requires having the boost.icl library. If the library is not installed
|
||||||
|
* or ACK tracking was disabled when compiling the library, then this method
|
||||||
|
* will throw an exception.
|
||||||
|
*/
|
||||||
|
void enable_ack_tracking();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Indicates whether ACK number tracking is enabled
|
||||||
|
*/
|
||||||
|
bool ack_tracking_enabled() const;
|
||||||
|
|
||||||
|
#ifdef TINS_HAVE_ACK_TRACKER
|
||||||
|
/**
|
||||||
|
* Retrieves the ACK tracker for this Flow (const)
|
||||||
|
*/
|
||||||
|
const AckTracker& ack_tracker() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the ACK tracker for this Flow
|
||||||
|
*/
|
||||||
|
AckTracker& ack_tracker();
|
||||||
|
#endif // TINS_HAVE_ACK_TRACKER
|
||||||
|
private:
|
||||||
|
// Compress all flags into just one struct using bitfields
|
||||||
|
struct flags {
|
||||||
|
flags() : ignore_data_packets(0), sack_permitted(0), ack_tracking(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t is_v6:1,
|
||||||
|
ignore_data_packets:1,
|
||||||
|
sack_permitted:1,
|
||||||
|
ack_tracking:1;
|
||||||
|
};
|
||||||
|
|
||||||
|
void store_payload(uint32_t seq, payload_type payload);
|
||||||
|
buffered_payload_type::iterator erase_iterator(buffered_payload_type::iterator iter);
|
||||||
|
void update_state(const TCP& tcp);
|
||||||
|
void initialize();
|
||||||
|
|
||||||
|
payload_type payload_;
|
||||||
|
buffered_payload_type buffered_payload_;
|
||||||
|
uint32_t seq_number_;
|
||||||
|
uint32_t total_buffered_bytes_;
|
||||||
|
std::array<uint8_t, 16> dest_address_;
|
||||||
|
uint16_t dest_port_;
|
||||||
|
data_available_callback_type on_data_callback_;
|
||||||
|
flow_packet_callback_type on_out_of_order_callback_;
|
||||||
|
State state_;
|
||||||
|
int mss_;
|
||||||
|
flags flags_;
|
||||||
|
#ifdef TINS_HAVE_ACK_TRACKER
|
||||||
|
AckTracker ack_tracker_;
|
||||||
|
#endif // TINS_HAVE_ACK_TRACKER
|
||||||
|
};
|
||||||
|
|
||||||
|
} // TCPIP
|
||||||
|
} // TINS
|
||||||
|
|
||||||
|
#endif // TINS_IS_CXX11
|
||||||
|
#endif // TINS_TCP_IP_FLOW_H
|
||||||
|
|
||||||
398
include/tins/tcp_ip/stream.h
Normal file
398
include/tins/tcp_ip/stream.h
Normal file
@@ -0,0 +1,398 @@
|
|||||||
|
/*
|
||||||
|
* 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_TCP_IP_STREAM_H
|
||||||
|
#define TINS_TCP_IP_STREAM_H
|
||||||
|
|
||||||
|
#include "../cxxstd.h"
|
||||||
|
|
||||||
|
// This classes use C++11 features
|
||||||
|
#if TINS_IS_CXX11
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <array>
|
||||||
|
#include <map>
|
||||||
|
#include <functional>
|
||||||
|
#include <chrono>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "../macros.h"
|
||||||
|
#include "../hw_address.h"
|
||||||
|
#include "flow.h"
|
||||||
|
|
||||||
|
namespace Tins {
|
||||||
|
|
||||||
|
class PDU;
|
||||||
|
class TCP;
|
||||||
|
class IPv4Address;
|
||||||
|
class IPv6Address;
|
||||||
|
|
||||||
|
namespace TCPIP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Represents a TCP stream
|
||||||
|
*
|
||||||
|
* A TCP stream is made out of 2 Flows, one in each direction, plus
|
||||||
|
* some other attributes and callbacks.
|
||||||
|
*
|
||||||
|
* This class works using callbacks. Whenever the stream is created, you should
|
||||||
|
* set at least the client/server callbacks so you are notified whenever the
|
||||||
|
* client/server has sent data. Note that setting these is not mandatory, so
|
||||||
|
* you can subscribe to just the callbacks you need.
|
||||||
|
*
|
||||||
|
* \sa Stream::auto_cleanup_payloads
|
||||||
|
*/
|
||||||
|
class TINS_API Stream {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* The type used to store payloads
|
||||||
|
*/
|
||||||
|
typedef Flow::payload_type payload_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type used to represent timestamps
|
||||||
|
*/
|
||||||
|
typedef std::chrono::microseconds timestamp_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type used for callbacks
|
||||||
|
*/
|
||||||
|
typedef std::function<void(Stream&)> stream_callback_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type used for packet-triggered callbacks
|
||||||
|
*
|
||||||
|
* /sa Flow::buffering_callback
|
||||||
|
*/
|
||||||
|
typedef std::function<void(Stream&,
|
||||||
|
uint32_t,
|
||||||
|
const payload_type&)> stream_packet_callback_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type used to store hardware addresses
|
||||||
|
*/
|
||||||
|
typedef HWAddress<6> hwaddress_type;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Constructs a TCP stream using the provided packet.
|
||||||
|
*
|
||||||
|
* \param initial_packet The first packet of the stream
|
||||||
|
* \param ts The first packet's timestamp
|
||||||
|
*/
|
||||||
|
Stream(PDU& initial_packet, const timestamp_type& ts = timestamp_type());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Processes this packet.
|
||||||
|
*
|
||||||
|
* This will forward the packet appropriately to the client
|
||||||
|
* or server flow.
|
||||||
|
*
|
||||||
|
* \param packet The packet to be processed
|
||||||
|
* \param ts The packet's timestamp
|
||||||
|
*/
|
||||||
|
void process_packet(PDU& packet, const timestamp_type& ts);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Processes this packet.
|
||||||
|
*
|
||||||
|
* This will forward the packet appropriately to the client
|
||||||
|
* or server flow.
|
||||||
|
*
|
||||||
|
* \param packet The packet to be processed
|
||||||
|
*/
|
||||||
|
void process_packet(PDU& packet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the client flow
|
||||||
|
*/
|
||||||
|
Flow& client_flow();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the client flow (const)
|
||||||
|
*/
|
||||||
|
const Flow& client_flow() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the server flow
|
||||||
|
*/
|
||||||
|
Flow& server_flow();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the server flow (const)
|
||||||
|
*/
|
||||||
|
const Flow& server_flow() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Indicates whether this stream is finished.
|
||||||
|
*
|
||||||
|
* This stream is finished if either peer sent a packet with
|
||||||
|
* the RST flag on, or both peers sent a FIN.
|
||||||
|
*/
|
||||||
|
bool is_finished() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this packet uses IPv6 addresses
|
||||||
|
*/
|
||||||
|
bool is_v6() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the client's IPv4 address
|
||||||
|
*
|
||||||
|
* Note that it's only valid to call this method if is_v6() == false
|
||||||
|
*/
|
||||||
|
IPv4Address client_addr_v4() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the client's IPv6 address
|
||||||
|
*
|
||||||
|
* Note that it's only valid to call this method if is_v6() == true
|
||||||
|
*/
|
||||||
|
IPv6Address client_addr_v6() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the client's hardware address.
|
||||||
|
*
|
||||||
|
* Note that this is not the actual hardware address of the client, but
|
||||||
|
* just the address seen from packets coming from it. If the client
|
||||||
|
* is on another network, then this will be the address of the last
|
||||||
|
* device (switch, route, etc) the packet went through.
|
||||||
|
*/
|
||||||
|
const hwaddress_type& client_hw_addr() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the server's hardware address.
|
||||||
|
*
|
||||||
|
* Note that this is not the actual hardware address of the server, but
|
||||||
|
* just the address seen from packets coming from it. If the server
|
||||||
|
* is on another network, then this will be the address of the last
|
||||||
|
* device (switch, route, etc) the packet went through.
|
||||||
|
*/
|
||||||
|
const hwaddress_type& server_hw_addr() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the server's IPv4 address
|
||||||
|
*
|
||||||
|
* Note that it's only valid to call this method if is_v6() == false
|
||||||
|
*/
|
||||||
|
IPv4Address server_addr_v4() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the server's IPv6 address
|
||||||
|
*
|
||||||
|
* Note that it's only valid to call this method if is_v6() == true
|
||||||
|
*/
|
||||||
|
IPv6Address server_addr_v6() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the client's port
|
||||||
|
*/
|
||||||
|
uint16_t client_port() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the server's port
|
||||||
|
*/
|
||||||
|
uint16_t server_port() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the client's payload (const)
|
||||||
|
*/
|
||||||
|
const payload_type& client_payload() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the client's payload
|
||||||
|
*/
|
||||||
|
payload_type& client_payload();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the server's payload (const)
|
||||||
|
*/
|
||||||
|
const payload_type& server_payload() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the server's payload
|
||||||
|
*/
|
||||||
|
payload_type& server_payload();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the creation time of this stream
|
||||||
|
*/
|
||||||
|
const timestamp_type& create_time() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the last seen time of this stream
|
||||||
|
*/
|
||||||
|
const timestamp_type& last_seen() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sets the callback to be executed when the stream is closed
|
||||||
|
*
|
||||||
|
* \param callback The callback to be set
|
||||||
|
*/
|
||||||
|
void stream_closed_callback(const stream_callback_type& callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sets the callback to be executed when there's client data
|
||||||
|
*
|
||||||
|
* \sa Flow::data_callback
|
||||||
|
* \param callback The callback to be set
|
||||||
|
*/
|
||||||
|
void client_data_callback(const stream_callback_type& callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sets the callback to be executed when there's server data
|
||||||
|
*
|
||||||
|
* \sa Flow::data_callback
|
||||||
|
* \param callback The callback to be set
|
||||||
|
*/
|
||||||
|
void server_data_callback(const stream_callback_type& callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sets the callback to be executed when there's new buffered
|
||||||
|
* client data
|
||||||
|
*
|
||||||
|
* \sa Flow::buffering_callback
|
||||||
|
* \param callback The callback to be set
|
||||||
|
*/
|
||||||
|
void client_out_of_order_callback(const stream_packet_callback_type& callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sets the callback to be executed when there's new buffered
|
||||||
|
* client data
|
||||||
|
*
|
||||||
|
* \sa Flow::buffering_callback
|
||||||
|
* \param callback The callback to be set
|
||||||
|
*/
|
||||||
|
void server_out_of_order_callback(const stream_packet_callback_type& callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Indicates that the data packets sent by the client should be
|
||||||
|
* ignored
|
||||||
|
*
|
||||||
|
* \sa Flow::ignore_data_packets
|
||||||
|
*/
|
||||||
|
void ignore_client_data();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Indicates that the data packets sent by the server should be
|
||||||
|
* ignored
|
||||||
|
*
|
||||||
|
* \sa Flow::ignore_data_packets
|
||||||
|
*/
|
||||||
|
void ignore_server_data();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sets the internal callbacks.
|
||||||
|
*
|
||||||
|
* This shouldn't normally need to be called except if you're constructing
|
||||||
|
* this object and then moving it around before persisting it somewhere.
|
||||||
|
*/
|
||||||
|
void setup_flows_callbacks();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Indicates whether each flow's payloads should be automatically
|
||||||
|
* erased.
|
||||||
|
*
|
||||||
|
* If this property is true, then whenever there's new data for a stream,
|
||||||
|
* the appropriate callback will be executed and then the payload will be
|
||||||
|
* erased.
|
||||||
|
*
|
||||||
|
* If this property is false, then the payload <b>will not</b> be erased
|
||||||
|
* and the user is responsible for clearing the payload vector.
|
||||||
|
*
|
||||||
|
* Setting this property to false is useful if it's desired to hold all
|
||||||
|
* of the data sent on the stream before processing it. Note that this
|
||||||
|
* can lead to the memory growing a lot.
|
||||||
|
*
|
||||||
|
* This property is true by default.
|
||||||
|
*
|
||||||
|
* \param value The value to be set for this property
|
||||||
|
*/
|
||||||
|
void auto_cleanup_payloads(bool value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Indicates whether the client flow's payloads should be
|
||||||
|
* automatically erased.
|
||||||
|
*
|
||||||
|
* \sa auto_cleanup_payloads
|
||||||
|
*/
|
||||||
|
void auto_cleanup_client_data(bool value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Indicates whether the server flow's payloads should be
|
||||||
|
* automatically erased.
|
||||||
|
*
|
||||||
|
* \sa auto_cleanup_payloads
|
||||||
|
*/
|
||||||
|
void auto_cleanup_server_data(bool value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables tracking of acknowledged segments
|
||||||
|
*
|
||||||
|
* \sa Flow::enable_ack_tracking
|
||||||
|
*/
|
||||||
|
void enable_ack_tracking();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Indicates whether ACK number tracking is enabled for this stream
|
||||||
|
*/
|
||||||
|
bool ack_tracking_enabled() const;
|
||||||
|
private:
|
||||||
|
static Flow extract_client_flow(const PDU& packet);
|
||||||
|
static Flow extract_server_flow(const PDU& packet);
|
||||||
|
|
||||||
|
void on_client_flow_data(const Flow& flow);
|
||||||
|
void on_server_flow_data(const Flow& flow);
|
||||||
|
void on_client_out_of_order(const Flow& flow,
|
||||||
|
uint32_t seq,
|
||||||
|
const payload_type& payload);
|
||||||
|
void on_server_out_of_order(const Flow& flow,
|
||||||
|
uint32_t seq,
|
||||||
|
const payload_type& payload);
|
||||||
|
|
||||||
|
Flow client_flow_;
|
||||||
|
Flow server_flow_;
|
||||||
|
stream_callback_type on_stream_closed_;
|
||||||
|
stream_callback_type on_client_data_callback_;
|
||||||
|
stream_callback_type on_server_data_callback_;
|
||||||
|
stream_packet_callback_type on_client_out_of_order_callback_;
|
||||||
|
stream_packet_callback_type on_server_out_of_order_callback_;
|
||||||
|
hwaddress_type client_hw_addr_;
|
||||||
|
hwaddress_type server_hw_addr_;
|
||||||
|
timestamp_type create_time_;
|
||||||
|
timestamp_type last_seen_;
|
||||||
|
bool auto_cleanup_client_;
|
||||||
|
bool auto_cleanup_server_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // TCPIP
|
||||||
|
} // Tins
|
||||||
|
|
||||||
|
#endif // TINS_IS_CXX11
|
||||||
|
|
||||||
|
#endif // TINS_TCP_IP_STREAM_H
|
||||||
251
include/tins/tcp_ip/stream_follower.h
Normal file
251
include/tins/tcp_ip/stream_follower.h
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
/*
|
||||||
|
* 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_TCP_IP_STREAM_FOLLOWER_H
|
||||||
|
#define TINS_TCP_IP_STREAM_FOLLOWER_H
|
||||||
|
|
||||||
|
#include "../cxxstd.h"
|
||||||
|
|
||||||
|
// This classes use C++11 features
|
||||||
|
#if TINS_IS_CXX11
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
|
namespace Tins {
|
||||||
|
|
||||||
|
class PDU;
|
||||||
|
class TCP;
|
||||||
|
class IPv4Address;
|
||||||
|
class IPv6Address;
|
||||||
|
class Packet;
|
||||||
|
|
||||||
|
namespace TCPIP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Represents a class that follows TCP and reassembles streams
|
||||||
|
*
|
||||||
|
* This class processes packets and whenever it detects a new connection
|
||||||
|
* being open, it starts tracking it. This will follow all data sent by
|
||||||
|
* each peer and make it available to the user in a simple way.
|
||||||
|
*
|
||||||
|
* In order to use this class, just create an instance and set the
|
||||||
|
* new stream callback to some function that you want:
|
||||||
|
*
|
||||||
|
* \code
|
||||||
|
* void on_new_stream(TCPStream& stream) {
|
||||||
|
* // Do something with it.
|
||||||
|
* // This is the perfect time to set the stream's client/server
|
||||||
|
* // write callbacks so you are notified whenever there's new
|
||||||
|
* // data on the stream
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Create it
|
||||||
|
* StreamFollower follower;
|
||||||
|
* // Set the callback
|
||||||
|
* follower.new_stream_callback(&on_new_stream);
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
class TINS_API StreamFollower {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* \brief The type used for callbacks
|
||||||
|
*/
|
||||||
|
typedef Stream::stream_callback_type stream_callback_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum to indicate the reason why a stream was terminated
|
||||||
|
*/
|
||||||
|
enum TerminationReason {
|
||||||
|
TIMEOUT, ///< The stream was terminated due to a timeout
|
||||||
|
BUFFERED_DATA, ///< The stream was terminated because it had too much buffered data
|
||||||
|
SACKED_SEGMENTS ///< The stream was terminated because it had too many SACKed segments
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief The type used for stream termination callbacks
|
||||||
|
*
|
||||||
|
* \sa StreamFollower::stream_termination_callback
|
||||||
|
*/
|
||||||
|
typedef std::function<void(Stream&, TerminationReason)> stream_termination_callback_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Unique identifies a stream.
|
||||||
|
*
|
||||||
|
* This struct is used to track TCP streams. It keeps track of minimum and maximum
|
||||||
|
* addresses/ports in a stream to match packets coming from any of the 2 endpoints
|
||||||
|
* into the same object.
|
||||||
|
*/
|
||||||
|
struct stream_id {
|
||||||
|
/**
|
||||||
|
* The type used to store each endpoint's address
|
||||||
|
*/
|
||||||
|
typedef std::array<uint8_t, 16> address_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
|
stream_id();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a stream_id
|
||||||
|
*
|
||||||
|
* \param client_addr Client's address
|
||||||
|
* \param client_port Port's port
|
||||||
|
* \param server_addr Server's address
|
||||||
|
* \param server_port Server's port
|
||||||
|
*/
|
||||||
|
stream_id(const address_type& client_addr, uint16_t client_port,
|
||||||
|
const address_type& server_addr, uint16_t server_port);
|
||||||
|
|
||||||
|
bool operator<(const stream_id& rhs) const;
|
||||||
|
bool operator==(const stream_id& rhs) const;
|
||||||
|
|
||||||
|
address_type min_address;
|
||||||
|
address_type max_address;
|
||||||
|
uint16_t min_address_port;
|
||||||
|
uint16_t max_address_port;
|
||||||
|
|
||||||
|
static address_type serialize(IPv4Address address);
|
||||||
|
static address_type serialize(const IPv6Address& address);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
|
StreamFollower();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Processes a packet
|
||||||
|
*
|
||||||
|
* This will detect if this packet belongs to an existing stream
|
||||||
|
* and process it, or if it belongs to a new one, in which case it
|
||||||
|
* starts tracking it.
|
||||||
|
*
|
||||||
|
* \param packet The packet to be processed
|
||||||
|
*/
|
||||||
|
void process_packet(PDU& packet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Processes a packet
|
||||||
|
*
|
||||||
|
* This will detect if this packet belongs to an existing stream
|
||||||
|
* and process it, or if it belongs to a new one, in which case it
|
||||||
|
* starts tracking it.
|
||||||
|
*
|
||||||
|
* \param packet The packet to be processed
|
||||||
|
*/
|
||||||
|
void process_packet(Packet& packet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sets the callback to be executed when a new stream is captured.
|
||||||
|
*
|
||||||
|
* Whenever a new stream is captured, the provided callback will be
|
||||||
|
* executed.
|
||||||
|
*
|
||||||
|
* \param callback The callback to be set
|
||||||
|
*/
|
||||||
|
void new_stream_callback(const stream_callback_type& callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sets the stream termination callback
|
||||||
|
*
|
||||||
|
* A stream is terminated when either:
|
||||||
|
*
|
||||||
|
* * It contains too much buffered data.
|
||||||
|
* * No packets have been seen for some time interval.
|
||||||
|
*
|
||||||
|
* \param callback The callback to be executed on stream termination
|
||||||
|
* \sa StreamFollower::stream_keep_alive
|
||||||
|
*/
|
||||||
|
void stream_termination_callback(const stream_termination_callback_type& callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sets the maximum time a stream will be followed without capturing
|
||||||
|
* packets that belong to it.
|
||||||
|
*
|
||||||
|
* \param keep_alive The maximum time to keep unseen streams
|
||||||
|
*/
|
||||||
|
template <typename Rep, typename Period>
|
||||||
|
void stream_keep_alive(const std::chrono::duration<Rep, Period>& keep_alive) {
|
||||||
|
stream_keep_alive_ = keep_alive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the stream identified by the provided arguments.
|
||||||
|
*
|
||||||
|
* \param client_addr The client's address
|
||||||
|
* \param client_port The client's port
|
||||||
|
* \param server_addr The server's address
|
||||||
|
* \param server_addr The server's port
|
||||||
|
*/
|
||||||
|
Stream& find_stream(const IPv4Address& client_addr, uint16_t client_port,
|
||||||
|
const IPv4Address& server_addr, uint16_t server_port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the stream identified by the provided arguments.
|
||||||
|
*
|
||||||
|
* \param client_addr The client's address
|
||||||
|
* \param client_port The client's port
|
||||||
|
* \param server_addr The server's address
|
||||||
|
* \param server_addr The server's port
|
||||||
|
*/
|
||||||
|
Stream& find_stream(const IPv6Address& client_addr, uint16_t client_port,
|
||||||
|
const IPv6Address& server_addr, uint16_t server_port);
|
||||||
|
private:
|
||||||
|
typedef Stream::timestamp_type timestamp_type;
|
||||||
|
|
||||||
|
static const size_t DEFAULT_MAX_BUFFERED_CHUNKS;
|
||||||
|
static const size_t DEFAULT_MAX_SACKED_INTERVALS;
|
||||||
|
static const uint32_t DEFAULT_MAX_BUFFERED_BYTES;
|
||||||
|
static const timestamp_type DEFAULT_KEEP_ALIVE;
|
||||||
|
|
||||||
|
typedef std::map<stream_id, Stream> streams_type;
|
||||||
|
|
||||||
|
static stream_id make_stream_id(const PDU& packet);
|
||||||
|
Stream& find_stream(const stream_id& id);
|
||||||
|
void process_packet(PDU& packet, const timestamp_type& ts);
|
||||||
|
void cleanup_streams(const timestamp_type& now);
|
||||||
|
|
||||||
|
streams_type streams_;
|
||||||
|
stream_callback_type on_new_connection_;
|
||||||
|
stream_termination_callback_type on_stream_termination_;
|
||||||
|
size_t max_buffered_chunks_;
|
||||||
|
uint32_t max_buffered_bytes_;
|
||||||
|
timestamp_type last_cleanup_;
|
||||||
|
timestamp_type stream_keep_alive_;
|
||||||
|
bool attach_to_flows_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // TCPIP
|
||||||
|
} // Tins
|
||||||
|
|
||||||
|
#endif // TINS_IS_CXX11
|
||||||
|
|
||||||
|
#endif // TINS_TCP_IP_STREAM_FOLLOWER_H
|
||||||
@@ -60,13 +60,21 @@ namespace Tins {
|
|||||||
*
|
*
|
||||||
* \sa RawPDU
|
* \sa RawPDU
|
||||||
*/
|
*/
|
||||||
class UDP : public PDU {
|
class TINS_API UDP : public PDU {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* \brief This PDU's flag.
|
* \brief This PDU's flag.
|
||||||
*/
|
*/
|
||||||
static const PDU::PDUType pdu_flag = PDU::UDP;
|
static const PDU::PDUType pdu_flag = PDU::UDP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 UDP constructor.
|
* \brief UDP constructor.
|
||||||
*
|
*
|
||||||
@@ -158,7 +166,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. This size includes the
|
* This method overrides PDU::header_size. This size includes the
|
||||||
* payload and options size. \sa PDU::header_size
|
* payload and options size. \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ ADD_LIBRARY(
|
|||||||
snap.cpp
|
snap.cpp
|
||||||
sniffer.cpp
|
sniffer.cpp
|
||||||
tcp.cpp
|
tcp.cpp
|
||||||
|
tcp_ip/ack_tracker.cpp
|
||||||
|
tcp_ip/flow.cpp
|
||||||
|
tcp_ip/stream.cpp
|
||||||
|
tcp_ip/stream_follower.cpp
|
||||||
tcp_stream.cpp
|
tcp_stream.cpp
|
||||||
udp.cpp
|
udp.cpp
|
||||||
utils.cpp
|
utils.cpp
|
||||||
|
|||||||
@@ -43,6 +43,13 @@ using Tins::Memory::OutputMemoryStream;
|
|||||||
|
|
||||||
namespace Tins {
|
namespace Tins {
|
||||||
|
|
||||||
|
PDU::metadata ARP::extract_metadata(const uint8_t *buffer, uint32_t total_sz) {
|
||||||
|
if (TINS_UNLIKELY(total_sz < sizeof(arp_header))) {
|
||||||
|
throw malformed_packet();
|
||||||
|
}
|
||||||
|
return metadata(sizeof(arp_header), pdu_flag, PDU::UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
ARP::ARP(ipaddress_type target_ip,
|
ARP::ARP(ipaddress_type target_ip,
|
||||||
ipaddress_type sender_ip,
|
ipaddress_type sender_ip,
|
||||||
const hwaddress_type& target_hw,
|
const hwaddress_type& target_hw,
|
||||||
|
|||||||
@@ -29,13 +29,13 @@
|
|||||||
|
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
|
|
||||||
#ifdef HAVE_DOT11
|
#ifdef TINS_HAVE_DOT11
|
||||||
|
|
||||||
#ifdef HAVE_WPA2_DECRYPTION
|
#ifdef TINS_HAVE_WPA2_DECRYPTION
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
#include <openssl/aes.h>
|
#include <openssl/aes.h>
|
||||||
#endif // HAVE_WPA2_DECRYPTION
|
#endif // TINS_HAVE_WPA2_DECRYPTION
|
||||||
#include "dot11/dot11_data.h"
|
#include "dot11/dot11_data.h"
|
||||||
#include "dot11/dot11_beacon.h"
|
#include "dot11/dot11_beacon.h"
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
@@ -130,7 +130,7 @@ PDU* WEPDecrypter::decrypt(RawPDU& raw, const string& password) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_WPA2_DECRYPTION
|
#ifdef TINS_HAVE_WPA2_DECRYPTION
|
||||||
// WPA2Decrypter
|
// WPA2Decrypter
|
||||||
|
|
||||||
using WPA2::SessionKeys;
|
using WPA2::SessionKeys;
|
||||||
@@ -491,7 +491,7 @@ bool SessionKeys::uses_ccmp() const {
|
|||||||
// supplicant_data
|
// supplicant_data
|
||||||
|
|
||||||
SupplicantData::SupplicantData(const string& psk, const string& ssid)
|
SupplicantData::SupplicantData(const string& psk, const string& ssid)
|
||||||
: pmk_(SessionKeys::PMK_SIZE) {
|
: pmk_(SessionKeys::PMK_SIZE), ssid_(ssid) {
|
||||||
PKCS5_PBKDF2_HMAC_SHA1(
|
PKCS5_PBKDF2_HMAC_SHA1(
|
||||||
psk.c_str(),
|
psk.c_str(),
|
||||||
psk.size(),
|
psk.size(),
|
||||||
@@ -506,6 +506,11 @@ SupplicantData::SupplicantData(const string& psk, const string& ssid)
|
|||||||
const SupplicantData::pmk_type& SupplicantData::pmk() const {
|
const SupplicantData::pmk_type& SupplicantData::pmk() const {
|
||||||
return pmk_;
|
return pmk_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const string& SupplicantData::ssid() const {
|
||||||
|
return ssid_;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace WPA2
|
} // namespace WPA2
|
||||||
|
|
||||||
void WPA2Decrypter::add_ap_data(const string& psk, const string& ssid) {
|
void WPA2Decrypter::add_ap_data(const string& psk, const string& ssid) {
|
||||||
@@ -525,6 +530,12 @@ void WPA2Decrypter::add_access_point(const string& ssid, const address_type& add
|
|||||||
throw runtime_error("Supplicant data not registered");
|
throw runtime_error("Supplicant data not registered");
|
||||||
}
|
}
|
||||||
aps_.insert(make_pair(addr, it->second));
|
aps_.insert(make_pair(addr, it->second));
|
||||||
|
|
||||||
|
#ifdef TINS_HAVE_WPA2_CALLBACKS
|
||||||
|
if (ap_found_callback_) {
|
||||||
|
ap_found_callback_(ssid, addr);
|
||||||
|
}
|
||||||
|
#endif // TINS_HAVE_WPA2_CALLBACKS
|
||||||
}
|
}
|
||||||
|
|
||||||
void WPA2Decrypter::add_decryption_keys(const addr_pair& addresses,
|
void WPA2Decrypter::add_decryption_keys(const addr_pair& addresses,
|
||||||
@@ -540,6 +551,14 @@ void WPA2Decrypter::try_add_keys(const Dot11Data& dot11, const RSNHandshake& hs)
|
|||||||
try {
|
try {
|
||||||
SessionKeys session(hs, it->second.pmk());
|
SessionKeys session(hs, it->second.pmk());
|
||||||
keys_[addr_p] = session;
|
keys_[addr_p] = session;
|
||||||
|
#ifdef TINS_HAVE_WPA2_CALLBACKS
|
||||||
|
if (handshake_captured_callback_) {
|
||||||
|
address_type bssid = dot11.bssid_addr();
|
||||||
|
address_type client = (bssid == addr_p.first) ? addr_p.second
|
||||||
|
: addr_p.first;
|
||||||
|
handshake_captured_callback_(it->second.ssid(), bssid, client);
|
||||||
|
}
|
||||||
|
#endif // TINS_HAVE_WPA2_CALLBACKS
|
||||||
}
|
}
|
||||||
catch(WPA2::invalid_handshake&) {
|
catch(WPA2::invalid_handshake&) {
|
||||||
|
|
||||||
@@ -629,9 +648,21 @@ bool WPA2Decrypter::decrypt(PDU& pdu) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HAVE_WPA2_DECRYPTION
|
#ifdef TINS_HAVE_WPA2_CALLBACKS
|
||||||
|
|
||||||
|
void WPA2Decrypter::handshake_captured_callback(const handshake_captured_callback_type& callback) {
|
||||||
|
handshake_captured_callback_ = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WPA2Decrypter::ap_found_callback(const ap_found_callback_type& callback) {
|
||||||
|
ap_found_callback_ = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TINS_HAVE_WPA2_CALLBACKS
|
||||||
|
|
||||||
|
#endif // TINS_HAVE_WPA2_DECRYPTION
|
||||||
|
|
||||||
} // namespace Crypto
|
} // namespace Crypto
|
||||||
} // namespace Tins
|
} // namespace Tins
|
||||||
|
|
||||||
#endif // HAVE_DOT11
|
#endif // TINS_HAVE_DOT11
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user