From 816ed5945463f58eb0e2511e310bd62ce535ae33 Mon Sep 17 00:00:00 2001 From: aled-ua Date: Tue, 24 Dec 2024 07:58:19 +0000 Subject: [PATCH 01/36] Fix vuln OSV-2024-947 --- Packet++/src/SomeIpSdLayer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Packet++/src/SomeIpSdLayer.cpp b/Packet++/src/SomeIpSdLayer.cpp index d7f2c9de76..d62267b3e2 100644 --- a/Packet++/src/SomeIpSdLayer.cpp +++ b/Packet++/src/SomeIpSdLayer.cpp @@ -498,6 +498,10 @@ namespace pcpp while (remainingLen > 0) { + // Ensure there is enough remaining length for a new entry + if (remainingLen < sizeof(SomeIpSdEntry::someipsdhdrentry)) { + break; + } entry = new SomeIpSdEntry(this, offset); size_t entryLen = entry->getLength(); From 1606c6f94d37843231e79aff5efd269fcf02f6bd Mon Sep 17 00:00:00 2001 From: aled-ua Date: Sat, 4 Jan 2025 20:08:07 +0800 Subject: [PATCH 02/36] Fix format err --- Packet++/src/SomeIpSdLayer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Packet++/src/SomeIpSdLayer.cpp b/Packet++/src/SomeIpSdLayer.cpp index d62267b3e2..00433d56c3 100644 --- a/Packet++/src/SomeIpSdLayer.cpp +++ b/Packet++/src/SomeIpSdLayer.cpp @@ -498,10 +498,10 @@ namespace pcpp while (remainingLen > 0) { - // Ensure there is enough remaining length for a new entry - if (remainingLen < sizeof(SomeIpSdEntry::someipsdhdrentry)) { - break; - } + // Ensure there is enough remaining length for a new entry + if (remainingLen < sizeof(SomeIpSdEntry::someipsdhdrentry)) { + break; + } entry = new SomeIpSdEntry(this, offset); size_t entryLen = entry->getLength(); From 3fc55816706a4fa3f36983cabae16983a46c61e8 Mon Sep 17 00:00:00 2001 From: aled-ua Date: Fri, 10 Jan 2025 15:37:25 +0800 Subject: [PATCH 03/36] Fix format err --- Packet++/src/SomeIpSdLayer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Packet++/src/SomeIpSdLayer.cpp b/Packet++/src/SomeIpSdLayer.cpp index 00433d56c3..2556231111 100644 --- a/Packet++/src/SomeIpSdLayer.cpp +++ b/Packet++/src/SomeIpSdLayer.cpp @@ -499,7 +499,8 @@ namespace pcpp while (remainingLen > 0) { // Ensure there is enough remaining length for a new entry - if (remainingLen < sizeof(SomeIpSdEntry::someipsdhdrentry)) { + if (remainingLen < sizeof(SomeIpSdEntry::someipsdhdrentry)) + { break; } entry = new SomeIpSdEntry(this, offset); From 28f01b99a8316d3cd01bd899ef035d453223c739 Mon Sep 17 00:00:00 2001 From: aled-ua Date: Sat, 11 Jan 2025 23:24:45 +0800 Subject: [PATCH 04/36] Fix format err --- Packet++/src/SomeIpSdLayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packet++/src/SomeIpSdLayer.cpp b/Packet++/src/SomeIpSdLayer.cpp index 2556231111..6b64f6191d 100644 --- a/Packet++/src/SomeIpSdLayer.cpp +++ b/Packet++/src/SomeIpSdLayer.cpp @@ -499,7 +499,7 @@ namespace pcpp while (remainingLen > 0) { // Ensure there is enough remaining length for a new entry - if (remainingLen < sizeof(SomeIpSdEntry::someipsdhdrentry)) + if (remainingLen < sizeof(SomeIpSdEntry::someipsdhdrentry)) { break; } From c4c655aea7898fa1f111906ccd08816d006e6418 Mon Sep 17 00:00:00 2001 From: aled-ua Date: Thu, 16 Jan 2025 13:31:35 +0800 Subject: [PATCH 05/36] Fix format err --- Packet++/src/SomeIpSdLayer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Packet++/src/SomeIpSdLayer.cpp b/Packet++/src/SomeIpSdLayer.cpp index 6b64f6191d..51ad99b4f9 100644 --- a/Packet++/src/SomeIpSdLayer.cpp +++ b/Packet++/src/SomeIpSdLayer.cpp @@ -498,8 +498,8 @@ namespace pcpp while (remainingLen > 0) { - // Ensure there is enough remaining length for a new entry - if (remainingLen < sizeof(SomeIpSdEntry::someipsdhdrentry)) + // Ensure there is enough remaining length for a new entry + if (remainingLen < sizeof(SomeIpSdEntry::someipsdhdrentry)) { break; } From 6a49ae5a00b70bbc316b2d2d44205afe91d84021 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Thu, 23 Jan 2025 08:59:20 +0200 Subject: [PATCH 06/36] Refactored MacAddress to use std::array internally. (#1692) * Replaced MacAddress internal C-array with std::array. * Lint * Added header to all places where removing from MacAddress broke memset. * Moved include from cpp to header. * Added to PTF header as it uses memcmp in macros. --- Common++/header/MacAddress.h | 46 ++++++++++++--------- Packet++/header/StpLayer.h | 1 + Packet++/src/CotpLayer.cpp | 2 + Packet++/src/EthDot3Layer.cpp | 2 + Packet++/src/LLCLayer.cpp | 2 + Packet++/src/S7CommLayer.cpp | 1 + Packet++/src/TpktLayer.cpp | 1 + Packet++/src/VxlanLayer.cpp | 2 + Tests/PcppTestFramework/PcppTestFramework.h | 1 + 9 files changed, 38 insertions(+), 20 deletions(-) diff --git a/Common++/header/MacAddress.h b/Common++/header/MacAddress.h index e34c9d99a9..1cf5852e6b 100644 --- a/Common++/header/MacAddress.h +++ b/Common++/header/MacAddress.h @@ -5,8 +5,8 @@ #include #include #include -#include #include +#include /// @file @@ -28,11 +28,17 @@ namespace pcpp /// The byte array length should be 6 (as MAC address is 6-byte long), and the remaining bytes are ignored. /// If the byte array is invalid, the constructor throws an exception. /// @param[in] addr A pointer to the byte array containing 6 bytes representing the MAC address - explicit MacAddress(const uint8_t* addr) + explicit MacAddress(const uint8_t addr[6]) { - memcpy(m_Address, addr, sizeof(m_Address)); + std::copy(addr, addr + 6, m_Address.begin()); } + /// A constructor that creates an instance of the class out of a std::array. + /// The array length should be 6 (as MAC address is 6-byte long). + /// @param [in] addr A std::array containing 6 bytes representing the MAC address + explicit MacAddress(const std::array& addr) : m_Address(addr) + {} + /// A constructor that creates an instance of the class out of a std::string. /// If the string doesn't represent a valid MAC address, the constructor throws an exception. /// @param[in] addr the string representing the MAC address in format "00:00:00:00:00:00" @@ -54,14 +60,8 @@ namespace pcpp /// @param[in] sixthOctet Represent the sixth octet in the address MacAddress(uint8_t firstOctet, uint8_t secondOctet, uint8_t thirdOctet, uint8_t fourthOctet, uint8_t fifthOctet, uint8_t sixthOctet) - { - m_Address[0] = firstOctet; - m_Address[1] = secondOctet; - m_Address[2] = thirdOctet; - m_Address[3] = fourthOctet; - m_Address[4] = fifthOctet; - m_Address[5] = sixthOctet; - } + : m_Address{ firstOctet, secondOctet, thirdOctet, fourthOctet, fifthOctet, sixthOctet } + {} /// A constructor that creates an instance out of the initializer list. /// The byte list length should be 6 (as MAC address is 6-byte long). @@ -69,7 +69,7 @@ namespace pcpp /// @param[in] octets An initializer list containing the values of type uint8_t representing the MAC address MacAddress(std::initializer_list octets) { - if (octets.size() != sizeof(m_Address)) + if (octets.size() != m_Address.size()) { throw std::invalid_argument("Invalid initializer list size, should be 6"); } @@ -81,7 +81,7 @@ namespace pcpp /// @return True if addresses are equal, false otherwise bool operator==(const MacAddress& other) const { - return memcmp(m_Address, other.m_Address, sizeof(m_Address)) == 0; + return m_Address == other.m_Address; } /// Overload of the not-equal operator @@ -103,7 +103,7 @@ namespace pcpp throw std::invalid_argument("Invalid initializer list size, should be 6"); } - std::copy(octets.begin(), octets.end(), std::begin(m_Address)); + std::copy(octets.begin(), octets.end(), m_Address.begin()); return *this; } @@ -111,35 +111,41 @@ namespace pcpp /// @return The pointer to raw data const uint8_t* getRawData() const { - return m_Address; + return m_Address.data(); } /// Returns a std::string representation of the address /// @return A string representation of the address std::string toString() const; + /// @return A 6-byte integer representing the MAC address + std::array toByteArray() const + { + return m_Address; + } + /// Allocates a byte array of length 6 and copies address value into it. Array deallocation is user /// responsibility /// @param[in] arr A pointer to where array will be allocated void copyTo(uint8_t** arr) const { - *arr = new uint8_t[sizeof(m_Address)]; - memcpy(*arr, m_Address, sizeof(m_Address)); + *arr = new uint8_t[m_Address.size()]; + std::copy(m_Address.begin(), m_Address.end(), *arr); } /// Gets a pointer to an already allocated byte array and copies the address value to it. /// This method assumes array allocated size is at least 6 (the size of a MAC address) /// @param[in] arr A pointer to the array which address will be copied to - void copyTo(uint8_t* arr) const + void copyTo(uint8_t arr[6]) const { - memcpy(arr, m_Address, sizeof(m_Address)); + std::copy(m_Address.begin(), m_Address.end(), arr); } /// A static value representing a zero value of MAC address, meaning address of value "00:00:00:00:00:00" static MacAddress Zero; private: - uint8_t m_Address[6] = { 0 }; + std::array m_Address{}; }; inline std::ostream& operator<<(std::ostream& oss, const pcpp::MacAddress& macAddress) diff --git a/Packet++/header/StpLayer.h b/Packet++/header/StpLayer.h index f1b3cf75fd..d153bbb995 100644 --- a/Packet++/header/StpLayer.h +++ b/Packet++/header/StpLayer.h @@ -2,6 +2,7 @@ #include "Layer.h" #include "MacAddress.h" +#include /// @file diff --git a/Packet++/src/CotpLayer.cpp b/Packet++/src/CotpLayer.cpp index 2a218f547a..1183df5f13 100644 --- a/Packet++/src/CotpLayer.cpp +++ b/Packet++/src/CotpLayer.cpp @@ -2,6 +2,8 @@ #include "S7CommLayer.h" #include +#include + namespace pcpp { diff --git a/Packet++/src/EthDot3Layer.cpp b/Packet++/src/EthDot3Layer.cpp index 7a97897337..7091cd2eba 100644 --- a/Packet++/src/EthDot3Layer.cpp +++ b/Packet++/src/EthDot3Layer.cpp @@ -3,6 +3,8 @@ #include "PayloadLayer.h" #include "LLCLayer.h" +#include + namespace pcpp { diff --git a/Packet++/src/LLCLayer.cpp b/Packet++/src/LLCLayer.cpp index fe5c3c2fe5..5cfe5d84da 100644 --- a/Packet++/src/LLCLayer.cpp +++ b/Packet++/src/LLCLayer.cpp @@ -4,6 +4,8 @@ #include "PayloadLayer.h" #include "StpLayer.h" +#include + namespace pcpp { diff --git a/Packet++/src/S7CommLayer.cpp b/Packet++/src/S7CommLayer.cpp index 33358d23bb..0affaa8145 100644 --- a/Packet++/src/S7CommLayer.cpp +++ b/Packet++/src/S7CommLayer.cpp @@ -2,6 +2,7 @@ #include "S7CommLayer.h" #include +#include #include namespace pcpp diff --git a/Packet++/src/TpktLayer.cpp b/Packet++/src/TpktLayer.cpp index 2d003cd5e7..c3fe3a9ff7 100644 --- a/Packet++/src/TpktLayer.cpp +++ b/Packet++/src/TpktLayer.cpp @@ -2,6 +2,7 @@ #include "EndianPortable.h" #include "CotpLayer.h" #include "PayloadLayer.h" +#include #include namespace pcpp diff --git a/Packet++/src/VxlanLayer.cpp b/Packet++/src/VxlanLayer.cpp index ec1acc1657..6001b4197b 100644 --- a/Packet++/src/VxlanLayer.cpp +++ b/Packet++/src/VxlanLayer.cpp @@ -2,6 +2,8 @@ #include "EthLayer.h" #include "EndianPortable.h" +#include + namespace pcpp { diff --git a/Tests/PcppTestFramework/PcppTestFramework.h b/Tests/PcppTestFramework/PcppTestFramework.h index 9a1e60cad3..143e24332e 100644 --- a/Tests/PcppTestFramework/PcppTestFramework.h +++ b/Tests/PcppTestFramework/PcppTestFramework.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include "memplumber.h" #include "PcppTestFrameworkCommon.h" From 2d0fc5ae06d40766e2bbd55d3ef2bacc016b8317 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Thu, 23 Jan 2025 08:59:47 +0200 Subject: [PATCH 07/36] Fixed ostream operator<< declared outside the class namespace, preventing ADL. (#1696) --- Packet++/header/Layer.h | 11 +++---- Packet++/header/LdapLayer.h | 66 ++++++++++++++++++------------------- Packet++/header/Packet.h | 11 +++---- 3 files changed, 43 insertions(+), 45 deletions(-) diff --git a/Packet++/header/Layer.h b/Packet++/header/Layer.h index 828cb5c84f..f2e1755e14 100644 --- a/Packet++/header/Layer.h +++ b/Packet++/header/Layer.h @@ -232,10 +232,9 @@ namespace pcpp virtual bool shortenLayer(int offsetInLayer, size_t numOfBytesToShorten); }; + inline std::ostream& operator<<(std::ostream& os, const pcpp::Layer& layer) + { + os << layer.toString(); + return os; + } } // namespace pcpp - -inline std::ostream& operator<<(std::ostream& os, const pcpp::Layer& layer) -{ - os << layer.toString(); - return os; -} diff --git a/Packet++/header/LdapLayer.h b/Packet++/header/LdapLayer.h index 09e82c9ba1..9ab9b888dd 100644 --- a/Packet++/header/LdapLayer.h +++ b/Packet++/header/LdapLayer.h @@ -1320,47 +1320,47 @@ namespace pcpp : LdapResponseLayer(std::move(asn1Record), data, dataLen, prevLayer, packet) {} }; -} // namespace pcpp - -inline std::ostream& operator<<(std::ostream& os, const pcpp::LdapControl& control) -{ - os << "{" << control.controlType << ", " << control.controlValue << "}"; - return os; -} -inline std::ostream& operator<<(std::ostream& os, const pcpp::LdapAttribute& attr) -{ - os << "{" << attr.type << ", {"; + inline std::ostream& operator<<(std::ostream& os, const pcpp::LdapControl& control) + { + os << "{" << control.controlType << ", " << control.controlValue << "}"; + return os; + } - std::string separator; - for (const auto& value : attr.values) + inline std::ostream& operator<<(std::ostream& os, const pcpp::LdapAttribute& attr) { - os << separator << value; - if (separator.empty()) + os << "{" << attr.type << ", {"; + + std::string separator; + for (const auto& value : attr.values) { - separator = ", "; + os << separator << value; + if (separator.empty()) + { + separator = ", "; + } } - } - os << "}}"; - return os; -} - -inline std::ostream& operator<<(std::ostream& os, - const pcpp::LdapBindRequestLayer::SaslAuthentication& saslAuthentication) -{ - os << "{" << saslAuthentication.mechanism << ", {"; + os << "}}"; + return os; + } - std::string separator; - for (const auto& value : saslAuthentication.credentials) + inline std::ostream& operator<<(std::ostream& os, + const pcpp::LdapBindRequestLayer::SaslAuthentication& saslAuthentication) { - os << separator << "0x" << std::hex << static_cast(value) << std::dec; - if (separator.empty()) + os << "{" << saslAuthentication.mechanism << ", {"; + + std::string separator; + for (const auto& value : saslAuthentication.credentials) { - separator = ", "; + os << separator << "0x" << std::hex << static_cast(value) << std::dec; + if (separator.empty()) + { + separator = ", "; + } } - } - os << "}}"; - return os; -} + os << "}}"; + return os; + } +} // namespace pcpp diff --git a/Packet++/header/Packet.h b/Packet++/header/Packet.h index 4e7760f678..65324f6f26 100644 --- a/Packet++/header/Packet.h +++ b/Packet++/header/Packet.h @@ -445,10 +445,9 @@ namespace pcpp return dynamic_cast(curLayer); } + inline std::ostream& operator<<(std::ostream& os, const pcpp::Packet& packet) + { + os << packet.toString(); + return os; + } } // namespace pcpp - -inline std::ostream& operator<<(std::ostream& os, const pcpp::Packet& packet) -{ - os << packet.toString(); - return os; -} From 3af73830d5f04f756fe4b3afb499dad5a684ac8b Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Wed, 29 Jan 2025 09:55:00 +0200 Subject: [PATCH 08/36] Overhaul of the Logging Infrastructure (#1596) * Pulled ostream operators for IPAddress and MacAddress into the namespace to satisfy ADL requirements. * Refactor of Logger. - LogLevel is now a top level enum class. - Added a new log level Off to disable output from a specific module. - Logger::LogLevel is a deprecated alias to LogLevel. - Logger::Info, Debug, Error are deprecated aliases to LogLevel::... - Removed public "internal*" functions from Logger.Logger - Added LogSource struct to encapsulate source information. - Added shouldLog method to check if a log should be emitted for a given level and module. - Removed nonfunctional artifacts "m_LogStream" and "Logger::operator<<" - Added templated "log" functions that are friends to Logger. - Reworked PCPP_LOG macros to no longer utilize the now removed internal functions. - Added PCPP_LOG_INFO macro level. - Changed PCPP_LOG_ERROR to now check if the log should be emitted. - Fixed NetworkUtils log module name overlapping with NetworkUtils class. - Fixed missing enum value for PacketLogModuleSll2Layer. * Cleanup and fixes. * Added the new Off log level to the string conversion. * Fixed wrong variable name. * Added documentation to log source. * Lint. * Fixed docstring for LogSource. * Fixed extra / * Fixed explicit warning. * Moved log functions inside logger. * Revert "Moved log functions inside logger." This reverts commit be95ab890d242fdfa3d1ad89bfc720aac06b6cab. * Moved the log functions to the Logger class. - Added optional compile time elimination of log calls below set level. * Fixed typo in macro names. * Changed value param to const-ref. * Added "venv" and "./out" to ignored directories by codespell. * Reverted to previous optimizations to keep executable binary size low. - Renamed printLogMessage to emit and changed visibility to public. - Added new class LogContext to encapsulate a single emittable log message. - Added new methods createLogContext which is practically a rework of internalCreateLogStream but returns a LogContext. - Added optional use of object pooling optimization for reusing log contexts. (Enabled via preprocessor flag PCPP_LOG_USE_OBJECT_POOL) * Fixed warnings about unreferenced local variables if the compile time minimum log level set to too high severity.. * Removed useless variable. * Fixed friend class definition. * Fixed variable assignment. * Added method useContextPooling to control if the logger should use context pooling. - Removed preprocessor variable PCPP_LOG_USE_OBJECT_POOL. - Disabled context pooling for the unit tests as it interferes with the memory leak checker. * Fixed more warnings about unreferenced local variables if the compile time minimum log level set to too high severity.. * Addressed warnings and documentation. - Added documentation to new methods and classes. - Addressed explicit constructor warnings. - Moved disable of context pooling for unit tests to the main.cpp files of the respective tests. * Fixed include. * Fixed pointer dereference. * Fixed memory checker issues with logger. - Added 2 preallocated log contexts to the object pool. * Lint * Added mutex lock on the default log printer to support proper multi-threading and eliminate possibility of data races during log emission. * Fixed typos in documentation. * Changed level variable to private. * Changed LogPrinter definition to use the metaprogramming construct std::add_pointer. * Replaced C library includes with C++ equivalents. * Updated documentation format. * Added full namespace qualifier for marco code. * Changed C-array to std::array. * Added a mutex lock when writing or reading to last error string to prevent tearing. * Fixed object pool member variables. * Added mutators to change the max size of an object pool at runtime. * Added exception if pool preallocation size is larger then the maximum allowed pool size. * Added tests for ObjectPool. - Changed infinite pool size to be maximum value of size_t instead of 0, to fix an issue if max size is set to 0. - Added size getter to the pool. - Marked the pool mutex as mutable. * Lint * Added option to set the max pool size for the Logger context pool. * Disabled logger context pooling in the tests as it is detected as a false positive memory leak. * Lint * Lint * Updated logger tests. - Changed `pcpp::Logger::getInstance()` to use a cached `logger` variable. - Removed the need for fully qualified names in the logger test. - C-style casts to Cpp casts. * Added tests for `shouldLog`. * Moved iostream and iomanip to Logger.cpp as they are unnessesary in the header. * Lint * Added iostream to examples that depended on transitively including iostream from Logger.h * Added to examples that depended on transitively including from Logger.h * Moved ObjectPool to internal namespace. * Renamed ObjectPool to DynamicObjectPool. * Renamed preallocate ctor parameter to initialSize. * Removed unused logging functions. * Fixed missed include . --- .codespellrc | 2 +- Common++/CMakeLists.txt | 1 + Common++/header/IpAddress.h | 1 - Common++/header/Logger.h | 272 ++++++++++++++---- Common++/header/ObjectPool.h | 185 ++++++++++++ Common++/src/IpAddress.cpp | 2 + Common++/src/IpUtils.cpp | 2 + Common++/src/Logger.cpp | 75 +++-- Examples/KniPong/main.cpp | 1 + Examples/PfRingExample-FilterTraffic/main.cpp | 2 + Pcap++/src/NetworkUtils.cpp | 2 +- Pcap++/src/PcapLiveDevice.cpp | 1 + Pcap++/src/PcapLiveDeviceList.cpp | 1 + Pcap++/src/PcapRemoteDeviceList.cpp | 2 + Tests/Packet++Test/main.cpp | 3 +- Tests/Pcap++Test/CMakeLists.txt | 1 + Tests/Pcap++Test/TestDefinition.h | 3 + Tests/Pcap++Test/Tests/LoggerTests.cpp | 68 +++-- Tests/Pcap++Test/Tests/ObjectPoolTests.cpp | 79 +++++ Tests/Pcap++Test/main.cpp | 7 +- 20 files changed, 607 insertions(+), 103 deletions(-) create mode 100644 Common++/header/ObjectPool.h create mode 100644 Tests/Pcap++Test/Tests/ObjectPoolTests.cpp diff --git a/.codespellrc b/.codespellrc index c7019c766a..7506fd03df 100644 --- a/.codespellrc +++ b/.codespellrc @@ -1,4 +1,4 @@ [codespell] -skip = *.dat,typos-config.toml,.git,.venv,./ci,./Dist,./mk,./Tests/ExamplesTest/expected_output,./Tests/ExamplesTest/pcap_examples,./Tests/Packet++Test/PacketExamples,./Tests/Pcap++Test/PcapExamples,./3rdParty,./Examples/PcapSearch/dirent-for-Visual-Studio +skip = *.dat,typos-config.toml,.git,.venv,venv,./out,./ci,./Dist,./mk,./Tests/ExamplesTest/expected_output,./Tests/ExamplesTest/pcap_examples,./Tests/Packet++Test/PacketExamples,./Tests/Pcap++Test/PcapExamples,./3rdParty,./Examples/PcapSearch/dirent-for-Visual-Studio ignore-words = codespell-ignore-list.txt count = diff --git a/Common++/CMakeLists.txt b/Common++/CMakeLists.txt index 9170aea53e..8ef1ca1f79 100644 --- a/Common++/CMakeLists.txt +++ b/Common++/CMakeLists.txt @@ -22,6 +22,7 @@ set( header/Logger.h header/LRUList.h header/MacAddress.h + header/ObjectPool.h header/OUILookup.h header/PcapPlusPlusVersion.h header/PointerVector.h diff --git a/Common++/header/IpAddress.h b/Common++/header/IpAddress.h index 38936e8570..d93a341b70 100644 --- a/Common++/header/IpAddress.h +++ b/Common++/header/IpAddress.h @@ -876,5 +876,4 @@ namespace pcpp oss << network.toString(); return oss; } - } // namespace pcpp diff --git a/Common++/header/Logger.h b/Common++/header/Logger.h index 2b5ec3954f..df9ce372ee 100644 --- a/Common++/header/Logger.h +++ b/Common++/header/Logger.h @@ -1,10 +1,14 @@ #pragma once #include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include "DeprecationUtils.h" +#include "ObjectPool.h" #ifndef LOG_MODULE # define LOG_MODULE UndefinedLogModule @@ -17,35 +21,29 @@ # define PCAPPP_FILENAME __FILE__ #endif -#define PCPP_LOG(level, message) \ - do \ - { \ - std::ostringstream* sstream = pcpp::Logger::getInstance().internalCreateLogStream(); \ - (*sstream) << message; \ - pcpp::Logger::getInstance().internalPrintLogMessage(sstream, level, PCAPPP_FILENAME, __FUNCTION__, __LINE__); \ - } while (0) - -#define PCPP_LOG_DEBUG(message) \ - do \ - { \ - if (pcpp::Logger::getInstance().logsEnabled() && pcpp::Logger::getInstance().isDebugEnabled(LOG_MODULE)) \ - { \ - PCPP_LOG(pcpp::Logger::Debug, message); \ - } \ - } while (0) +/// @file -#define PCPP_LOG_ERROR(message) \ - do \ - { \ - PCPP_LOG(pcpp::Logger::Error, message); \ - } while (0) +// Compile time log levels. +// Allows for conditional removal of unwanted log calls at compile time. +#define PCPP_LOG_LEVEL_OFF 0 +#define PCPP_LOG_LEVEL_ERROR 1 +#define PCPP_LOG_LEVEL_INFO 2 +#define PCPP_LOG_LEVEL_DEBUG 3 -/// @file +// All log messages built via a PCPP_LOG_* macro below the PCPP_ACTIVE_LOG_LEVEL will be removed at compile time. +// Uses the PCPP_ACTIVE_LOG_LEVEL if it is defined, otherwise defaults to PCAP_LOG_LEVEL_DEBUG +#ifndef PCPP_ACTIVE_LOG_LEVEL +# define PCPP_ACTIVE_LOG_LEVEL PCPP_LOG_LEVEL_DEBUG +#endif // !PCPP_ACTIVE_LOG_LEVEL /// @namespace pcpp /// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { + /// Cross-platform and thread-safe version of strerror + /// @param errnum Value of errno + /// @return String representation of the error number + std::string getErrorString(int errnum); /// An enum representing all PcapPlusPlus modules enum LogModule : uint8_t @@ -75,6 +73,7 @@ namespace pcpp PacketLogModuleGreLayer, ///< GreLayer module (Packet++) PacketLogModuleSSLLayer, ///< SSLLayer module (Packet++) PacketLogModuleSllLayer, ///< SllLayer module (Packet++) + PacketLogModuleSll2Layer, ///< Sll2Layer module (Packet++) PacketLogModuleNflogLayer, ///< NflogLayer module (Packet++) PacketLogModuleDhcpLayer, ///< DhcpLayer module (Packet++) PacketLogModuleDhcpV6Layer, ///< DhcpV6Layer module (Packet++) @@ -109,14 +108,100 @@ namespace pcpp PcapLogModuleDpdkDevice, ///< DpdkDevice module (Pcap++) PcapLogModuleKniDevice, ///< KniDevice module (Pcap++) PcapLogModuleXdpDevice, ///< XdpDevice module (Pcap++) - NetworkUtils, ///< NetworkUtils module (Pcap++) + PcapLogModuleNetworkUtils, ///< Network Utils module (Pcap++) NumOfLogModules }; - /// Cross-platform and thread-safe version of strerror - /// @param errnum Value of errno - /// @return String representation of the error number - std::string getErrorString(int errnum); + /// @struct LogSource + /// Represents the source of a log message. + /// Contains information about the source file, function, line number, and the log module. + struct LogSource + { + /// Default constructor for LogSource. + constexpr LogSource() = default; + + /// Constructor for LogSource with only the log module. + /// @param logModule The log module. + explicit constexpr LogSource(LogModule logModule) : logModule(logModule) + {} + + /// Constructor for LogSource with all parameters. + /// @param logModule The log module. + /// @param file The source file. + /// @param function The source function. + /// @param line The line number. + constexpr LogSource(LogModule logModule, const char* file, const char* function, int line) + : file(file), function(function), line(line), logModule(logModule) + {} + + const char* file = nullptr; /**< The source file. */ + const char* function = nullptr; /**< The source function. */ + int line = 0; /**< The line number. */ + LogModule logModule = UndefinedLogModule; /**< The log module. */ + }; + + /// An enum representing the log level. Currently 4 log levels are supported: Off, Error, Info and Debug. Info is + /// the default log level + enum class LogLevel + { + Off = PCPP_LOG_LEVEL_OFF, ///< No log messages are emitted. + Error = PCPP_LOG_LEVEL_ERROR, ///< Error level logs are emitted. + Info = PCPP_LOG_LEVEL_INFO, ///< Info level logs and above are emitted. + Debug = PCPP_LOG_LEVEL_DEBUG ///< Debug level logs and above are emitted. + }; + + inline std::ostream& operator<<(std::ostream& s, LogLevel v) + { + return s << static_cast::type>(v); + } + + // Forward declaration + class Logger; + + namespace internal + { + /// @class LogContext + /// @brief A context encapsulating the details of a single log message to be passed to the Logger. + class LogContext + { + public: + friend class pcpp::Logger; + + /// @brief Creates a context with an empty message with Info level and no source. + LogContext() = default; + + /// @brief Creates a context with an empty message with the given level and source. + /// @param level The log level for this message. + /// @param source The log source. + explicit LogContext(LogLevel level, LogSource const& source = {}) : m_Source(source), m_Level(level) + {} + + /// @brief Initializes the context with an empty message and the given level and source. + /// @param level The log level for this message. + /// @param source The log source. + void init(LogLevel level, LogSource const& source) + { + m_Source = source; + m_Level = level; + m_Stream.clear(); + m_Stream.str({}); + } + + /// @brief Appends to the message. + /// @param value The value to append. + /// @return A reference to this context. + template inline LogContext& operator<<(T const& value) + { + m_Stream << value; + return *this; + } + + private: + std::ostringstream m_Stream; + LogSource m_Source; + LogLevel m_Level = LogLevel::Info; + }; + } // namespace internal /// @class Logger /// PcapPlusPlus logger manager. @@ -138,14 +223,14 @@ namespace pcpp class Logger { public: - /// An enum representing the log level. Currently 3 log levels are supported: Error, Info and Debug. Info is the - /// default log level - enum LogLevel : uint8_t - { - Error, ///< Error log level - Info, ///< Info log level - Debug ///< Debug log level - }; + // Deprecated, Use the LogLevel in the pcpp namespace instead. + using LogLevel = pcpp::LogLevel; + PCPP_DEPRECATED("Use the LogLevel in the pcpp namespace instead.") + static const LogLevel Error = LogLevel::Error; + PCPP_DEPRECATED("Use the LogLevel in the pcpp namespace instead.") + static const LogLevel Info = LogLevel::Info; + PCPP_DEPRECATED("Use the LogLevel in the pcpp namespace instead.") + static const LogLevel Debug = LogLevel::Debug; /// @typedef LogPrinter /// Log printer callback. Used for printing the logs in a custom way. @@ -154,7 +239,10 @@ namespace pcpp /// @param[in] file The source file in PcapPlusPlus code the log message is coming from /// @param[in] method The method in PcapPlusPlus code the log message is coming from /// @param[in] line The line in PcapPlusPlus code the log message is coming from - using LogPrinter = void (*)(LogLevel, const std::string&, const std::string&, const std::string&, const int); + /// @remarks The printer callback should support being called from multiple threads simultaneously. + using LogPrinter = + std::add_pointer::type; /// A static method for converting the log level enum to a string. /// @param[in] logLevel A log level enum @@ -182,7 +270,16 @@ namespace pcpp /// @return True if this module log level is "debug". False otherwise bool isDebugEnabled(LogModule module) const { - return m_LogModulesArray[module] == Debug; + return m_LogModulesArray[module] == LogLevel::Debug; + } + + /// @brief Check whether a log level should be emitted by the logger. + /// @param level The level of the log message. + /// @param module PcapPlusPlus module + /// @return True if the message should be emitted. False otherwise. + bool shouldLog(LogLevel level, LogModule module) const + { + return level != LogLevel::Off && m_LogModulesArray[module] >= level; } /// Set all PcapPlusPlus modules to a certain log level @@ -209,8 +306,9 @@ namespace pcpp } /// @return Get the last error message - std::string getLastError() + std::string getLastError() const { + std::lock_guard lock(m_LastErrorMtx); return m_LastError; } @@ -233,17 +331,32 @@ namespace pcpp return m_LogsEnabled; } - template Logger& operator<<(const T& msg) + /// @brief Controls if the logger should use a pool of LogContext objects. + /// + /// If enabled is set to false, preallocate and maxPoolSize are ignored. + /// @param enabled True to enable context pooling, false to disable. + /// @param preallocate The number of LogContext objects to preallocate in the pool. + /// @param maxPoolSize The maximum number of LogContext objects to keep in the pool. + /// @remarks Disabling the pooling clears the pool. + void useContextPooling(bool enabled, std::size_t preallocate = 2, std::size_t maxPoolSize = 10) { - (*m_LogStream) << msg; - return *this; - } + m_UseContextPooling = enabled; - static std::ostringstream* internalCreateLogStream(); + if (m_UseContextPooling) + { + m_LogContextPool.setMaxSize(maxPoolSize); - /// An internal method to print log messages. Shouldn't be used externally. - void internalPrintLogMessage(std::ostringstream* logStream, Logger::LogLevel logLevel, const char* file, - const char* method, int line); + if (preallocate > 0) + { + m_LogContextPool.preallocate(preallocate); + } + } + else + { + // Clear the pool if we're disabling pooling. + m_LogContextPool.clear(); + } + } /// Get access to Logger singleton /// @todo: make this singleton thread-safe/ @@ -254,12 +367,37 @@ namespace pcpp return instance; } + /// @brief Creates a new LogContext with Info level and no source. + /// @return A new LogContext. + std::unique_ptr createLogContext(); + + /// @brief Creates a new LogContext with the given level and source. + /// @param level The log level for this message. + /// @param source The log source. + /// @return A new LogContext. + std::unique_ptr createLogContext(LogLevel level, LogSource const& source = {}); + + /// @brief Directly emits a log message bypassing all level checks. + /// @param source The log source. + /// @param level The log level for this message. This is only used for the log printer. + /// @param message The log message. + void emit(LogSource const& source, LogLevel level, std::string const& message); + + /// @brief Directly emits a log message bypassing all level checks. + /// @param message The log message. + void emit(std::unique_ptr message); + private: bool m_LogsEnabled; - Logger::LogLevel m_LogModulesArray[NumOfLogModules]{}; + std::array m_LogModulesArray; LogPrinter m_LogPrinter; + + mutable std::mutex m_LastErrorMtx; std::string m_LastError; - std::ostringstream* m_LogStream{}; + + bool m_UseContextPooling = true; + // Keep a maximum of 10 LogContext objects in the pool. + internal::DynamicObjectPool m_LogContextPool{ 10, 2 }; // private c'tor - this class is a singleton Logger(); @@ -267,4 +405,36 @@ namespace pcpp static void defaultLogPrinter(LogLevel logLevel, const std::string& logMessage, const std::string& file, const std::string& method, int line); }; + } // namespace pcpp + +#define PCPP_LOG(level, message) \ + do \ + { \ + auto& logger = pcpp::Logger::getInstance(); \ + if (logger.shouldLog(level, LOG_MODULE)) \ + { \ + auto ctx = \ + logger.createLogContext(level, pcpp::LogSource(LOG_MODULE, PCAPPP_FILENAME, __FUNCTION__, __LINE__)); \ + (*ctx) << message; \ + logger.emit(std::move(ctx)); \ + } \ + } while (0) + +#if PCPP_ACTIVE_LOG_LEVEL >= PCPP_LOG_LEVEL_DEBUG +# define PCPP_LOG_DEBUG(message) PCPP_LOG(pcpp::LogLevel::Debug, message) +#else +# define PCPP_LOG_DEBUG(message) (void)0 +#endif + +#if PCPP_ACTIVE_LOG_LEVEL >= PCPP_LOG_LEVEL_INFO +# define PCPP_LOG_INFO(message) PCPP_LOG(pcpp::LogLevel::Info, message) +#else +# define PCPP_LOG_INFO(message) (void)0 +#endif + +#if PCPP_ACTIVE_LOG_LEVEL >= PCPP_LOG_LEVEL_ERROR +# define PCPP_LOG_ERROR(message) PCPP_LOG(pcpp::LogLevel::Error, message) +#else +# define PCPP_LOG_ERROR(message) (void)0 +#endif diff --git a/Common++/header/ObjectPool.h b/Common++/header/ObjectPool.h new file mode 100644 index 0000000000..15d479cb90 --- /dev/null +++ b/Common++/header/ObjectPool.h @@ -0,0 +1,185 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace pcpp +{ + namespace internal + { + /// @brief A generic object pool implementation. + /// + /// This class provides a generic object pool that can be used to efficiently manage and reuse objects of any + /// type. Objects can be acquired from the pool using the `acquireObject` method, and released back to the pool + /// using the `releaseObject` method. If the pool is empty when acquiring an object, a new object will be + /// created. If the pool is full when releasing an object, the object will be deleted. + /// + /// @tparam T The type of objects managed by the pool. Must be default constructable. + template ::value, bool>::type = true> + class DynamicObjectPool + { + public: + constexpr static std::size_t DEFAULT_POOL_SIZE = 100; +#pragma push_macro("max") // Undefine max to avoid conflict with std::numeric_limits::max() +#undef max + constexpr static std::size_t INFINITE_POOL_SIZE = std::numeric_limits::max(); +#pragma pop_macro("max") + + /// A constructor for this class that creates a pool of objects + /// @param[in] maxPoolSize The maximum number of objects in the pool + /// @param[in] initialSize The number of objects to preallocate in the pool + explicit DynamicObjectPool(std::size_t maxPoolSize = DEFAULT_POOL_SIZE, std::size_t initialSize = 0) + : m_MaxPoolSize(maxPoolSize) + { + if (initialSize > maxPoolSize) + throw std::invalid_argument("Preallocated objects cannot exceed the maximum pool size"); + + if (initialSize > 0) + this->preallocate(initialSize); + } + + // These don't strictly need to be deleted, but don't need to be implemented for now either. + DynamicObjectPool(const DynamicObjectPool&) = delete; + DynamicObjectPool(DynamicObjectPool&&) = delete; + DynamicObjectPool& operator=(const DynamicObjectPool&) = delete; + DynamicObjectPool& operator=(DynamicObjectPool&&) = delete; + + /// A destructor for this class that deletes all objects in the pool + ~DynamicObjectPool() + { + clear(); + } + + /// @brief Acquires a unique pointer to an object from the pool. + /// + /// This method acquires a unique pointer to an object from the pool. + /// If the pool is empty, a new object will be created. + /// + /// @return A unique pointer to an object from the pool. + std::unique_ptr acquireObject() + { + return std::unique_ptr(acquireObjectRaw()); + } + + /// @brief Acquires a raw pointer to an object from the pool. + /// + /// This method acquires a raw pointer to an object from the pool. + /// If the pool is empty, a new object will be created. + /// + /// @return A raw pointer to an object from the pool. + T* acquireObjectRaw() + { + std::unique_lock lock(m_Mutex); + + if (m_Pool.empty()) + { + // We don't need the lock anymore, so release it. + lock.unlock(); + return new T(); + } + + T* obj = m_Pool.top(); + m_Pool.pop(); + return obj; + } + + /// @brief Releases a unique pointer to an object back to the pool. + /// + /// This method releases a unique pointer to an object back to the pool. + /// If the pool is full, the object will be deleted. + /// + /// @param[in] obj The unique pointer to the object to release. + void releaseObject(std::unique_ptr obj) + { + releaseObjectRaw(obj.release()); + } + + /// @brief Releases a raw pointer to an object back to the pool. + /// + /// This method releases a raw pointer to an object back to the pool. + /// If the pool is full, the object will be deleted. + /// + /// @param[in] obj The raw pointer to the object to release. + void releaseObjectRaw(T* obj) + { + std::unique_lock lock(m_Mutex); + + if (m_MaxPoolSize == INFINITE_POOL_SIZE || m_Pool.size() < m_MaxPoolSize) + { + m_Pool.push(obj); + } + else + { + // We don't need the lock anymore, so release it. + lock.unlock(); + delete obj; + } + } + + /// @brief Gets the current number of objects in the pool. + std::size_t size() const + { + std::lock_guard lock(m_Mutex); + return m_Pool.size(); + } + + /// @brief Gets the maximum number of objects in the pool. + std::size_t maxSize() const + { + std::lock_guard lock(m_Mutex); + return m_MaxPoolSize; + } + + /// @brief Sets the maximum number of objects in the pool. + void setMaxSize(std::size_t maxSize) + { + std::lock_guard lock(m_Mutex); + m_MaxPoolSize = maxSize; + + // If the new max size is less than the current size, we need to remove some objects from the pool. + while (m_Pool.size() > m_MaxPoolSize) + { + delete m_Pool.top(); + m_Pool.pop(); + } + } + + /// @brief Pre-allocates up to a minimum number of objects in the pool. + /// @param count The number of objects to pre-allocate. + void preallocate(std::size_t count) + { + std::unique_lock lock(m_Mutex); + + if (m_MaxPoolSize < count) + { + throw std::invalid_argument("Preallocated objects cannot exceed the maximum pool size"); + } + + // If the pool is already larger than the requested count, we don't need to do anything. + for (std::size_t i = m_Pool.size(); i < count; i++) + { + m_Pool.push(new T()); + } + } + + /// @brief Deallocates and releases all objects currently held by the pool. + void clear() + { + std::unique_lock lock(m_Mutex); + while (!m_Pool.empty()) + { + delete m_Pool.top(); + m_Pool.pop(); + } + } + + private: + std::size_t m_MaxPoolSize; ///< The maximum number of objects in the pool + mutable std::mutex m_Mutex; ///< Mutex for thread safety + std::stack m_Pool; ///< The pool of objects + }; + } // namespace internal +} // namespace pcpp diff --git a/Common++/src/IpAddress.cpp b/Common++/src/IpAddress.cpp index 90ef1b59fe..f42ddbcf87 100644 --- a/Common++/src/IpAddress.cpp +++ b/Common++/src/IpAddress.cpp @@ -68,6 +68,7 @@ namespace pcpp } catch (const std::invalid_argument& e) { + (void)e; // Suppress the unreferenced local variable warning when PCPP_LOG_ERROR is disabled PCPP_LOG_ERROR(e.what()); return false; } @@ -130,6 +131,7 @@ namespace pcpp } catch (const std::invalid_argument& e) { + (void)e; // Suppress the unreferenced local variable warning when PCPP_LOG_ERROR is disabled PCPP_LOG_ERROR(e.what()); return false; } diff --git a/Common++/src/IpUtils.cpp b/Common++/src/IpUtils.cpp index 44bd7e1f90..e6fa1150b6 100644 --- a/Common++/src/IpUtils.cpp +++ b/Common++/src/IpUtils.cpp @@ -41,6 +41,7 @@ namespace pcpp } catch (const std::invalid_argument& e) { + (void)e; // Suppress the unreferenced local variable warning when PCPP_LOG_DEBUG is disabled PCPP_LOG_DEBUG("Extraction failed: " << e.what() << " Returning nullptr."); return nullptr; } @@ -69,6 +70,7 @@ namespace pcpp } catch (const std::invalid_argument& e) { + (void)e; // Suppress the unreferenced local variable warning when PCPP_LOG_DEBUG is disabled PCPP_LOG_DEBUG("Extraction failed: " << e.what() << " Returning nullptr."); return nullptr; } diff --git a/Common++/src/Logger.cpp b/Common++/src/Logger.cpp index e67388ea5a..39056120cc 100644 --- a/Common++/src/Logger.cpp +++ b/Common++/src/Logger.cpp @@ -1,9 +1,11 @@ -#include -#include -#include -#include #include "Logger.h" +#include +#include +#include +#include +#include + namespace pcpp { @@ -33,49 +35,76 @@ namespace pcpp Logger::Logger() : m_LogsEnabled(true), m_LogPrinter(&defaultLogPrinter) { m_LastError.reserve(200); - std::fill(m_LogModulesArray, m_LogModulesArray + NumOfLogModules, Info); + m_LogModulesArray.fill(LogLevel::Info); } std::string Logger::logLevelAsString(LogLevel logLevel) { switch (logLevel) { - case Logger::Error: + case LogLevel::Off: + return "OFF"; + case LogLevel::Error: return "ERROR"; - case Logger::Info: + case LogLevel::Info: return "INFO"; - default: + case LogLevel::Debug: return "DEBUG"; + default: + return "UNKNOWN"; } } - void Logger::defaultLogPrinter(LogLevel logLevel, const std::string& logMessage, const std::string& file, - const std::string& method, const int line) + std::unique_ptr Logger::createLogContext() { - std::ostringstream sstream; - sstream << file << ": " << method << ":" << line; - std::cerr << std::left << "[" << std::setw(5) << Logger::logLevelAsString(logLevel) << ": " << std::setw(45) - << sstream.str() << "] " << logMessage << '\n'; + return createLogContext(LogLevel::Info, {}); // call the other createLogContext method + } + std::unique_ptr Logger::createLogContext(LogLevel level, LogSource const& source) + { + if (m_UseContextPooling) + { + auto ctx = m_LogContextPool.acquireObject(); + ctx->init(level, source); + return ctx; + } + return std::unique_ptr(new internal::LogContext(level, source)); } - std::ostringstream* Logger::internalCreateLogStream() + void Logger::emit(std::unique_ptr message) { - return new std::ostringstream(); + emit(message->m_Source, message->m_Level, message->m_Stream.str()); + // Pushes the message back to the pool if pooling is enabled. Otherwise, the message is deleted. + if (m_UseContextPooling) + { + m_LogContextPool.releaseObject(std::move(message)); + } } - void Logger::internalPrintLogMessage(std::ostringstream* logStream, Logger::LogLevel logLevel, const char* file, - const char* method, int line) + void Logger::emit(LogSource const& source, LogLevel logLevel, std::string const& message) { - const std::string logMessage = logStream->str(); - delete logStream; - if (logLevel == Logger::Error) + // If the log level is an error, save the error to the last error message variable. + if (logLevel == LogLevel::Error) { - m_LastError = logMessage; + std::lock_guard lock(m_LastErrorMtx); + m_LastError = message; } if (m_LogsEnabled) { - m_LogPrinter(logLevel, logMessage, file, method, line); + m_LogPrinter(logLevel, message, source.file, source.function, source.line); } } + void Logger::defaultLogPrinter(LogLevel logLevel, const std::string& logMessage, const std::string& file, + const std::string& method, const int line) + { + // This mutex is used to prevent multiple threads from writing to the console at the same time. + static std::mutex logMutex; + + std::ostringstream sstream; + sstream << file << ": " << method << ":" << line; + + std::unique_lock lock(logMutex); + std::cerr << std::left << "[" << std::setw(5) << Logger::logLevelAsString(logLevel) << ": " << std::setw(45) + << sstream.str() << "] " << logMessage << std::endl; + } } // namespace pcpp diff --git a/Examples/KniPong/main.cpp b/Examples/KniPong/main.cpp index e77db3188a..beb5f89e97 100644 --- a/Examples/KniPong/main.cpp +++ b/Examples/KniPong/main.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include diff --git a/Examples/PfRingExample-FilterTraffic/main.cpp b/Examples/PfRingExample-FilterTraffic/main.cpp index f070fceb67..7f7583ac9c 100644 --- a/Examples/PfRingExample-FilterTraffic/main.cpp +++ b/Examples/PfRingExample-FilterTraffic/main.cpp @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include // clang-format off diff --git a/Pcap++/src/NetworkUtils.cpp b/Pcap++/src/NetworkUtils.cpp index 61269bc26c..75a19e5de8 100644 --- a/Pcap++/src/NetworkUtils.cpp +++ b/Pcap++/src/NetworkUtils.cpp @@ -1,4 +1,4 @@ -#define LOG_MODULE NetworkUtils +#define LOG_MODULE PcapLogModuleNetworkUtils #include #include diff --git a/Pcap++/src/PcapLiveDevice.cpp b/Pcap++/src/PcapLiveDevice.cpp index cff0fdd476..213295cee7 100644 --- a/Pcap++/src/PcapLiveDevice.cpp +++ b/Pcap++/src/PcapLiveDevice.cpp @@ -1046,6 +1046,7 @@ namespace pcpp } catch (const std::exception& e) { + (void)e; // Suppress the unreferenced local variable warning when PCPP_LOG_ERROR is disabled PCPP_LOG_ERROR("Error retrieving default gateway address: " << e.what()); } break; diff --git a/Pcap++/src/PcapLiveDeviceList.cpp b/Pcap++/src/PcapLiveDeviceList.cpp index 9fb46b4ce4..a68e65a406 100644 --- a/Pcap++/src/PcapLiveDeviceList.cpp +++ b/Pcap++/src/PcapLiveDeviceList.cpp @@ -51,6 +51,7 @@ namespace pcpp } catch (const std::exception& e) { + (void)e; // Suppress the unreferenced local variable warning when PCPP_LOG_ERROR is disabled PCPP_LOG_ERROR(e.what()); } diff --git a/Pcap++/src/PcapRemoteDeviceList.cpp b/Pcap++/src/PcapRemoteDeviceList.cpp index 01791d6dde..ca8629c8f3 100644 --- a/Pcap++/src/PcapRemoteDeviceList.cpp +++ b/Pcap++/src/PcapRemoteDeviceList.cpp @@ -94,6 +94,7 @@ namespace pcpp } catch (const std::exception& e) { + (void)e; // Suppress the unreferenced local variable warning when PCPP_LOG_ERROR is disabled PCPP_LOG_ERROR(e.what()); return nullptr; } @@ -118,6 +119,7 @@ namespace pcpp { delete device; } + (void)e; // Suppress the unreferenced local variable warning when PCPP_LOG_ERROR is disabled PCPP_LOG_ERROR("Error creating remote devices: " << e.what()); return nullptr; } diff --git a/Tests/Packet++Test/main.cpp b/Tests/Packet++Test/main.cpp index 4163780110..ebf1838620 100644 --- a/Tests/Packet++Test/main.cpp +++ b/Tests/Packet++Test/main.cpp @@ -85,7 +85,8 @@ int main(int argc, char* argv[]) #endif // The logger singleton looks like a memory leak. Invoke it before starting the memory check - pcpp::Logger::getInstance(); + // Disables context pooling to avoid false positives in the memory leak check, as the contexts persist in the pool. + pcpp::Logger::getInstance().useContextPooling(false); // cppcheck-suppress knownConditionTrueFalse if (skipMemLeakCheck) diff --git a/Tests/Pcap++Test/CMakeLists.txt b/Tests/Pcap++Test/CMakeLists.txt index 07262ffb81..1727a4d15b 100644 --- a/Tests/Pcap++Test/CMakeLists.txt +++ b/Tests/Pcap++Test/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable( Tests/KniTests.cpp Tests/LiveDeviceTests.cpp Tests/LoggerTests.cpp + Tests/ObjectPoolTests.cpp Tests/PacketParsingTests.cpp Tests/PfRingTests.cpp Tests/RawSocketTests.cpp diff --git a/Tests/Pcap++Test/TestDefinition.h b/Tests/Pcap++Test/TestDefinition.h index ccaaec4756..74188ff885 100644 --- a/Tests/Pcap++Test/TestDefinition.h +++ b/Tests/Pcap++Test/TestDefinition.h @@ -12,6 +12,9 @@ PTF_TEST_CASE(TestIPv4Network); PTF_TEST_CASE(TestIPv6Network); PTF_TEST_CASE(TestIPNetwork); +// Implemented in ObjectPoolTests.cpp +PTF_TEST_CASE(TestObjectPool); + // Implemented in LoggerTests.cpp PTF_TEST_CASE(TestLogger); PTF_TEST_CASE(TestLoggerMultiThread); diff --git a/Tests/Pcap++Test/Tests/LoggerTests.cpp b/Tests/Pcap++Test/Tests/LoggerTests.cpp index 2d53a491e8..5579c350c5 100644 --- a/Tests/Pcap++Test/Tests/LoggerTests.cpp +++ b/Tests/Pcap++Test/Tests/LoggerTests.cpp @@ -136,7 +136,7 @@ class LoggerCleaner ~LoggerCleaner() { pcpp::Logger::getInstance().enableLogs(); - pcpp::Logger::getInstance().setAllModulesToLogLevel(pcpp::Logger::Info); + pcpp::Logger::getInstance().setAllModulesToLogLevel(pcpp::LogLevel::Info); pcpp::Logger::getInstance().resetLogPrinter(); std::cout.clear(); LogPrinter::clean(); @@ -190,24 +190,39 @@ PTF_TEST_CASE(TestLoggerMultiThread) PTF_TEST_CASE(TestLogger) { + using pcpp::Logger; + using pcpp::LogLevel; + using pcpp::LogModule; + + auto& logger = Logger::getInstance(); + // cppcheck-suppress unusedVariable LoggerCleaner loggerCleaner; // verify all modules are on info log level - for (int module = 1; module < pcpp::NumOfLogModules; module++) + for (int moduleInt = 1; moduleInt < LogModule::NumOfLogModules; moduleInt++) { - PTF_ASSERT_EQUAL(pcpp::Logger::getInstance().getLogLevel((pcpp::LogModule)module), pcpp::Logger::Info, enum); - PTF_ASSERT_FALSE(pcpp::Logger::getInstance().isDebugEnabled((pcpp::LogModule)module)); + const LogModule moduleEnum = static_cast(moduleInt); + + PTF_ASSERT_EQUAL(logger.getLogLevel(moduleEnum), LogLevel::Info, enum); + PTF_ASSERT_FALSE(logger.isDebugEnabled(moduleEnum)); + + PTF_ASSERT_TRUE(logger.shouldLog(LogLevel::Error, moduleEnum)); + PTF_ASSERT_TRUE(logger.shouldLog(LogLevel::Info, moduleEnum)); + PTF_ASSERT_FALSE(logger.shouldLog(LogLevel::Debug, moduleEnum)); + PTF_ASSERT_FALSE(logger.shouldLog(LogLevel::Off, moduleEnum)); } // invoke debug and error logs - expect to see only the error log - pcpp::Logger::getInstance().setLogPrinter(&LogPrinter::logPrinter); + logger.setLogPrinter(&LogPrinter::logPrinter); + pcpp::invokeDebugLog(); PTF_ASSERT_EQUAL(LogPrinter::lastLogLevelSeen, 999); PTF_ASSERT_EQUAL(LogPrinter::lastLineSeen, 99999); PTF_ASSERT_NULL(LogPrinter::lastLogMessageSeen); PTF_ASSERT_NULL(LogPrinter::lastFilenameSeen); PTF_ASSERT_NULL(LogPrinter::lastMethodSeen); + pcpp::invokeErrorLog(); PTF_ASSERT_EQUAL(LogPrinter::lastLogLevelSeen, (int)pcpp::Logger::Error); PTF_ASSERT_EQUAL(*LogPrinter::lastLogMessageSeen, "error log"); @@ -216,9 +231,9 @@ PTF_TEST_CASE(TestLogger) PTF_ASSERT_EQUAL(LogPrinter::lastLineSeen, 21); // change one module log level - pcpp::Logger::getInstance().setLogLevel(pcpp::PacketLogModuleArpLayer, pcpp::Logger::Debug); - PTF_ASSERT_EQUAL(pcpp::Logger::getInstance().getLogLevel(pcpp::PacketLogModuleArpLayer), pcpp::Logger::Debug, enum); - PTF_ASSERT_TRUE(pcpp::Logger::getInstance().isDebugEnabled(pcpp::PacketLogModuleArpLayer)); + logger.setLogLevel(pcpp::PacketLogModuleArpLayer, pcpp::Logger::Debug); + PTF_ASSERT_EQUAL(logger.getLogLevel(pcpp::PacketLogModuleArpLayer), pcpp::LogLevel::Debug, enum); + PTF_ASSERT_TRUE(logger.isDebugEnabled(pcpp::PacketLogModuleArpLayer)); // invoke debug and error logs - expect to see both pcpp::invokeDebugLog(); @@ -236,14 +251,21 @@ PTF_TEST_CASE(TestLogger) PTF_ASSERT_EQUAL(LogPrinter::lastLineSeen, 21); // verify the last error message - PTF_ASSERT_EQUAL(pcpp::Logger::getInstance().getLastError(), "error log"); + PTF_ASSERT_EQUAL(logger.getLastError(), "error log"); // change all modules log level - pcpp::Logger::getInstance().setAllModulesToLogLevel(pcpp::Logger::Debug); - for (int module = 1; module < pcpp::NumOfLogModules; module++) + logger.setAllModulesToLogLevel(LogLevel::Debug); + for (int moduleInt = 1; moduleInt < LogModule::NumOfLogModules; moduleInt++) { - PTF_ASSERT_EQUAL(pcpp::Logger::getInstance().getLogLevel((pcpp::LogModule)module), pcpp::Logger::Debug, enum); - PTF_ASSERT_TRUE(pcpp::Logger::getInstance().isDebugEnabled((pcpp::LogModule)module)); + auto const moduleEnum = static_cast(moduleInt); + + PTF_ASSERT_EQUAL(logger.getLogLevel(static_cast(moduleEnum)), pcpp::LogLevel::Debug, enum); + PTF_ASSERT_TRUE(logger.isDebugEnabled(static_cast(moduleEnum))); + + PTF_ASSERT_TRUE(logger.shouldLog(LogLevel::Error, moduleEnum)); + PTF_ASSERT_TRUE(logger.shouldLog(LogLevel::Info, moduleEnum)); + PTF_ASSERT_TRUE(logger.shouldLog(LogLevel::Debug, moduleEnum)); + PTF_ASSERT_FALSE(logger.shouldLog(LogLevel::Off, moduleEnum)); } // invoke debug log - expect to see it @@ -255,9 +277,9 @@ PTF_TEST_CASE(TestLogger) PTF_ASSERT_EQUAL(LogPrinter::lastLineSeen, 16); // suppress logs - PTF_ASSERT_TRUE(pcpp::Logger::getInstance().logsEnabled()) - pcpp::Logger::getInstance().suppressLogs(); - PTF_ASSERT_FALSE(pcpp::Logger::getInstance().logsEnabled()) + PTF_ASSERT_TRUE(logger.logsEnabled()) + logger.suppressLogs(); + PTF_ASSERT_FALSE(logger.logsEnabled()) // reset LogPrinter LogPrinter::clean(); @@ -270,32 +292,32 @@ PTF_TEST_CASE(TestLogger) // invoke another error log - expect to see it as the last error message although logs are suppressed pcpp::invokeErrorLog("2"); - PTF_ASSERT_EQUAL(pcpp::Logger::getInstance().getLastError(), "error log2"); + PTF_ASSERT_EQUAL(logger.getLastError(), "error log2"); // re-enable logs - pcpp::Logger::getInstance().enableLogs(); - PTF_ASSERT_TRUE(pcpp::Logger::getInstance().logsEnabled()) + logger.enableLogs(); + PTF_ASSERT_TRUE(logger.logsEnabled()) // invoke error log - expect to see it pcpp::invokeErrorLog(); - PTF_ASSERT_EQUAL(LogPrinter::lastLogLevelSeen, (int)pcpp::Logger::Error); + PTF_ASSERT_EQUAL(LogPrinter::lastLogLevelSeen, static_cast(pcpp::LogLevel::Error)); PTF_ASSERT_EQUAL(*LogPrinter::lastLogMessageSeen, "error log"); PTF_ASSERT_EQUAL(getLowerCaseFileName(*LogPrinter::lastFilenameSeen), "loggertests.cpp"); PTF_ASSERT_EQUAL(getMethodWithoutNamespace(*LogPrinter::lastMethodSeen), "invokeErrorLog"); - PTF_ASSERT_EQUAL(pcpp::Logger::getInstance().getLastError(), "error log"); + PTF_ASSERT_EQUAL(logger.getLastError(), "error log"); PTF_ASSERT_EQUAL(LogPrinter::lastLineSeen, 21); // reset LogPrinter LogPrinter::clean(); // reset the log printer - pcpp::Logger::getInstance().resetLogPrinter(); + logger.resetLogPrinter(); // disable std::cout for a bit std::cout.setstate(std::ios_base::failbit); // set debug log for a module, don't expect to see it in the custom log printer - pcpp::Logger::getInstance().setLogLevel(pcpp::PacketLogModuleArpLayer, pcpp::Logger::Debug); + logger.setLogLevel(pcpp::PacketLogModuleArpLayer, pcpp::LogLevel::Debug); pcpp::invokeDebugLog(); pcpp::invokeErrorLog(); PTF_ASSERT_EQUAL(LogPrinter::lastLogLevelSeen, 999); diff --git a/Tests/Pcap++Test/Tests/ObjectPoolTests.cpp b/Tests/Pcap++Test/Tests/ObjectPoolTests.cpp new file mode 100644 index 0000000000..3f79e0ef30 --- /dev/null +++ b/Tests/Pcap++Test/Tests/ObjectPoolTests.cpp @@ -0,0 +1,79 @@ + +#include "../TestDefinition.h" + +#include "ObjectPool.h" + +PTF_TEST_CASE(TestObjectPool) +{ + using pcpp::internal::DynamicObjectPool; + + { + DynamicObjectPool pool; + PTF_ASSERT_EQUAL(pool.size(), 0); + PTF_ASSERT_EQUAL(pool.maxSize(), 100); + + pool.preallocate(2); + PTF_ASSERT_EQUAL(pool.size(), 2); + + pool.setMaxSize(1); + PTF_ASSERT_EQUAL(pool.size(), 1); + PTF_ASSERT_EQUAL(pool.maxSize(), 1); + + PTF_ASSERT_RAISES(pool.preallocate(2), std::invalid_argument, + "Preallocated objects cannot exceed the maximum pool size"); + + pool.clear(); + PTF_ASSERT_EQUAL(pool.size(), 0); + PTF_ASSERT_EQUAL(pool.maxSize(), 1); + } + + { + DynamicObjectPool pool(10, 2); + PTF_ASSERT_EQUAL(pool.size(), 2); + PTF_ASSERT_EQUAL(pool.maxSize(), 10); + + PTF_ASSERT_RAISES(DynamicObjectPool(0, 2), std::invalid_argument, + "Preallocated objects cannot exceed the maximum pool size"); + } + + { + DynamicObjectPool pool; + PTF_ASSERT_EQUAL(pool.size(), 0); + + // Acquire an object, since the pool is empty, a new object will be created. + auto obj1 = pool.acquireObject(); + PTF_ASSERT_NOT_NULL(obj1); + + // Acquire a second object, since the pool is still empty, a new object will be created. + auto obj2 = pool.acquireObject(); + + // For the purposes of this test a value will be assigned to track the object. + *obj1 = 55; + *obj2 = 66; + + // Release the objects back to the pool. + pool.releaseObject(std::move(obj1)); + pool.releaseObject(std::move(obj2)); + + PTF_ASSERT_EQUAL(pool.size(), 2); + + // Acquire an object again, this time the object should be reused. + // Since the pool is a LIFO stack the object that was released last should be acquired first. + obj1 = pool.acquireObject(); + + // The value should be the same as the one assigned before releasing the object. + PTF_ASSERT_EQUAL(*obj1, 66); + + // Acquire the second object, this time the object that was released first should be acquired. + obj2 = pool.acquireObject(); + PTF_ASSERT_EQUAL(*obj2, 55); + + // Set the max size of the pool to zero to test the deletion of objects. + pool.setMaxSize(0); + + // Release the objects back to the pool, this time the objects should be deleted. + pool.releaseObject(std::move(obj1)); + pool.releaseObject(std::move(obj2)); + PTF_ASSERT_EQUAL(pool.size(), 0); + } +} diff --git a/Tests/Pcap++Test/main.cpp b/Tests/Pcap++Test/main.cpp index 784a9e0d6f..204e34fee7 100644 --- a/Tests/Pcap++Test/main.cpp +++ b/Tests/Pcap++Test/main.cpp @@ -143,8 +143,9 @@ int main(int argc, char* argv[]) << " https://github.com/cpputest/cpputest/issues/786#issuecomment-148921958" << std::endl; #endif - // The logger singleton looks like a memory leak. Invoke it before starting the memory check - pcpp::Logger::getInstance(); + // The logger singleton looks like a memory leak. Invoke it before starting the memory check. + // Disables context pooling to avoid false positives in the memory leak check, as the contexts persist in the pool. + pcpp::Logger::getInstance().useContextPooling(false); // cppcheck-suppress knownConditionTrueFalse if (skipMemLeakCheck) @@ -209,6 +210,8 @@ int main(int argc, char* argv[]) PTF_RUN_TEST(TestIPv6Network, "no_network;ip"); PTF_RUN_TEST(TestIPNetwork, "no_network;ip"); + PTF_RUN_TEST(TestObjectPool, "no_network"); + PTF_RUN_TEST(TestLogger, "no_network;logger"); PTF_RUN_TEST(TestLoggerMultiThread, "no_network;logger;skip_mem_leak_check"); From 2ae8837405506db9d857a0400e3ecf37bd406dc0 Mon Sep 17 00:00:00 2001 From: seladb Date: Sat, 1 Feb 2025 13:21:02 -0800 Subject: [PATCH 09/36] Auto precommit update (#1701) * Auto pre-commit update * Update .pre-commit-config.yaml --------- Co-authored-by: GitHub Co-authored-by: Liu, An-Chi --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 77ca6d1a3c..c59e90eeef 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -38,17 +38,17 @@ repos: - id: cppcheck args: ["--std=c++11", "--language=c++", "--suppressions-list=cppcheckSuppressions.txt", "--inline-suppr", "--force"] - repo: https://github.com/BlankSpruce/gersemi - rev: 0.17.1 + rev: 0.18.2 hooks: - id: gersemi args: ["-c"] - repo: https://github.com/codespell-project/codespell - rev: v2.3.0 + rev: v2.4.1 hooks: - id: codespell pass_filenames: false - repo: https://github.com/crate-ci/typos - rev: codespell-dict-v0.5.0 + rev: typos-dict-v0.12.4 hooks: - id: typos args: ['--config=typos-config.toml'] From 4ea938b4d3267ff1a3f062ee070fcb57734db46c Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Sun, 2 Feb 2025 21:17:29 +0200 Subject: [PATCH 10/36] Added static asserts to fixed length header structures used for decoding layer data. (#1693) --- Packet++/header/BgpLayer.h | 1 + Packet++/header/CotpLayer.h | 5 +++-- Packet++/header/DhcpLayer.h | 1 + Packet++/header/DhcpV6Layer.h | 1 + Packet++/header/DnsLayer.h | 1 + Packet++/header/EthDot3Layer.h | 1 + Packet++/header/EthLayer.h | 1 + Packet++/header/GreLayer.h | 3 +++ Packet++/header/GtpLayer.h | 2 +- Packet++/header/IPSecLayer.h | 2 ++ Packet++/header/IPv4Layer.h | 1 + Packet++/header/IPv6Layer.h | 1 + Packet++/header/IcmpLayer.h | 15 +++++++++++++++ Packet++/header/IcmpV6Layer.h | 2 ++ Packet++/header/IgmpLayer.h | 3 +++ Packet++/header/LLCLayer.h | 1 + Packet++/header/MplsLayer.h | 1 + Packet++/header/NflogLayer.h | 1 + Packet++/header/NtpLayer.h | 6 +++++- Packet++/header/PPPoELayer.h | 1 + Packet++/header/RadiusLayer.h | 1 + Packet++/header/S7CommLayer.h | 2 ++ Packet++/header/SSHLayer.h | 1 + Packet++/header/SSLCommon.h | 5 +++++ Packet++/header/Sll2Layer.h | 1 + Packet++/header/SllLayer.h | 1 + Packet++/header/SomeIpLayer.h | 2 ++ Packet++/header/SomeIpSdLayer.h | 6 ++++++ Packet++/header/StpLayer.h | 6 ++++++ Packet++/header/TcpLayer.h | 1 + Packet++/header/TpktLayer.h | 1 + Packet++/header/UdpLayer.h | 1 + Packet++/header/VlanLayer.h | 1 + Packet++/header/VrrpLayer.h | 1 + Packet++/header/VxlanLayer.h | 1 + Packet++/header/WakeOnLanLayer.h | 1 + Packet++/header/WireGuardLayer.h | 2 ++ 37 files changed, 80 insertions(+), 4 deletions(-) diff --git a/Packet++/header/BgpLayer.h b/Packet++/header/BgpLayer.h index 39030acf65..8bb7bf3946 100644 --- a/Packet++/header/BgpLayer.h +++ b/Packet++/header/BgpLayer.h @@ -59,6 +59,7 @@ namespace pcpp uint8_t messageType; }; #pragma pack(pop) + static_assert(sizeof(bgp_common_header) == 19, "bgp_common_header size is not 19 bytes"); /** * @return BGP message type diff --git a/Packet++/header/CotpLayer.h b/Packet++/header/CotpLayer.h index 3897e1eb83..5cd39c20b4 100644 --- a/Packet++/header/CotpLayer.h +++ b/Packet++/header/CotpLayer.h @@ -11,7 +11,7 @@ namespace pcpp * Represents a COTP protocol header */ #pragma pack(push, 1) - typedef struct + struct cotphdr { /** length */ uint8_t length; @@ -19,8 +19,9 @@ namespace pcpp uint8_t pduType; /** TPDU number sequence*/ uint8_t tpduNumber; - } cotphdr; + }; #pragma pack(pop) + static_assert(sizeof(cotphdr) == 3, "cotphdr size is not 3 bytes"); /** * @class CotpLayer diff --git a/Packet++/header/DhcpLayer.h b/Packet++/header/DhcpLayer.h index 90230593d7..f53e39b1e1 100644 --- a/Packet++/header/DhcpLayer.h +++ b/Packet++/header/DhcpLayer.h @@ -54,6 +54,7 @@ namespace pcpp uint32_t magicNumber; }; #pragma pack(pop) + static_assert(sizeof(dhcp_header) == 240, "dhcp_header size is not 240 bytes"); /** * BootP opcodes diff --git a/Packet++/header/DhcpV6Layer.h b/Packet++/header/DhcpV6Layer.h index 5a07cdad6b..6f8aa4a367 100644 --- a/Packet++/header/DhcpV6Layer.h +++ b/Packet++/header/DhcpV6Layer.h @@ -275,6 +275,7 @@ namespace pcpp /** DHCPv6 transaction ID (last byte) */ uint8_t transactionId3; }; + static_assert(sizeof(dhcpv6_header) == 4, "dhcpv6_header size is not 4 bytes"); /** * @class DhcpV6Layer diff --git a/Packet++/header/DnsLayer.h b/Packet++/header/DnsLayer.h index 7749989af3..1fe4b84a26 100644 --- a/Packet++/header/DnsLayer.h +++ b/Packet++/header/DnsLayer.h @@ -79,6 +79,7 @@ namespace pcpp uint16_t numberOfAdditional; }; #pragma pack(pop) + static_assert(sizeof(dnshdr) == 12, "dnshdr size is not 12 bytes"); // forward declarations class DnsQuery; diff --git a/Packet++/header/EthDot3Layer.h b/Packet++/header/EthDot3Layer.h index c2a39e9afe..0a95144bf4 100644 --- a/Packet++/header/EthDot3Layer.h +++ b/Packet++/header/EthDot3Layer.h @@ -27,6 +27,7 @@ namespace pcpp uint16_t length; }; #pragma pack(pop) + static_assert(sizeof(ether_dot3_header) == 14, "ether_dot3_header size is not 14 bytes"); /** * @class EthDot3Layer diff --git a/Packet++/header/EthLayer.h b/Packet++/header/EthLayer.h index 4e9a354c80..2854c611eb 100644 --- a/Packet++/header/EthLayer.h +++ b/Packet++/header/EthLayer.h @@ -27,6 +27,7 @@ namespace pcpp uint16_t etherType; }; #pragma pack(pop) + static_assert(sizeof(ether_header) == 14, "ether_header size is not 14 bytes"); /* Ethernet protocol ID's */ diff --git a/Packet++/header/GreLayer.h b/Packet++/header/GreLayer.h index 53a6cc4229..487cfd845d 100644 --- a/Packet++/header/GreLayer.h +++ b/Packet++/header/GreLayer.h @@ -65,6 +65,7 @@ namespace pcpp uint16_t protocol; }; #pragma pack(pop) + static_assert(sizeof(gre_basic_header) == 4, "gre_basic_header size is not 4 bytes"); /** * @struct gre1_header @@ -79,6 +80,7 @@ namespace pcpp uint16_t callID; }; #pragma pack(pop) + static_assert(sizeof(gre1_header) == 8, "gre1_header size is not 8 bytes"); /** * @struct ppp_pptp_header @@ -95,6 +97,7 @@ namespace pcpp uint16_t protocol; }; #pragma pack(pop) + static_assert(sizeof(ppp_pptp_header) == 4, "ppp_pptp_header size is not 4 bytes"); /** * @class GreLayer diff --git a/Packet++/header/GtpLayer.h b/Packet++/header/GtpLayer.h index 74c9ba7828..27ce036c18 100644 --- a/Packet++/header/GtpLayer.h +++ b/Packet++/header/GtpLayer.h @@ -59,8 +59,8 @@ namespace pcpp * tunnel */ uint32_t teid; }; - #pragma pack(pop) + static_assert(sizeof(gtpv1_header) == 8, "gtpv1_header size is not 8 bytes"); /** * An enum representing the possible GTP v1 message types. diff --git a/Packet++/header/IPSecLayer.h b/Packet++/header/IPSecLayer.h index 2ef17bd905..77a8be2af9 100644 --- a/Packet++/header/IPSecLayer.h +++ b/Packet++/header/IPSecLayer.h @@ -29,6 +29,7 @@ namespace pcpp uint32_t sequenceNumber; }; #pragma pack(pop) + static_assert(sizeof(ipsec_authentication_header) == 12, "ipsec_authentication_header size is not 12 bytes"); /** * @struct ipsec_esp @@ -43,6 +44,7 @@ namespace pcpp uint32_t sequenceNumber; }; #pragma pack(pop) + static_assert(sizeof(ipsec_esp) == 8, "ipsec_esp size is not 8 bytes"); /** * @class AuthenticationHeaderLayer diff --git a/Packet++/header/IPv4Layer.h b/Packet++/header/IPv4Layer.h index 4d7317872b..3159ff0284 100644 --- a/Packet++/header/IPv4Layer.h +++ b/Packet++/header/IPv4Layer.h @@ -57,6 +57,7 @@ namespace pcpp /*The options start here. */ }; #pragma pack(pop) + static_assert(sizeof(iphdr) == 20, "iphdr size is not 20 bytes"); /** * An enum for all possible IPv4 and IPv6 protocol types diff --git a/Packet++/header/IPv6Layer.h b/Packet++/header/IPv6Layer.h index 2c96f5f35d..2316181f99 100644 --- a/Packet++/header/IPv6Layer.h +++ b/Packet++/header/IPv6Layer.h @@ -46,6 +46,7 @@ namespace pcpp uint8_t ipDst[16]; }; #pragma pack(pop) + static_assert(sizeof(ip6_hdr) == 40, "ip6_hdr size is not 40 bytes"); /** * @class IPv6Layer diff --git a/Packet++/header/IcmpLayer.h b/Packet++/header/IcmpLayer.h index f1330ec4c0..dacfbcaebd 100644 --- a/Packet++/header/IcmpLayer.h +++ b/Packet++/header/IcmpLayer.h @@ -33,6 +33,7 @@ namespace pcpp uint16_t checksum; } icmphdr; #pragma pack(pop) + static_assert(sizeof(icmphdr) == 4, "icmphdr size is not 4 bytes"); /** * An enum of all supported ICMP message types @@ -134,6 +135,7 @@ namespace pcpp uint64_t timestamp; } icmp_echo_hdr; #pragma pack(pop) + static_assert(sizeof(icmp_echo_hdr) == 16, "icmp_echo_hdr size is not 16 bytes"); /** * @struct icmp_echo_request @@ -174,12 +176,14 @@ namespace pcpp uint32_t transmitTimestamp; } icmp_timestamp_request; #pragma pack(pop) + static_assert(sizeof(icmp_timestamp_request) == 20, "icmp_timestamp_request size is not 20 bytes"); /** * @typedef icmp_timestamp_reply * ICMP timestamp reply message structure, same as icmp_timestamp_request */ typedef icmp_timestamp_request icmp_timestamp_reply; + static_assert(sizeof(icmp_timestamp_reply) == 20, "icmp_timestamp_reply size is not 20 bytes"); /** * @struct icmp_destination_unreachable @@ -194,6 +198,7 @@ namespace pcpp uint16_t nextHopMTU; } icmp_destination_unreachable; #pragma pack(pop) + static_assert(sizeof(icmp_destination_unreachable) == 8, "icmp_destination_unreachable size is not 8 bytes"); /** * @struct icmp_time_exceeded @@ -206,12 +211,14 @@ namespace pcpp uint32_t unused; } icmp_time_exceeded; #pragma pack(pop) + static_assert(sizeof(icmp_time_exceeded) == 8, "icmp_time_exceeded size is not 8 bytes"); /** * @typedef icmp_source_quench * ICMP source quence message structure, same as icmp_time_exceeded */ typedef icmp_time_exceeded icmp_source_quench; + static_assert(sizeof(icmp_source_quench) == 8, "icmp_source_quench size is not 8 bytes"); /** * @struct icmp_param_problem @@ -229,12 +236,14 @@ namespace pcpp uint16_t unused2; } icmp_param_problem; #pragma pack(pop) + static_assert(sizeof(icmp_param_problem) == 8, "icmp_param_problem size is not 8 bytes"); /** * @typedef icmp_router_solicitation * ICMP router solicitation message structure, same as icmphdr */ typedef icmphdr icmp_router_solicitation; + static_assert(sizeof(icmp_router_solicitation) == 4, "icmp_router_solicitation size is not 4 bytes"); /** * @struct icmp_redirect @@ -247,6 +256,7 @@ namespace pcpp uint32_t gatewayAddress; } icmp_redirect; #pragma pack(pop) + static_assert(sizeof(icmp_redirect) == 8, "icmp_redirect size is not 8 bytes"); /** * @struct icmp_router_address_structure @@ -278,6 +288,7 @@ namespace pcpp } }; #pragma pack(pop) + static_assert(sizeof(icmp_router_address_structure) == 8, "icmp_router_address_structure size is not 8 bytes"); /** * @struct icmp_router_advertisement_hdr @@ -296,6 +307,7 @@ namespace pcpp uint16_t lifetime; } icmp_router_advertisement_hdr; #pragma pack(pop) + static_assert(sizeof(icmp_router_advertisement_hdr) == 8, "icmp_router_advertisement_hdr size is not 8 bytes"); /** * @struct icmp_router_advertisement @@ -331,6 +343,7 @@ namespace pcpp uint32_t addressMask; } icmp_address_mask_request; #pragma pack(pop) + static_assert(sizeof(icmp_address_mask_request) == 12, "icmp_address_mask_request size is not 12 bytes"); /** * @typedef icmp_address_mask_reply @@ -351,12 +364,14 @@ namespace pcpp uint16_t sequence; } icmp_info_request; #pragma pack(pop) + static_assert(sizeof(icmp_info_request) == 8, "icmp_info_request size is not 8 bytes"); /** * @typedef icmp_info_reply * ICMP information reply message structure, same as icmp_info_request */ typedef icmp_info_request icmp_info_reply; + static_assert(sizeof(icmp_info_reply) == 8, "icmp_info_reply size is not 8 bytes"); /** * @class IcmpLayer diff --git a/Packet++/header/IcmpV6Layer.h b/Packet++/header/IcmpV6Layer.h index 0ee8cd12e8..2fbf1f07fe 100644 --- a/Packet++/header/IcmpV6Layer.h +++ b/Packet++/header/IcmpV6Layer.h @@ -110,6 +110,7 @@ namespace pcpp uint16_t checksum; }; #pragma pack(pop) + static_assert(sizeof(icmpv6hdr) == 4, "icmpv6hdr size is not 4 bytes"); /** * @struct icmpv6_echo_hdr @@ -124,6 +125,7 @@ namespace pcpp uint16_t sequence; } icmpv6_echo_hdr; #pragma pack(pop) + static_assert(sizeof(icmpv6_echo_hdr) == 8, "icmpv6_echo_hdr size is not 8 bytes"); /** * @class IcmpV6Layer diff --git a/Packet++/header/IgmpLayer.h b/Packet++/header/IgmpLayer.h index 97b1b5f46d..68ecc59140 100644 --- a/Packet++/header/IgmpLayer.h +++ b/Packet++/header/IgmpLayer.h @@ -29,6 +29,7 @@ namespace pcpp */ uint32_t groupAddress; }; + static_assert(sizeof(igmp_header) == 8, "igmp_header size is not 8 bytes"); /** * @struct igmpv3_query_header @@ -52,6 +53,7 @@ namespace pcpp /** This field specifies the number of source addresses present in the Query */ uint16_t numOfSources; }; + static_assert(sizeof(igmpv3_query_header) == 12, "igmpv3_query_header size is not 12 bytes"); /** * @struct igmpv3_report_header @@ -70,6 +72,7 @@ namespace pcpp /** This field specifies the number of group records present in the Report */ uint16_t numOfGroupRecords; }; + static_assert(sizeof(igmpv3_report_header) == 8, "igmpv3_report_header size is not 8 bytes"); /** * @struct igmpv3_group_record diff --git a/Packet++/header/LLCLayer.h b/Packet++/header/LLCLayer.h index a3595a107c..d5a5793ffc 100644 --- a/Packet++/header/LLCLayer.h +++ b/Packet++/header/LLCLayer.h @@ -25,6 +25,7 @@ namespace pcpp control; }; #pragma pack(pop) + static_assert(sizeof(llc_header) == 3, "llc_header size is not 3 bytes"); /** * @class LLCLayer diff --git a/Packet++/header/MplsLayer.h b/Packet++/header/MplsLayer.h index dc111da685..eb341fd87d 100644 --- a/Packet++/header/MplsLayer.h +++ b/Packet++/header/MplsLayer.h @@ -26,6 +26,7 @@ namespace pcpp uint8_t ttl; }; #pragma pack(pop) + static_assert(sizeof(mpls_header) == 4, "mpls_header size is not 4 bytes"); mpls_header* getMplsHeader() const { diff --git a/Packet++/header/NflogLayer.h b/Packet++/header/NflogLayer.h index 12052911c0..a5301799b7 100644 --- a/Packet++/header/NflogLayer.h +++ b/Packet++/header/NflogLayer.h @@ -27,6 +27,7 @@ namespace pcpp uint16_t resourceId; }; #pragma pack(pop) + static_assert(sizeof(nflog_header) == 4, "nflog_header size is not 4 bytes"); /** * @enum NflogTlvType diff --git a/Packet++/header/NtpLayer.h b/Packet++/header/NtpLayer.h index 2fc062bc33..9099ede363 100644 --- a/Packet++/header/NtpLayer.h +++ b/Packet++/header/NtpLayer.h @@ -116,6 +116,7 @@ namespace pcpp transmitTimestamp; }; #pragma pack(pop) + static_assert(sizeof(ntp_header) == 48, "ntp_header size is not 48 bytes"); #pragma pack(push, 1) struct ntp_v3_auth @@ -126,6 +127,7 @@ namespace pcpp uint8_t dgst[8]; // 64 bit DES based }; #pragma pack(pop) + static_assert(sizeof(ntp_v3_auth) == 12, "ntp_v3_auth size is not 12 bytes"); #pragma pack(push, 1) struct ntp_v4_auth_md5 @@ -136,6 +138,7 @@ namespace pcpp uint8_t dgst[16]; }; #pragma pack(pop) + static_assert(sizeof(ntp_v4_auth_md5) == 20, "ntp_v4_auth_md5 size is not 20 bytes"); #pragma pack(push, 1) struct ntp_v4_auth_sha1 @@ -146,10 +149,11 @@ namespace pcpp uint8_t dgst[20]; }; #pragma pack(pop) + static_assert(sizeof(ntp_v4_auth_sha1) == 24, "ntp_v4_auth_sha1 size is not 24 bytes"); ntp_header* getNtpHeader() const { - return (ntp_header*)m_Data; + return reinterpret_cast(m_Data); } public: diff --git a/Packet++/header/PPPoELayer.h b/Packet++/header/PPPoELayer.h index 60f773df22..2a3622f56d 100644 --- a/Packet++/header/PPPoELayer.h +++ b/Packet++/header/PPPoELayer.h @@ -42,6 +42,7 @@ namespace pcpp uint16_t payloadLength; }; #pragma pack(pop) + static_assert(sizeof(pppoe_header) == 6, "pppoe_header size is not 6 bytes"); /** * @class PPPoELayer diff --git a/Packet++/header/RadiusLayer.h b/Packet++/header/RadiusLayer.h index 87cec5df2f..c7ab300175 100644 --- a/Packet++/header/RadiusLayer.h +++ b/Packet++/header/RadiusLayer.h @@ -29,6 +29,7 @@ namespace pcpp uint8_t authenticator[16]; }; #pragma pack(pop) + static_assert(sizeof(radius_header) == 20, "radius_header size is not 20 bytes"); /** * @class RadiusAttribute diff --git a/Packet++/header/S7CommLayer.h b/Packet++/header/S7CommLayer.h index d9c2175fad..7afac7d51b 100644 --- a/Packet++/header/S7CommLayer.h +++ b/Packet++/header/S7CommLayer.h @@ -26,6 +26,7 @@ namespace pcpp uint16_t dataLength; } s7commhdr; #pragma pack(pop) + static_assert(sizeof(s7commhdr) == 10, "s7commhdr size is not 10 bytes"); /** * @struct s7comm_ack_data_hdr @@ -40,6 +41,7 @@ namespace pcpp uint8_t errorCode; }; #pragma pack(pop) + static_assert(sizeof(s7comm_ack_data_hdr) == 12, "s7comm_ack_data_hdr size is not 12 bytes"); /** * @class S7CommParameter diff --git a/Packet++/header/SSHLayer.h b/Packet++/header/SSHLayer.h index 61b18272c6..84a03f2430 100644 --- a/Packet++/header/SSHLayer.h +++ b/Packet++/header/SSHLayer.h @@ -287,6 +287,7 @@ namespace pcpp uint8_t messageCode; }; #pragma pack(pop) + static_assert(sizeof(ssh_message_base) == 6, "ssh_message_base size is not 6 bytes"); // this layer supports only parsing SSHHandshakeMessage(); diff --git a/Packet++/header/SSLCommon.h b/Packet++/header/SSLCommon.h index 5f499f9ec9..bf5ef916a8 100644 --- a/Packet++/header/SSLCommon.h +++ b/Packet++/header/SSLCommon.h @@ -30,6 +30,7 @@ namespace pcpp uint16_t length; }; #pragma pack(pop) + static_assert(sizeof(ssl_tls_record_layer) == 5, "ssl_tls_record_layer size is not 5 bytes"); /** * @struct ssl_tls_handshake_layer @@ -46,6 +47,7 @@ namespace pcpp uint16_t length2; }; #pragma pack(pop) + static_assert(sizeof(ssl_tls_handshake_layer) == 4, "ssl_tls_handshake_layer size is not 4 bytes"); /** * @struct ssl_tls_client_server_hello @@ -60,6 +62,7 @@ namespace pcpp uint8_t random[32]; }; #pragma pack(pop) + static_assert(sizeof(ssl_tls_client_server_hello) == 38, "ssl_tls_client_server_hello size is not 38 bytes"); /** * @struct ssl_tls_change_cipher_spec @@ -72,6 +75,7 @@ namespace pcpp uint8_t changeCipherSpec; }; #pragma pack(pop) + static_assert(sizeof(ssl_tls_change_cipher_spec) == 1, "ssl_tls_change_cipher_spec size is not 1 byte"); /** * @struct ssl_tls_alert @@ -86,6 +90,7 @@ namespace pcpp uint8_t alertDescription; }; #pragma pack(pop) + static_assert(sizeof(ssl_tls_alert) == 2, "ssl_tls_alert size is not 2 bytes"); /** * SSL/TLS message types diff --git a/Packet++/header/Sll2Layer.h b/Packet++/header/Sll2Layer.h index 324cbb3c17..8bc6d06770 100644 --- a/Packet++/header/Sll2Layer.h +++ b/Packet++/header/Sll2Layer.h @@ -41,6 +41,7 @@ namespace pcpp uint8_t link_layer_addr[8]; }; #pragma pack(pop) + static_assert(sizeof(sll2_header) == 20, "sll2_header size is not 20 bytes"); /** * @class Sll2Layer diff --git a/Packet++/header/SllLayer.h b/Packet++/header/SllLayer.h index 6a02e86041..cd4d7deb46 100644 --- a/Packet++/header/SllLayer.h +++ b/Packet++/header/SllLayer.h @@ -36,6 +36,7 @@ namespace pcpp uint16_t protocol_type; }; #pragma pack(pop) + static_assert(sizeof(sll_header) == 16, "sll_header size is not 16 bytes"); /** * @class SllLayer diff --git a/Packet++/header/SomeIpLayer.h b/Packet++/header/SomeIpLayer.h index 0102e9d30d..d588ddd594 100644 --- a/Packet++/header/SomeIpLayer.h +++ b/Packet++/header/SomeIpLayer.h @@ -83,6 +83,7 @@ namespace pcpp uint8_t returnCode; }; #pragma pack(pop) + static_assert(sizeof(someiphdr) == 16, "someiphdr size is not 16 bytes"); /** * A constructor that creates the layer from an existing packet raw data @@ -391,6 +392,7 @@ namespace pcpp uint32_t offsetAndFlag; }; #pragma pack(pop) + static_assert(sizeof(someiptphdr) == 20, "someiptphdr size is not 20 bytes"); /** * A constructor that creates the layer from an existing packet raw data diff --git a/Packet++/header/SomeIpSdLayer.h b/Packet++/header/SomeIpSdLayer.h index 71c8bd3bf3..8301abccc9 100644 --- a/Packet++/header/SomeIpSdLayer.h +++ b/Packet++/header/SomeIpSdLayer.h @@ -80,6 +80,7 @@ namespace pcpp uint8_t reserved; }; #pragma pack(pop) + static_assert(sizeof(someipsdhdroptionsbase) == 4, "someipsdhdroptionsbase size is not 4 bytes"); /** * Destroy the SOME/IP-SD Option object and delete allocated data if it has been allocated by a constructor @@ -207,6 +208,7 @@ namespace pcpp uint16_t portNumber; }; #pragma pack(pop) + static_assert(sizeof(someipsdhdroptionsipv4) == 12, "someipsdhdroptionsipv4 size is not 12 bytes"); }; /** @@ -284,6 +286,7 @@ namespace pcpp uint16_t portNumber; }; #pragma pack(pop) + static_assert(sizeof(someipsdhdroptionsipv6) == 24, "someipsdhdroptionsipv6 size is not 24 bytes"); }; /** @@ -364,6 +367,7 @@ namespace pcpp uint16_t weight; }; #pragma pack(pop) + static_assert(sizeof(someipsdhdroptionsload) == 8, "someipsdhdroptionsload size is not 8 bytes"); }; /** @@ -434,6 +438,7 @@ namespace pcpp uint32_t data; }; #pragma pack(pop) + static_assert(sizeof(someipsdhdrentry) == 16, "someipsdhdrentry size is not 16 bytes"); /** * Construct a new SOME/IP-SD Service Entry Type @@ -770,6 +775,7 @@ namespace pcpp uint8_t reserved3; }; #pragma pack(pop) + static_assert(sizeof(someipsdhdr) == 20, "someipsdhdr size is not 20 bytes"); uint32_t m_NumOptions; diff --git a/Packet++/header/StpLayer.h b/Packet++/header/StpLayer.h index d153bbb995..0eb323247b 100644 --- a/Packet++/header/StpLayer.h +++ b/Packet++/header/StpLayer.h @@ -28,9 +28,11 @@ namespace pcpp uint8_t type; }; #pragma pack(pop) + static_assert(sizeof(stp_tcn_bpdu) == 4, "stp_tcn_bpdu size is not 4 bytes"); /// Spanning Tree protocol common header typedef stp_tcn_bpdu stp_header; + static_assert(sizeof(stp_header) == 4, "stp_header size is not 4 bytes"); /** * @struct stp_conf_bpdu @@ -59,6 +61,7 @@ namespace pcpp uint16_t forwardDelay; }; #pragma pack(pop) + static_assert(sizeof(stp_conf_bpdu) == 35, "stp_conf_bpdu size is not 35 bytes"); /** * @struct rstp_conf_bpdu @@ -71,6 +74,7 @@ namespace pcpp uint8_t version1Len; }; #pragma pack(pop) + static_assert(sizeof(rstp_conf_bpdu) == 36, "rstp_conf_bpdu size is not 36 bytes"); /** * @struct mstp_conf_bpdu @@ -97,6 +101,7 @@ namespace pcpp uint8_t remainId; }; #pragma pack(pop) + static_assert(sizeof(mstp_conf_bpdu) == 102, "mstp_conf_bpdu size is not 102 bytes"); /** * @struct msti_conf_msg @@ -119,6 +124,7 @@ namespace pcpp uint8_t remainingHops; }; #pragma pack(pop) + static_assert(sizeof(msti_conf_msg) == 16, "msti_conf_msg size is not 16 bytes"); /** * @class StpLayer diff --git a/Packet++/header/TcpLayer.h b/Packet++/header/TcpLayer.h index fe17f8f593..b042e98b54 100644 --- a/Packet++/header/TcpLayer.h +++ b/Packet++/header/TcpLayer.h @@ -85,6 +85,7 @@ namespace pcpp uint16_t urgentPointer; }; #pragma pack(pop) + static_assert(sizeof(tcphdr) == 20, "tcphdr size is not 20 bytes"); /** * TCP options types diff --git a/Packet++/header/TpktLayer.h b/Packet++/header/TpktLayer.h index 35bdbcca03..e0b8130bee 100644 --- a/Packet++/header/TpktLayer.h +++ b/Packet++/header/TpktLayer.h @@ -27,6 +27,7 @@ namespace pcpp uint16_t length; }; #pragma pack(pop) + static_assert(sizeof(tpkthdr) == 4, "tpkthdr size is not 4 bytes"); /** * @class TpktLayer diff --git a/Packet++/header/UdpLayer.h b/Packet++/header/UdpLayer.h index f219bb20f1..53f12f07b9 100644 --- a/Packet++/header/UdpLayer.h +++ b/Packet++/header/UdpLayer.h @@ -28,6 +28,7 @@ namespace pcpp uint16_t headerChecksum; }; #pragma pack(pop) + static_assert(sizeof(udphdr) == 8, "udphdr size is not 8 bytes"); /** * @class UdpLayer diff --git a/Packet++/header/VlanLayer.h b/Packet++/header/VlanLayer.h index 32c1bae9f9..d4463bc44d 100644 --- a/Packet++/header/VlanLayer.h +++ b/Packet++/header/VlanLayer.h @@ -33,6 +33,7 @@ namespace pcpp uint16_t etherType; }; #pragma pack(pop) + static_assert(sizeof(vlan_header) == 4, "vlan_header size is not 4 bytes"); /** * @class VlanLayer diff --git a/Packet++/header/VrrpLayer.h b/Packet++/header/VrrpLayer.h index 48d6cc1b15..4875116d0e 100644 --- a/Packet++/header/VrrpLayer.h +++ b/Packet++/header/VrrpLayer.h @@ -106,6 +106,7 @@ namespace pcpp /** This specifies one or more IPvX addresses that are associated with the virtual router. */ uint8_t* ipAddresses[]; }; + static_assert(sizeof(vrrp_header) == 8, "vrrp_header size is not 8 bytes"); /** * @class VrrpLayer diff --git a/Packet++/header/VxlanLayer.h b/Packet++/header/VxlanLayer.h index e31b10bcd5..12e099ea32 100644 --- a/Packet++/header/VxlanLayer.h +++ b/Packet++/header/VxlanLayer.h @@ -63,6 +63,7 @@ namespace pcpp uint32_t pad : 8; }; #pragma pack(pop) + static_assert(sizeof(vxlan_header) == 8, "vxlan_header size is not 8 bytes"); /** * @class VxlanLayer diff --git a/Packet++/header/WakeOnLanLayer.h b/Packet++/header/WakeOnLanLayer.h index 5b5a999085..1e9eec506f 100644 --- a/Packet++/header/WakeOnLanLayer.h +++ b/Packet++/header/WakeOnLanLayer.h @@ -34,6 +34,7 @@ namespace pcpp uint8_t addrBody[6 * 16]; }; #pragma pack(pop) + static_assert(sizeof(wol_header) == 102, "wol_header size is not 102 bytes"); /** * A constructor that creates the layer from an existing packet raw data diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index acb0bf8c24..99be143f22 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -33,6 +33,8 @@ namespace pcpp uint8_t reserved[3]; }; #pragma pack(pop) + static_assert(sizeof(wg_common_header) == 4, "wg_common_header size is not 4 bytes"); + wg_common_header* getBasicHeader() const { return reinterpret_cast(m_Data); From 66ccbe8f4e515d4e44781c8270482f6925140ccd Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Mon, 3 Feb 2025 02:47:59 +0200 Subject: [PATCH 11/36] Reformat Packet++ documentation to use triple-slash doxygen format. (#1659) * Converted some files to tripple slash docs. * Converted more files. * Converted more files. * more conversions... * Converted more files * Converted more files. * converted files * converted more files. * Reformatted SSH layer. PS: Formatting ASCII drawings is annoying. * Converted SSL layer files. PS: Formating ASCII Drawings. * Attempt at suppressing multi-line comment warning due to backslashes in ASCII drawings. * Converted Stplayer. * Converted remaining files. * Wrapped diagrams in ASCII borders to avoid the multi-line comment compiler errors. * Wrapped more diagrams that triggered the multi-line error. The error is triggered by having a \ as the last character before a new-line. * Reformatted /** */ style comments to /// and // comments. * Added empty lines around verbatim blocks to attempt to fix doxygen error. * Replaced verbatim blocks with @code{.unparsed} as per this workaround. https://web.archive.org/web/20240724083629/https://technicalwriting.dev/src/verbatim-wrangling.html * Lint * Removed borders and instances of \ at the end of the line --- Packet++/header/ArpLayer.h | 133 +-- Packet++/header/Asn1Codec.h | 363 +++--- Packet++/header/BgpLayer.h | 656 ++++------ Packet++/header/CotpLayer.h | 93 +- Packet++/header/DhcpLayer.h | 770 ++++++------ Packet++/header/DhcpV6Layer.h | 422 +++---- Packet++/header/DnsLayer.h | 587 ++++----- Packet++/header/DnsLayerEnums.h | 140 ++- Packet++/header/DnsResource.h | 188 ++- Packet++/header/DnsResourceData.h | 308 ++--- Packet++/header/EthDot3Layer.h | 110 +- Packet++/header/EthLayer.h | 150 +-- Packet++/header/FtpLayer.h | 208 ++-- Packet++/header/GreLayer.h | 415 +++---- Packet++/header/GtpLayer.h | 1187 ++++++++----------- Packet++/header/HttpLayer.h | 737 +++++------- Packet++/header/IPLayer.h | 34 +- Packet++/header/IPReassembly.h | 504 ++++---- Packet++/header/IPSecLayer.h | 148 +-- Packet++/header/IPv4Layer.h | 570 ++++----- Packet++/header/IPv6Extensions.h | 427 +++---- Packet++/header/IPv6Layer.h | 210 ++-- Packet++/header/IcmpLayer.h | 724 +++++------ Packet++/header/IcmpV6Layer.h | 241 ++-- Packet++/header/IgmpLayer.h | 510 ++++---- Packet++/header/LLCLayer.h | 68 +- Packet++/header/Layer.h | 171 +-- Packet++/header/LdapLayer.h | 982 ++++++--------- Packet++/header/MplsLayer.h | 98 +- Packet++/header/NdpLayer.h | 290 ++--- Packet++/header/NflogLayer.h | 192 ++- Packet++/header/NtpLayer.h | 472 +++----- Packet++/header/NullLoopbackLayer.h | 78 +- Packet++/header/PPPoELayer.h | 635 +++++----- Packet++/header/Packet.h | 478 ++++---- Packet++/header/PacketTrailerLayer.h | 87 +- Packet++/header/PacketUtils.h | 93 +- Packet++/header/PayloadLayer.h | 81 +- Packet++/header/ProtocolType.h | 307 ++--- Packet++/header/RadiusLayer.h | 311 ++--- Packet++/header/RawPacket.h | 552 ++++----- Packet++/header/S7CommLayer.h | 156 +-- Packet++/header/SSHLayer.h | 467 ++++---- Packet++/header/SSLCommon.h | 546 ++++----- Packet++/header/SSLHandshake.h | 1069 +++++++---------- Packet++/header/SSLLayer.h | 667 +++++------ Packet++/header/SdpLayer.h | 197 ++- Packet++/header/SingleCommandTextProtocol.h | 33 +- Packet++/header/SipLayer.h | 705 +++++------ Packet++/header/Sll2Layer.h | 181 ++- Packet++/header/SllLayer.h | 95 +- Packet++/header/SmtpLayer.h | 186 ++- Packet++/header/SomeIpLayer.h | 439 +++---- Packet++/header/SomeIpSdLayer.h | 665 ++++------- Packet++/header/StpLayer.h | 652 ++++------ Packet++/header/TLVData.h | 266 ++--- Packet++/header/TcpLayer.h | 548 ++++----- Packet++/header/TcpReassembly.h | 565 ++++----- Packet++/header/TelnetLayer.h | 145 +-- Packet++/header/TextBasedProtocol.h | 229 ++-- Packet++/header/TpktLayer.h | 111 +- Packet++/header/UdpLayer.h | 88 +- Packet++/header/VlanLayer.h | 133 +-- Packet++/header/VrrpLayer.h | 432 +++---- Packet++/header/VxlanLayer.h | 121 +- Packet++/header/WakeOnLanLayer.h | 148 +-- Packet++/header/WireGuardLayer.h | 478 +++----- Packet++/src/EthDot3Layer.cpp | 16 +- Packet++/src/EthLayer.cpp | 18 +- Packet++/src/HttpLayer.cpp | 8 +- Packet++/src/IcmpV6Layer.cpp | 13 +- Packet++/src/IgmpLayer.cpp | 26 +- Packet++/src/NdpLayer.cpp | 16 +- Packet++/src/NflogLayer.cpp | 4 +- Packet++/src/SSLHandshake.cpp | 8 +- Packet++/src/SomeIpLayer.cpp | 2 +- Packet++/src/SomeIpSdLayer.cpp | 56 +- Packet++/src/VrrpLayer.cpp | 18 +- 78 files changed, 9664 insertions(+), 14573 deletions(-) diff --git a/Packet++/header/ArpLayer.h b/Packet++/header/ArpLayer.h index 4fb1b0db4c..0b1a3278e6 100644 --- a/Packet++/header/ArpLayer.h +++ b/Packet++/header/ArpLayer.h @@ -6,126 +6,103 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct arphdr - * Represents an ARP protocol header - */ + /// @struct arphdr + /// Represents an ARP protocol header #pragma pack(push, 1) struct arphdr { - /** Hardware type (HTYPE) */ + /// Hardware type (HTYPE) uint16_t hardwareType; - /** Protocol type (PTYPE). The permitted PTYPE values share a numbering space with those for EtherType */ + /// Protocol type (PTYPE). The permitted PTYPE values share a numbering space with those for EtherType uint16_t protocolType; - /** Hardware address length (HLEN). For IPv4, this has the value 0x0800 */ + /// Hardware address length (HLEN). For IPv4, this has the value 0x0800 uint8_t hardwareSize; - /** Protocol length (PLEN). Length (in octets) of addresses used in the upper layer protocol. (The upper layer - * protocol specified in PTYPE.) IPv4 address size is 4 */ + /// Protocol length (PLEN). Length (in octets) of addresses used in the upper layer protocol. (The upper layer + /// protocol specified in PTYPE.) IPv4 address size is 4 uint8_t protocolSize; - /** Specifies the operation that the sender is performing: 1 (::ARP_REQUEST) for request, 2 (::ARP_REPLY) for - * reply */ + /// Specifies the operation that the sender is performing: 1 (::ARP_REQUEST) for request, 2 (::ARP_REPLY) for + /// reply uint16_t opcode; - /** Sender hardware address (SHA) */ + /// Sender hardware address (SHA) uint8_t senderMacAddr[6]; - /** Sender protocol address (SPA) */ + /// Sender protocol address (SPA) uint32_t senderIpAddr; - /** Target hardware address (THA) */ + /// Target hardware address (THA) uint8_t targetMacAddr[6]; - /** Target protocol address (TPA) */ + /// Target protocol address (TPA) uint32_t targetIpAddr; }; #pragma pack(pop) - /** - * An enum for ARP message type - */ + /// An enum for ARP message type enum ArpOpcode { ARP_REQUEST = 0x0001, ///< ARP request ARP_REPLY = 0x0002 ///< ARP reply (response) }; - /** - * @class ArpLayer - * Represents an ARP protocol layer. Currently only IPv4 ARP messages are supported - */ + /// @class ArpLayer + /// Represents an ARP protocol layer. Currently only IPv4 ARP messages are supported class ArpLayer : public Layer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to @ref arphdr) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to @ref arphdr) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in ArpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, ARP) { m_DataLen = sizeof(arphdr); } - /** - * A constructor that allocates a new ARP header - * @param[in] opCode ARP message type (ARP request or ARP reply) - * @param[in] senderMacAddr The sender MAC address (will be put in arphdr#senderMacAddr) - * @param[in] targetMacAddr The target MAC address (will be put in arphdr#targetMacAddr) - * @param[in] senderIpAddr The sender IP address (will be put in arphdr#senderIpAddr) - * @param[in] targetIpAddr The target IP address (will be put in arphdr#targetIpAddr) - */ + /// A constructor that allocates a new ARP header + /// @param[in] opCode ARP message type (ARP request or ARP reply) + /// @param[in] senderMacAddr The sender MAC address (will be put in arphdr#senderMacAddr) + /// @param[in] targetMacAddr The target MAC address (will be put in arphdr#targetMacAddr) + /// @param[in] senderIpAddr The sender IP address (will be put in arphdr#senderIpAddr) + /// @param[in] targetIpAddr The target IP address (will be put in arphdr#targetIpAddr) ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const MacAddress& targetMacAddr, const IPv4Address& senderIpAddr, const IPv4Address& targetIpAddr); ~ArpLayer() override = default; - /** - * Get a pointer to the ARP header. Notice this points directly to the data, so every change will change the - * actual packet data - * @return A pointer to the @ref arphdr - */ + /// Get a pointer to the ARP header. Notice this points directly to the data, so every change will change the + /// actual packet data + /// @return A pointer to the @ref arphdr inline arphdr* getArpHeader() const { return reinterpret_cast(m_Data); } - /** - * Get the sender hardware address (SHA) in the form of MacAddress - * @return A MacAddress containing the sender hardware address (SHA) - */ + /// Get the sender hardware address (SHA) in the form of MacAddress + /// @return A MacAddress containing the sender hardware address (SHA) inline MacAddress getSenderMacAddress() const { return MacAddress(getArpHeader()->senderMacAddr); } - /** - * Get the target hardware address (THA) in the form of MacAddress - * @return A MacAddress containing the target hardware address (THA) - */ + /// Get the target hardware address (THA) in the form of MacAddress + /// @return A MacAddress containing the target hardware address (THA) inline MacAddress getTargetMacAddress() const { return MacAddress(getArpHeader()->targetMacAddr); } - /** - * Get the sender protocol address (SPA) in the form of IPv4Address - * @return An IPv4Address containing the sender protocol address (SPA) - */ + /// Get the sender protocol address (SPA) in the form of IPv4Address + /// @return An IPv4Address containing the sender protocol address (SPA) inline IPv4Address getSenderIpAddr() const { return getArpHeader()->senderIpAddr; } - /** - * Get the target protocol address (TPA) in the form of IPv4Address - * @return An IPv4Address containing the target protocol address (TPA) - */ + /// Get the target protocol address (TPA) in the form of IPv4Address + /// @return An IPv4Address containing the target protocol address (TPA) inline IPv4Address getTargetIpAddr() const { return getArpHeader()->targetIpAddr; @@ -133,38 +110,28 @@ namespace pcpp // implement abstract methods - /** - * Does nothing for this layer (ArpLayer is always last) - */ + /// Does nothing for this layer (ArpLayer is always last) void parseNextLayer() override {} - /** - * @return The size of @ref arphdr - */ + /// @return The size of @ref arphdr size_t getHeaderLen() const override { return sizeof(arphdr); } - /** - * Calculate the following fields: - * - @ref arphdr#hardwareType = Ethernet (1) - * - @ref arphdr#hardwareSize = 6 - * - @ref arphdr#protocolType = ETHERTYPE_IP (assume IPv4 over ARP) - * - @ref arphdr#protocolSize = 4 (assume IPv4 over ARP) - * - if it's an ARP request: @ref arphdr#targetMacAddr = MacAddress("00:00:00:00:00:00") - */ + /// Calculate the following fields: + /// - @ref arphdr#hardwareType = Ethernet (1) + /// - @ref arphdr#hardwareSize = 6 + /// - @ref arphdr#protocolType = ETHERTYPE_IP (assume IPv4 over ARP) + /// - @ref arphdr#protocolSize = 4 (assume IPv4 over ARP) + /// - if it's an ARP request: @ref arphdr#targetMacAddr = MacAddress("00:00:00:00:00:00") void computeCalculateFields() override; - /** - * Is this packet an ARP request? - */ + /// Is this packet an ARP request? bool isRequest() const; - /** - * Is this packet an ARP reply? - */ + /// Is this packet an ARP reply? bool isReply() const; std::string toString() const override; diff --git a/Packet++/header/Asn1Codec.h b/Packet++/header/Asn1Codec.h index 57db3ae258..1d0f74da26 100644 --- a/Packet++/header/Asn1Codec.h +++ b/Packet++/header/Asn1Codec.h @@ -8,194 +8,165 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * An enum for representing ASN.1 tag class - */ + /// An enum for representing ASN.1 tag class enum class Asn1TagClass : uint8_t { - /** The Universal tag class */ + /// The Universal tag class Universal = 0, - /** The Application tag class */ + /// The Application tag class Application = 1, - /** The Context-Specific tag class */ + /// The Context-Specific tag class ContextSpecific = 2, - /** The Private tag class */ + /// The Private tag class Private = 3, }; - /** - * An enum for representing ASN.1 Universal tag types - */ + /// An enum for representing ASN.1 Universal tag types enum class Asn1UniversalTagType : uint8_t { - /** The reserved identifier for the End-of-Contents marker in an indefinite length encoding */ + /// The reserved identifier for the End-of-Contents marker in an indefinite length encoding EndOfContent = 0, - /** The universal tag type for Boolean */ + /// The universal tag type for Boolean Boolean = 1, - /** The universal tag type for Integer */ + /// The universal tag type for Integer Integer = 2, - /** The universal tag type for Bit String */ + /// The universal tag type for Bit String BitString = 3, - /** The universal tag type for Octet String */ + /// The universal tag type for Octet String OctetString = 4, - /** The universal tag type for Null */ + /// The universal tag type for Null Null = 5, - /** The universal tag type for Object Identifier */ + /// The universal tag type for Object Identifier ObjectIdentifier = 6, - /** The universal tag type for Object Descriptor */ + /// The universal tag type for Object Descriptor ObjectDescriptor = 7, - /** The universal tag type for External */ + /// The universal tag type for External External = 8, - /** The universal tag type for Real */ + /// The universal tag type for Real Real = 9, - /** The universal tag type for Enumerated */ + /// The universal tag type for Enumerated Enumerated = 10, - /** The universal tag type for Embedded-PDV */ + /// The universal tag type for Embedded-PDV EmbeddedPDV = 11, - /** The universal tag type for UTF8 String */ + /// The universal tag type for UTF8 String UTF8String = 12, - /** The universal tag type for Relative Object Identifier */ + /// The universal tag type for Relative Object Identifier RelativeObjectIdentifier = 13, - /** The universal tag type for Time */ + /// The universal tag type for Time Time = 14, - /** A reserved value */ + /// A reserved value Reserved = 15, - /** The universal tag type Sequence */ + /// The universal tag type Sequence Sequence = 16, - /** The universal tag type for Set */ + /// The universal tag type for Set Set = 17, - /** The universal tag type for Numeric String */ + /// The universal tag type for Numeric String NumericString = 18, - /** The universal tag type for Printable String */ + /// The universal tag type for Printable String PrintableString = 19, - /** The universal tag type for T61String */ + /// The universal tag type for T61String T61String = 20, - /** The universal tag type for Videotex String */ + /// The universal tag type for Videotex String VideotexString = 21, - /** The universal tag type for IA5String */ + /// The universal tag type for IA5String IA5String = 22, - /** The universal tag type for UTC time */ + /// The universal tag type for UTC time UTCTime = 23, - /** The universal tag type for Generalized time */ + /// The universal tag type for Generalized time GeneralizedTime = 24, - /** The universal tag type for GraphicString */ + /// The universal tag type for GraphicString GraphicString = 25, - /** The universal tag type for VisibleString */ + /// The universal tag type for VisibleString VisibleString = 26, - /** The universal tag type for GeneralString */ + /// The universal tag type for GeneralString GeneralString = 27, - /** The universal tag type for UniversalString */ + /// The universal tag type for UniversalString UniversalString = 28, - /** The universal tag type for CharacterString */ + /// The universal tag type for CharacterString CharacterString = 29, - /** The universal tag type for BMPString */ + /// The universal tag type for BMPString BMPString = 30, - /** The universal tag type for Date */ + /// The universal tag type for Date Date = 31, - /** The universal tag type for Time of Day */ + /// The universal tag type for Time of Day TimeOfDay = 32, - /** The universal tag type for Date-Time */ + /// The universal tag type for Date-Time DateTime = 33, - /** The universal tag type for Duration */ + /// The universal tag type for Duration Duration = 34, - /** The universal tag type for Object Identifier Internationalized Resource Identifier (IRI) */ + /// The universal tag type for Object Identifier Internationalized Resource Identifier (IRI) ObjectIdentifierIRI = 35, - /** The universal tag type for Relative Object Identifier Internationalized Resource Identifier (IRI) */ + /// The universal tag type for Relative Object Identifier Internationalized Resource Identifier (IRI) RelativeObjectIdentifierIRI = 36, - /** A non-applicable value */ + /// A non-applicable value NotApplicable = 255 }; - /** - * @class Asn1Record - * Represents an ASN.1 record, as described in ITU-T Recommendation X.680: - * - * - * - */ + /// @class Asn1Record + /// Represents an ASN.1 record, as described in ITU-T Recommendation X.680: + /// + /// class Asn1Record { public: - /** - * A static method to decode a byte array into an Asn1Record - * @param data A byte array to decode - * @param dataLen The byte array length - * @param lazy Use lazy decoding, set to true by default. Lazy decoding entails delaying the decoding - * of the record value until it is accessed - * @return A smart pointer to the decoded ASN.1 record. If the byte stream is not a valid ASN.1 record - * an exception is thrown - */ + /// A static method to decode a byte array into an Asn1Record + /// @param data A byte array to decode + /// @param dataLen The byte array length + /// @param lazy Use lazy decoding, set to true by default. Lazy decoding entails delaying the decoding + /// of the record value until it is accessed + /// @return A smart pointer to the decoded ASN.1 record. If the byte stream is not a valid ASN.1 record + /// an exception is thrown static std::unique_ptr decode(const uint8_t* data, size_t dataLen, bool lazy = true); - /** - * Encode this record and convert it to a byte stream - * @return A vector of bytes representing the record - */ + /// Encode this record and convert it to a byte stream + /// @return A vector of bytes representing the record std::vector encode(); - /** - * @return The ASN.1 tag class - */ + /// @return The ASN.1 tag class Asn1TagClass getTagClass() const { return m_TagClass; } - /** - * @return True if it's a constructed record, or false if it's a primitive record - */ + /// @return True if it's a constructed record, or false if it's a primitive record bool isConstructed() const { return m_IsConstructed; } - /** - * @return The ASN.1 Universal tag type if the record is of class Universal, otherwise - * Asn1UniversalTagType#NotApplicable - */ + /// @return The ASN.1 Universal tag type if the record is of class Universal, otherwise + /// Asn1UniversalTagType#NotApplicable Asn1UniversalTagType getUniversalTagType() const; - /** - * @return The ASN.1 tag type value - */ + /// @return The ASN.1 tag type value uint8_t getTagType() const { return m_TagType; } - /** - * @return The length of the record value - */ + /// @return The length of the record value size_t getValueLength() const { return m_ValueLength; } - /** - * @return The total length of the record - */ + /// @return The total length of the record size_t getTotalLength() const { return m_TotalLength; } - /** - * @return A string representation of the record - */ + /// @return A string representation of the record std::string toString(); - /** - * A templated method that accepts a class derived from Asn1Record as its template argument and attempts - * to cast the current instance to that type - * @tparam Asn1RecordType The type to cast to - * @return A pointer to the type after casting - */ + /// A templated method that accepts a class derived from Asn1Record as its template argument and attempts + /// to cast the current instance to that type + /// @tparam Asn1RecordType The type to cast to + /// @return A pointer to the type after casting template Asn1RecordType* castAs() { auto result = dynamic_cast(this); @@ -237,41 +208,33 @@ namespace pcpp friend class Asn1ConstructedRecord; }; - /** - * @class Asn1GenericRecord - * Represents a generic ASN.1 record, either of an unknown type or of a known type that doesn't - * have a dedicated parser yet - */ + /// @class Asn1GenericRecord + /// Represents a generic ASN.1 record, either of an unknown type or of a known type that doesn't + /// have a dedicated parser yet class Asn1GenericRecord : public Asn1Record { friend class Asn1Record; public: - /** - * A constructor to create a generic record - * @param tagClass The record tag class - * @param isConstructed A flag to indicate if the record is constructed or primitive - * @param tagType The record tag type value - * @param value A byte array of the tag value - * @param valueLen The length of the value byte array - */ + /// A constructor to create a generic record + /// @param tagClass The record tag class + /// @param isConstructed A flag to indicate if the record is constructed or primitive + /// @param tagType The record tag type value + /// @param value A byte array of the tag value + /// @param valueLen The length of the value byte array Asn1GenericRecord(Asn1TagClass tagClass, bool isConstructed, uint8_t tagType, const uint8_t* value, size_t valueLen); - /** - * A constructor to create a generic record - * @param tagClass The record tag class - * @param isConstructed A flag to indicate if the record is constructed or primitive - * @param tagType The record tag type value - * @param value A string representing the tag value - */ + /// A constructor to create a generic record + /// @param tagClass The record tag class + /// @param isConstructed A flag to indicate if the record is constructed or primitive + /// @param tagType The record tag type value + /// @param value A string representing the tag value Asn1GenericRecord(Asn1TagClass tagClass, bool isConstructed, uint8_t tagType, const std::string& value); ~Asn1GenericRecord() override; - /** - * @return A pointer to the tag value - */ + /// @return A pointer to the tag value const uint8_t* getValue() { decodeValueIfNeeded(); @@ -290,37 +253,29 @@ namespace pcpp void init(Asn1TagClass tagClass, bool isConstructed, uint8_t tagType, const uint8_t* value, size_t valueLen); }; - /** - * @class Asn1ConstructedRecord - * Represents a constructed ASN.1 record, which is a record that has sub-records - */ + /// @class Asn1ConstructedRecord + /// Represents a constructed ASN.1 record, which is a record that has sub-records class Asn1ConstructedRecord : public Asn1Record { friend class Asn1Record; public: - /** - * A constructor to create a constructed record - * @param tagClass The record tag class - * @param tagType The record tag type value - * @param subRecords A list of sub-records to assign as the record value - */ + /// A constructor to create a constructed record + /// @param tagClass The record tag class + /// @param tagType The record tag type value + /// @param subRecords A list of sub-records to assign as the record value explicit Asn1ConstructedRecord(Asn1TagClass tagClass, uint8_t tagType, const std::vector& subRecords); - /** - * A constructor to create a constructed record - * @param tagClass The record tag class - * @param tagType The record tag type value - * @param subRecords A PointerVector of sub-records to assign as the record value - */ + /// A constructor to create a constructed record + /// @param tagClass The record tag class + /// @param tagType The record tag type value + /// @param subRecords A PointerVector of sub-records to assign as the record value explicit Asn1ConstructedRecord(Asn1TagClass tagClass, uint8_t tagType, const PointerVector& subRecords); - /** - * @return A reference to the list of sub-records. It's important to note that any modifications made to - * this list will directly affect the internal structure - */ + /// @return A reference to the list of sub-records. It's important to note that any modifications made to + /// this list will directly affect the internal structure PointerVector& getSubRecords() { decodeValueIfNeeded(); @@ -358,61 +313,47 @@ namespace pcpp PointerVector m_SubRecords; }; - /** - * @class Asn1SequenceRecord - * Represents an ASN.1 record with a value of type Sequence - */ + /// @class Asn1SequenceRecord + /// Represents an ASN.1 record with a value of type Sequence class Asn1SequenceRecord : public Asn1ConstructedRecord { friend class Asn1Record; public: - /** - * A constructor to create a record of type Sequence - * @param subRecords A list of sub-records to assign as the record value - */ + /// A constructor to create a record of type Sequence + /// @param subRecords A list of sub-records to assign as the record value explicit Asn1SequenceRecord(const std::vector& subRecords); - /** - * A constructor to create a record of type Sequence - * @param subRecords A PointerVector of sub-records to assign as the record value - */ + /// A constructor to create a record of type Sequence + /// @param subRecords A PointerVector of sub-records to assign as the record value explicit Asn1SequenceRecord(const PointerVector& subRecords); private: Asn1SequenceRecord() = default; }; - /** - * @class Asn1SetRecord - * Represents an ASN.1 record with a value of type Set - */ + /// @class Asn1SetRecord + /// Represents an ASN.1 record with a value of type Set class Asn1SetRecord : public Asn1ConstructedRecord { friend class Asn1Record; public: - /** - * A constructor to create a record of type Set - * @param subRecords A list of sub-records to assign as the record value - */ + /// A constructor to create a record of type Set + /// @param subRecords A list of sub-records to assign as the record value explicit Asn1SetRecord(const std::vector& subRecords); - /** - * A constructor to create a record of type Set - * @param subRecords A PointerVector of sub-records to assign as the record value - */ + /// A constructor to create a record of type Set + /// @param subRecords A PointerVector of sub-records to assign as the record value explicit Asn1SetRecord(const PointerVector& subRecords); private: Asn1SetRecord() = default; }; - /** - * @class Asn1PrimitiveRecord - * Represents a primitive ASN.1 record, meaning a record that doesn't have sub-records. - * This is an abstract class that cannot be instantiated - */ + /// @class Asn1PrimitiveRecord + /// Represents a primitive ASN.1 record, meaning a record that doesn't have sub-records. + /// This is an abstract class that cannot be instantiated class Asn1PrimitiveRecord : public Asn1Record { friend class Asn1Record; @@ -422,24 +363,18 @@ namespace pcpp explicit Asn1PrimitiveRecord(Asn1UniversalTagType tagType); }; - /** - * @class Asn1IntegerRecord - * Represents an ASN.1 record with a value of type Integer - */ + /// @class Asn1IntegerRecord + /// Represents an ASN.1 record with a value of type Integer class Asn1IntegerRecord : public Asn1PrimitiveRecord { friend class Asn1Record; public: - /** - * A constructor to create a record of type Integer - * @param value An integer to set as the record value - */ + /// A constructor to create a record of type Integer + /// @param value An integer to set as the record value explicit Asn1IntegerRecord(uint32_t value); - /** - * @return The integer value of this record - */ + /// @return The integer value of this record uint32_t getValue() { decodeValueIfNeeded(); @@ -458,50 +393,38 @@ namespace pcpp uint32_t m_Value = 0; }; - /** - * @class Asn1EnumeratedRecord - * Represents an ASN.1 record with a value of type Enumerated - */ + /// @class Asn1EnumeratedRecord + /// Represents an ASN.1 record with a value of type Enumerated class Asn1EnumeratedRecord : public Asn1IntegerRecord { friend class Asn1Record; public: - /** - * A constructor to create a record of type Enumerated - * @param value An integer to set as the record value - */ + /// A constructor to create a record of type Enumerated + /// @param value An integer to set as the record value explicit Asn1EnumeratedRecord(uint32_t value); private: Asn1EnumeratedRecord() = default; }; - /** - * @class Asn1OctetStringRecord - * Represents an ASN.1 record with a value of type Octet String - */ + /// @class Asn1OctetStringRecord + /// Represents an ASN.1 record with a value of type Octet String class Asn1OctetStringRecord : public Asn1PrimitiveRecord { friend class Asn1Record; public: - /** - * A constructor to create a record of type Octet String from a printable value - * @param value A string to set as the record value - */ + /// A constructor to create a record of type Octet String from a printable value + /// @param value A string to set as the record value explicit Asn1OctetStringRecord(const std::string& value); - /** - * A constructor to create a record of type Octet String from a non-printable value - * @param value A byte array to set as the record value - * @param valueLength The length of the byte array - */ + /// A constructor to create a record of type Octet String from a non-printable value + /// @param value A byte array to set as the record value + /// @param valueLength The length of the byte array explicit Asn1OctetStringRecord(const uint8_t* value, size_t valueLength); - /** - * @return The string value of this record - */ + /// @return The string value of this record std::string getValue() { decodeValueIfNeeded(); @@ -521,24 +444,18 @@ namespace pcpp Asn1OctetStringRecord() = default; }; - /** - * @class Asn1BooleanRecord - * Represents an ASN.1 record with a value of type Boolean - */ + /// @class Asn1BooleanRecord + /// Represents an ASN.1 record with a value of type Boolean class Asn1BooleanRecord : public Asn1PrimitiveRecord { friend class Asn1Record; public: - /** - * A constructor to create a record of type Boolean - * @param value A boolean to set as the record value - */ + /// A constructor to create a record of type Boolean + /// @param value A boolean to set as the record value explicit Asn1BooleanRecord(bool value); - /** - * @return The boolean value of this record - */ + /// @return The boolean value of this record bool getValue() { decodeValueIfNeeded(); @@ -557,18 +474,14 @@ namespace pcpp bool m_Value = false; }; - /** - * @class Asn1NullRecord - * Represents an ASN.1 record with a value of type Null - */ + /// @class Asn1NullRecord + /// Represents an ASN.1 record with a value of type Null class Asn1NullRecord : public Asn1PrimitiveRecord { friend class Asn1Record; public: - /** - * A constructor to create a record of type Null - */ + /// A constructor to create a record of type Null Asn1NullRecord(); protected: diff --git a/Packet++/header/BgpLayer.h b/Packet++/header/BgpLayer.h index 8bb7bf3946..00ced23bfe 100644 --- a/Packet++/header/BgpLayer.h +++ b/Packet++/header/BgpLayer.h @@ -4,108 +4,86 @@ #include "Layer.h" #include "IpAddress.h" -/** - * @file - * This file contains classes for parsing, creating and editing Border Gateway Protocol (BGP) version 4 packets. - * It contains an abstract class named BgpLayer which has common functionality and 5 inherited classes that - * represent the different BGP message types: OPEN, UPDATE, NOTIFICATION, KEEPALIVE and ROUTE-REFRESH. - * Each of these classes contains unique functionality for parsing. creating and editing of these message. - */ - -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @file +/// This file contains classes for parsing, creating and editing Border Gateway Protocol (BGP) version 4 packets. +/// It contains an abstract class named BgpLayer which has common functionality and 5 inherited classes that +/// represent the different BGP message types: OPEN, UPDATE, NOTIFICATION, KEEPALIVE and ROUTE-REFRESH. +/// Each of these classes contains unique functionality for parsing. creating and editing of these message. + +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @class BgpLayer - * Represents Border Gateway Protocol (BGP) v4 protocol layer. This is an abstract class that cannot be - * instantiated, and contains functionality which is common to all BGP message types. - */ + /// @class BgpLayer + /// Represents Border Gateway Protocol (BGP) v4 protocol layer. This is an abstract class that cannot be + /// instantiated, and contains functionality which is common to all BGP message types. class BgpLayer : public Layer { public: - /** - * An enum representing BGP message types - */ + /// An enum representing BGP message types enum BgpMessageType { - /** BGP OPEN message */ + /// BGP OPEN message Open = 1, - /** BGP UPDATE message */ + /// BGP UPDATE message Update = 2, - /** BGP NOTIFICATION message */ + /// BGP NOTIFICATION message Notification = 3, - /** BGP KEEPALIVE message */ + /// BGP KEEPALIVE message Keepalive = 4, - /** BGP ROUTE-REFRESH message */ + /// BGP ROUTE-REFRESH message RouteRefresh = 5, }; #pragma pack(push, 1) - /** - * @struct bgp_common_header - * Represents the common fields of a BGP 4 message - */ + /// @struct bgp_common_header + /// Represents the common fields of a BGP 4 message struct bgp_common_header { - /** 16-octet marker */ + /// 16-octet marker uint8_t marker[16]; - /** Total length of the message, including the header */ + /// Total length of the message, including the header uint16_t length; - /** BGP message type */ + /// BGP message type uint8_t messageType; }; #pragma pack(pop) static_assert(sizeof(bgp_common_header) == 19, "bgp_common_header size is not 19 bytes"); - /** - * @return BGP message type - */ + /// @return BGP message type virtual BgpMessageType getBgpMessageType() const = 0; - /** - * @return BGP message type as string. Return value can be one of the following: - * "OPEN", "UPDATE", "NOTIFICATION", "KEEPALIVE", "ROUTE-REFRESH", "Unknown" - */ + /// @return BGP message type as string. Return value can be one of the following: + /// "OPEN", "UPDATE", "NOTIFICATION", "KEEPALIVE", "ROUTE-REFRESH", "Unknown" std::string getMessageTypeAsString() const; - /** - * A static method that checks whether a source or dest port match those associated with the BGP protocol - * @param[in] portSrc Source port number to check - * @param[in] portDst Dest port number to check - * @return True if the source or dest port match those associated with the BGP protocol - */ + /// A static method that checks whether a source or dest port match those associated with the BGP protocol + /// @param[in] portSrc Source port number to check + /// @param[in] portDst Dest port number to check + /// @return True if the source or dest port match those associated with the BGP protocol static bool isBgpPort(uint16_t portSrc, uint16_t portDst) { return portSrc == 179 || portDst == 179; } - /** - * A method that creates a BGP layer from packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored - * @return A newly allocated BGP layer of one of the following types (according to the message type): - * BgpOpenMessageLayer, BgpUpdateMessageLayer, BgpNotificationMessageLayer, BgpKeepaliveMessageLayer, - * BgpRouteRefreshMessageLayer - */ + /// A method that creates a BGP layer from packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored + /// @return A newly allocated BGP layer of one of the following types (according to the message type): + /// BgpOpenMessageLayer, BgpUpdateMessageLayer, BgpNotificationMessageLayer, BgpKeepaliveMessageLayer, + /// BgpRouteRefreshMessageLayer static BgpLayer* parseBgpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); // implement abstract methods - /** - * @return The size of the BGP message - */ + /// @return The size of the BGP message size_t getHeaderLen() const override; - /** - * Multiple BGP messages can reside in a single packet, and the only layer that can come after a BGP message - * is another BGP message. This method checks for remaining data and parses it as another BGP layer - */ + /// Multiple BGP messages can reside in a single packet, and the only layer that can come after a BGP message + /// is another BGP message. This method checks for remaining data and parses it as another BGP layer void parseNextLayer() override; std::string toString() const override; @@ -115,12 +93,10 @@ namespace pcpp return OsiModelApplicationLayer; } - /** - * Calculates the basic BGP fields: - * - Set marker to all ones - * - Set message type value - * - Set message length - */ + /// Calculates the basic BGP fields: + /// - Set marker to all ones + /// - Set message type value + /// - Set message length void computeCalculateFields() override; protected: @@ -139,136 +115,109 @@ namespace pcpp void setBgpFields(size_t messageLen = 0); }; - /** - * @class BgpOpenMessageLayer - * Represents a BGP v4 OPEN message - */ + /// @class BgpOpenMessageLayer + /// Represents a BGP v4 OPEN message class BgpOpenMessageLayer : public BgpLayer { public: #pragma pack(push, 1) - /** - * @struct bgp_open_message - * BGP OPEN message structure - */ + /// @struct bgp_open_message + /// BGP OPEN message structure typedef struct bgp_open_message : bgp_common_header { - /** BGP version number */ + /// BGP version number uint8_t version; - /** Autonomous System number of the sender */ + /// Autonomous System number of the sender uint16_t myAutonomousSystem; - /** The number of seconds the sender proposes for the value of the Hold Timer */ + /// The number of seconds the sender proposes for the value of the Hold Timer uint16_t holdTime; - /** BGP Identifier of the sender */ + /// BGP Identifier of the sender uint32_t bgpId; - /** The total length of the Optional Parameters field */ + /// The total length of the Optional Parameters field uint8_t optionalParameterLength; } bgp_open_message; #pragma pack(pop) - /** - * @struct optional_parameter - * A structure that represents BGP OPEN message optional parameters - */ + /// @struct optional_parameter + /// A structure that represents BGP OPEN message optional parameters struct optional_parameter { - /** Parameter type */ + /// Parameter type uint8_t type; - /** Parameter length */ + /// Parameter length uint8_t length; - /** Parameter data */ + /// Parameter data uint8_t value[32]; - /** - * A default c'tor that zeroes all data - */ + // FIXME: This does not actually zero the data. + /// A default c'tor that zeroes all data optional_parameter() {} - /** - * A c'tor that initializes the values of the struct - * @param[in] typeVal Parameter type value - * @param[in] valueAsHexString Parameter data as hex string. The length field will be set accordingly. - * If this parameter is not a valid hex string the data will remain zeroed and length will be also zero - */ + /// A c'tor that initializes the values of the struct + /// @param[in] typeVal Parameter type value + /// @param[in] valueAsHexString Parameter data as hex string. The length field will be set accordingly. + /// If this parameter is not a valid hex string the data will remain zeroed and length will be also zero optional_parameter(uint8_t typeVal, const std::string& valueAsHexString); }; - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in BgpOpenMessageLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : BgpLayer(data, dataLen, prevLayer, packet) {} - /** - * A c'tor that creates a new BGP OPEN message - * @param[in] myAutonomousSystem The Autonomous System number of the sender - * @param[in] holdTime The number of seconds the sender proposes for the value of the Hold Timer - * @param[in] bgpId The BGP Identifier of the sender - * @param[in] optionalParams A vector of optional parameters. This parameter is optional and if not provided no - * parameters will be set on the message - */ + /// A c'tor that creates a new BGP OPEN message + /// @param[in] myAutonomousSystem The Autonomous System number of the sender + /// @param[in] holdTime The number of seconds the sender proposes for the value of the Hold Timer + /// @param[in] bgpId The BGP Identifier of the sender + /// @param[in] optionalParams A vector of optional parameters. This parameter is optional and if not provided no + /// parameters will be set on the message BgpOpenMessageLayer(uint16_t myAutonomousSystem, uint16_t holdTime, const IPv4Address& bgpId, const std::vector& optionalParams = std::vector()); - /** - * Get a pointer to the open message data. Notice this points directly to the data, so any change will modify - * the actual packet data - * @return A pointer to a bgp_open_message structure containing the data - */ + /// Get a pointer to the open message data. Notice this points directly to the data, so any change will modify + /// the actual packet data + /// @return A pointer to a bgp_open_message structure containing the data bgp_open_message* getOpenMsgHeader() const { return reinterpret_cast(m_Data); } - /** - * @return The BGP identifier as IPv4Address object - */ + /// @return The BGP identifier as IPv4Address object IPv4Address getBgpId() const { return IPv4Address(getOpenMsgHeader()->bgpId); } - /** - * Set the BGP identifier - * @param[in] newBgpId BGP identifier to set. If value is not a valid IPv4 address it won't be set - */ + /// Set the BGP identifier + /// @param[in] newBgpId BGP identifier to set. If value is not a valid IPv4 address it won't be set void setBgpId(const IPv4Address& newBgpId); - /** - * Get a vector of the optional parameters in the message - * @param[out] optionalParameters The vector where the optional parameters will be written to. This method - * doesn't remove any existing data on this vector before pushing data to it - */ + /// Get a vector of the optional parameters in the message + /// @param[out] optionalParameters The vector where the optional parameters will be written to. This method + /// doesn't remove any existing data on this vector before pushing data to it void getOptionalParameters(std::vector& optionalParameters); - /** - * @return The length in [bytes] of the optional parameters data in the message - */ + /// @return The length in [bytes] of the optional parameters data in the message size_t getOptionalParametersLength(); - /** - * Set optional parameters in the message. This method will override all existing optional parameters currently - * in the message. If the input is an empty vector all optional parameters will be cleared. This method - * automatically sets the bgp_common_header#length and the bgp_open_message#optionalParameterLength fields on - * the message - * @param[in] optionalParameters A vector of new optional parameters to set in the message - * @return True if all optional parameters were set successfully or false otherwise. In case of an error an - * appropriate message will be printed to log - */ + /// Set optional parameters in the message. This method will override all existing optional parameters currently + /// in the message. If the input is an empty vector all optional parameters will be cleared. This method + /// automatically sets the bgp_common_header#length and the bgp_open_message#optionalParameterLength fields on + /// the message + /// @param[in] optionalParameters A vector of new optional parameters to set in the message + /// @return True if all optional parameters were set successfully or false otherwise. In case of an error an + /// appropriate message will be printed to log bool setOptionalParameters(const std::vector& optionalParameters); - /** - * Clear all optional parameters currently in the message. This is equivalent to calling setOptionalParameters() - * with an empty vector as a parameter - * @return True if all optional parameters were successfully cleared or false otherwise. In case of an error an - * appropriate message will be printed to log - */ + /// Clear all optional parameters currently in the message. This is equivalent to calling + /// setOptionalParameters() with an empty vector as a parameter + /// @return True if all optional parameters were successfully cleared or false otherwise. In case of an error an + /// appropriate message will be printed to log bool clearOptionalParameters(); // implement abstract methods @@ -283,200 +232,155 @@ namespace pcpp size_t maxByteArrSize); }; - /** - * @class BgpUpdateMessageLayer - * Represents a BGP v4 UPDATE message - */ + /// @class BgpUpdateMessageLayer + /// Represents a BGP v4 UPDATE message class BgpUpdateMessageLayer : public BgpLayer { public: - /** - * @struct prefix_and_ip - * A structure that contains IPv4 address and IP address mask (prefix) information. - * It's used to represent BGP Withdrawn Routes and Network Layer Reachability Information (NLRI) - */ + /// @struct prefix_and_ip + /// A structure that contains IPv4 address and IP address mask (prefix) information. + /// It's used to represent BGP Withdrawn Routes and Network Layer Reachability Information (NLRI) struct prefix_and_ip { - /** IPv4 address mask, must contain one of the values: 8, 16, 24, 32 */ + /// IPv4 address mask, must contain one of the values: 8, 16, 24, 32 uint8_t prefix; - /** IPv4 address */ + /// IPv4 address IPv4Address ipAddr; - /** - * A default c'tor that zeroes all data - */ + /// A default c'tor that zeroes all data prefix_and_ip() : prefix(0), ipAddr(IPv4Address::Zero) {} - /** - * A c'tor that initializes the values of the struct - * @param[in] prefixVal IPv4 address mask value - * @param[in] ipAddrVal IPv4 address - */ + /// A c'tor that initializes the values of the struct + /// @param[in] prefixVal IPv4 address mask value + /// @param[in] ipAddrVal IPv4 address prefix_and_ip(uint8_t prefixVal, const std::string& ipAddrVal) : prefix(prefixVal), ipAddr(ipAddrVal) {} }; - /** - * @struct path_attribute - * A structure that represents BGP OPEN message Path Attributes information - */ + /// @struct path_attribute + /// A structure that represents BGP OPEN message Path Attributes information struct path_attribute { - /** Path attribute flags */ + /// Path attribute flags uint8_t flags; - /** Path attribute type */ + /// Path attribute type uint8_t type; - /** Path attribute length */ + /// Path attribute length uint8_t length; - /** Path attribute data. Max supported data length is 32 bytes */ + /// Path attribute data. Max supported data length is 32 bytes uint8_t data[32]; - /** - * A default c'tor that zeroes all data - */ + // FIXME: This does not actually zero the data. + /// A default c'tor that zeroes all data path_attribute() {} - /** - * A c'tor that initializes the values of the struct - * @param[in] flagsVal Path attribute flags value - * @param[in] typeVal Path attribute type value - * @param[in] dataAsHexString Path attribute data as hex string. The path_attribute#length field will be set - * accordingly. If this parameter is not a valid hex string the data will remain zeroed and length will be - * also set to zero - */ + /// A c'tor that initializes the values of the struct + /// @param[in] flagsVal Path attribute flags value + /// @param[in] typeVal Path attribute type value + /// @param[in] dataAsHexString Path attribute data as hex string. The path_attribute#length field will be + /// set accordingly. If this parameter is not a valid hex string the data will remain zeroed and length will + /// be also set to zero path_attribute(uint8_t flagsVal, uint8_t typeVal, const std::string& dataAsHexString); }; - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in BgpUpdateMessageLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : BgpLayer(data, dataLen, prevLayer, packet) {} - /** - * A static method that takes a byte array and detects whether it is a BgpUpdateMessage - * @param[in] data A byte array - * @param[in] dataSize The byte array size (in bytes) - * @return True if the data looks like a valid BgpUpdateMessage layer - */ + /// A static method that takes a byte array and detects whether it is a BgpUpdateMessage + /// @param[in] data A byte array + /// @param[in] dataSize The byte array size (in bytes) + /// @return True if the data looks like a valid BgpUpdateMessage layer static bool isDataValid(const uint8_t* data, size_t dataSize); - /** - * A c'tor that creates a new BGP UPDATE message - * @param[in] withdrawnRoutes A vector of withdrawn routes data. If left empty (which is the default value) no - * withdrawn route information will be written to the message - * @param[in] pathAttributes A vector of path attributes data. If left empty (which is the default value) no - * path attribute information will be written to the message - * @param[in] nlri A vector of network layer reachability data. If left empty (which is the default value) no - * reachability information will be written to the message - */ + /// A c'tor that creates a new BGP UPDATE message + /// @param[in] withdrawnRoutes A vector of withdrawn routes data. If left empty (which is the default value) no + /// withdrawn route information will be written to the message + /// @param[in] pathAttributes A vector of path attributes data. If left empty (which is the default value) no + /// path attribute information will be written to the message + /// @param[in] nlri A vector of network layer reachability data. If left empty (which is the default value) no + /// reachability information will be written to the message explicit BgpUpdateMessageLayer( const std::vector& withdrawnRoutes = std::vector(), const std::vector& pathAttributes = std::vector(), const std::vector& nlri = std::vector()); - /** - * Get a pointer to the basic BGP message data. Notice this points directly to the data, so any change will - * modify the actual packet data - * @return A pointer to a bgp_common_header structure containing the data - */ + /// Get a pointer to the basic BGP message data. Notice this points directly to the data, so any change will + /// modify the actual packet data + /// @return A pointer to a bgp_common_header structure containing the data bgp_common_header* getBasicMsgHeader() const { return reinterpret_cast(m_Data); } - /** - * @return The size in [bytes] of the Withdrawn Routes data - */ + /// @return The size in [bytes] of the Withdrawn Routes data size_t getWithdrawnRoutesLength() const; - /** - * Get a vector of the Withdrawn Routes currently in the message - * @param[out] withdrawnRoutes A reference to a vector the Withdrawn Routes data will be written to - */ + /// Get a vector of the Withdrawn Routes currently in the message + /// @param[out] withdrawnRoutes A reference to a vector the Withdrawn Routes data will be written to void getWithdrawnRoutes(std::vector& withdrawnRoutes); - /** - * Set Withdrawn Routes in this message. This method will override any existing Withdrawn Routes in the message. - * If the input is an empty vector all Withdrawn Routes will be removed. This method automatically sets the - * bgp_common_header#length and the Withdrawn Routes length fields in the message - * @param[in] withdrawnRoutes New Withdrawn Routes to set in the message - * @return True if all Withdrawn Routes were set successfully or false otherwise. In case of an error an - * appropriate message will be printed to log - */ + /// Set Withdrawn Routes in this message. This method will override any existing Withdrawn Routes in the + /// message. If the input is an empty vector all Withdrawn Routes will be removed. This method automatically + /// sets the bgp_common_header#length and the Withdrawn Routes length fields in the message + /// @param[in] withdrawnRoutes New Withdrawn Routes to set in the message + /// @return True if all Withdrawn Routes were set successfully or false otherwise. In case of an error an + /// appropriate message will be printed to log bool setWithdrawnRoutes(const std::vector& withdrawnRoutes); - /** - * Clear all Withdrawn Routes data currently in the message. This is equivalent to calling setWithdrawnRoutes() - * with an empty vector as a parameter - * @return True if all Withdrawn Routes were successfully cleared or false otherwise. In case of an error an - * appropriate message will be printed to log - */ + /// Clear all Withdrawn Routes data currently in the message. This is equivalent to calling setWithdrawnRoutes() + /// with an empty vector as a parameter + /// @return True if all Withdrawn Routes were successfully cleared or false otherwise. In case of an error an + /// appropriate message will be printed to log bool clearWithdrawnRoutes(); - /** - * @return The size in [bytes] of the Path Attributes data - */ + /// @return The size in [bytes] of the Path Attributes data size_t getPathAttributesLength() const; - /** - * Get a vector of the Path Attributes currently in the message - * @param[out] pathAttributes A reference to a vector the Path Attributes data will be written to - */ + /// Get a vector of the Path Attributes currently in the message + /// @param[out] pathAttributes A reference to a vector the Path Attributes data will be written to void getPathAttributes(std::vector& pathAttributes); - /** - * Set Path Attributes in this message. This method will override any existing Path Attributes in the message. - * If the input is an empty vector all Path Attributes will be removed. This method automatically sets the - * bgp_common_header#length and the Path Attributes length fields in the message - * @param[in] pathAttributes New Path Attributes to set in the message - * @return True if all Path Attributes were set successfully or false otherwise. In case of an error an - * appropriate message will be printed to log - */ + /// Set Path Attributes in this message. This method will override any existing Path Attributes in the message. + /// If the input is an empty vector all Path Attributes will be removed. This method automatically sets the + /// bgp_common_header#length and the Path Attributes length fields in the message + /// @param[in] pathAttributes New Path Attributes to set in the message + /// @return True if all Path Attributes were set successfully or false otherwise. In case of an error an + /// appropriate message will be printed to log bool setPathAttributes(const std::vector& pathAttributes); - /** - * Clear all Path Attributes data currently in the message. This is equivalent to calling setPathAttributes() - * with an empty vector as a parameter - * @return True if all Path Attributes were successfully cleared or false otherwise. In case of an error an - * appropriate message will be printed to log - */ + /// Clear all Path Attributes data currently in the message. This is equivalent to calling setPathAttributes() + /// with an empty vector as a parameter + /// @return True if all Path Attributes were successfully cleared or false otherwise. In case of an error an + /// appropriate message will be printed to log bool clearPathAttributes(); - /** - * @return The size in [bytes] of the Network Layer Reachability Info - */ + /// @return The size in [bytes] of the Network Layer Reachability Info size_t getNetworkLayerReachabilityInfoLength() const; - /** - * Get a vector of the Network Layer Reachability Info currently in the message - * @param[out] nlri A reference to a vector the NLRI data will be written to - */ + /// Get a vector of the Network Layer Reachability Info currently in the message + /// @param[out] nlri A reference to a vector the NLRI data will be written to void getNetworkLayerReachabilityInfo(std::vector& nlri); - /** - * Set NLRI data in this message. This method will override any existing NLRI data in the message. - * If the input is an empty vector all NLRI data will be removed. This method automatically sets the - * bgp_common_header#length field in the message - * @param[in] nlri New NLRI data to set in the message - * @return True if all NLRI data was set successfully or false otherwise. In case of an error an appropriate - * message will be printed to log - */ + /// Set NLRI data in this message. This method will override any existing NLRI data in the message. + /// If the input is an empty vector all NLRI data will be removed. This method automatically sets the + /// bgp_common_header#length field in the message + /// @param[in] nlri New NLRI data to set in the message + /// @return True if all NLRI data was set successfully or false otherwise. In case of an error an appropriate + /// message will be printed to log bool setNetworkLayerReachabilityInfo(const std::vector& nlri); - /** - * Clear all NLRI data currently in the message. This is equivalent to calling setNetworkLayerReachabilityInfo() - * with an empty vector as a parameter - * @return True if all NLRI were successfully cleared or false otherwise. In case of an error an appropriate - * message will be printed to log - */ + /// Clear all NLRI data currently in the message. This is equivalent to calling + /// setNetworkLayerReachabilityInfo() with an empty vector as a parameter + /// @return True if all NLRI were successfully cleared or false otherwise. In case of an error an appropriate + /// message will be printed to log bool clearNetworkLayerReachabilityInfo(); // implement abstract methods @@ -496,113 +400,89 @@ namespace pcpp size_t maxByteArrSize); }; - /** - * @class BgpNotificationMessageLayer - * Represents a BGP v4 NOTIFICATION message - */ + /// @class BgpNotificationMessageLayer + /// Represents a BGP v4 NOTIFICATION message class BgpNotificationMessageLayer : public BgpLayer { public: #pragma pack(push, 1) - /** - * @struct bgp_notification_message - * BGP NOTIFICATION message structure - */ + /// @struct bgp_notification_message + /// BGP NOTIFICATION message structure typedef struct bgp_notification_message : bgp_common_header { - /** BGP notification error code */ + /// BGP notification error code uint8_t errorCode; - /** BGP notification error sub-code */ + /// BGP notification error sub-code uint8_t errorSubCode; } bgp_notification_message; #pragma pack(pop) - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in BgpNotificationMessageLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : BgpLayer(data, dataLen, prevLayer, packet) {} - /** - * A c'tor that creates a new BGP NOTIFICATION message - * @param[in] errorCode BGP notification error code - * @param[in] errorSubCode BGP notification error sub code - */ + /// A c'tor that creates a new BGP NOTIFICATION message + /// @param[in] errorCode BGP notification error code + /// @param[in] errorSubCode BGP notification error sub code BgpNotificationMessageLayer(uint8_t errorCode, uint8_t errorSubCode); - /** - * A c'tor that creates a new BGP Notification message - * @param[in] errorCode BGP notification error code - * @param[in] errorSubCode BGP notification error sub code - * @param[in] notificationData A byte array that contains the notification data - * @param[in] notificationDataLen The size of the byte array that contains the notification data - */ + /// A c'tor that creates a new BGP Notification message + /// @param[in] errorCode BGP notification error code + /// @param[in] errorSubCode BGP notification error sub code + /// @param[in] notificationData A byte array that contains the notification data + /// @param[in] notificationDataLen The size of the byte array that contains the notification data BgpNotificationMessageLayer(uint8_t errorCode, uint8_t errorSubCode, const uint8_t* notificationData, size_t notificationDataLen); - /** - * A c'tor that creates a new BGP Notification message - * @param[in] errorCode BGP notification error code - * @param[in] errorSubCode BGP notification error sub code - * @param[in] notificationData A hex string that contains the notification data. This string will be converted - * to a byte array that will be added to the message. If the input isn't a valid hex string notification data - * will remain empty and an error will be printed to log - */ + /// A c'tor that creates a new BGP Notification message + /// @param[in] errorCode BGP notification error code + /// @param[in] errorSubCode BGP notification error sub code + /// @param[in] notificationData A hex string that contains the notification data. This string will be converted + /// to a byte array that will be added to the message. If the input isn't a valid hex string notification data + /// will remain empty and an error will be printed to log BgpNotificationMessageLayer(uint8_t errorCode, uint8_t errorSubCode, const std::string& notificationData); - /** - * Get a pointer to the notification message data. Notice this points directly to the data, so any change will - * modify the actual packet data - * @return A pointer to a bgp_notification_message structure containing the data - */ + /// Get a pointer to the notification message data. Notice this points directly to the data, so any change will + /// modify the actual packet data + /// @return A pointer to a bgp_notification_message structure containing the data bgp_notification_message* getNotificationMsgHeader() const { return reinterpret_cast(m_Data); } - /** - * @return The size in [bytes] of the notification data. Notification data is a variable-length field used to - * diagnose the reason for the BGP NOTIFICATION - */ + /// @return The size in [bytes] of the notification data. Notification data is a variable-length field used to + /// diagnose the reason for the BGP NOTIFICATION size_t getNotificationDataLen() const; - /** - * @return A pointer to the notification data. Notification data is a variable-length field used to diagnose the - * reason for the BGP NOTIFICATION - */ + /// @return A pointer to the notification data. Notification data is a variable-length field used to diagnose + /// the reason for the BGP NOTIFICATION uint8_t* getNotificationData() const; - /** - * @return A hex string which represents the notification data. Notification data is a variable-length field - * used to diagnose the reason for the BGP NOTIFICATION - */ + /// @return A hex string which represents the notification data. Notification data is a variable-length field + /// used to diagnose the reason for the BGP NOTIFICATION std::string getNotificationDataAsHexString() const; - /** - * Set the notification data. This method will extend or shorten the existing layer to include the new - * notification data. If newNotificationData is nullptr or newNotificationDataLen is zero then notification data - * will be set to none. - * @param[in] newNotificationData A byte array containing the new notification data - * @param[in] newNotificationDataLen The size of the byte array - * @return True if notification data was set successfully or false if any error occurred. In case of an error an - * appropriate error message will be printed to log - */ + /// Set the notification data. This method will extend or shorten the existing layer to include the new + /// notification data. If newNotificationData is nullptr or newNotificationDataLen is zero then notification + /// data will be set to none. + /// @param[in] newNotificationData A byte array containing the new notification data + /// @param[in] newNotificationDataLen The size of the byte array + /// @return True if notification data was set successfully or false if any error occurred. In case of an error + /// an appropriate error message will be printed to log bool setNotificationData(const uint8_t* newNotificationData, size_t newNotificationDataLen); - /** - * Set the notification data. This method will extend or shorten the existing layer to include the new - * notification data. If newNotificationDataAsHexString is an empty string then notification data will be set to - * none. - * @param[in] newNotificationDataAsHexString A hex string representing the new notification data. If the string - * is not a valid hex string no data will be changed and an error will be returned - * @return True if notification data was set successfully or false if any error occurred or if the string is not - * a valid hex string. In case of an error an appropriate error message will be printed to log - */ + /// Set the notification data. This method will extend or shorten the existing layer to include the new + /// notification data. If newNotificationDataAsHexString is an empty string then notification data will be set + /// to none. + /// @param[in] newNotificationDataAsHexString A hex string representing the new notification data. If the string + /// is not a valid hex string no data will be changed and an error will be returned + /// @return True if notification data was set successfully or false if any error occurred or if the string is + /// not a valid hex string. In case of an error an appropriate error message will be printed to log bool setNotificationData(const std::string& newNotificationDataAsHexString); // implement abstract methods @@ -617,40 +497,30 @@ namespace pcpp size_t notificationDataLen); }; - /** - * @class BgpKeepaliveMessageLayer - * Represents a BGP v4 KEEPALIVE message - */ + /// @class BgpKeepaliveMessageLayer + /// Represents a BGP v4 KEEPALIVE message class BgpKeepaliveMessageLayer : public BgpLayer { public: - /** - * @typedef bgp_keepalive_message - * BGP KEEPALIVE message structure - */ + /// @typedef bgp_keepalive_message + /// BGP KEEPALIVE message structure typedef bgp_common_header bgp_keepalive_message; - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in BgpKeepaliveMessageLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : BgpLayer(data, dataLen, prevLayer, packet) {} - /** - * A c'tor that creates a new BGP KEEPALIVE message - */ + /// A c'tor that creates a new BGP KEEPALIVE message BgpKeepaliveMessageLayer(); - /** - * Get a pointer to the KeepAlive message data. Notice this points directly to the data, so any change will - * modify the actual packet data - * @return A pointer to a bgp_keepalive_message structure containing the data - */ + /// Get a pointer to the KeepAlive message data. Notice this points directly to the data, so any change will + /// modify the actual packet data + /// @return A pointer to a bgp_keepalive_message structure containing the data bgp_keepalive_message* getKeepaliveHeader() const { return reinterpret_cast(getBasicHeader()); @@ -664,52 +534,42 @@ namespace pcpp } }; - /** - * @class BgpRouteRefreshMessageLayer - * Represents a BGP v4 ROUTE-REFRESH message - */ + /// @class BgpRouteRefreshMessageLayer + /// Represents a BGP v4 ROUTE-REFRESH message class BgpRouteRefreshMessageLayer : public BgpLayer { public: #pragma pack(push, 1) - /** - * @struct bgp_route_refresh_message - * BGP ROUTE-REFRESH message structure - */ + /// @struct bgp_route_refresh_message + /// BGP ROUTE-REFRESH message structure typedef struct bgp_route_refresh_message : bgp_common_header { - /** Address Family Identifier */ + /// Address Family Identifier uint16_t afi; - /** Reserved field */ + /// Reserved field uint8_t reserved; - /** Subsequent Address Family Identifier */ + /// Subsequent Address Family Identifier uint8_t safi; } bgp_route_refresh_message; #pragma pack(pop) - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in BgpRouteRefreshMessageLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : BgpLayer(data, dataLen, prevLayer, packet) {} - /** - * A c'tor that creates a new BGP ROUTE-REFRESH message - * @param[in] afi The Address Family Identifier (AFI) value to set in the message - * @param[in] safi The Subsequent Address Family Identifier (SAFI) value to set in the message - */ + /// A c'tor that creates a new BGP ROUTE-REFRESH message + /// @param[in] afi The Address Family Identifier (AFI) value to set in the message + /// @param[in] safi The Subsequent Address Family Identifier (SAFI) value to set in the message BgpRouteRefreshMessageLayer(uint16_t afi, uint8_t safi); - /** - * Get a pointer to the ROUTE-REFRESH message data. Notice this points directly to the data, so any change will - * modify the actual packet data - * @return A pointer to a bgp_route_refresh_message structure containing the data - */ + /// Get a pointer to the ROUTE-REFRESH message data. Notice this points directly to the data, so any change will + /// modify the actual packet data + /// @return A pointer to a bgp_route_refresh_message structure containing the data bgp_route_refresh_message* getRouteRefreshHeader() const { return reinterpret_cast(getBasicHeader()); diff --git a/Packet++/header/CotpLayer.h b/Packet++/header/CotpLayer.h index 5cd39c20b4..bbd2ec5f18 100644 --- a/Packet++/header/CotpLayer.h +++ b/Packet++/header/CotpLayer.h @@ -3,110 +3,85 @@ #include "EthLayer.h" #include "Layer.h" +/// @file + +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - -/** - * @struct cotphdr - * Represents a COTP protocol header - */ + /// @struct cotphdr + /// Represents a COTP protocol header #pragma pack(push, 1) struct cotphdr { - /** length */ + /// length uint8_t length; - /** PDU type identifier */ + /// PDU type identifier uint8_t pduType; - /** TPDU number sequence*/ + /// TPDU number sequence uint8_t tpduNumber; }; #pragma pack(pop) static_assert(sizeof(cotphdr) == 3, "cotphdr size is not 3 bytes"); - /** - * @class CotpLayer - * Represents a COTP (Connection Oriented Transport Protocol) - */ + /// @class CotpLayer + /// Represents a COTP (Connection Oriented Transport Protocol) class CotpLayer : public Layer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to @ref cotphdr) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to @ref cotphdr) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in CotpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, COTP) {} - /** - * A constructor that allocates a new COTP header - * @param[in] tpduNumber Protocol TPDU number - */ + /// A constructor that allocates a new COTP header + /// @param[in] tpduNumber Protocol TPDU number explicit CotpLayer(uint8_t tpduNumber); ~CotpLayer() override = default; - /** - * @return COTP length - */ + /// @return COTP length uint8_t getLength() const; - /** - * @return COTP PDU type - */ + /// @return COTP PDU type uint8_t getPduType() const; - /** - * @return COTP TPDU number - */ + /// @return COTP TPDU number uint8_t getTpduNumber() const; - /** - * @return Size of @ref cotphdr - */ + /// @return Size of @ref cotphdr size_t getHeaderLen() const override { return sizeof(cotphdr); } - /** - * Set the value of the length - * @param[in] length The value of the length - */ + /// Set the value of the length + /// @param[in] length The value of the length void setLength(uint8_t length) const; - /** - * Set the value of the version - * @param[in] pduType The number of the PDU type - */ + /// Set the value of the version + /// @param[in] pduType The number of the PDU type void setPduType(uint8_t pduType) const; - /** - * Set the value of the version - * @param[in] tpduNumber The value of the TPDU number - */ + /// Set the value of the version + /// @param[in] tpduNumber The value of the TPDU number void setTpduNumber(uint8_t tpduNumber) const; - /** - * Does nothing for this layer - */ + /// Does nothing for this layer void computeCalculateFields() override {} - /** - * Currently parses the rest of the packet as a S7COMM or generic payload (PayloadLayer) - */ + /// Currently parses the rest of the packet as a S7COMM or generic payload (PayloadLayer) void parseNextLayer() override; - /** - * A static method that takes a byte array and detects whether it is a COTP - * @param[in] data A byte array - * @param[in] dataSize The byte array size (in bytes) - * @return True if the data looks like a valid COTP layer - */ + /// A static method that takes a byte array and detects whether it is a COTP + /// @param[in] data A byte array + /// @param[in] dataSize The byte array size (in bytes) + /// @return True if the data looks like a valid COTP layer static bool isDataValid(const uint8_t* data, size_t dataSize); std::string toString() const override; diff --git a/Packet++/header/DhcpLayer.h b/Packet++/header/DhcpLayer.h index f53e39b1e1..34daea5b8c 100644 --- a/Packet++/header/DhcpLayer.h +++ b/Packet++/header/DhcpLayer.h @@ -8,437 +8,414 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - -/** - * @struct dhcp_header - * Represents a DHCP protocol header - */ + /// @struct dhcp_header + /// Represents a DHCP protocol header #pragma pack(push, 1) struct dhcp_header { - /** BootP opcode */ + /// BootP opcode uint8_t opCode; - /** Hardware type, set to 1 (Ethernet) by default */ + /// Hardware type, set to 1 (Ethernet) by default uint8_t hardwareType; - /** Hardware address length, set to 6 (MAC address length) by default */ + /// Hardware address length, set to 6 (MAC address length) by default uint8_t hardwareAddressLength; - /** Hop count */ + /// Hop count uint8_t hops; - /** DHCP/BootP transaction ID */ + /// DHCP/BootP transaction ID uint32_t transactionID; - /** The elapsed time, in seconds since the client sent its first BOOTREQUEST message */ + /// The elapsed time, in seconds since the client sent its first BOOTREQUEST message uint16_t secondsElapsed; - /** BootP flags */ + /// BootP flags uint16_t flags; - /** Client IPv4 address */ + /// Client IPv4 address uint32_t clientIpAddress; - /** Your IPv4 address */ + /// Your IPv4 address uint32_t yourIpAddress; - /** Server IPv4 address */ + /// Server IPv4 address uint32_t serverIpAddress; - /** Gateway IPv4 address */ + /// Gateway IPv4 address uint32_t gatewayIpAddress; - /** Client hardware address, by default contains the MAC address (only 6 first bytes are used) */ + /// Client hardware address, by default contains the MAC address (only 6 first bytes are used) uint8_t clientHardwareAddress[16]; - /** BootP server name */ + /// BootP server name uint8_t serverName[64]; - /** BootP boot file name */ + /// BootP boot file name uint8_t bootFilename[128]; - /** DHCP magic number (set to the default value of 0x63538263) */ + /// DHCP magic number (set to the default value of 0x63538263) uint32_t magicNumber; }; #pragma pack(pop) static_assert(sizeof(dhcp_header) == 240, "dhcp_header size is not 240 bytes"); - /** - * BootP opcodes - */ + /// BootP opcodes enum BootpOpCodes { - /** BootP request */ + /// BootP request DHCP_BOOTREQUEST = 1, - /** BootP reply */ + /// BootP reply DHCP_BOOTREPLY = 2 }; - /** - * DHCP message types - */ + /// DHCP message types enum DhcpMessageType { - /** Unknown message type */ + /// Unknown message type DHCP_UNKNOWN_MSG_TYPE = 0, - /** Discover message type */ + /// Discover message type DHCP_DISCOVER = 1, - /** Offer message type */ + /// Offer message type DHCP_OFFER = 2, - /** Request message type */ + /// Request message type DHCP_REQUEST = 3, - /** Decline message type */ + /// Decline message type DHCP_DECLINE = 4, - /** Acknowledge message type */ + /// Acknowledge message type DHCP_ACK = 5, - /** Non-acknowledge message type */ + /// Non-acknowledge message type DHCP_NAK = 6, - /** Release message type */ + /// Release message type DHCP_RELEASE = 7, - /** Inform message type */ + /// Inform message type DHCP_INFORM = 8 }; - /** - * DHCP option types. - */ + /// DHCP option types. enum DhcpOptionTypes { - /** Unknown option type */ + /// Unknown option type DHCPOPT_UNKNOWN = -1, - /** Pad */ + /// Pad DHCPOPT_PAD = 0, - /** Subnet Mask Value */ + /// Subnet Mask Value DHCPOPT_SUBNET_MASK = 1, - /** Time Offset in Seconds from UTC */ + /// Time Offset in Seconds from UTC DHCPOPT_TIME_OFFSET = 2, - /** N/4 Router addresses */ + /// N/4 Router addresses DHCPOPT_ROUTERS = 3, - /** N/4 Timeserver addresses */ + /// N/4 Timeserver addresses DHCPOPT_TIME_SERVERS = 4, - /** N/4 IEN-116 Server addresses */ + /// N/4 IEN-116 Server addresses DHCPOPT_NAME_SERVERS = 5, - /** N/4 DNS Server addresses */ + /// N/4 DNS Server addresses DHCPOPT_DOMAIN_NAME_SERVERS = 6, - /** N/4 Logging Server addresses */ + /// N/4 Logging Server addresses DHCPOPT_LOG_SERVERS = 7, - /** N/4 Quotes Server addresses */ + /// N/4 Quotes Server addresses DHCPOPT_QUOTES_SERVERS = 8, - /** N/4 Quotes Server addresses */ + /// N/4 Quotes Server addresses DHCPOPT_LPR_SERVERS = 9, - /** N/4 Quotes Server addresses */ + /// N/4 Quotes Server addresses DHCPOPT_IMPRESS_SERVERS = 10, - /** N/4 RLP Server addresses */ + /// N/4 RLP Server addresses DHCPOPT_RESOURCE_LOCATION_SERVERS = 11, - /** Hostname string */ + /// Hostname string DHCPOPT_HOST_NAME = 12, - /** Size of boot file in 512 byte chunks */ + /// Size of boot file in 512 byte chunks DHCPOPT_BOOT_SIZE = 13, - /** Client to dump and name the file to dump it to */ + /// Client to dump and name the file to dump it to DHCPOPT_MERIT_DUMP = 14, - /** The DNS domain name of the client */ + /// The DNS domain name of the client DHCPOPT_DOMAIN_NAME = 15, - /** Swap Server address */ + /// Swap Server address DHCPOPT_SWAP_SERVER = 16, - /** Path name for root disk */ + /// Path name for root disk DHCPOPT_ROOT_PATH = 17, - /** Path name for more BOOTP info */ + /// Path name for more BOOTP info DHCPOPT_EXTENSIONS_PATH = 18, - /** Enable/Disable IP Forwarding */ + /// Enable/Disable IP Forwarding DHCPOPT_IP_FORWARDING = 19, - /** Enable/Disable Source Routing */ + /// Enable/Disable Source Routing DHCPOPT_NON_LOCAL_SOURCE_ROUTING = 20, - /** Routing Policy Filters */ + /// Routing Policy Filters DHCPOPT_POLICY_FILTER = 21, - /** Max Datagram Reassembly Size */ + /// Max Datagram Reassembly Size DHCPOPT_MAX_DGRAM_REASSEMBLY = 22, - /** Default IP Time to Live */ + /// Default IP Time to Live DEFAULT_IP_TTL = 23, - /** Path MTU Aging Timeout */ + /// Path MTU Aging Timeout DHCPOPT_PATH_MTU_AGING_TIMEOUT = 24, - /** Path MTU Plateau Table */ + /// Path MTU Plateau Table PATH_MTU_PLATEAU_TABLE = 25, - /** Interface MTU Size */ + /// Interface MTU Size DHCPOPT_INTERFACE_MTU = 26, - /** All Subnets are Local */ + /// All Subnets are Local DHCPOPT_ALL_SUBNETS_LOCAL = 27, - /** Broadcast Address */ + /// Broadcast Address DHCPOPT_BROADCAST_ADDRESS = 28, - /** Perform Mask Discovery */ + /// Perform Mask Discovery DHCPOPT_PERFORM_MASK_DISCOVERY = 29, - /** Provide Mask to Others */ + /// Provide Mask to Others DHCPOPT_MASK_SUPPLIER = 30, - /** Perform Router Discovery */ + /// Perform Router Discovery DHCPOPT_ROUTER_DISCOVERY = 31, - /** Router Solicitation Address */ + /// Router Solicitation Address DHCPOPT_ROUTER_SOLICITATION_ADDRESS = 32, - /** Static Routing Table */ + /// Static Routing Table DHCPOPT_STATIC_ROUTES = 33, - /** Trailer Encapsulation */ + /// Trailer Encapsulation DHCPOPT_TRAILER_ENCAPSULATION = 34, - /** ARP Cache Timeout */ + /// ARP Cache Timeout DHCPOPT_ARP_CACHE_TIMEOUT = 35, - /** IEEE802.3 Encapsulation */ + /// IEEE802.3 Encapsulation DHCPOPT_IEEE802_3_ENCAPSULATION = 36, - /** Default TCP Time to Live */ + /// Default TCP Time to Live DHCPOPT_DEFAULT_TCP_TTL = 37, - /** TCP Keepalive Interval */ + /// TCP Keepalive Interval DHCPOPT_TCP_KEEPALIVE_INTERVAL = 38, - /** TCP Keepalive Garbage */ + /// TCP Keepalive Garbage DHCPOPT_TCP_KEEPALIVE_GARBAGE = 39, - /** NIS Domain Name */ + /// NIS Domain Name DHCPOPT_NIS_DOMAIN = 40, - /** NIS Server Addresses */ + /// NIS Server Addresses DHCPOPT_NIS_SERVERS = 41, - /** NTP Server Addresses */ + /// NTP Server Addresses DHCPOPT_NTP_SERVERS = 42, - /** Vendor Specific Information */ + /// Vendor Specific Information DHCPOPT_VENDOR_ENCAPSULATED_OPTIONS = 43, - /** NETBIOS Name Servers */ + /// NETBIOS Name Servers DHCPOPT_NETBIOS_NAME_SERVERS = 44, - /** NETBIOS Datagram Distribution */ + /// NETBIOS Datagram Distribution DHCPOPT_NETBIOS_DD_SERVER = 45, - /** NETBIOS Node Type */ + /// NETBIOS Node Type DHCPOPT_NETBIOS_NODE_TYPE = 46, - /** NETBIOS Scope */ + /// NETBIOS Scope DHCPOPT_NETBIOS_SCOPE = 47, - /** X Window Font Server */ + /// X Window Font Server DHCPOPT_FONT_SERVERS = 48, - /** X Window Display Manager */ + /// X Window Display Manager DHCPOPT_X_DISPLAY_MANAGER = 49, - /** Requested IP Address */ + /// Requested IP Address DHCPOPT_DHCP_REQUESTED_ADDRESS = 50, - /** IP Address Lease Time */ + /// IP Address Lease Time DHCPOPT_DHCP_LEASE_TIME = 51, - /** Overload "sname" or "file" */ + /// Overload "sname" or "file" DHCPOPT_DHCP_OPTION_OVERLOAD = 52, - /** DHCP Message Type */ + /// DHCP Message Type DHCPOPT_DHCP_MESSAGE_TYPE = 53, - /** DHCP Server Identification */ + /// DHCP Server Identification DHCPOPT_DHCP_SERVER_IDENTIFIER = 54, - /** Parameter Request List */ + /// Parameter Request List DHCPOPT_DHCP_PARAMETER_REQUEST_LIST = 55, - /** DHCP Error Message */ + /// DHCP Error Message DHCPOPT_DHCP_MESSAGE = 56, - /** DHCP Maximum Message Size */ + /// DHCP Maximum Message Size DHCPOPT_DHCP_MAX_MESSAGE_SIZE = 57, - /** DHCP Renewal (T1) Time */ + /// DHCP Renewal (T1) Time DHCPOPT_DHCP_RENEWAL_TIME = 58, - /** DHCP Rebinding (T2) Time */ + /// DHCP Rebinding (T2) Time DHCPOPT_DHCP_REBINDING_TIME = 59, - /** Class Identifier */ + /// Class Identifier DHCPOPT_VENDOR_CLASS_IDENTIFIER = 60, - /** Class Identifier */ + /// Class Identifier DHCPOPT_DHCP_CLIENT_IDENTIFIER = 61, - /** NetWare/IP Domain Name */ + /// NetWare/IP Domain Name DHCPOPT_NWIP_DOMAIN_NAME = 62, - /** NetWare/IP sub Options */ + /// NetWare/IP sub Options DHCPOPT_NWIP_SUBOPTIONS = 63, - /** NIS+ v3 Client Domain Name */ + /// NIS+ v3 Client Domain Name DHCPOPT_NIS_DOMAIN_NAME = 64, - /** NIS+ v3 Server Addresses */ + /// NIS+ v3 Server Addresses DHCPOPT_NIS_SERVER_ADDRESS = 65, - /** TFTP Server Name */ + /// TFTP Server Name DHCPOPT_TFTP_SERVER_NAME = 66, - /** Boot File Name */ + /// Boot File Name DHCPOPT_BOOTFILE_NAME = 67, - /** Home Agent Addresses */ + /// Home Agent Addresses DHCPOPT_HOME_AGENT_ADDRESS = 68, - /** Simple Mail Server (SMTP) Addresses */ + /// Simple Mail Server (SMTP) Addresses DHCPOPT_SMTP_SERVER = 69, - /** Post Office (POP3) Server Addresses */ + /// Post Office (POP3) Server Addresses DHCPOPT_POP3_SERVER = 70, - /** Network News (NNTP) Server Addresses */ + /// Network News (NNTP) Server Addresses DHCPOPT_NNTP_SERVER = 71, - /** WWW Server Addresses */ + /// WWW Server Addresses DHCPOPT_WWW_SERVER = 72, - /** Finger Server Addresses */ + /// Finger Server Addresses DHCPOPT_FINGER_SERVER = 73, - /** Chat (IRC) Server Addresses */ + /// Chat (IRC) Server Addresses DHCPOPT_IRC_SERVER = 74, - /** StreetTalk Server Addresses */ + /// StreetTalk Server Addresses DHCPOPT_STREETTALK_SERVER = 75, - /** ST Directory Assist. Addresses */ + /// ST Directory Assist. Addresses DHCPOPT_STDA_SERVER = 76, - /** User Class Information */ + /// User Class Information DHCPOPT_USER_CLASS = 77, - /** Directory Agent Information */ + /// Directory Agent Information DHCPOPT_DIRECTORY_AGENT = 78, - /** Service Location Agent Scope */ + /// Service Location Agent Scope DHCPOPT_SERVICE_SCOPE = 79, - /** Rapid Commit */ + /// Rapid Commit DHCPOPT_RAPID_COMMIT = 80, - /** Fully Qualified Domain Name */ + /// Fully Qualified Domain Name DHCPOPT_FQDN = 81, - /** Relay Agent Information */ + /// Relay Agent Information DHCPOPT_DHCP_AGENT_OPTIONS = 82, - /** Internet Storage Name Service */ + /// Internet Storage Name Service DHCPOPT_ISNS = 83, - /** Novell Directory Services */ + /// Novell Directory Services DHCPOPT_NDS_SERVERS = 85, - /** Novell Directory Services */ + /// Novell Directory Services DHCPOPT_NDS_TREE_NAME = 86, - /** Novell Directory Services */ + /// Novell Directory Services DHCPOPT_NDS_CONTEXT = 87, - /** BCMCS Controller Domain Name list */ + /// BCMCS Controller Domain Name list DHCPOPT_BCMCS_CONTROLLER_DOMAIN_NAME_LIST = 88, - /** BCMCS Controller IPv4 address option */ + /// BCMCS Controller IPv4 address option DHCPOPT_BCMCS_CONTROLLER_IPV4_ADDRESS = 89, - /** Authentication */ + /// Authentication DHCPOPT_AUTHENTICATION = 90, - /** Client Last Transaction Time */ + /// Client Last Transaction Time DHCPOPT_CLIENT_LAST_TXN_TIME = 91, - /** Associated IP */ + /// Associated IP DHCPOPT_ASSOCIATED_IP = 92, - /** Client System Architecture */ + /// Client System Architecture DHCPOPT_CLIENT_SYSTEM = 93, - /** Client Network Device Interface */ + /// Client Network Device Interface DHCPOPT_CLIENT_NDI = 94, - /** Lightweight Directory Access Protocol [ */ + /// Lightweight Directory Access Protocol [ DHCPOPT_LDAP = 95, - /** UUID/GUID-based Client Identifier */ + /// UUID/GUID-based Client Identifier DHCPOPT_UUID_GUID = 97, - /** Open Group's User Authentication */ + /// Open Group's User Authentication DHCPOPT_USER_AUTH = 98, - /** GEOCONF_CIVIC */ + /// GEOCONF_CIVIC DHCPOPT_GEOCONF_CIVIC = 99, - /** IEEE 1003.1 TZ String */ + /// IEEE 1003.1 TZ String DHCPOPT_PCODE = 100, - /** Reference to the TZ Database */ + /// Reference to the TZ Database DHCPOPT_TCODE = 101, - /** NetInfo Parent Server Address */ + /// NetInfo Parent Server Address DHCPOPT_NETINFO_ADDRESS = 112, - /** NetInfo Parent Server Tag */ + /// NetInfo Parent Server Tag DHCPOPT_NETINFO_TAG = 113, - /** URL */ + /// URL DHCPOPT_URL = 114, - /** DHCP Auto-Configuration */ + /// DHCP Auto-Configuration DHCPOPT_AUTO_CONFIG = 116, - /** Name Service Search */ + /// Name Service Search DHCPOPT_NAME_SERVICE_SEARCH = 117, - /** Subnet Selection Option */ + /// Subnet Selection Option DHCPOPT_SUBNET_SELECTION = 118, - /** DNS Domain Search List */ + /// DNS Domain Search List DHCPOPT_DOMAIN_SEARCH = 119, - /** SIP Servers DHCP Option */ + /// SIP Servers DHCP Option DHCPOPT_SIP_SERVERS = 120, - /** Classless Static Route Option */ + /// Classless Static Route Option DHCPOPT_CLASSLESS_STATIC_ROUTE = 121, - /** CableLabs Client Configuration */ + /// CableLabs Client Configuration DHCPOPT_CCC = 122, - /** GeoConf Option */ + /// GeoConf Option DHCPOPT_GEOCONF = 123, - /** Vendor-Identifying Vendor Class */ + /// Vendor-Identifying Vendor Class DHCPOPT_V_I_VENDOR_CLASS = 124, - /** Vendor-Identifying Vendor-Specific Information */ + /// Vendor-Identifying Vendor-Specific Information DHCPOPT_V_I_VENDOR_OPTS = 125, - /** OPTION_PANA_AGENT */ + /// OPTION_PANA_AGENT DHCPOPT_OPTION_PANA_AGENT = 136, - /** OPTION_V4_LOST */ + /// OPTION_V4_LOST DHCPOPT_OPTION_V4_LOST = 137, - /** CAPWAP Access Controller addresses */ + /// CAPWAP Access Controller addresses DHCPOPT_OPTION_CAPWAP_AC_V4 = 138, - /** A Series Of Suboptions */ + /// A Series Of Suboptions DHCPOPT_OPTION_IPV4_ADDRESS_MOS = 139, - /** A Series Of Suboptions */ + /// A Series Of Suboptions DHCPOPT_OPTION_IPV4_FQDN_MOS = 140, - /** List of domain names to search for SIP User Agent Configuration */ + /// List of domain names to search for SIP User Agent Configuration DHCPOPT_SIP_UA_CONFIG = 141, - /** ANDSF IPv4 Address Option for DHCPv4 */ + /// ANDSF IPv4 Address Option for DHCPv4 DHCPOPT_OPTION_IPV4_ADDRESS_ANDSF = 142, - /** Geospatial Location with Uncertainty [RF */ + /// Geospatial Location with Uncertainty [RF DHCPOPT_GEOLOC = 144, - /** Forcerenew Nonce Capable */ + /// Forcerenew Nonce Capable DHCPOPT_FORCERENEW_NONCE_CAPABLE = 145, - /** Information for selecting RDNSS */ + /// Information for selecting RDNSS DHCPOPT_RDNSS_SELECTION = 146, - /** Status code and optional N byte text message describing status */ + /// Status code and optional N byte text message describing status DHCPOPT_STATUS_CODE = 151, - /** Absolute time (seconds since Jan 1, 1970) message was sent */ + /// Absolute time (seconds since Jan 1, 1970) message was sent DHCPOPT_BASE_TIME = 152, - /** Number of seconds in the past when client entered current state */ + /// Number of seconds in the past when client entered current state DHCPOPT_START_TIME_OF_STATE = 153, - /** Absolute time (seconds since Jan 1, 1970) for beginning of query */ + /// Absolute time (seconds since Jan 1, 1970) for beginning of query DHCPOPT_QUERY_START_TIME = 154, - /** Absolute time (seconds since Jan 1, 1970) for end of query */ + /// Absolute time (seconds since Jan 1, 1970) for end of query DHCPOPT_QUERY_END_TIME = 155, - /** State of IP address */ + /// State of IP address DHCPOPT_DHCP_STATE = 156, - /** Indicates information came from local or remote server */ + /// Indicates information came from local or remote server DHCPOPT_DATA_SOURCE = 157, - /** Includes one or multiple lists of PCP server IP addresses; each list is treated as a separate PCP server */ + /// Includes one or multiple lists of PCP server IP addresses; each list is treated as a separate PCP server DHCPOPT_OPTION_V4_PCP_SERVER = 158, - /** This option is used to configure a set of ports bound to a shared IPv4 address */ + /// This option is used to configure a set of ports bound to a shared IPv4 address DHCPOPT_OPTION_V4_PORTPARAMS = 159, - /** DHCP Captive-Portal */ + /// DHCP Captive-Portal DHCPOPT_CAPTIVE_PORTAL = 160, - /** Manufacturer Usage Descriptions */ + /// Manufacturer Usage Descriptions DHCPOPT_OPTION_MUD_URL_V4 = 161, - /** Etherboot */ + /// Etherboot DHCPOPT_ETHERBOOT = 175, - /** IP Telephone */ + /// IP Telephone DHCPOPT_IP_TELEPHONE = 176, - /** Magic string = F1:00:74:7E */ + /// Magic string = F1:00:74:7E DHCPOPT_PXELINUX_MAGIC = 208, - /** Configuration file */ + /// Configuration file DHCPOPT_CONFIGURATION_FILE = 209, - /** Path Prefix Option */ + /// Path Prefix Option DHCPOPT_PATH_PREFIX = 210, - /** Reboot Time */ + /// Reboot Time DHCPOPT_REBOOT_TIME = 211, - /** OPTION_6RD with N/4 6rd BR addresses */ + /// OPTION_6RD with N/4 6rd BR addresses DHCPOPT_OPTION_6RD = 212, - /** Access Network Domain Name */ + /// Access Network Domain Name DHCPOPT_OPTION_V4_ACCESS_DOMAIN = 213, - /** Subnet Allocation Option */ + /// Subnet Allocation Option DHCPOPT_SUBNET_ALLOCATION = 220, - /** Virtual Subnet Selection (VSS) Option */ + /// Virtual Subnet Selection (VSS) Option DHCPOPT_VIRTUAL_SUBNET_SELECTION = 221, - /** End (last option) */ + /// End (last option) DHCPOPT_END = 255 }; - /** - * @class DhcpOption - * A wrapper class for DHCP options. This class does not create or modify DHCP option records, but rather - * serves as a wrapper and provides useful methods for setting and retrieving data to/from them - */ + /// @class DhcpOption + /// A wrapper class for DHCP options. This class does not create or modify DHCP option records, but rather + /// serves as a wrapper and provides useful methods for setting and retrieving data to/from them class DhcpOption : public TLVRecord { public: - /** - * A c'tor for this class that gets a pointer to the option raw data (byte array) - * @param[in] optionRawData A pointer to the option raw data - */ + /// A c'tor for this class that gets a pointer to the option raw data (byte array) + /// @param[in] optionRawData A pointer to the option raw data explicit DhcpOption(uint8_t* optionRawData) : TLVRecord(optionRawData) {} - /** - * A d'tor for this class, currently does nothing - */ + /// A d'tor for this class, currently does nothing ~DhcpOption() override = default; - /** - * Retrieve DHCP option data as IPv4 address. Relevant only if option value is indeed an IPv4 address - * @return DHCP option data as IPv4 address - */ + /// Retrieve DHCP option data as IPv4 address. Relevant only if option value is indeed an IPv4 address + /// @return DHCP option data as IPv4 address IPv4Address getValueAsIpAddr() const { return getValueAs(); } - /** - * Set DHCP option data as IPv4 address. This method copies the 4 bytes of the IP address to the option value - * @param[in] addr The IPv4 address to set - * @param[in] valueOffset An optional parameter that specifies where to start set the option data (default set - * to 0). For example: if option data is 20 bytes long and you want to set the IP address in the 4 last bytes - * then use this method like this: setValueIpAddr(your_addr, 16) - */ + /// Set DHCP option data as IPv4 address. This method copies the 4 bytes of the IP address to the option value + /// @param[in] addr The IPv4 address to set + /// @param[in] valueOffset An optional parameter that specifies where to start set the option data (default set + /// to 0). For example: if option data is 20 bytes long and you want to set the IP address in the 4 last bytes + /// then use this method like this: setValueIpAddr(your_addr, 16) void setValueIpAddr(const IPv4Address& addr, int valueOffset = 0) { setValue(addr.toInt(), valueOffset); } - /** - * Retrieve DHCP option data as string. Relevant only if option value is indeed a string - * @param[in] valueOffset An optional parameter that specifies where to start copy the DHCP option data. For - * example: when retrieving Client FQDN option, you may ignore the flags and RCODE fields using this method like - * this: getValueAsString(3). The default is 0 - start copying from the beginning of option data - * @return DHCP option data as string - */ + /// Retrieve DHCP option data as string. Relevant only if option value is indeed a string + /// @param[in] valueOffset An optional parameter that specifies where to start copy the DHCP option data. For + /// example: when retrieving Client FQDN option, you may ignore the flags and RCODE fields using this method + /// like this: getValueAsString(3). The default is 0 - start copying from the beginning of option data + /// @return DHCP option data as string std::string getValueAsString(int valueOffset = 0) const { if (m_Data == nullptr || m_Data->recordLen - valueOffset < 1) @@ -448,14 +425,12 @@ namespace pcpp static_cast(m_Data->recordLen) - valueOffset); } - /** - * Set DHCP option data as string. This method copies the string to the option value. If the string is longer - * than option length the string is trimmed so it will fit the option length - * @param[in] stringValue The string to set - * @param[in] valueOffset An optional parameter that specifies where to start set the option data (default set - * to 0). For example: if option data is 20 bytes long and you want to set a 6 char-long string in the 6 last - * bytes then use this method like this: setValueString("string", 14) - */ + /// Set DHCP option data as string. This method copies the string to the option value. If the string is longer + /// than option length the string is trimmed so it will fit the option length + /// @param[in] stringValue The string to set + /// @param[in] valueOffset An optional parameter that specifies where to start set the option data (default set + /// to 0). For example: if option data is 20 bytes long and you want to set a 6 char-long string in the 6 last + /// bytes then use this method like this: setValueString("string", 14) void setValueString(const std::string& stringValue, int valueOffset = 0) { // calculate the maximum length of the destination buffer @@ -468,12 +443,10 @@ namespace pcpp memcpy(m_Data->recordValue + valueOffset, stringValue.data(), len); } - /** - * Check if a pointer can be assigned to the TLV record data - * @param[in] recordRawData A pointer to the TLV record raw data - * @param[in] tlvDataLen The size of the TLV record raw data - * @return True if data is valid and can be assigned - */ + /// Check if a pointer can be assigned to the TLV record data + /// @param[in] recordRawData A pointer to the TLV record raw data + /// @param[in] tlvDataLen The size of the TLV record raw data + /// @return True if data is valid and can be assigned static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen) { auto data = reinterpret_cast(recordRawData); @@ -517,347 +490,266 @@ namespace pcpp } }; - /** - * @class DhcpOptionBuilder - * A class for building DHCP options. This builder receives the option parameters in its c'tor, - * builds the DHCP option raw buffer and provides a build() method to get a DhcpOption object out of it - */ + /// @class DhcpOptionBuilder + /// A class for building DHCP options. This builder receives the option parameters in its c'tor, + /// builds the DHCP option raw buffer and provides a build() method to get a DhcpOption object out of it class DhcpOptionBuilder : public TLVRecordBuilder { public: - /** - * A c'tor for building DHCP options which their value is a byte array. The DhcpOption object can later - * be retrieved by calling build() - * @param[in] optionType DHCP option type - * @param[in] optionValue A buffer containing the option value. This buffer is read-only and isn't modified in - * any way - * @param[in] optionValueLen DHCP option value length in bytes - */ + /// A c'tor for building DHCP options which their value is a byte array. The DhcpOption object can later + /// be retrieved by calling build() + /// @param[in] optionType DHCP option type + /// @param[in] optionValue A buffer containing the option value. This buffer is read-only and isn't modified in + /// any way + /// @param[in] optionValueLen DHCP option value length in bytes DhcpOptionBuilder(DhcpOptionTypes optionType, const uint8_t* optionValue, uint8_t optionValueLen) : TLVRecordBuilder(static_cast(optionType), optionValue, optionValueLen) {} - /** - * A c'tor for building DHCP options which have a 1-byte value. The DhcpOption object can later be retrieved - * by calling build() - * @param[in] optionType DHCP option type - * @param[in] optionValue A 1-byte option value - */ + /// A c'tor for building DHCP options which have a 1-byte value. The DhcpOption object can later be retrieved + /// by calling build() + /// @param[in] optionType DHCP option type + /// @param[in] optionValue A 1-byte option value DhcpOptionBuilder(DhcpOptionTypes optionType, uint8_t optionValue) : TLVRecordBuilder(static_cast(optionType), optionValue) {} - /** - * A c'tor for building DHCP options which have a 2-byte value. The DhcpOption object can later be retrieved - * by calling build() - * @param[in] optionType DHCP option type - * @param[in] optionValue A 2-byte option value - */ + /// A c'tor for building DHCP options which have a 2-byte value. The DhcpOption object can later be retrieved + /// by calling build() + /// @param[in] optionType DHCP option type + /// @param[in] optionValue A 2-byte option value DhcpOptionBuilder(DhcpOptionTypes optionType, uint16_t optionValue) : TLVRecordBuilder(static_cast(optionType), optionValue) {} - /** - * A c'tor for building DHCP options which have a 4-byte value. The DhcpOption object can later be retrieved - * by calling build() - * @param[in] optionType DHCP option type - * @param[in] optionValue A 4-byte option value - */ + /// A c'tor for building DHCP options which have a 4-byte value. The DhcpOption object can later be retrieved + /// by calling build() + /// @param[in] optionType DHCP option type + /// @param[in] optionValue A 4-byte option value DhcpOptionBuilder(DhcpOptionTypes optionType, uint32_t optionValue) : TLVRecordBuilder(static_cast(optionType), optionValue) {} - /** - * A c'tor for building DHCP options which have an IPv4Address value. The DhcpOption object can later be - * retrieved by calling build() - * @param[in] optionType DHCP option type - * @param[in] optionValue The IPv4 address option value - */ + /// A c'tor for building DHCP options which have an IPv4Address value. The DhcpOption object can later be + /// retrieved by calling build() + /// @param[in] optionType DHCP option type + /// @param[in] optionValue The IPv4 address option value DhcpOptionBuilder(DhcpOptionTypes optionType, const IPv4Address& optionValue) : TLVRecordBuilder(static_cast(optionType), optionValue) {} - /** - * A c'tor for building DHCP options which have a string value. The DhcpOption object can later be retrieved - * by calling build() - * @param[in] optionType DHCP option type - * @param[in] optionValue The string option value - */ + /// A c'tor for building DHCP options which have a string value. The DhcpOption object can later be retrieved + /// by calling build() + /// @param[in] optionType DHCP option type + /// @param[in] optionValue The string option value DhcpOptionBuilder(DhcpOptionTypes optionType, const std::string& optionValue) : TLVRecordBuilder(static_cast(optionType), optionValue) {} - /** - * A copy c'tor which copies all the data from another instance of DhcpOptionBuilder - * @param[in] other The instance to copy from - */ + /// A copy c'tor which copies all the data from another instance of DhcpOptionBuilder + /// @param[in] other The instance to copy from DhcpOptionBuilder(const DhcpOptionBuilder& other) : TLVRecordBuilder(other) {} - /** - * Assignment operator that copies all data from another instance of DhcpOptionBuilder - * @param[in] other The instance to assign from - * @return A reference to the assignee - */ + /// Assignment operator that copies all data from another instance of DhcpOptionBuilder + /// @param[in] other The instance to assign from + /// @return A reference to the assignee DhcpOptionBuilder& operator=(const DhcpOptionBuilder& other) { TLVRecordBuilder::operator=(other); return *this; } - /** - * Build the DhcpOption object out of the parameters defined in the c'tor - * @return The DhcpOption object - */ + /// Build the DhcpOption object out of the parameters defined in the c'tor + /// @return The DhcpOption object DhcpOption build() const; }; - /** - * @class DhcpLayer - * Represents a DHCP (Dynamic Host Configuration Protocol) protocol layer - */ + /// @class DhcpLayer + /// Represents a DHCP (Dynamic Host Configuration Protocol) protocol layer class DhcpLayer : public Layer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in DhcpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * A constructor that creates the layer from scratch. Adds a ::DHCPOPT_DHCP_MESSAGE_TYPE and a ::DHCPOPT_END - * options - * @param[in] msgType A DHCP message type to be set - * @param[in] clientMacAddr A client MAC address to set in dhcp_header#clientHardwareAddress field - */ + /// A constructor that creates the layer from scratch. Adds a ::DHCPOPT_DHCP_MESSAGE_TYPE and a ::DHCPOPT_END + /// options + /// @param[in] msgType A DHCP message type to be set + /// @param[in] clientMacAddr A client MAC address to set in dhcp_header#clientHardwareAddress field DhcpLayer(DhcpMessageType msgType, const MacAddress& clientMacAddr); - /** - * A constructor that creates the layer from scratch with clean data - */ + /// A constructor that creates the layer from scratch with clean data DhcpLayer(); - /** - * A destructor for this layer - */ + /// A destructor for this layer ~DhcpLayer() override = default; - /** - * Get a pointer to the DHCP header. Notice this points directly to the data, so every change will change the - * actual packet data - * @return A pointer to the @ref dhcp_header - */ + /// Get a pointer to the DHCP header. Notice this points directly to the data, so every change will change the + /// actual packet data + /// @return A pointer to the @ref dhcp_header dhcp_header* getDhcpHeader() const { return reinterpret_cast(m_Data); } - /** - * @return The BootP opcode of this message - */ + /// @return The BootP opcode of this message BootpOpCodes getOpCode() const { return static_cast(getDhcpHeader()->opCode); } - /** - * @return The client IPv4 address (as extracted from dhcp_header#clientIpAddress converted to IPv4Address - * object) - */ + /// @return The client IPv4 address (as extracted from dhcp_header#clientIpAddress converted to IPv4Address + /// object) IPv4Address getClientIpAddress() const { return getDhcpHeader()->clientIpAddress; } - /** - * Set the client IPv4 address in dhcp_header#clientIpAddress - * @param[in] addr The IPv4 address to set - */ + /// Set the client IPv4 address in dhcp_header#clientIpAddress + /// @param[in] addr The IPv4 address to set void setClientIpAddress(const IPv4Address& addr) { getDhcpHeader()->clientIpAddress = addr.toInt(); } - /** - * @return The server IPv4 address (as extracted from dhcp_header#serverIpAddress converted to IPv4Address - * object) - */ + /// @return The server IPv4 address (as extracted from dhcp_header#serverIpAddress converted to IPv4Address + /// object) IPv4Address getServerIpAddress() const { return getDhcpHeader()->serverIpAddress; } - /** - * Set the server IPv4 address in dhcp_header#serverIpAddress - * @param[in] addr The IPv4 address to set - */ + /// Set the server IPv4 address in dhcp_header#serverIpAddress + /// @param[in] addr The IPv4 address to set void setServerIpAddress(const IPv4Address& addr) { getDhcpHeader()->serverIpAddress = addr.toInt(); } - /** - * @return Your IPv4 address (as extracted from dhcp_header#yourIpAddress converted to IPv4Address object) - */ + /// @return Your IPv4 address (as extracted from dhcp_header#yourIpAddress converted to IPv4Address object) IPv4Address getYourIpAddress() const { return getDhcpHeader()->yourIpAddress; } - /** - * Set your IPv4 address in dhcp_header#yourIpAddress - * @param[in] addr The IPv4 address to set - */ + /// Set your IPv4 address in dhcp_header#yourIpAddress + /// @param[in] addr The IPv4 address to set void setYourIpAddress(const IPv4Address& addr) { getDhcpHeader()->yourIpAddress = addr.toInt(); } - /** - * @return Gateway IPv4 address (as extracted from dhcp_header#gatewayIpAddress converted to IPv4Address object) - */ + /// @return Gateway IPv4 address (as extracted from dhcp_header#gatewayIpAddress converted to IPv4Address + /// object) IPv4Address getGatewayIpAddress() const { return getDhcpHeader()->gatewayIpAddress; } - /** - * Set the gateway IPv4 address in dhcp_header#gatewayIpAddress - * @param[in] addr The IPv4 address to set - */ + /// Set the gateway IPv4 address in dhcp_header#gatewayIpAddress + /// @param[in] addr The IPv4 address to set void setGatewayIpAddress(const IPv4Address& addr) { getDhcpHeader()->gatewayIpAddress = addr.toInt(); } - /** - * @return The client MAC address as extracted from dhcp_header#clientHardwareAddress, assuming - * dhcp_header#hardwareType is 1 (Ethernet) and dhcp_header#hardwareAddressLength is 6 (MAC address length). - * Otherwise returns MacAddress#Zero - */ + /// @return The client MAC address as extracted from dhcp_header#clientHardwareAddress, assuming + /// dhcp_header#hardwareType is 1 (Ethernet) and dhcp_header#hardwareAddressLength is 6 (MAC address length). + /// Otherwise returns MacAddress#Zero MacAddress getClientHardwareAddress() const; - /** - * Set a MAC address into the first 6 bytes of dhcp_header#clientHardwareAddress. This method also sets - * dhcp_header#hardwareType to 1 (Ethernet) and dhcp_header#hardwareAddressLength to 6 (MAC address length) - * @param[in] addr The MAC address to set - */ + /// Set a MAC address into the first 6 bytes of dhcp_header#clientHardwareAddress. This method also sets + /// dhcp_header#hardwareType to 1 (Ethernet) and dhcp_header#hardwareAddressLength to 6 (MAC address length) + /// @param[in] addr The MAC address to set void setClientHardwareAddress(const MacAddress& addr); - /** - * @return DHCP message type as extracted from ::DHCPOPT_DHCP_MESSAGE_TYPE option. If this option doesn't exist - * the value of - * ::DHCP_UNKNOWN_MSG_TYPE is returned - */ + /// @return DHCP message type as extracted from ::DHCPOPT_DHCP_MESSAGE_TYPE option. If this option doesn't exist + /// the value of + /// ::DHCP_UNKNOWN_MSG_TYPE is returned DhcpMessageType getMessageType() const; - /** - * Set DHCP message type. This method searches for existing ::DHCPOPT_DHCP_MESSAGE_TYPE option. If found, it - * sets the requested message type as its value. If not, it creates a ::DHCPOPT_DHCP_MESSAGE_TYPE option and - * sets the requested message type as its value - * @param[in] msgType Message type to set - * @return True if message type was set successfully or false if msgType is ::DHCP_UNKNOWN_MSG_TYPE or if failed - * to add - * ::DHCPOPT_DHCP_MESSAGE_TYPE option - */ + /// Set DHCP message type. This method searches for existing ::DHCPOPT_DHCP_MESSAGE_TYPE option. If found, it + /// sets the requested message type as its value. If not, it creates a ::DHCPOPT_DHCP_MESSAGE_TYPE option and + /// sets the requested message type as its value + /// @param[in] msgType Message type to set + /// @return True if message type was set successfully or false if msgType is ::DHCP_UNKNOWN_MSG_TYPE or if + /// failed to add + /// ::DHCPOPT_DHCP_MESSAGE_TYPE option bool setMessageType(DhcpMessageType msgType); - /** - * @return The first DHCP option in the packet. If there are no DHCP options the returned value will contain - * a logical null (DhcpOption#isNull() == true) - */ + /// @return The first DHCP option in the packet. If there are no DHCP options the returned value will contain + /// a logical null (DhcpOption#isNull() == true) DhcpOption getFirstOptionData() const; - /** - * Get the DHCP option that comes after a given option. If the given option was the last one, the - * returned value will contain a logical null (DhcpOption#isNull() == true) - * @param[in] dhcpOption A given DHCP option - * @return A DhcpOption object containing the option data that comes next, or logical null if the given DHCP - * option: (1) was the last one; (2) contains a logical null or (3) doesn't belong to this packet - */ + /// Get the DHCP option that comes after a given option. If the given option was the last one, the + /// returned value will contain a logical null (DhcpOption#isNull() == true) + /// @param[in] dhcpOption A given DHCP option + /// @return A DhcpOption object containing the option data that comes next, or logical null if the given DHCP + /// option: (1) was the last one; (2) contains a logical null or (3) doesn't belong to this packet DhcpOption getNextOptionData(DhcpOption dhcpOption) const; - /** - * Get a DHCP option by type - * @param[in] option DHCP option type - * @return A DhcpOption object containing the first DHCP option data that matches this type, or logical null - * (DhcpOption#isNull() == true) if no such option found - */ + /// Get a DHCP option by type + /// @param[in] option DHCP option type + /// @return A DhcpOption object containing the first DHCP option data that matches this type, or logical null + /// (DhcpOption#isNull() == true) if no such option found DhcpOption getOptionData(DhcpOptionTypes option) const; - /** - * @return The number of DHCP options in this layer - */ + /// @return The number of DHCP options in this layer size_t getOptionsCount() const; - /** - * Add a new DHCP option at the end of the layer - * @param[in] optionBuilder A DhcpOptionBuilder object that contains the requested DHCP option data to add - * @return A DhcpOption object containing the newly added DHCP option data or logical null - * (DhcpOption#isNull() == true) if addition failed - */ + /// Add a new DHCP option at the end of the layer + /// @param[in] optionBuilder A DhcpOptionBuilder object that contains the requested DHCP option data to add + /// @return A DhcpOption object containing the newly added DHCP option data or logical null + /// (DhcpOption#isNull() == true) if addition failed DhcpOption addOption(const DhcpOptionBuilder& optionBuilder); - /** - * Add a new DHCP option after an existing one - * @param[in] optionBuilder A DhcpOptionBuilder object that contains the requested DHCP option data to add - * @param[in] prevOption The DHCP option type which the newly added option will come after - * @return A DhcpOption object containing the newly added DHCP option data or logical null - * (DhcpOption#isNull() == true) if addition failed - */ + /// Add a new DHCP option after an existing one + /// @param[in] optionBuilder A DhcpOptionBuilder object that contains the requested DHCP option data to add + /// @param[in] prevOption The DHCP option type which the newly added option will come after + /// @return A DhcpOption object containing the newly added DHCP option data or logical null + /// (DhcpOption#isNull() == true) if addition failed DhcpOption addOptionAfter(const DhcpOptionBuilder& optionBuilder, DhcpOptionTypes prevOption); - /** - * Remove an existing DHCP option from the layer - * @param[in] optionType The DHCP option type to remove - * @return True if DHCP option was successfully removed or false if type wasn't found or if removal failed - */ + /// Remove an existing DHCP option from the layer + /// @param[in] optionType The DHCP option type to remove + /// @return True if DHCP option was successfully removed or false if type wasn't found or if removal failed bool removeOption(DhcpOptionTypes optionType); - /** - * Remove all DHCP options in this layer - * @return True if all DHCP options were successfully removed or false if removal failed for some reason - */ + /// Remove all DHCP options in this layer + /// @return True if all DHCP options were successfully removed or false if removal failed for some reason bool removeAllOptions(); - /** - * A static method that checks whether a pair of ports are considered DHCP ports - * @param[in] portSrc The source port number to check - * @param[in] portDst The destination port number to check - * @return True if these are DHCP port numbers, false otherwise - */ + /// A static method that checks whether a pair of ports are considered DHCP ports + /// @param[in] portSrc The source port number to check + /// @param[in] portDst The destination port number to check + /// @return True if these are DHCP port numbers, false otherwise static inline bool isDhcpPorts(uint16_t portSrc, uint16_t portDst); // implement abstract methods - /** - * Does nothing for this layer (DhcpLayer is always last) - */ + /// Does nothing for this layer (DhcpLayer is always last) void parseNextLayer() override {} - /** - * @return The size of @ref dhcp_header + size of options - */ + /// @return The size of @ref dhcp_header + size of options size_t getHeaderLen() const override { return m_DataLen; } - /** - * Calculate the following fields: - * - @ref dhcp_header#magicNumber = DHCP magic number (0x63538263) - * - @ref dhcp_header#opCode = ::DHCP_BOOTREQUEST for message types: ::DHCP_DISCOVER, ::DHCP_REQUEST, - * ::DHCP_DECLINE, ::DHCP_RELEASE, - * ::DHCP_INFORM, ::DHCP_UNKNOWN_MSG_TYPE - * ::DHCP_BOOTREPLY for message types: ::DHCP_OFFER, ::DHCP_ACK, ::DHCP_NAK - * - @ref dhcp_header#hardwareType = 1 (Ethernet) - * - @ref dhcp_header#hardwareAddressLength = 6 (MAC address length) - */ + /// Calculate the following fields: + /// - @ref dhcp_header#magicNumber = DHCP magic number (0x63538263) + /// - @ref dhcp_header#opCode = ::DHCP_BOOTREQUEST for message types: ::DHCP_DISCOVER, ::DHCP_REQUEST, + /// ::DHCP_DECLINE, ::DHCP_RELEASE, + /// ::DHCP_INFORM, ::DHCP_UNKNOWN_MSG_TYPE + /// ::DHCP_BOOTREPLY for message types: ::DHCP_OFFER, ::DHCP_ACK, ::DHCP_NAK + /// - @ref dhcp_header#hardwareType = 1 (Ethernet) + /// - @ref dhcp_header#hardwareAddressLength = 6 (MAC address length) void computeCalculateFields() override; std::string toString() const override; diff --git a/Packet++/header/DhcpV6Layer.h b/Packet++/header/DhcpV6Layer.h index 6f8aa4a367..019274d550 100644 --- a/Packet++/header/DhcpV6Layer.h +++ b/Packet++/header/DhcpV6Layer.h @@ -5,216 +5,200 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * DHCPv6 message types - */ + /// DHCPv6 message types enum DhcpV6MessageType { - /** Unknown message type */ + /// Unknown message type DHCPV6_UNKNOWN_MSG_TYPE = 0, - /** Solicit message type (Client to Server) */ + /// Solicit message type (Client to Server) DHCPV6_SOLICIT = 1, - /** Advertise message type (Server to Client) */ + /// Advertise message type (Server to Client) DHCPV6_ADVERTISE = 2, - /** Request message type (Client to Server) */ + /// Request message type (Client to Server) DHCPV6_REQUEST = 3, - /** Confirm message type (Client to Server) */ + /// Confirm message type (Client to Server) DHCPV6_CONFIRM = 4, - /** Renew message type (Client to Server) */ + /// Renew message type (Client to Server) DHCPV6_RENEW = 5, - /** Rebind message type (Client to Server) */ + /// Rebind message type (Client to Server) DHCPV6_REBIND = 6, - /** Reply message type (Server to Client) */ + /// Reply message type (Server to Client) DHCPV6_REPLY = 7, - /** Release message type (Client to Server) */ + /// Release message type (Client to Server) DHCPV6_RELEASE = 8, - /** Decline message type (Client to Server) */ + /// Decline message type (Client to Server) DHCPV6_DECLINE = 9, - /** Reconfigure message type (Server to Client) */ + /// Reconfigure message type (Server to Client) DHCPV6_RECONFIGURE = 10, - /** Information-Request message type (Client to Server) */ + /// Information-Request message type (Client to Server) DHCPV6_INFORMATION_REQUEST = 11, - /** Relay-Forward message type (Relay agent to Server) */ + /// Relay-Forward message type (Relay agent to Server) DHCPV6_RELAY_FORWARD = 12, - /** Relay-Reply message type (Server to Relay agent) */ + /// Relay-Reply message type (Server to Relay agent) DHCPV6_RELAY_REPLY = 13 }; - /** - * DHCPv6 option types. - * Resources for more information: - * - https://onlinelibrary.wiley.com/doi/pdf/10.1002/9781118073810.app2 - * - https://datatracker.ietf.org/doc/html/rfc5970 - * - https://datatracker.ietf.org/doc/html/rfc6607 - * - https://datatracker.ietf.org/doc/html/rfc8520 - */ + /// DHCPv6 option types. + /// Resources for more information: + /// - https://onlinelibrary.wiley.com/doi/pdf/10.1002/9781118073810.app2 + /// - https://datatracker.ietf.org/doc/html/rfc5970 + /// - https://datatracker.ietf.org/doc/html/rfc6607 + /// - https://datatracker.ietf.org/doc/html/rfc8520 enum DhcpV6OptionType { - /** Unknown option type */ + /// Unknown option type DHCPV6_OPT_UNKNOWN = 0, - /** Client Identifier (DUID of client) */ + /// Client Identifier (DUID of client) DHCPV6_OPT_CLIENTID = 1, - /** Server Identifier (DUID of server) */ + /// Server Identifier (DUID of server) DHCPV6_OPT_SERVERID = 2, - /** Identity Association for Non-temporary addresses */ + /// Identity Association for Non-temporary addresses DHCPV6_OPT_IA_NA = 3, - /** Identity Association for Temporary addresses */ + /// Identity Association for Temporary addresses DHCPV6_OPT_IA_TA = 4, - /** IA Address option */ + /// IA Address option DHCPV6_OPT_IAADDR = 5, - /** Option Request Option */ + /// Option Request Option DHCPV6_OPT_ORO = 6, - /** Preference setting */ + /// Preference setting DHCPV6_OPT_PREFERENCE = 7, - /** The amount of time since the client began the current DHCP transaction */ + /// The amount of time since the client began the current DHCP transaction DHCPV6_OPT_ELAPSED_TIME = 8, - /** The DHCP message being relayed by a relay agent */ + /// The DHCP message being relayed by a relay agent DHCPV6_OPT_RELAY_MSG = 9, - /** Authentication information */ + /// Authentication information DHCPV6_OPT_AUTH = 11, - /** Server unicast */ + /// Server unicast DHCPV6_OPT_UNICAST = 12, - /** Status code */ + /// Status code DHCPV6_OPT_STATUS_CODE = 13, - /** Rapid commit */ + /// Rapid commit DHCPV6_OPT_RAPID_COMMIT = 14, - /** User class */ + /// User class DHCPV6_OPT_USER_CLASS = 15, - /** Vendor class */ + /// Vendor class DHCPV6_OPT_VENDOR_CLASS = 16, - /** Vendor specific information */ + /// Vendor specific information DHCPV6_OPT_VENDOR_OPTS = 17, - /** Interface ID */ + /// Interface ID DHCPV6_OPT_INTERFACE_ID = 18, - /** Reconfigure Message */ + /// Reconfigure Message DHCPV6_OPT_RECONF_MSG = 19, - /** Reconfigure Accept */ + /// Reconfigure Accept DHCPV6_OPT_RECONF_ACCEPT = 20, - /** SIP Servers Domain Name */ + /// SIP Servers Domain Name DHCPV6_OPT_SIP_SERVERS_D = 21, - /** SIP Servers IPv6 Address List */ + /// SIP Servers IPv6 Address List DHCPV6_OPT_SIP_SERVERS_A = 22, - /** DNS Recursive Name Server */ + /// DNS Recursive Name Server DHCPV6_OPT_DNS_SERVERS = 23, - /** Domain Search List */ + /// Domain Search List DHCPV6_OPT_DOMAIN_LIST = 24, - /** Identity Association for Prefix Delegation */ + /// Identity Association for Prefix Delegation DHCPV6_OPT_IA_PD = 25, - /** IA_PD Prefix */ + /// IA_PD Prefix DHCPV6_OPT_IAPREFIX = 26, - /** Network Information Service (NIS) Servers */ + /// Network Information Service (NIS) Servers DHCPV6_OPT_NIS_SERVERS = 27, - /** Network Information Service v2 (NIS+) Servers */ + /// Network Information Service v2 (NIS+) Servers DHCPV6_OPT_NISP_SERVERS = 28, - /** Network Information Service (NIS) domain name */ + /// Network Information Service (NIS) domain name DHCPV6_OPT_NIS_DOMAIN_NAME = 29, - /** Network Information Service v2 (NIS+) domain name */ + /// Network Information Service v2 (NIS+) domain name DHCPV6_OPT_NISP_DOMAIN_NAME = 30, - /** Simple Network Time Protocol (SNTP) servers */ + /// Simple Network Time Protocol (SNTP) servers DHCPV6_OPT_SNTP_SERVERS = 31, - /** Information Refresh */ + /// Information Refresh DHCPV6_OPT_INFORMATION_REFRESH_TIME = 32, - /** Broadcast and Multicast Service (BCMCS) Domain Name List */ + /// Broadcast and Multicast Service (BCMCS) Domain Name List DHCPV6_OPT_BCMCS_SERVER_D = 33, - /** Broadcast and Multicast Service (BCMCS) IPv6 Address List */ + /// Broadcast and Multicast Service (BCMCS) IPv6 Address List DHCPV6_OPT_BCMCS_SERVER_A = 34, - /** Geographical location in civic (e.g., postal) format */ + /// Geographical location in civic (e.g., postal) format DHCPV6_OPT_GEOCONF_CIVIC = 36, - /** Relay Agent Remote ID */ + /// Relay Agent Remote ID DHCPV6_OPT_REMOTE_ID = 37, - /** Relay Agent Subscriber ID */ + /// Relay Agent Subscriber ID DHCPV6_OPT_SUBSCRIBER_ID = 38, - /** FQDN */ + /// FQDN DHCPV6_OPT_CLIENT_FQDN = 39, - /** One or more IPv6 addresses associated with PANA (Protocol for carrying Authentication for Network Access) - * Authentication Agents */ + /// One or more IPv6 addresses associated with PANA (Protocol for carrying Authentication for Network Access) + /// Authentication Agents DHCPV6_OPT_PANA_AGENT = 40, - /** Time zone to be used by the client in IEEE 1003.1 format */ + /// Time zone to be used by the client in IEEE 1003.1 format DHCPV6_OPT_NEW_POSIX_TIMEZONE = 41, - /** Time zone (TZ) database entry referred to by entry name */ + /// Time zone (TZ) database entry referred to by entry name DHCPV6_OPT_NEW_TZDB_TIMEZONE = 42, - /** Relay Agent Echo Request */ + /// Relay Agent Echo Request DHCPV6_OPT_ERO = 43, - /** Query option */ + /// Query option DHCPV6_OPT_LQ_QUERY = 44, - /** Client Data */ + /// Client Data DHCPV6_OPT_CLIENT_DATA = 45, - /** Client Last Transaction Time */ + /// Client Last Transaction Time DHCPV6_OPT_CLT_TIME = 46, - /** Relay data */ + /// Relay data DHCPV6_OPT_LQ_RELAY_DATA = 47, - /** Client link */ + /// Client link DHCPV6_OPT_LQ_CLIENT_LINK = 48, - /** Mobile IPv6 Home Network Information */ + /// Mobile IPv6 Home Network Information DHCPV6_OPT_MIP6_HNINF = 49, - /** Mobile IPv6 Relay Agent */ + /// Mobile IPv6 Relay Agent DHCPV6_OPT_MIP6_RELAY = 50, - /** Location to Service Translation (LoST) server domain name */ + /// Location to Service Translation (LoST) server domain name DHCPV6_OPT_V6_LOST = 51, - /** Access Points (CAPWAP) Access Controller IPv6 addresses */ + /// Access Points (CAPWAP) Access Controller IPv6 addresses DHCPV6_OPT_CAPWAP_AC_V6 = 52, - /** DHCPv6 Bulk LeaseQuery */ + /// DHCPv6 Bulk LeaseQuery DHCPV6_OPT_RELAY_ID = 53, - /** List of IPv6 addresses for servers providing particular types of IEEE 802.21 Mobility Service (MoS) */ + /// List of IPv6 addresses for servers providing particular types of IEEE 802.21 Mobility Service (MoS) DHCPV6_OPT_IPH6_ADDRESS_MOS = 54, - /** List of FQDNs for servers providing particular types of IEEE 802.21 Mobility Service (MoS) */ + /// List of FQDNs for servers providing particular types of IEEE 802.21 Mobility Service (MoS) DHCPV6_OPT_IPV6_FQDN_MOS = 55, - /** Network Time Protocol (NTP) or Simple NTP (SNTP) Server Location */ + /// Network Time Protocol (NTP) or Simple NTP (SNTP) Server Location DHCPV6_OPT_NTP_SERVER = 56, - /** Boot File Uniform Resource Locator (URL) */ + /// Boot File Uniform Resource Locator (URL) DHCPV6_OPT_BOOTFILE_URL = 59, - /** Boot File Parameters */ + /// Boot File Parameters DHCPV6_OPT_BOOTFILE_PARAM = 60, - /** Client System Architecture Type */ + /// Client System Architecture Type DHCPV6_OPT_CLIENT_ARCH_TYPE = 61, - /** Client Network Interface Identifier */ + /// Client Network Interface Identifier DHCPV6_OPT_NII = 62, - /** ERP Local Domain Name */ + /// ERP Local Domain Name DHCPV6_OPT_ERP_LOCAL_DOMAIN_NAME = 65, - /** Relay supplied options */ + /// Relay supplied options DHCPV6_OPT_RELAY_SUPPLIED_OPTIONS = 66, - /** Virtual Subnet Selection */ + /// Virtual Subnet Selection DHCPV6_OPT_VSS = 68, - /** Client link layer */ + /// Client link layer DHCPV6_OPT_CLIENT_LINKLAYER_ADDR = 79, - /** Manufacturer Usage Description */ + /// Manufacturer Usage Description DHCPV6_OPT_MUD_URL = 112 }; - /** - * @class DhcpV6Option - * A wrapper class for DHCPv6 options. This class does not create or modify DHCP option records, but rather - * serves as a wrapper and provides useful methods for setting and retrieving data to/from them - */ + /// @class DhcpV6Option + /// A wrapper class for DHCPv6 options. This class does not create or modify DHCP option records, but rather + /// serves as a wrapper and provides useful methods for setting and retrieving data to/from them class DhcpV6Option : public TLVRecord { public: - /** - * A c'tor for this class that gets a pointer to the option raw data (byte array) - * @param[in] optionRawData A pointer to the option raw data - */ + /// A c'tor for this class that gets a pointer to the option raw data (byte array) + /// @param[in] optionRawData A pointer to the option raw data explicit DhcpV6Option(uint8_t* optionRawData) : TLVRecord(optionRawData) {} - /** - * A d'tor for this class, currently does nothing - */ + /// A d'tor for this class, currently does nothing ~DhcpV6Option() override = default; - /** - * @return The option type converted to ::DhcpV6OptionType enum - */ + /// @return The option type converted to ::DhcpV6OptionType enum DhcpV6OptionType getType() const; - /** - * @return The raw option value (byte array) as a hex string - */ + /// @return The raw option value (byte array) as a hex string std::string getValueAsHexString() const; // implement abstract methods @@ -223,212 +207,158 @@ namespace pcpp size_t getDataSize() const override; }; - /** - * @class DhcpV6OptionBuilder - * A class for building DHCPv6 options. This builder receives the option parameters in its c'tor, - * builds the DHCPv6 option raw buffer and provides a build() method to get a DhcpV6Option object out of it - */ + /// @class DhcpV6OptionBuilder + /// A class for building DHCPv6 options. This builder receives the option parameters in its c'tor, + /// builds the DHCPv6 option raw buffer and provides a build() method to get a DhcpV6Option object out of it class DhcpV6OptionBuilder : public TLVRecordBuilder { public: - /** - * A c'tor for building DHCPv6 options from a string representing the hex stream of the raw byte value. - * The DhcpV6Option object can later be retrieved by calling build() - * @param[in] optionType DHCPv6 option type - * @param[in] optionValueAsHexStream The value as a hex stream string - */ + /// A c'tor for building DHCPv6 options from a string representing the hex stream of the raw byte value. + /// The DhcpV6Option object can later be retrieved by calling build() + /// @param[in] optionType DHCPv6 option type + /// @param[in] optionValueAsHexStream The value as a hex stream string DhcpV6OptionBuilder(DhcpV6OptionType optionType, const std::string& optionValueAsHexStream) : TLVRecordBuilder(static_cast(optionType), optionValueAsHexStream, true) {} - /** - * A c'tor for building DHCPv6 options from a byte array representing their value. The DhcpV6Option object can - * be later retrieved by calling build() - * @param[in] optionType DHCPv6 option type - * @param[in] optionValue A buffer containing the option value. This buffer is read-only and isn't modified in - * any way. - * @param[in] optionValueLen Option value length in bytes - */ + /// A c'tor for building DHCPv6 options from a byte array representing their value. The DhcpV6Option object can + /// be later retrieved by calling build() + /// @param[in] optionType DHCPv6 option type + /// @param[in] optionValue A buffer containing the option value. This buffer is read-only and isn't modified in + /// any way. + /// @param[in] optionValueLen Option value length in bytes DhcpV6OptionBuilder(DhcpV6OptionType optionType, const uint8_t* optionValue, uint8_t optionValueLen) : TLVRecordBuilder(static_cast(optionType), optionValue, optionValueLen) {} - /** - * Build the DhcpV6Option object out of the parameters defined in the c'tor - * @return The DhcpV6Option object - */ + /// Build the DhcpV6Option object out of the parameters defined in the c'tor + /// @return The DhcpV6Option object DhcpV6Option build() const; }; - /** - * @struct dhcpv6_header - * Represents the basic DHCPv6 protocol header - */ + /// @struct dhcpv6_header + /// Represents the basic DHCPv6 protocol header struct dhcpv6_header { - /** DHCPv6 message type */ + /// DHCPv6 message type uint8_t messageType; - /** DHCPv6 transaction ID (first byte) */ + /// DHCPv6 transaction ID (first byte) uint8_t transactionId1; - /** DHCPv6 transaction ID (second byte) */ + /// DHCPv6 transaction ID (second byte) uint8_t transactionId2; - /** DHCPv6 transaction ID (last byte) */ + /// DHCPv6 transaction ID (last byte) uint8_t transactionId3; }; static_assert(sizeof(dhcpv6_header) == 4, "dhcpv6_header size is not 4 bytes"); - /** - * @class DhcpV6Layer - * Represents a DHCPv6 (Dynamic Host Configuration Protocol version 6) protocol layer - */ + /// @class DhcpV6Layer + /// Represents a DHCPv6 (Dynamic Host Configuration Protocol version 6) protocol layer class DhcpV6Layer : public Layer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in DhcpV6Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * A constructor that creates the layer from scratch - * @param[in] messageType A DHCPv6 message type to be set - * @param[in] transactionId The transaction ID to be set. Notice the transaction ID is 3-byte long so the value - * shouldn't exceed 0xFFFFFF - */ + /// A constructor that creates the layer from scratch + /// @param[in] messageType A DHCPv6 message type to be set + /// @param[in] transactionId The transaction ID to be set. Notice the transaction ID is 3-byte long so the value + /// shouldn't exceed 0xFFFFFF DhcpV6Layer(DhcpV6MessageType messageType, uint32_t transactionId); - /** - * @return The message type of this DHCPv6 message - */ + /// @return The message type of this DHCPv6 message DhcpV6MessageType getMessageType() const; - /** - * @return The string value of the message type of this DHCPv6 message - */ + /// @return The string value of the message type of this DHCPv6 message std::string getMessageTypeAsString() const; - /** - * Set the message type for this layer - * @param[in] messageType The message type to set - */ + /// Set the message type for this layer + /// @param[in] messageType The message type to set void setMessageType(DhcpV6MessageType messageType); - /** - * @return The transaction ID of this DHCPv6 message - */ + /// @return The transaction ID of this DHCPv6 message uint32_t getTransactionID() const; - /** - * Set the transaction ID for this DHCPv6 message - * @param[in] transactionId The transaction ID value to set - */ + /// Set the transaction ID for this DHCPv6 message + /// @param[in] transactionId The transaction ID value to set void setTransactionID(uint32_t transactionId) const; - /** - * @return The first DHCPv6 option in the packet. If there are no DHCPv6 options the returned value will contain - * a logical null (DhcpV6Option#isNull() == true) - */ + /// @return The first DHCPv6 option in the packet. If there are no DHCPv6 options the returned value will + /// contain a logical null (DhcpV6Option#isNull() == true) DhcpV6Option getFirstOptionData() const; - /** - * Get the DHCPv6 option that comes after a given option. If the given option was the last one, the - * returned value will contain a logical null (DhcpV6Option#isNull() == true) - * @param[in] dhcpv6Option A given DHCPv6 option - * @return A DhcpV6Option object containing the option data that comes next, or logical null if the given - * DHCPv6 option: (1) was the last one; (2) contains a logical null or (3) doesn't belong to this packet - */ + /// Get the DHCPv6 option that comes after a given option. If the given option was the last one, the + /// returned value will contain a logical null (DhcpV6Option#isNull() == true) + /// @param[in] dhcpv6Option A given DHCPv6 option + /// @return A DhcpV6Option object containing the option data that comes next, or logical null if the given + /// DHCPv6 option: (1) was the last one; (2) contains a logical null or (3) doesn't belong to this packet DhcpV6Option getNextOptionData(DhcpV6Option dhcpv6Option) const; - /** - * Get a DHCPv6 option by type - * @param[in] option DHCPv6 option type - * @return A DhcpV6OptionType object containing the first DHCP option data that matches this type, or logical - * null (DhcpV6Option#isNull() == true) if no such option found - */ + /// Get a DHCPv6 option by type + /// @param[in] option DHCPv6 option type + /// @return A DhcpV6OptionType object containing the first DHCP option data that matches this type, or logical + /// null (DhcpV6Option#isNull() == true) if no such option found DhcpV6Option getOptionData(DhcpV6OptionType option) const; - /** - * @return The number of DHCPv6 options in this layer - */ + /// @return The number of DHCPv6 options in this layer size_t getOptionCount() const; - /** - * Add a new DHCPv6 option at the end of the layer - * @param[in] optionBuilder A DhcpV6OptionBuilder object that contains the requested DHCPv6 option data to add - * @return A DhcpV6Option object containing the newly added DHCP option data or logical null - * (DhcpV6Option#isNull() == true) if addition failed - */ + /// Add a new DHCPv6 option at the end of the layer + /// @param[in] optionBuilder A DhcpV6OptionBuilder object that contains the requested DHCPv6 option data to add + /// @return A DhcpV6Option object containing the newly added DHCP option data or logical null + /// (DhcpV6Option#isNull() == true) if addition failed DhcpV6Option addOption(const DhcpV6OptionBuilder& optionBuilder); - /** - * Add a new DHCPv6 option after an existing one - * @param[in] optionBuilder A DhcpV6OptionBuilder object that contains the requested DHCPv6 option data to add - * @param[in] optionType The DHCPv6 option type which the newly added option will come after - * @return A DhcpV6Option object containing the newly added DHCPv6 option data or logical null - * (DhcpV6Option#isNull() == true) if addition failed - */ + /// Add a new DHCPv6 option after an existing one + /// @param[in] optionBuilder A DhcpV6OptionBuilder object that contains the requested DHCPv6 option data to add + /// @param[in] optionType The DHCPv6 option type which the newly added option will come after + /// @return A DhcpV6Option object containing the newly added DHCPv6 option data or logical null + /// (DhcpV6Option#isNull() == true) if addition failed DhcpV6Option addOptionAfter(const DhcpV6OptionBuilder& optionBuilder, DhcpV6OptionType optionType); - /** - * Add a new DHCPv6 option before an existing one - * @param[in] optionBuilder A DhcpV6OptionBuilder object that contains the requested DHCPv6 option data to add - * @param[in] optionType The DHCPv6 option type which the newly added option will come before - * @return A DhcpV6Option object containing the newly added DHCPv6 option data or logical null - * (DhcpV6Option#isNull() == true) if addition failed - */ + /// Add a new DHCPv6 option before an existing one + /// @param[in] optionBuilder A DhcpV6OptionBuilder object that contains the requested DHCPv6 option data to add + /// @param[in] optionType The DHCPv6 option type which the newly added option will come before + /// @return A DhcpV6Option object containing the newly added DHCPv6 option data or logical null + /// (DhcpV6Option#isNull() == true) if addition failed DhcpV6Option addOptionBefore(const DhcpV6OptionBuilder& optionBuilder, DhcpV6OptionType optionType); - /** - * Remove an existing DHCPv6 option from the layer - * @param[in] optionType The DHCPv6 option type to remove - * @return True if DHCPv6 option was successfully removed or false if type wasn't found or if removal failed - */ + /// Remove an existing DHCPv6 option from the layer + /// @param[in] optionType The DHCPv6 option type to remove + /// @return True if DHCPv6 option was successfully removed or false if type wasn't found or if removal failed bool removeOption(DhcpV6OptionType optionType); - /** - * Remove all DHCPv6 options in this layer - * @return True if all DHCPv6 options were successfully removed or false if removal failed for some reason - */ + /// Remove all DHCPv6 options in this layer + /// @return True if all DHCPv6 options were successfully removed or false if removal failed for some reason bool removeAllOptions(); - /** - * A static method that checks whether a port is considered as a DHCPv6 port - * @param[in] port The port number to check - * @return True if this is a DHCPv6 port number, false otherwise - */ + /// A static method that checks whether a port is considered as a DHCPv6 port + /// @param[in] port The port number to check + /// @return True if this is a DHCPv6 port number, false otherwise static inline bool isDhcpV6Port(uint16_t port); - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of an DHCPv6 layer - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent an DHCPv6 layer - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of an DHCPv6 layer + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent an DHCPv6 layer static inline bool isDataValid(const uint8_t* data, size_t dataLen); // implement abstract methods - /** - * Does nothing for this layer (DhcpV6Layer is always last) - */ + /// Does nothing for this layer (DhcpV6Layer is always last) void parseNextLayer() override {} - /** - * @return The size of @ref dhcpv6_header + size of options - */ + /// @return The size of @ref dhcpv6_header + size of options size_t getHeaderLen() const override { return m_DataLen; } - /** - * Does nothing for this layer - */ + /// Does nothing for this layer void computeCalculateFields() override {} diff --git a/Packet++/header/DnsLayer.h b/Packet++/header/DnsLayer.h index 1fe4b84a26..c79f269e27 100644 --- a/Packet++/header/DnsLayer.h +++ b/Packet++/header/DnsLayer.h @@ -7,75 +7,70 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct dnshdr - * Represents the fixed part of the DNS header, meaning the part that doesn't include the DNS data (queries, - * answers, authorities and additional records) - */ + /// @struct dnshdr + /// Represents the fixed part of the DNS header, meaning the part that doesn't include the DNS data (queries, + /// answers, authorities and additional records) #pragma pack(push, 1) struct dnshdr { - /** DNS query identification */ + /// DNS query identification uint16_t transactionID; #if (BYTE_ORDER == LITTLE_ENDIAN) uint16_t - /** Recursion desired flag */ + /// Recursion desired flag recursionDesired : 1, - /** Truncated flag */ + /// Truncated flag truncation : 1, - /** Authoritative answer flag */ + /// Authoritative answer flag authoritativeAnswer : 1, - /** Operation Code */ + /// Operation Code opcode : 4, - /** Query/Response flag */ + /// Query/Response flag queryOrResponse : 1, - /** Return Code */ + /// Return Code responseCode : 4, - /** Checking disabled flag */ + /// Checking disabled flag checkingDisabled : 1, - /** Authenticated data flag */ + /// Authenticated data flag authenticData : 1, - /** Zero flag (Reserved) */ + /// Zero flag (Reserved) zero : 1, - /** Recursion available flag */ + /// Recursion available flag recursionAvailable : 1; #elif (BYTE_ORDER == BIG_ENDIAN) uint16_t - /** Query/Response flag */ + /// Query/Response flag queryOrResponse : 1, - /** Operation Code */ + /// Operation Code opcode : 4, - /** Authoritative answer flag */ + /// Authoritative answer flag authoritativeAnswer : 1, - /** Truncated flag */ + /// Truncated flag truncation : 1, - /** Recursion desired flag */ + /// Recursion desired flag recursionDesired : 1, - /** Recursion available flag */ + /// Recursion available flag recursionAvailable : 1, - /** Zero flag (Reserved) */ + /// Zero flag (Reserved) zero : 1, - /** Authenticated data flag */ + /// Authenticated data flag authenticData : 1, - /** Checking disabled flag */ + /// Checking disabled flag checkingDisabled : 1, - /** Return Code */ + /// Return Code responseCode : 4; #endif - /** Number of DNS query records in packet */ + /// Number of DNS query records in packet uint16_t numberOfQuestions; - /** Number of DNS answer records in packet */ + /// Number of DNS answer records in packet uint16_t numberOfAnswers; - /** Number of authority records in packet */ + /// Number of authority records in packet uint16_t numberOfAuthority; - /** Number of additional records in packet */ + /// Number of additional records in packet uint16_t numberOfAdditional; }; #pragma pack(pop) @@ -87,10 +82,8 @@ namespace pcpp class DnsResource; class IDnsResourceData; - /** - * @class DnsLayer - * Represents the DNS protocol layer - */ + /// @class DnsLayer + /// Represents the DNS protocol layer class DnsLayer : public Layer { friend class IDnsResource; @@ -98,358 +91,276 @@ namespace pcpp friend class DnsResource; public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in DnsLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * A constructor that creates an empty DNS layer: all members of dnshdr are set to 0 and layer will contain no - * records - */ + /// A constructor that creates an empty DNS layer: all members of dnshdr are set to 0 and layer will contain no + /// records DnsLayer(); - /** - * A copy constructor for this layer - * @param[in] other The DNS layer to copy from - */ + /// A copy constructor for this layer + /// @param[in] other The DNS layer to copy from DnsLayer(const DnsLayer& other); - /** - * An assignment operator for this layer - * @param[in] other The DNS layer to assign - * @return A reference to the assignee - */ + /// An assignment operator for this layer + /// @param[in] other The DNS layer to assign + /// @return A reference to the assignee DnsLayer& operator=(const DnsLayer& other); ~DnsLayer() override; - /** - * Get a pointer to the DNS header (as opposed to the DNS data which is the queries, answers, etc. Data can be - * retrieved through the other methods of this layer. Notice the return value points directly to the data, so - * every change will change the actual packet data - * @return A pointer to the @ref dnshdr - */ + /// Get a pointer to the DNS header (as opposed to the DNS data which is the queries, answers, etc. Data can be + /// retrieved through the other methods of this layer. Notice the return value points directly to the data, so + /// every change will change the actual packet data + /// @return A pointer to the @ref dnshdr dnshdr* getDnsHeader() const; - /** - * Searches for a DNS query by its name field. Notice this method returns only a query which its name equals to - * the requested name. If several queries match the requested name, the first one will be returned. If no - * queries match the requested name, nullptr will be returned - * @param[in] name The name of the query to search - * @param[in] exactMatch Indicate whether to match the whole name or just a part of it - * @return The first matching DNS query or nullptr if no queries were found - */ + /// Searches for a DNS query by its name field. Notice this method returns only a query which its name equals to + /// the requested name. If several queries match the requested name, the first one will be returned. If no + /// queries match the requested name, nullptr will be returned + /// @param[in] name The name of the query to search + /// @param[in] exactMatch Indicate whether to match the whole name or just a part of it + /// @return The first matching DNS query or nullptr if no queries were found DnsQuery* getQuery(const std::string& name, bool exactMatch) const; - /** - * @return The first DNS query in the packet or nullptr if packet doesn't contain any queries - */ + /// @return The first DNS query in the packet or nullptr if packet doesn't contain any queries DnsQuery* getFirstQuery() const; - /** - * Get the DNS query following a certain query - * @param[in] query A pointer to a DNS query that exist in the packet - * @return The DNS query following 'query'. If 'query' is nullptr or 'query' is the last query in the packet - * nullptr will be returned - */ + /// Get the DNS query following a certain query + /// @param[in] query A pointer to a DNS query that exist in the packet + /// @return The DNS query following 'query'. If 'query' is nullptr or 'query' is the last query in the packet + /// nullptr will be returned DnsQuery* getNextQuery(DnsQuery* query) const; - /** - * @return The number of DNS queries in the packet - */ + /// @return The number of DNS queries in the packet size_t getQueryCount() const; - /** - * Add a new DNS query to the layer - * @param[in] name The value that shall be set in the name field of the query - * @param[in] dnsType The value that shall be set in the DNS type field of the query - * @param[in] dnsClass The value that shall be set in the DNS class field of the query - * @return A pointer to the newly created DNS query or nullptr if query could not be created (an appropriate - * error log message will be printed in this case) - */ + /// Add a new DNS query to the layer + /// @param[in] name The value that shall be set in the name field of the query + /// @param[in] dnsType The value that shall be set in the DNS type field of the query + /// @param[in] dnsClass The value that shall be set in the DNS class field of the query + /// @return A pointer to the newly created DNS query or nullptr if query could not be created (an appropriate + /// error log message will be printed in this case) DnsQuery* addQuery(const std::string& name, DnsType dnsType, DnsClass dnsClass); - /** - * Add a new DNS query similar to an already existing DNS query. All query fields will be copied from the - * existing query - * @param[in] copyQuery The record to create the new record from. copyQuery won't be changed in any way - * @return A pointer to the newly created DNS query or nullptr if query could not be created (an appropriate - * error log message will be printed in this case) - */ + /// Add a new DNS query similar to an already existing DNS query. All query fields will be copied from the + /// existing query + /// @param[in] copyQuery The record to create the new record from. copyQuery won't be changed in any way + /// @return A pointer to the newly created DNS query or nullptr if query could not be created (an appropriate + /// error log message will be printed in this case) DnsQuery* addQuery(DnsQuery* const copyQuery); - /** - * Remove an existing query by name. If several queries matches the name, the first match will be removed - * @param[in] queryNameToRemove The name of the query to remove - * @param[in] exactMatch Indicate whether to match the whole name or just a part of it - * @return True if query was found and successfully removed or false if query was not found or couldn't be - * removed - */ + /// Remove an existing query by name. If several queries matches the name, the first match will be removed + /// @param[in] queryNameToRemove The name of the query to remove + /// @param[in] exactMatch Indicate whether to match the whole name or just a part of it + /// @return True if query was found and successfully removed or false if query was not found or couldn't be + /// removed bool removeQuery(const std::string& queryNameToRemove, bool exactMatch); - /** - * Remove an existing query - * @param[in] queryToRemove A pointer to the query to remove - * @return True if query was found and successfully removed or false if query was not found or couldn't be - * removed - */ + /// Remove an existing query + /// @param[in] queryToRemove A pointer to the query to remove + /// @return True if query was found and successfully removed or false if query was not found or couldn't be + /// removed bool removeQuery(DnsQuery* queryToRemove); - /** - * Searches for a DNS answer by its name field. Notice this method returns only an answer which its name equals - * to the requested name. If several answers match the requested name, the first one will be returned. If no - * answers match the requested name, nullptr will be returned - * @param[in] name The name of the answer to search - * @param[in] exactMatch Indicate whether to match the whole name or just a part of it - * @return The first matching DNS answer or nullptr if no answers were found - */ + /// Searches for a DNS answer by its name field. Notice this method returns only an answer which its name equals + /// to the requested name. If several answers match the requested name, the first one will be returned. If no + /// answers match the requested name, nullptr will be returned + /// @param[in] name The name of the answer to search + /// @param[in] exactMatch Indicate whether to match the whole name or just a part of it + /// @return The first matching DNS answer or nullptr if no answers were found DnsResource* getAnswer(const std::string& name, bool exactMatch) const; - /** - * @return The first DNS answer in the packet or nullptr if packet doesn't contain any answers - */ + /// @return The first DNS answer in the packet or nullptr if packet doesn't contain any answers DnsResource* getFirstAnswer() const; - /** - * Get the DNS answer following a certain answer - * @param[in] answer A pointer to a DNS answer that exist in the packet - * @return The DNS answer following 'answer'. If 'answer' is nullptr or 'answer' is the last answer in the - * packet nullptr will be returned - */ + /// Get the DNS answer following a certain answer + /// @param[in] answer A pointer to a DNS answer that exist in the packet + /// @return The DNS answer following 'answer'. If 'answer' is nullptr or 'answer' is the last answer in the + /// packet nullptr will be returned DnsResource* getNextAnswer(DnsResource* answer) const; - /** - * @return The number of DNS answers in the packet - */ + /// @return The number of DNS answers in the packet size_t getAnswerCount() const; - /** - * Add a new DNS answer to the layer - * @param[in] name The value that shall be set in the name field of the answer - * @param[in] dnsType The value that shall be set in the DNS type field of the answer - * @param[in] dnsClass The value that shall be set in the DNS class field of the answer - * @param[in] ttl The value that shall be set in the 'time-to-leave' field of the answer - * @param[in] data The answer data to be set. The type of the data should match the type of the DNS record - * (for example: DNS record of type A should have data of type IPv4DnsResourceData. Please see - * DnsResource#setData() for more info on this - * @return A pointer to the newly created DNS answer or nullptr if answer could not be created (an appropriate - * error log message will be printed in this case) - */ + /// Add a new DNS answer to the layer + /// @param[in] name The value that shall be set in the name field of the answer + /// @param[in] dnsType The value that shall be set in the DNS type field of the answer + /// @param[in] dnsClass The value that shall be set in the DNS class field of the answer + /// @param[in] ttl The value that shall be set in the 'time-to-leave' field of the answer + /// @param[in] data The answer data to be set. The type of the data should match the type of the DNS record + /// (for example: DNS record of type A should have data of type IPv4DnsResourceData. Please see + /// DnsResource#setData() for more info on this + /// @return A pointer to the newly created DNS answer or nullptr if answer could not be created (an appropriate + /// error log message will be printed in this case) DnsResource* addAnswer(const std::string& name, DnsType dnsType, DnsClass dnsClass, uint32_t ttl, IDnsResourceData* data); - /** - * Add a new DNS answer similar to an already existing DNS answer. All answer fields will be copied from the - * existing answer - * @param[in] copyAnswer The record to create the new record from. copyAnswer won't be changed in any way - * @return A pointer to the newly created DNS answer or nullptr if query could not be created (an appropriate - * error log message will be printed in this case) - */ + /// Add a new DNS answer similar to an already existing DNS answer. All answer fields will be copied from the + /// existing answer + /// @param[in] copyAnswer The record to create the new record from. copyAnswer won't be changed in any way + /// @return A pointer to the newly created DNS answer or nullptr if query could not be created (an appropriate + /// error log message will be printed in this case) DnsResource* addAnswer(DnsResource* const copyAnswer); - /** - * Remove an existing answer by name. If several answers matches the name, the first match will be removed - * @param[in] answerNameToRemove The name of the answer to remove - * @param[in] exactMatch Indicate whether to match the whole name or just a part of it - * @return True if answer was found and successfully removed or false if answer was not found or couldn't be - * removed - */ + /// Remove an existing answer by name. If several answers matches the name, the first match will be removed + /// @param[in] answerNameToRemove The name of the answer to remove + /// @param[in] exactMatch Indicate whether to match the whole name or just a part of it + /// @return True if answer was found and successfully removed or false if answer was not found or couldn't be + /// removed bool removeAnswer(const std::string& answerNameToRemove, bool exactMatch); - /** - * Remove an existing answer - * @param[in] answerToRemove A pointer to the answer to remove - * @return True if answer was found and successfully removed or false if answer was not found or couldn't be - * removed - */ + /// Remove an existing answer + /// @param[in] answerToRemove A pointer to the answer to remove + /// @return True if answer was found and successfully removed or false if answer was not found or couldn't be + /// removed bool removeAnswer(DnsResource* answerToRemove); - /** - * Searches for a DNS authority by its name field. Notice this method returns only an authority which its name - * equals to the requested name. If several authorities match the requested name, the first one will be - * returned. If no authorities match the requested name, nullptr will be returned - * @param[in] name The name of the authority to search - * @param[in] exactMatch Indicate whether to match the whole name or just a part of it - * @return The first matching DNS authority or nullptr if no authorities were found - */ + /// Searches for a DNS authority by its name field. Notice this method returns only an authority which its name + /// equals to the requested name. If several authorities match the requested name, the first one will be + /// returned. If no authorities match the requested name, nullptr will be returned + /// @param[in] name The name of the authority to search + /// @param[in] exactMatch Indicate whether to match the whole name or just a part of it + /// @return The first matching DNS authority or nullptr if no authorities were found DnsResource* getAuthority(const std::string& name, bool exactMatch) const; - /** - * @return The first DNS authority in the packet or nullptr if packet doesn't contain any authorities - */ + /// @return The first DNS authority in the packet or nullptr if packet doesn't contain any authorities DnsResource* getFirstAuthority() const; - /** - * Get the DNS authority following a certain authority - * @param[in] authority A pointer to a DNS authority that exist in the packet - * @return The DNS authority following 'authority'. If 'authority' is nullptr or 'authority' is the last - * authority in the packet nullptr will be returned - */ + /// Get the DNS authority following a certain authority + /// @param[in] authority A pointer to a DNS authority that exist in the packet + /// @return The DNS authority following 'authority'. If 'authority' is nullptr or 'authority' is the last + /// authority in the packet nullptr will be returned DnsResource* getNextAuthority(DnsResource* authority) const; - /** - * @return The number of DNS authorities in the packet - */ + /// @return The number of DNS authorities in the packet size_t getAuthorityCount() const; - /** - * Add a new DNS authority to the layer - * @param[in] name The value that shall be set in the name field of the authority - * @param[in] dnsType The value that shall be set in the DNS type field of the authority - * @param[in] dnsClass The value that shall be set in the DNS class field of the authority - * @param[in] ttl The value that shall be set in the 'time-to-leave' field of the authority - * @param[in] data The authority data to be set. The type of the data should match the type of the DNS record - * (for example: DNS record of type A should have data of type IPv4DnsResourceData. Please see - * DnsResource#setData() for more info on this - * @return A pointer to the newly created DNS authority or nullptr if authority could not be created (an - * appropriate error log message will be printed in this case) - */ + /// Add a new DNS authority to the layer + /// @param[in] name The value that shall be set in the name field of the authority + /// @param[in] dnsType The value that shall be set in the DNS type field of the authority + /// @param[in] dnsClass The value that shall be set in the DNS class field of the authority + /// @param[in] ttl The value that shall be set in the 'time-to-leave' field of the authority + /// @param[in] data The authority data to be set. The type of the data should match the type of the DNS record + /// (for example: DNS record of type A should have data of type IPv4DnsResourceData. Please see + /// DnsResource#setData() for more info on this + /// @return A pointer to the newly created DNS authority or nullptr if authority could not be created (an + /// appropriate error log message will be printed in this case) DnsResource* addAuthority(const std::string& name, DnsType dnsType, DnsClass dnsClass, uint32_t ttl, IDnsResourceData* data); - /** - * Add a new DNS authority similar to an already existing DNS authority. All authority fields will be copied - * from the existing authority - * @param[in] copyAuthority The record to create the new record from. copyAuthority won't be changed in any way - * @return A pointer to the newly created DNS authority or nullptr if query could not be created (an appropriate - * error log message will be printed in this case) - */ + /// Add a new DNS authority similar to an already existing DNS authority. All authority fields will be copied + /// from the existing authority + /// @param[in] copyAuthority The record to create the new record from. copyAuthority won't be changed in any way + /// @return A pointer to the newly created DNS authority or nullptr if query could not be created (an + /// appropriate error log message will be printed in this case) DnsResource* addAuthority(DnsResource* const copyAuthority); - /** - * Remove an existing authority by name. If several authorities matches the name, the first match will be - * removed - * @param[in] authorityNameToRemove The name of the authority to remove - * @param[in] exactMatch Indicate whether to match the whole name or just a part of it - * @return True if authority was found and successfully removed or false if authority was not found or couldn't - * be removed - */ + /// Remove an existing authority by name. If several authorities matches the name, the first match will be + /// removed + /// @param[in] authorityNameToRemove The name of the authority to remove + /// @param[in] exactMatch Indicate whether to match the whole name or just a part of it + /// @return True if authority was found and successfully removed or false if authority was not found or couldn't + /// be removed bool removeAuthority(const std::string& authorityNameToRemove, bool exactMatch); - /** - * Remove an existing authority - * @param[in] authorityToRemove A pointer to the authority to remove - * @return True if authority was found and successfully removed or false if authority was not found or couldn't - * be removed - */ + /// Remove an existing authority + /// @param[in] authorityToRemove A pointer to the authority to remove + /// @return True if authority was found and successfully removed or false if authority was not found or couldn't + /// be removed bool removeAuthority(DnsResource* authorityToRemove); - /** - * Searches for a DNS additional record by its name field. Notice this method returns only an additional record - * which its name equals to the requested name. If several additional records match the requested name, the - * first one will be returned. If no additional records match the requested name, nullptr will be returned - * @param[in] name The name of the additional record to search - * @param[in] exactMatch Indicate whether to match the whole name or just a part of it - * @return The first matching DNS additional record or nullptr if no additional records were found - */ + /// Searches for a DNS additional record by its name field. Notice this method returns only an additional record + /// which its name equals to the requested name. If several additional records match the requested name, the + /// first one will be returned. If no additional records match the requested name, nullptr will be returned + /// @param[in] name The name of the additional record to search + /// @param[in] exactMatch Indicate whether to match the whole name or just a part of it + /// @return The first matching DNS additional record or nullptr if no additional records were found DnsResource* getAdditionalRecord(const std::string& name, bool exactMatch) const; - /** - * @return The first DNS additional record in the packet or nullptr if packet doesn't contain any additional - * records - */ + /// @return The first DNS additional record in the packet or nullptr if packet doesn't contain any additional + /// records DnsResource* getFirstAdditionalRecord() const; - /** - * Get the DNS additional record following a certain additional record - * @param[in] additionalRecord A pointer to a DNS additional record that exist in the packet - * @return The DNS additional record following 'additionalRecord'. If 'additionalRecord' is nullptr or - * 'additionalRecord' is the last additional record in the packet nullptr will be returned - */ + /// Get the DNS additional record following a certain additional record + /// @param[in] additionalRecord A pointer to a DNS additional record that exist in the packet + /// @return The DNS additional record following 'additionalRecord'. If 'additionalRecord' is nullptr or + /// 'additionalRecord' is the last additional record in the packet nullptr will be returned DnsResource* getNextAdditionalRecord(DnsResource* additionalRecord) const; - /** - * @return The number of DNS additional records in the packet - */ + /// @return The number of DNS additional records in the packet size_t getAdditionalRecordCount() const; - /** - * Add a new DNS additional record to the layer - * @param[in] name The value that shall be set in the name field of the additional record - * @param[in] dnsType The value that shall be set in the DNS type field of the additional record - * @param[in] dnsClass The value that shall be set in the DNS class field of the additional record - * @param[in] ttl The value that shall be set in the 'time-to-leave' field of the additional record - * @param[in] data The additional record data to be set. The type of the data should match the type of the DNS - * record (for example: DNS record of type A should have data of type IPv4DnsResourceData. Please see - * DnsResource#setData() for more info on this - * @return A pointer to the newly created DNS additional record or nullptr if additional record could not be - * created (an appropriate error log message will be printed in this case) - */ + /// Add a new DNS additional record to the layer + /// @param[in] name The value that shall be set in the name field of the additional record + /// @param[in] dnsType The value that shall be set in the DNS type field of the additional record + /// @param[in] dnsClass The value that shall be set in the DNS class field of the additional record + /// @param[in] ttl The value that shall be set in the 'time-to-leave' field of the additional record + /// @param[in] data The additional record data to be set. The type of the data should match the type of the DNS + /// record (for example: DNS record of type A should have data of type IPv4DnsResourceData. Please see + /// DnsResource#setData() for more info on this + /// @return A pointer to the newly created DNS additional record or nullptr if additional record could not be + /// created (an appropriate error log message will be printed in this case) DnsResource* addAdditionalRecord(const std::string& name, DnsType dnsType, DnsClass dnsClass, uint32_t ttl, IDnsResourceData* data); - /** - * Add a new DNS additional record to the layer that doesn't have DNS class and TTL. Instead these bytes may - * contains some arbitrary data. In the future I may add support for these kinds of additional data records. For - * now, these bytes are set as raw - * @param[in] name The value that shall be set in the name field of the additional record - * @param[in] dnsType The value that shall be set in the DNS type field of the additional record - * @param[in] customData1 Two bytes of the arbitrary data that will be set in the offset usually used for the - * DNS class - * @param[in] customData2 Four bytes of the arbitrary data that will be set in the offset usually used for the - * TTL - * @param[in] data The additional record data to be set. The type of the data should match the type of the DNS - * record. (for example: DNS record of type A should have data of type IPv4DnsResourceData. Please see - * DnsResource#setData() for more info on this - * @return A pointer to the newly created DNS additional record or nullptr if additional record could not be - * created (an appropriate error log message will be printed in this case) - */ + /// Add a new DNS additional record to the layer that doesn't have DNS class and TTL. Instead these bytes may + /// contains some arbitrary data. In the future I may add support for these kinds of additional data records. + /// For now, these bytes are set as raw + /// @param[in] name The value that shall be set in the name field of the additional record + /// @param[in] dnsType The value that shall be set in the DNS type field of the additional record + /// @param[in] customData1 Two bytes of the arbitrary data that will be set in the offset usually used for the + /// DNS class + /// @param[in] customData2 Four bytes of the arbitrary data that will be set in the offset usually used for the + /// TTL + /// @param[in] data The additional record data to be set. The type of the data should match the type of the DNS + /// record. (for example: DNS record of type A should have data of type IPv4DnsResourceData. Please see + /// DnsResource#setData() for more info on this + /// @return A pointer to the newly created DNS additional record or nullptr if additional record could not be + /// created (an appropriate error log message will be printed in this case) DnsResource* addAdditionalRecord(const std::string& name, DnsType dnsType, uint16_t customData1, uint32_t customData2, IDnsResourceData* data); - /** - * Add a new DNS additional record similar to an already existing DNS additional record. All additional record - * fields will be copied from the existing additional record - * @param[in] copyAdditionalRecord The record to create the new record from. copyAdditionalRecord won't be - * changed in any way - * @return A pointer to the newly created DNS additional record or nullptr if query could not be created (an - * appropriate error log message will be printed in this case) - */ + /// Add a new DNS additional record similar to an already existing DNS additional record. All additional record + /// fields will be copied from the existing additional record + /// @param[in] copyAdditionalRecord The record to create the new record from. copyAdditionalRecord won't be + /// changed in any way + /// @return A pointer to the newly created DNS additional record or nullptr if query could not be created (an + /// appropriate error log message will be printed in this case) DnsResource* addAdditionalRecord(DnsResource* const copyAdditionalRecord); - /** - * Remove an existing additional record by name. If several additional records matches the name, the first match - * will be removed - * @param[in] additionalRecordNameToRemove The name of the additional record to remove - * @param[in] exactMatch Indicate whether to match the whole name or just a part of it - * @return True if additional record was found and successfully removed or false if additional record was not - * found or couldn't be removed - */ + /// Remove an existing additional record by name. If several additional records matches the name, the first + /// match will be removed + /// @param[in] additionalRecordNameToRemove The name of the additional record to remove + /// @param[in] exactMatch Indicate whether to match the whole name or just a part of it + /// @return True if additional record was found and successfully removed or false if additional record was not + /// found or couldn't be removed bool removeAdditionalRecord(const std::string& additionalRecordNameToRemove, bool exactMatch); - /** - * Remove an existing additional record - * @param[in] additionalRecordToRemove A pointer to the additional record to remove - * @return True if additional record was found and successfully removed or false if additional record was not - * found or couldn't be removed - */ + /// Remove an existing additional record + /// @param[in] additionalRecordToRemove A pointer to the additional record to remove + /// @return True if additional record was found and successfully removed or false if additional record was not + /// found or couldn't be removed bool removeAdditionalRecord(DnsResource* additionalRecordToRemove); // implement abstract methods - /** - * Does nothing for this layer (DnsLayer is always last) - */ + /// Does nothing for this layer (DnsLayer is always last) void parseNextLayer() override {} - /** - * @return The size of the DNS data in the packet including he DNS header and size of all queries, answers, - * authorities and additional records - */ + /// @return The size of the DNS data in the packet including he DNS header and size of all queries, answers, + /// authorities and additional records size_t getHeaderLen() const override { return m_DataLen; } // No layer above DNS - /** - * Does nothing for this layer - */ + /// Does nothing for this layer void computeCalculateFields() override {} @@ -460,21 +371,17 @@ namespace pcpp return OsiModelApplicationLayer; } - /** - * A static method that checks whether the port is considered as DNS - * @param[in] port The port number to be checked - * @return True if the port is associated with the DNS protocol - */ + /// A static method that checks whether the port is considered as DNS + /// @param[in] port The port number to be checked + /// @return True if the port is associated with the DNS protocol static inline bool isDnsPort(uint16_t port); - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of a DNS packet - * @param[in] dataLen The length of the byte stream - * @param[in] dnsOverTcp Should be set to "true" if this is DNS is over TCP, otherwise set to "false" - * (which is also the default value) - * @return True if the data is valid and can represent a DNS packet - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of a DNS packet + /// @param[in] dataLen The length of the byte stream + /// @param[in] dnsOverTcp Should be set to "true" if this is DNS is over TCP, otherwise set to "false" + /// (which is also the default value) + /// @return True if the data is valid and can represent a DNS packet static inline bool isDataValid(const uint8_t* data, size_t dataLen, bool dnsOverTcp = false); protected: @@ -513,60 +420,46 @@ namespace pcpp bool removeResource(IDnsResource* resourceToRemove); }; - /** - * @class DnsOverTcpLayer - * Represents the DNS over TCP layer. - * DNS over TCP is described here: https://tools.ietf.org/html/rfc7766 . - * It is very similar to DNS over UDP, except for one field: TCP message length which is added in the beginning of - * the message before the other DNS data properties. The rest of the data is similar. - * - * Note: DNS over TCP can spread over more than one packet, but this implementation doesn't support this use-case - * and assumes the whole message fits in a single packet. - */ + /// @class DnsOverTcpLayer + /// Represents the DNS over TCP layer. + /// DNS over TCP is described here: https://tools.ietf.org/html/rfc7766 . + /// It is very similar to DNS over UDP, except for one field: TCP message length which is added in the beginning of + /// the message before the other DNS data properties. The rest of the data is similar. + + /// Note: DNS over TCP can spread over more than one packet, but this implementation doesn't support this use-case + /// and assumes the whole message fits in a single packet. class DnsOverTcpLayer : public DnsLayer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in DnsOverTcpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : DnsLayer(data, dataLen, prevLayer, packet, sizeof(uint16_t)) {} - /** - * A constructor that creates an empty DNS layer: all members of dnshdr are set to 0 and layer will contain no - * records - */ + /// A constructor that creates an empty DNS layer: all members of dnshdr are set to 0 and layer will contain no + /// records DnsOverTcpLayer() : DnsLayer(sizeof(uint16_t)) {} - /** - * A copy constructor for this layer - * @param[in] other The DNS over TCP layer to copy from - */ + /// A copy constructor for this layer + /// @param[in] other The DNS over TCP layer to copy from DnsOverTcpLayer(const DnsOverTcpLayer& other) : DnsLayer(other) {} - /** - * @return The value of the TCP message length as described in https://tools.ietf.org/html/rfc7766#section-8 - */ + /// @return The value of the TCP message length as described in https://tools.ietf.org/html/rfc7766#section-8 uint16_t getTcpMessageLength(); - /** - * Set the TCP message length value as described in https://tools.ietf.org/html/rfc7766#section-8 - * @param[in] value The value to set - */ + /// Set the TCP message length value as described in https://tools.ietf.org/html/rfc7766#section-8 + /// @param[in] value The value to set void setTcpMessageLength(uint16_t value); // overridden methods - /** - * Calculate the TCP message length field - */ + /// Calculate the TCP message length field void computeCalculateFields() override; }; diff --git a/Packet++/header/DnsLayerEnums.h b/Packet++/header/DnsLayerEnums.h index 9c986fb9cf..d9807993a6 100644 --- a/Packet++/header/DnsLayerEnums.h +++ b/Packet++/header/DnsLayerEnums.h @@ -2,152 +2,144 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * An enum for all possible DNS record types - */ + /// An enum for all possible DNS record types enum DnsType { - /** IPv4 address record */ + /// IPv4 address record DNS_TYPE_A = 1, - /** Name Server record */ + /// Name Server record DNS_TYPE_NS, - /** Obsolete, replaced by MX */ + /// Obsolete, replaced by MX DNS_TYPE_MD, - /** Obsolete, replaced by MX */ + /// Obsolete, replaced by MX DNS_TYPE_MF, - /** Canonical name record */ + /// Canonical name record DNS_TYPE_CNAME, - /** Start of Authority record */ + /// Start of Authority record DNS_TYPE_SOA, - /** mailbox domain name record */ + /// mailbox domain name record DNS_TYPE_MB, - /** mail group member record */ + /// mail group member record DNS_TYPE_MG, - /** mail rename domain name record */ + /// mail rename domain name record DNS_TYPE_MR, - /** Null record */ + /// Null record DNS_TYPE_NULL_R, - /** well known service description record */ + /// well known service description record DNS_TYPE_WKS, - /** Pointer record */ + /// Pointer record DNS_TYPE_PTR, - /** Host information record */ + /// Host information record DNS_TYPE_HINFO, - /** mailbox or mail list information record */ + /// mailbox or mail list information record DNS_TYPE_MINFO, - /** Mail exchanger record */ + /// Mail exchanger record DNS_TYPE_MX, - /** Text record */ + /// Text record DNS_TYPE_TXT, - /** Responsible person record */ + /// Responsible person record DNS_TYPE_RP, - /** AFS database record */ + /// AFS database record DNS_TYPE_AFSDB, - /** DNS X25 resource record */ + /// DNS X25 resource record DNS_TYPE_X25, - /** Integrated Services Digital Network record */ + /// Integrated Services Digital Network record DNS_TYPE_ISDN, - /** Route Through record */ + /// Route Through record DNS_TYPE_RT, - /** network service access point address record */ + /// network service access point address record DNS_TYPE_NSAP, - /** network service access point address pointer record */ + /// network service access point address pointer record DNS_TYPE_NSAP_PTR, - /** Signature record */ + /// Signature record DNS_TYPE_SIG, - /** Key record */ + /// Key record DNS_TYPE_KEY, - /** Mail Mapping Information record */ + /// Mail Mapping Information record DNS_TYPE_PX, - /** DNS Geographical Position record */ + /// DNS Geographical Position record DNS_TYPE_GPOS, - /** IPv6 address record */ + /// IPv6 address record DNS_TYPE_AAAA, - /** Location record */ + /// Location record DNS_TYPE_LOC, - /** Obsolete record */ + /// Obsolete record DNS_TYPE_NXT, - /** DNS Endpoint Identifier record */ + /// DNS Endpoint Identifier record DNS_TYPE_EID, - /** DNS Nimrod Locator record */ + /// DNS Nimrod Locator record DNS_TYPE_NIMLOC, - /** Service locator record */ + /// Service locator record DNS_TYPE_SRV, - /** Asynchronous Transfer Mode address record */ + /// Asynchronous Transfer Mode address record DNS_TYPE_ATMA, - /** Naming Authority Pointer record */ + /// Naming Authority Pointer record DNS_TYPE_NAPTR, - /** Key eXchanger record */ + /// Key eXchanger record DNS_TYPE_KX, - /** Certificate record */ + /// Certificate record DNS_TYPE_CERT, - /** Obsolete, replaced by AAAA type */ + /// Obsolete, replaced by AAAA type DNS_TYPE_A6, - /** Delegation Name record */ + /// Delegation Name record DNS_TYPE_DNAM, - /** Kitchen sink record */ + /// Kitchen sink record DNS_TYPE_SINK, - /** Option record */ + /// Option record DNS_TYPE_OPT, - /** Address Prefix List record */ + /// Address Prefix List record DNS_TYPE_APL, - /** Delegation signer record */ + /// Delegation signer record DNS_TYPE_DS, - /** SSH Public Key Fingerprint record */ + /// SSH Public Key Fingerprint record DNS_TYPE_SSHFP, - /** IPsec Key record */ + /// IPsec Key record DNS_TYPE_IPSECKEY, - /** DNSSEC signature record */ + /// DNSSEC signature record DNS_TYPE_RRSIG, - /** Next-Secure record */ + /// Next-Secure record DNS_TYPE_NSEC, - /** DNS Key record */ + /// DNS Key record DNS_TYPE_DNSKEY, - /** DHCP identifier record */ + /// DHCP identifier record DNS_TYPE_DHCID, - /** NSEC record version 3 */ + /// NSEC record version 3 DNS_TYPE_NSEC3, - /** NSEC3 parameters */ + /// NSEC3 parameters DNS_TYPE_NSEC3PARAM, - /** All cached records */ + /// All cached records DNS_TYPE_ALL = 255 }; - /** - * An enum for all possible DNS classes - */ + /// An enum for all possible DNS classes enum DnsClass { - /** Internet class */ + /// Internet class DNS_CLASS_IN = 1, - /** Internet class with QU flag set to True */ + /// Internet class with QU flag set to True DNS_CLASS_IN_QU = 32769, - /** Chaos class */ + /// Chaos class DNS_CLASS_CH = 3, - /** Hesiod class */ + /// Hesiod class DNS_CLASS_HS = 4, - /** ANY class */ + /// ANY class DNS_CLASS_ANY = 255 }; - /** - * An enum for representing the 4 types of possible DNS records - */ + /// An enum for representing the 4 types of possible DNS records enum DnsResourceType { - /** DNS query record */ + /// DNS query record DnsQueryType = 0, - /** DNS answer record */ + /// DNS answer record DnsAnswerType = 1, - /** DNS authority record */ + /// DNS authority record DnsAuthorityType = 2, - /** DNS additional record */ + /// DNS additional record DnsAdditionalType = 3 }; diff --git a/Packet++/header/DnsResource.h b/Packet++/header/DnsResource.h index b1b47cfd25..74d5796034 100644 --- a/Packet++/header/DnsResource.h +++ b/Packet++/header/DnsResource.h @@ -9,10 +9,8 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { // forward declarations @@ -20,12 +18,10 @@ namespace pcpp class IDnsResourceData; class DnsResourceDataPtr; - /** - * @class IDnsResource - * An abstract class for representing all types of DNS records. This class gives access to all available record data - * such as DNS type, class, name, type of record, etc. The DnsLayer holds an instance of (inherited type of) this - * class for each DNS record in the DNS packet - */ + /// @class IDnsResource + /// An abstract class for representing all types of DNS records. This class gives access to all available record + /// data such as DNS type, class, name, type of record, etc. The DnsLayer holds an instance of (inherited type of) + /// this class for each DNS record in the DNS packet class IDnsResource { protected: @@ -63,76 +59,56 @@ namespace pcpp public: virtual ~IDnsResource() = default; - /** - * @return The DNS type of this record - */ + /// @return The DNS type of this record DnsType getDnsType() const; - /** - * Set DNS type for this record - * @param[in] newType The type to set - */ + /// Set DNS type for this record + /// @param[in] newType The type to set void setDnsType(DnsType newType); - /** - * @return The DNS class of this record - */ + /// @return The DNS class of this record DnsClass getDnsClass() const; - /** - * Set DNS class for this record - * @param[in] newClass The class to set - */ + /// Set DNS class for this record + /// @param[in] newClass The class to set void setDnsClass(DnsClass newClass); - /** - * @return The name of this record - */ + /// @return The name of this record const std::string& getName() const { return m_DecodedName; } - /** - * @return The record name's offset in the packet - */ + /// @return The record name's offset in the packet size_t getNameOffset() const { return m_OffsetInLayer; } - /** - * Set the name of this record. The input name can be a standard hostname (e.g 'google.com'), or it may contain - * a pointer to another string in the packet (as explained here: http://www.zytrax.com/books/dns/ch15/#name). - * The pointer is used to reduce the DNS packet size and avoid unnecessary duplications. In case you - * want to use a pointer in your string you should use the following format: 'some.domain.#{offset}' where - * '#{offset}' is a the offset from the start of the layer. For example: if the string 'yahoo.com' already - * appears in offset 12 in the packet and you want to set the name of the current record to - * 'my.subdomain.yahoo.com' you may use the following string: 'my.subdomain.#12'. This will result in writing - * 'my.subdomain' and a pointer to offset 12.
Please notice the new name can be shorter or longer of the old - * name, so this method can cause the packet to be shorten or extended - * @param[in] newName The name to set - * @return True if name was set successfully or false if input string is malformed or if an error occurred - */ + /// Set the name of this record. The input name can be a standard hostname (e.g 'google.com'), or it may contain + /// a pointer to another string in the packet (as explained here: http://www.zytrax.com/books/dns/ch15/#name). + /// The pointer is used to reduce the DNS packet size and avoid unnecessary duplications. In case you + /// want to use a pointer in your string you should use the following format: 'some.domain.#{offset}' where + /// '#{offset}' is a the offset from the start of the layer. For example: if the string 'yahoo.com' already + /// appears in offset 12 in the packet and you want to set the name of the current record to + /// 'my.subdomain.yahoo.com' you may use the following string: 'my.subdomain.#12'. This will result in writing + /// 'my.subdomain' and a pointer to offset 12.
Please notice the new name can be shorter or longer of the + /// old name, so this method can cause the packet to be shorten or extended + /// @param[in] newName The name to set + /// @return True if name was set successfully or false if input string is malformed or if an error occurred bool setName(const std::string& newName); // abstract methods - /** - * @return The total size in bytes of this record - */ + /// @return The total size in bytes of this record virtual size_t getSize() const = 0; - /** - * @return The type of this record (query, answer, authority, additional) - */ + /// @return The type of this record (query, answer, authority, additional) virtual DnsResourceType getType() const = 0; }; - /** - * @class DnsQuery - * Representing a DNS query record - */ + /// @class DnsQuery + /// Representing a DNS query record class DnsQuery : public IDnsResource { friend class DnsLayer; @@ -158,10 +134,8 @@ namespace pcpp } }; - /** - * @class DnsResource - * Representing DNS record other than DNS query - */ + /// @class DnsResource + /// Representing DNS record other than DNS query class DnsResource : public IDnsResource { friend class DnsLayer; @@ -182,78 +156,62 @@ namespace pcpp public: ~DnsResource() override = default; - /** - * @return The time-to-leave value for this record - */ + /// @return The time-to-leave value for this record uint32_t getTTL() const; - /** - * Set time-to-leave value for this record - * @param[in] newTTL The new TTL value to set - */ + /// Set time-to-leave value for this record + /// @param[in] newTTL The new TTL value to set void setTTL(uint32_t newTTL); - /** - * @return The data length value for this record (taken from the "data length" field of the record) - */ + /// @return The data length value for this record (taken from the "data length" field of the record) size_t getDataLength() const; - /** - * @return A smart pointer to an IDnsResourceData object that contains the DNS resource data. It is guaranteed - * that the smart pointer will always point to an object and never to nullptr. The specific object type depends - * on the DNS type of this record:
- * - For type A (::DNS_TYPE_A): the return value is a smart pointer to IPv4DnsResourceData object that contains - * the IPv4 address
- * - For type AAAA (::DNS_TYPE_AAAA): the return value is a smart pointer to IPv6DnsResourceData object that - * contains the IPv6 address
- * - For types NS, CNAME, DNAME, PTR (::DNS_TYPE_NS, ::DNS_TYPE_CNAME, ::DNS_TYPE_DNAM, ::DNS_TYPE_PTR): the - * return value is a smart pointer to StringDnsResourceData object that contains the name
- * - For type MX (::DNS_TYPE_MX): the return value is a smart pointer to MxDnsResourceData object that contains - * the MX data (preference and mail exchange name)
- * - For all other types: the return value is a smart pointer to GenericDnsResourceData which contains a byte - * array of the data - */ + /// @return A smart pointer to an IDnsResourceData object that contains the DNS resource data. It is guaranteed + /// that the smart pointer will always point to an object and never to nullptr. The specific object type depends + /// on the DNS type of this record:
+ /// - For type A (::DNS_TYPE_A): the return value is a smart pointer to IPv4DnsResourceData object that contains + /// the IPv4 address
+ /// - For type AAAA (::DNS_TYPE_AAAA): the return value is a smart pointer to IPv6DnsResourceData object that + /// contains the IPv6 address
+ /// - For types NS, CNAME, DNAME, PTR (::DNS_TYPE_NS, ::DNS_TYPE_CNAME, ::DNS_TYPE_DNAM, ::DNS_TYPE_PTR): the + /// return value is a smart pointer to StringDnsResourceData object that contains the name
+ /// - For type MX (::DNS_TYPE_MX): the return value is a smart pointer to MxDnsResourceData object that contains + /// the MX data (preference and mail exchange name)
+ /// - For all other types: the return value is a smart pointer to GenericDnsResourceData which contains a byte + /// array of the data DnsResourceDataPtr getData() const; - /** - * @return The offset of data in the DNS layer - */ + /// @return The offset of data in the DNS layer size_t getDataOffset() const; - /** - * Set resource data. The given IDnsResourceData input object is validated against the DNS type of the resource. - * For example: if DNS type is A and data isn't of type IPv4DnsResourceData (which contains the IPv4 address) a - * log error will be printed and the method will return false. This method currently supports the following DNS - * types:
- * - ::DNS_TYPE_A (IPv4 address) - data is expected to be a pointer to IPv4DnsResourceData with a valid IPv4 - * address - * - ::DNS_TYPE_AAAA (IPv6 address) - data is expected to be a pointer to IPv6DnsResourceData with a valid IPv6 - * address - * - ::DNS_TYPE_NS, ::DNS_TYPE_CNAME, ::DNS_TYPE_DNAM, ::DNS_TYPE_PTR (name data) - data is expected to be a - * pointer to StringDnsResourceData object that contains a host name, e.g: 'www.google.com' - * - ::DNS_TYPE_MX (MX data) - data is expected to be a pointer to MxDnsResourceData object that contains the MX - * data - * - else: data is expected to be a pointer to GenericDnsResourceData object that contains a valid hex string - * (valid hex string means a string which has an even number of characters representing a valid hex data. e.g: - * '0d0a45569a9b') - * @param[in] data The pointer to the data object, as described above - * @return True if data was properly set or false if data is illegal or method couldn't extend or shorted the - * packet (appropriate error log is printed in all cases) - */ + /// Set resource data. The given IDnsResourceData input object is validated against the DNS type of the + /// resource. For example: if DNS type is A and data isn't of type IPv4DnsResourceData (which contains the IPv4 + /// address) a log error will be printed and the method will return false. This method currently supports the + /// following DNS types:
+ /// - ::DNS_TYPE_A (IPv4 address) - data is expected to be a pointer to IPv4DnsResourceData with a valid IPv4 + /// address + /// - ::DNS_TYPE_AAAA (IPv6 address) - data is expected to be a pointer to IPv6DnsResourceData with a valid IPv6 + /// address + /// - ::DNS_TYPE_NS, ::DNS_TYPE_CNAME, ::DNS_TYPE_DNAM, ::DNS_TYPE_PTR (name data) - data is expected to be a + /// pointer to StringDnsResourceData object that contains a host name, e.g: 'www.google.com' + /// - ::DNS_TYPE_MX (MX data) - data is expected to be a pointer to MxDnsResourceData object that contains the + /// MX data + /// - else: data is expected to be a pointer to GenericDnsResourceData object that contains a valid hex string + /// (valid hex string means a string which has an even number of characters representing a valid hex data. e.g: + /// '0d0a45569a9b') + /// @param[in] data The pointer to the data object, as described above + /// @return True if data was properly set or false if data is illegal or method couldn't extend or shorted the + /// packet (appropriate error log is printed in all cases) bool setData(IDnsResourceData* data); - /** - * Some records don't have a DNS class and the bytes used for storing the DNS class are used for other purpose. - * This method enables the user to receive these bytes - * @return The value stored in this place - */ + /// Some records don't have a DNS class and the bytes used for storing the DNS class are used for other purpose. + /// This method enables the user to receive these bytes + /// @return The value stored in this place uint16_t getCustomDnsClass() const; - /** - * Some records don't have a DNS class and the bytes used for storing the DNS class are used for other purpose. - * This method enables the user to set these bytes - * @param[in] customValue The value to set - */ + /// Some records don't have a DNS class and the bytes used for storing the DNS class are used for other purpose. + /// This method enables the user to set these bytes + /// @param[in] customValue The value to set void setCustomDnsClass(uint16_t customValue); // implementation of abstract methods diff --git a/Packet++/header/DnsResourceData.h b/Packet++/header/DnsResourceData.h index 082670bcc6..fc68c26bb7 100644 --- a/Packet++/header/DnsResourceData.h +++ b/Packet++/header/DnsResourceData.h @@ -8,22 +8,18 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { // forward declarations class IDnsResource; - /** - * @class IDnsResourceData - * A wrapper class for storing DNS RR (resource record) data. This is the base class which introduces several - * abstract methods for derived classes to implement for setting and retrieving the stored data. Each derived class - * will store different type of DNS RR data and implement these methods accordingly (for example: IPv4/IPv6 - * addresses, MX data, hostnames, raw byte data etc.) - */ + /// @class IDnsResourceData + /// A wrapper class for storing DNS RR (resource record) data. This is the base class which introduces several + /// abstract methods for derived classes to implement for setting and retrieving the stored data. Each derived class + /// will store different type of DNS RR data and implement these methods accordingly (for example: IPv4/IPv6 + /// addresses, MX data, hostnames, raw byte data etc.) class IDnsResourceData { protected: @@ -37,105 +33,83 @@ namespace pcpp IDnsResource* dnsResource) const; public: - /** - * A virtual d'tor, does nothing - */ + /// A virtual d'tor, does nothing virtual ~IDnsResourceData() = default; - /** - * A templated method which takes a class that derives from IDnsResourceData as the template argument and - * checks whether this instance is of this type - * @return True if this instance is of the requested type, false otherwise - */ + /// A templated method which takes a class that derives from IDnsResourceData as the template argument and + /// checks whether this instance is of this type + /// @return True if this instance is of the requested type, false otherwise template bool isTypeOf() const { return dynamic_cast(this) != nullptr; } - /** - * A templated method which take a class that derives from IDnsResourceData as the template argument and tries - * to cast the current instance as that type - * @return A pointer to the current instance casted as the requested type or nullptr if this instance isn't of - * this type - */ + /// A templated method which take a class that derives from IDnsResourceData as the template argument and tries + /// to cast the current instance as that type + /// @return A pointer to the current instance casted as the requested type or nullptr if this instance isn't of + /// this type template IDnsResourceDataType* castAs() { return dynamic_cast(this); } - /** - * @return A string that represents the current DNS RR data - */ + /// @return A string that represents the current DNS RR data virtual std::string toString() const = 0; - /** - * Convert the DNS RR data into a byte array - * @param[out] arr A pointer to a pre-allocated byte array where the result will be written to - * @param[out] arrLength A reference to a 2-byte number where the result array length will be written to - * @param[in] dnsResource A pointer to a DNS resource object where this DNS RR data will be stored - * @return True if the DNS RR data was successfully converted into a byte array and written to the given array - * or false if stored DNS RR data is invalid or if it could not be written to the given array - */ + /// Convert the DNS RR data into a byte array + /// @param[out] arr A pointer to a pre-allocated byte array where the result will be written to + /// @param[out] arrLength A reference to a 2-byte number where the result array length will be written to + /// @param[in] dnsResource A pointer to a DNS resource object where this DNS RR data will be stored + /// @return True if the DNS RR data was successfully converted into a byte array and written to the given array + /// or false if stored DNS RR data is invalid or if it could not be written to the given array virtual bool toByteArr(uint8_t* arr, size_t& arrLength, IDnsResource* dnsResource) const = 0; }; - /** - * @class DnsResourceDataPtr - * A smart pointer class that holds pointers of type IDnsResourceData. This object is used in DnsResource#getData() - */ + /// @class DnsResourceDataPtr + /// A smart pointer class that holds pointers of type IDnsResourceData. This object is used in DnsResource#getData() class DnsResourceDataPtr : public std::unique_ptr { public: - /** - * A c'tor to this class - * @param[in] ptr A pointer to IDnsResourceData - */ + /// A c'tor to this class + /// @param[in] ptr A pointer to IDnsResourceData explicit DnsResourceDataPtr(IDnsResourceData* ptr) : std::unique_ptr(ptr) {} - /** - * A templated method which takes a class that derives from IDnsResourceData as the template argument and - * checks whether the pointer stored in this object is of this type - * @return True if the stored pointer is of the requested type, false otherwise - */ + /// A templated method which takes a class that derives from IDnsResourceData as the template argument and + /// checks whether the pointer stored in this object is of this type + /// @return True if the stored pointer is of the requested type, false otherwise template bool isTypeOf() const { return get()->isTypeOf(); } - /** - * A templated method which take a class that derives from IDnsResourceData as the template argument and tries - * to cast the pointer stored in this object as that type - * @return A pointer to the stored pointer casted as the requested type or nullptr if it isn't of this type - */ + /// A templated method which take a class that derives from IDnsResourceData as the template argument and tries + /// to cast the pointer stored in this object as that type + /// @return A pointer to the stored pointer casted as the requested type or nullptr if it isn't of this type template IDnsResourceDataType* castAs() { return get()->castAs(); } }; - /** - * @class StringDnsResourceData - * A class that represents DNS RR string data, mainly used in DNS RRs that store hostnames (like CNAME, DNAME, NS, - * etc.) - */ + /// @class StringDnsResourceData + /// A class that represents DNS RR string data, mainly used in DNS RRs that store hostnames (like CNAME, DNAME, NS, + /// etc.) class StringDnsResourceData : public IDnsResourceData { private: std::string m_Data; public: - /** - * A c'tor for this class - * @param[in] data The string data to store in this object. If this string represents a hostname it's possible - * to include a pointer to another string in the DNS layer (as explained here: - * http://www.zytrax.com/books/dns/ch15/#name). These pointers are often used to reduce the DNS packet size and - * avoid unnecessary duplications. The way to include pointers in a hostname string is to use the following - * format: 'some.domain.#{offset}' where '#{offset}' is the offset from the start of the DNS layer. For example: - * if the string 'yahoo.com' already appears in offset 12 in the packet and you want to set the DNS RR data as - * 'my.subdomain.yahoo.com' you may use the following string: 'my.subdomain.#12'. This will result in writing - * 'my.subdomain' and a pointer to offset 12 - */ + /// A c'tor for this class + /// @param[in] data The string data to store in this object. If this string represents a hostname it's possible + /// to include a pointer to another string in the DNS layer (as explained here: + /// http://www.zytrax.com/books/dns/ch15/#name). These pointers are often used to reduce the DNS packet size and + /// avoid unnecessary duplications. The way to include pointers in a hostname string is to use the following + /// format: 'some.domain.#{offset}' where '#{offset}' is the offset from the start of the DNS layer. For + /// example: if the string 'yahoo.com' already appears in offset 12 in the packet and you want to set the DNS RR + /// data as 'my.subdomain.yahoo.com' you may use the following string: 'my.subdomain.#12'. This will result in + /// writing 'my.subdomain' and a pointer to offset 12 explicit StringDnsResourceData(const std::string& data) : m_Data(data) {} @@ -143,11 +117,9 @@ namespace pcpp ~StringDnsResourceData() override = default; - /** - * Equality operator overload for this class that compares the strings stored in each object - * @param[in] other The object to compare with - * @return True if the string data is the same in both objects, false otherwise - */ + /// Equality operator overload for this class that compares the strings stored in each object + /// @param[in] other The object to compare with + /// @return True if the string data is the same in both objects, false otherwise bool operator==(const StringDnsResourceData& other) const { return m_Data == other.m_Data; @@ -162,50 +134,38 @@ namespace pcpp bool toByteArr(uint8_t* arr, size_t& arrLength, IDnsResource* dnsResource) const override; }; - /** - * @class IPv4DnsResourceData - * A class that represents DNS RR IPv4 data, mainly used in DNS RRs of type ::DNS_TYPE_A - */ + /// @class IPv4DnsResourceData + /// A class that represents DNS RR IPv4 data, mainly used in DNS RRs of type ::DNS_TYPE_A class IPv4DnsResourceData : public IDnsResourceData { private: IPv4Address m_Data; public: - /** - * A c'tor for this class - * @param[in] dataPtr A byte array of size 4 that contains an IPv4 address (each byte represents 1 octet) - * @param[in] dataLen The byte array size, expected to be 4 - */ + /// A c'tor for this class + /// @param[in] dataPtr A byte array of size 4 that contains an IPv4 address (each byte represents 1 octet) + /// @param[in] dataLen The byte array size, expected to be 4 IPv4DnsResourceData(const uint8_t* dataPtr, size_t dataLen); - /** - * A c'tor for this class - * @param[in] addr The IPv4 address to store in this object - */ + /// A c'tor for this class + /// @param[in] addr The IPv4 address to store in this object explicit IPv4DnsResourceData(const IPv4Address& addr) : m_Data(addr) {} - /** - * A c'tor for this class - * @param[in] addrAsString A string representation of an IPv4 address to store in this object - */ + /// A c'tor for this class + /// @param[in] addrAsString A string representation of an IPv4 address to store in this object explicit IPv4DnsResourceData(const std::string& addrAsString) : m_Data(addrAsString) {} - /** - * Equality operator overload for this class that compares the IPv4 addresses stored in each object - * @param[in] other The object to compare with - * @return True if IPv4 addresses are the same in both objects, false otherwise - */ + /// Equality operator overload for this class that compares the IPv4 addresses stored in each object + /// @param[in] other The object to compare with + /// @return True if IPv4 addresses are the same in both objects, false otherwise bool operator==(const IPv4DnsResourceData& other) const { return m_Data == other.m_Data; } - /** - * @return The IPv4 address stored in this object - */ + /// @return The IPv4 address stored in this object IPv4Address getIpAddress() const { return m_Data; @@ -220,50 +180,38 @@ namespace pcpp bool toByteArr(uint8_t* arr, size_t& arrLength, IDnsResource* dnsResource) const override; }; - /** - * @class IPv6DnsResourceData - * A class that represents DNS RR IPv6 data, mainly used in DNS RRs of type ::DNS_TYPE_AAAA - */ + /// @class IPv6DnsResourceData + /// A class that represents DNS RR IPv6 data, mainly used in DNS RRs of type ::DNS_TYPE_AAAA class IPv6DnsResourceData : public IDnsResourceData { private: IPv6Address m_Data; public: - /** - * A c'tor for this class - * @param[in] dataPtr A byte array of size 16 that contains an IPv6 address (each byte represents 1 octet) - * @param[in] dataLen The byte array size, expected to be 16 - */ + /// A c'tor for this class + /// @param[in] dataPtr A byte array of size 16 that contains an IPv6 address (each byte represents 1 octet) + /// @param[in] dataLen The byte array size, expected to be 16 IPv6DnsResourceData(const uint8_t* dataPtr, size_t dataLen); - /** - * A c'tor for this class - * @param[in] addr The IPv6 address to store in this object - */ + /// A c'tor for this class + /// @param[in] addr The IPv6 address to store in this object explicit IPv6DnsResourceData(const IPv6Address& addr) : m_Data(addr) {} - /** - * A c'tor for this class - * @param[in] addrAsString A string representation of an IPv6 address to store in this object - */ + /// A c'tor for this class + /// @param[in] addrAsString A string representation of an IPv6 address to store in this object explicit IPv6DnsResourceData(const std::string& addrAsString) : m_Data(addrAsString) {} - /** - * Equality operator overload for this class that compares the IPv6 addresses stored in each object - * @param[in] other The object to compare with - * @return True if IPv6 addresses are the same in both objects, false otherwise - */ + /// Equality operator overload for this class that compares the IPv6 addresses stored in each object + /// @param[in] other The object to compare with + /// @return True if IPv6 addresses are the same in both objects, false otherwise bool operator==(const IPv6DnsResourceData& other) const { return m_Data == other.m_Data; } - /** - * @return The IPv6 address stored in this object - */ + /// @return The IPv6 address stored in this object IPv6Address getIpAddress() const { return m_Data; @@ -278,76 +226,60 @@ namespace pcpp bool toByteArr(uint8_t* arr, size_t& arrLength, IDnsResource* dnsResource) const override; }; - /** - * @class MxDnsResourceData - * A class that represents DNS RR mail exchange (MX) data, used in DNS RRs of type ::DNS_TYPE_MX - */ + /// @class MxDnsResourceData + /// A class that represents DNS RR mail exchange (MX) data, used in DNS RRs of type ::DNS_TYPE_MX class MxDnsResourceData : public IDnsResourceData { public: - /** - * A struct that represents mail exchange (MX) data - */ + /// A struct that represents mail exchange (MX) data struct MxData { - /** Preference value */ + /// Preference value uint16_t preference; - /** Mail exchange hostname */ + /// Mail exchange hostname std::string mailExchange; }; - /** - * A c'tor for this class - * @param[in] dataPtr A byte array that contains the raw MX data (as written in the DNS packet) - * @param[in] dataLen The byte array size - * @param[in] dnsResource A pointer to a DNS resource object where this DNS RR data will be stored - */ + /// A c'tor for this class + /// @param[in] dataPtr A byte array that contains the raw MX data (as written in the DNS packet) + /// @param[in] dataLen The byte array size + /// @param[in] dnsResource A pointer to a DNS resource object where this DNS RR data will be stored MxDnsResourceData(uint8_t* dataPtr, size_t dataLen, IDnsResource* dnsResource); - /** - * A c'tor for this class - * @param[in] preference The MX preference value to store in this object - * @param[in] mailExchange The MX hostname value to store in this object. It's possible to include a pointer to - * another string in the DNS layer (as explained here: http://www.zytrax.com/books/dns/ch15/#name). These - * pointers are often used to reduce the DNS packet size and avoid unnecessary duplications. The way to include - * pointers in the hostname string is to use the following format: 'some.domain.#{offset}' where '#{offset}' is - * the offset from the start of the DNS layer. For example: if the string 'yahoo.com' already appears in offset - * 12 in the packet and you want to set the DNS RR data as 'my.subdomain.yahoo.com' you may use the following - * string: 'my.subdomain.#12'. This will result in writing 'my.subdomain' and a pointer to offset 12 - */ + /// A c'tor for this class + /// @param[in] preference The MX preference value to store in this object + /// @param[in] mailExchange The MX hostname value to store in this object. It's possible to include a pointer to + /// another string in the DNS layer (as explained here: http://www.zytrax.com/books/dns/ch15/#name). These + /// pointers are often used to reduce the DNS packet size and avoid unnecessary duplications. The way to include + /// pointers in the hostname string is to use the following format: 'some.domain.#{offset}' where '#{offset}' is + /// the offset from the start of the DNS layer. For example: if the string 'yahoo.com' already appears in offset + /// 12 in the packet and you want to set the DNS RR data as 'my.subdomain.yahoo.com' you may use the following + /// string: 'my.subdomain.#12'. This will result in writing 'my.subdomain' and a pointer to offset 12 MxDnsResourceData(const uint16_t& preference, const std::string& mailExchange); ~MxDnsResourceData() override = default; - /** - * Equality operator overload for this class that compares the MX data stored in each object - * @param[in] other The object to compare with - * @return True if MX data is the same in both objects, meaning both preference and MX hostname are the same, - * false otherwise - */ + /// Equality operator overload for this class that compares the MX data stored in each object + /// @param[in] other The object to compare with + /// @return True if MX data is the same in both objects, meaning both preference and MX hostname are the same, + /// false otherwise bool operator==(const MxDnsResourceData& other) const; - /** - * @return The MX data stored in this object - */ + /// @return The MX data stored in this object MxData getMxData() const { return m_Data; } - /** - * Set the MX data stored in this object - * @param[in] preference The MX preference value to store in this object - * @param[in] mailExchange The MX hostname value to store in this object - */ + /// Set the MX data stored in this object + /// @param[in] preference The MX preference value to store in this object + /// @param[in] mailExchange The MX hostname value to store in this object void setMxData(uint16_t preference, std::string mailExchange); // implement abstract methods - /** - * A string representation of the MX data stored in this object. The string format is as follows: - * 'pref: {preference_value}; mx: {mail_exchange_hostname_value}' - */ + /// A string representation of the MX data stored in this object. The string format is as follows: + /// 'pref: {preference_value}; mx: {mail_exchange_hostname_value}' std::string toString() const override; bool toByteArr(uint8_t* arr, size_t& arrLength, IDnsResource* dnsResource) const override; @@ -356,11 +288,9 @@ namespace pcpp MxData m_Data; }; - /** - * @class GenericDnsResourceData - * A class that represents generic DNS RR data which cannot be represented in any of the other classes. It stores - * the DNS RR data as byte array - */ + /// @class GenericDnsResourceData + /// A class that represents generic DNS RR data which cannot be represented in any of the other classes. It stores + /// the DNS RR data as byte array class GenericDnsResourceData : public IDnsResourceData { private: @@ -368,24 +298,18 @@ namespace pcpp size_t m_DataLen; public: - /** - * A c'tor for this class - * @param[in] dataPtr A byte array that contains the raw data (as it written in the DNS packet). The data will - * be copied from this byte array to the object - * @param[in] dataLen The byte array size - */ + /// A c'tor for this class + /// @param[in] dataPtr A byte array that contains the raw data (as it written in the DNS packet). The data will + /// be copied from this byte array to the object + /// @param[in] dataLen The byte array size GenericDnsResourceData(const uint8_t* dataPtr, size_t dataLen); - /** - * A c'tor for this class - * @param[in] dataAsHexString A hex string that represents the DNS RR data - */ + /// A c'tor for this class + /// @param[in] dataAsHexString A hex string that represents the DNS RR data explicit GenericDnsResourceData(const std::string& dataAsHexString); - /** - * A copy c'tor for this class - * @param[in] other The instance to copy from - */ + /// A copy c'tor for this class + /// @param[in] other The instance to copy from GenericDnsResourceData(const GenericDnsResourceData& other); ~GenericDnsResourceData() override @@ -396,11 +320,9 @@ namespace pcpp GenericDnsResourceData& operator=(const GenericDnsResourceData& other); - /** - * Equality operator overload for this class that compares the raw data stored in each object - * @param[in] other The object to compare with - * @return True if data is the same in both objects, meaning byte streams are equal, false otherwise - */ + /// Equality operator overload for this class that compares the raw data stored in each object + /// @param[in] other The object to compare with + /// @return True if data is the same in both objects, meaning byte streams are equal, false otherwise bool operator==(const GenericDnsResourceData& other) const; // implement abstract methods diff --git a/Packet++/header/EthDot3Layer.h b/Packet++/header/EthDot3Layer.h index 0a95144bf4..c725cd86f4 100644 --- a/Packet++/header/EthDot3Layer.h +++ b/Packet++/header/EthDot3Layer.h @@ -5,109 +5,87 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @struct ether_dot3_header - * Represents an IEEE 802.3 Ethernet header - */ + /// @struct ether_dot3_header + /// Represents an IEEE 802.3 Ethernet header #pragma pack(push, 1) struct ether_dot3_header { - /** Destination MAC */ + /// Destination MAC uint8_t dstMac[6]; - /** Source MAC */ + /// Source MAC uint8_t srcMac[6]; - /** EtherType */ + /// EtherType uint16_t length; }; #pragma pack(pop) static_assert(sizeof(ether_dot3_header) == 14, "ether_dot3_header size is not 14 bytes"); - /** - * @class EthDot3Layer - * Represents an IEEE 802.3 Ethernet protocol layer - */ + /// @class EthDot3Layer + /// Represents an IEEE 802.3 Ethernet protocol layer class EthDot3Layer : public Layer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to ether_dot3_header) - * @param[in] dataLen Size of the data in bytes - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to ether_dot3_header) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] packet A pointer to the Packet instance where layer will be stored in EthDot3Layer(uint8_t* data, size_t dataLen, Packet* packet) : Layer(data, dataLen, nullptr, packet, EthernetDot3) {} - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to ether_header) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to ether_header) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in EthDot3Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, EthernetDot3) {} - /** - * A constructor that creates a new IEEE 802.3 Ethernet header and allocates the data - * @param[in] sourceMac The source MAC address - * @param[in] destMac The destination MAC address - * @param[in] length The frame length - */ + /// A constructor that creates a new IEEE 802.3 Ethernet header and allocates the data + /// @param[in] sourceMac The source MAC address + /// @param[in] destMac The destination MAC address + /// @param[in] length The frame length EthDot3Layer(const MacAddress& sourceMac, const MacAddress& destMac, uint16_t length); ~EthDot3Layer() override = default; - /** - * Get a pointer to the Ethernet header. Notice this points directly to the data, so every change will change - * the actual packet data - * @return A pointer to the ether_header - */ + /// Get a pointer to the Ethernet header. Notice this points directly to the data, so every change will change + /// the actual packet data + /// @return A pointer to the ether_header ether_dot3_header* getEthHeader() const { return reinterpret_cast(m_Data); } - /** - * Get the source MAC address - * @return The source MAC address - */ + /// Get the source MAC address + /// @return The source MAC address MacAddress getSourceMac() const { return MacAddress(getEthHeader()->srcMac); } - /** - * Set source MAC address - * @param sourceMac Source MAC to set - */ + /// Set source MAC address + /// @param sourceMac Source MAC to set void setSourceMac(const MacAddress& sourceMac) { sourceMac.copyTo(getEthHeader()->srcMac); } - /** - * Get the destination MAC address - * @return The destination MAC address - */ + /// Get the destination MAC address + /// @return The destination MAC address MacAddress getDestMac() const { return MacAddress(getEthHeader()->dstMac); } - /** - * Set destination MAC address - * @param destMac Destination MAC to set - */ + /// Set destination MAC address + /// @param destMac Destination MAC to set void setDestMac(const MacAddress& destMac) { destMac.copyTo(getEthHeader()->dstMac); @@ -115,22 +93,16 @@ namespace pcpp // implement abstract methods - /** - * Parses next layer - */ + /// Parses next layer void parseNextLayer() override; - /** - * @return Size of ether_dot3_header - */ + /// @return Size of ether_dot3_header size_t getHeaderLen() const override { return sizeof(ether_dot3_header); } - /** - * Does nothing for this layer - */ + /// Does nothing for this layer void computeCalculateFields() override {} @@ -141,12 +113,10 @@ namespace pcpp return OsiModelDataLinkLayer; } - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of an IEEE 802.3 Eth packet - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent an IEEE 802.3 Eth packet - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of an IEEE 802.3 Eth packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent an IEEE 802.3 Eth packet static bool isDataValid(const uint8_t* data, size_t dataLen); }; diff --git a/Packet++/header/EthLayer.h b/Packet++/header/EthLayer.h index 2854c611eb..750dbfe691 100644 --- a/Packet++/header/EthLayer.h +++ b/Packet++/header/EthLayer.h @@ -5,146 +5,124 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @struct ether_header - * Represents an Ethernet II header - */ + /// @struct ether_header + /// Represents an Ethernet II header #pragma pack(push, 1) struct ether_header { - /** Destination MAC */ + /// Destination MAC uint8_t dstMac[6]; - /** Source MAC */ + /// Source MAC uint8_t srcMac[6]; - /** EtherType */ + /// EtherType uint16_t etherType; }; #pragma pack(pop) static_assert(sizeof(ether_header) == 14, "ether_header size is not 14 bytes"); - /* Ethernet protocol ID's */ + // Ethernet protocol ID's - /** IP */ + /// IP #define PCPP_ETHERTYPE_IP 0x0800 - /** Address resolution */ + /// Address resolution #define PCPP_ETHERTYPE_ARP 0x0806 - /** Transparent Ethernet Bridging */ + /// Transparent Ethernet Bridging #define PCPP_ETHERTYPE_ETHBRIDGE 0x6558 - /** Reverse ARP */ + /// Reverse ARP #define PCPP_ETHERTYPE_REVARP 0x8035 - /** AppleTalk protocol */ + /// AppleTalk protocol #define PCPP_ETHERTYPE_AT 0x809B - /** AppleTalk ARP */ + /// AppleTalk ARP #define PCPP_ETHERTYPE_AARP 0x80F3 - /** IEEE 802.1Q VLAN tagging */ + /// IEEE 802.1Q VLAN tagging #define PCPP_ETHERTYPE_VLAN 0x8100 - /** IPX */ + /// IPX #define PCPP_ETHERTYPE_IPX 0x8137 - /** IP protocol version 6 */ + /// IP protocol version 6 #define PCPP_ETHERTYPE_IPV6 0x86dd - /** used to test interfaces */ + /// used to test interfaces #define PCPP_ETHERTYPE_LOOPBACK 0x9000 - /** PPPoE discovery */ + /// PPPoE discovery #define PCPP_ETHERTYPE_PPPOED 0x8863 - /** PPPoE session */ + /// PPPoE session #define PCPP_ETHERTYPE_PPPOES 0x8864 - /** MPLS */ + /// MPLS #define PCPP_ETHERTYPE_MPLS 0x8847 - /** Point-to-point protocol (PPP) */ + /// Point-to-point protocol (PPP) #define PCPP_ETHERTYPE_PPP 0x880B - /** RDMA over Converged Ethernet (RoCEv1) */ + /// RDMA over Converged Ethernet (RoCEv1) #define PCPP_ETHERTYPE_ROCEV1 0x8915 - /** IEEE 802.1ad Provider Bridge, Q-in-Q */ + /// IEEE 802.1ad Provider Bridge, Q-in-Q #define PCPP_ETHERTYPE_IEEE_802_1AD 0x88A8 - /** Wake on LAN */ + /// Wake on LAN #define PCPP_ETHERTYPE_WAKE_ON_LAN 0x0842 - /** - * @class EthLayer - * Represents an Ethernet II protocol layer - */ + /// @class EthLayer + /// Represents an Ethernet II protocol layer class EthLayer : public Layer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to ether_header) - * @param[in] dataLen Size of the data in bytes - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to ether_header) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] packet A pointer to the Packet instance where layer will be stored in EthLayer(uint8_t* data, size_t dataLen, Packet* packet) : Layer(data, dataLen, nullptr, packet, Ethernet) {} - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to ether_header) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to ether_header) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in EthLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, Ethernet) {} - /** - * A constructor that creates a new Ethernet header and allocates the data - * @param[in] sourceMac The source MAC address - * @param[in] destMac The destination MAC address - * @param[in] etherType The EtherType to be used. It's an optional parameter, a value of 0 will be set if not - * provided - */ + /// A constructor that creates a new Ethernet header and allocates the data + /// @param[in] sourceMac The source MAC address + /// @param[in] destMac The destination MAC address + /// @param[in] etherType The EtherType to be used. It's an optional parameter, a value of 0 will be set if not + /// provided EthLayer(const MacAddress& sourceMac, const MacAddress& destMac, uint16_t etherType = 0); ~EthLayer() override = default; - /** - * Get a pointer to the Ethernet header. Notice this points directly to the data, so every change will change - * the actual packet data - * @return A pointer to the ether_header - */ + /// Get a pointer to the Ethernet header. Notice this points directly to the data, so every change will change + /// the actual packet data + /// @return A pointer to the ether_header inline ether_header* getEthHeader() const { return reinterpret_cast(m_Data); } - /** - * Get the source MAC address - * @return The source MAC address - */ + /// Get the source MAC address + /// @return The source MAC address inline MacAddress getSourceMac() const { return MacAddress(getEthHeader()->srcMac); } - /** - * Set source MAC address - * @param sourceMac Source MAC to set - */ + /// Set source MAC address + /// @param sourceMac Source MAC to set inline void setSourceMac(const MacAddress& sourceMac) { sourceMac.copyTo(getEthHeader()->srcMac); } - /** - * Get the destination MAC address - * @return The destination MAC address - */ + /// Get the destination MAC address + /// @return The destination MAC address inline MacAddress getDestMac() const { return MacAddress(getEthHeader()->dstMac); } - /** - * Set destination MAC address - * @param destMac Destination MAC to set - */ + /// Set destination MAC address + /// @param destMac Destination MAC to set inline void setDestMac(const MacAddress& destMac) { destMac.copyTo(getEthHeader()->dstMac); @@ -152,23 +130,17 @@ namespace pcpp // implement abstract methods - /** - * Currently identifies the following next layers: IPv4Layer, IPv6Layer, ArpLayer, VlanLayer, PPPoESessionLayer, - * PPPoEDiscoveryLayer, MplsLayer. Otherwise sets PayloadLayer - */ + /// Currently identifies the following next layers: IPv4Layer, IPv6Layer, ArpLayer, VlanLayer, + /// PPPoESessionLayer, PPPoEDiscoveryLayer, MplsLayer. Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * @return Size of ether_header - */ + /// @return Size of ether_header size_t getHeaderLen() const override { return sizeof(ether_header); } - /** - * Calculate ether_header#etherType for known protocols: IPv4, IPv6, ARP, VLAN - */ + /// Calculate ether_header#etherType for known protocols: IPv4, IPv6, ARP, VLAN void computeCalculateFields() override; std::string toString() const override; @@ -178,12 +150,10 @@ namespace pcpp return OsiModelDataLinkLayer; } - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of an Ethernet II packet - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent an Ethernet II packet - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of an Ethernet II packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent an Ethernet II packet static bool isDataValid(const uint8_t* data, size_t dataLen); }; diff --git a/Packet++/header/FtpLayer.h b/Packet++/header/FtpLayer.h index 0b429ffcd5..63cd6565b4 100644 --- a/Packet++/header/FtpLayer.h +++ b/Packet++/header/FtpLayer.h @@ -5,16 +5,11 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * Class for general FTP message - */ + /// Class for general FTP message class FtpLayer : public SingleCommandTextProtocol { protected: @@ -24,19 +19,15 @@ namespace pcpp : SingleCommandTextProtocol(command, option, FTP) {}; public: - /** - * A static method that checks whether the port is considered as FTP control - * @param[in] port The port number to be checked - */ + /// A static method that checks whether the port is considered as FTP control + /// @param[in] port The port number to be checked static bool isFtpPort(uint16_t port) { return port == 21; } - /** - * A static method that checks whether the port is considered as FTP data - * @param[in] port The port number to be checked - */ + /// A static method that checks whether the port is considered as FTP data + /// @param[in] port The port number to be checked static bool isFtpDataPort(uint16_t port) { return port == 20; @@ -48,9 +39,7 @@ namespace pcpp void parseNextLayer() override {} - /** - * @return Get the size of the layer - */ + /// @return Get the size of the layer size_t getHeaderLen() const override { return m_DataLen; @@ -60,24 +49,18 @@ namespace pcpp void computeCalculateFields() override {} - /** - * @return The OSI layer level of FTP (Application Layer). - */ + /// @return The OSI layer level of FTP (Application Layer). OsiModelLayer getOsiModelLayer() const override { return OsiModelApplicationLayer; } }; - /** - * Class for representing the request messages of FTP Layer - */ + /// Class for representing the request messages of FTP Layer class FtpRequestLayer : public FtpLayer { public: - /** - * Enum for FTP command codes - */ + /// Enum for FTP command codes enum class FtpCommand : int { /// Unknown command @@ -228,87 +211,64 @@ namespace pcpp XSEN = ('X') | ('S' << 8) | ('E' << 16) | ('N' << 24) }; - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in FtpRequestLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : FtpLayer(data, dataLen, prevLayer, packet) {}; - /** - * A constructor that creates layer with provided input values - * @param[in] command FTP command - * @param[in] option Argument of the command - */ + /// A constructor that creates layer with provided input values + /// @param[in] command FTP command + /// @param[in] option Argument of the command explicit FtpRequestLayer(const FtpCommand& command, const std::string& option = "") : FtpLayer(getCommandAsString(command), option) {}; - /** - * Set the command of request message - * @param[in] code Value to set command - * @return True if the operation is successful, false otherwise - */ + /// Set the command of request message + /// @param[in] code Value to set command + /// @return True if the operation is successful, false otherwise bool setCommand(FtpCommand code); - /** - * Get the command of request message - * @return FtpCommand Value of the command - */ + /// Get the command of request message + /// @return FtpCommand Value of the command FtpCommand getCommand() const; - /** - * Get the command of request message as string - * @return std::string Value of the command as string - */ + /// Get the command of request message as string + /// @return std::string Value of the command as string std::string getCommandString() const; - /** - * Set the command argument of request message - * @param[in] value Value to set command argument - * @return True if the operation is successful, false otherwise - */ + /// Set the command argument of request message + /// @param[in] value Value to set command argument + /// @return True if the operation is successful, false otherwise bool setCommandOption(const std::string& value); - /** - * Get the command argument of request message - * @param[in] removeEscapeCharacters Whether non-alphanumerical characters should be removed or not - * @return std::string Value of command argument - */ + /// Get the command argument of request message + /// @param[in] removeEscapeCharacters Whether non-alphanumerical characters should be removed or not + /// @return std::string Value of command argument std::string getCommandOption(bool removeEscapeCharacters = true) const; - /** - * Convert the command info to readable string - * @param[in] code Command code to convert - * @return std::string Returns the command info as readable string - */ + /// Convert the command info to readable string + /// @param[in] code Command code to convert + /// @return std::string Returns the command info as readable string static std::string getCommandInfo(FtpCommand code); - /** - * Convert the command to readable string - * @param[in] code Command code to convert - * @return std::string Returns the command as readable string - */ + /// Convert the command to readable string + /// @param[in] code Command code to convert + /// @return std::string Returns the command as readable string static std::string getCommandAsString(FtpCommand code); // overridden methods - /** - * @return Returns the protocol info as readable string - */ + /// @return Returns the protocol info as readable string std::string toString() const override; }; - /** - * Class for representing the response messages of FTP Layer - */ + /// Class for representing the response messages of FTP Layer class FtpResponseLayer : public FtpLayer { public: - /** - * Enum for FTP response codes - */ + /// Enum for FTP response codes enum class FtpStatusCode : int { /// Unknown status code @@ -427,92 +387,70 @@ namespace pcpp CONFIDENTIALITY_PROTECTED = 633 }; - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in FtpResponseLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : FtpLayer(data, dataLen, prevLayer, packet) {}; - /** - * A constructor that creates layer with provided input values - * @param[in] code Status code - * @param[in] option Argument of the status code - */ + /// A constructor that creates layer with provided input values + /// @param[in] code Status code + /// @param[in] option Argument of the status code explicit FtpResponseLayer(const FtpStatusCode& code, const std::string& option = "") : FtpLayer(std::to_string(int(code)), option) {}; - /** - * Set the status code of response message - * @param[in] code Value to set status code - * @return True if the operation is successful, false otherwise - */ + /// Set the status code of response message + /// @param[in] code Value to set status code + /// @return True if the operation is successful, false otherwise bool setStatusCode(FtpStatusCode code); - /** - * Get the status code of response message - * @return FtpStatusCode Value of the status code - */ + /// Get the status code of response message + /// @return FtpStatusCode Value of the status code FtpStatusCode getStatusCode() const; - /** - * Get the status code of response message as string - * @return std::string Value of the status code as string - */ + /// Get the status code of response message as string + /// @return std::string Value of the status code as string std::string getStatusCodeString() const; - /** - * Set the argument of response message - * @param[in] value Value to set argument - * @return True if the operation is successful, false otherwise - */ + /// Set the argument of response message + /// @param[in] value Value to set argument + /// @return True if the operation is successful, false otherwise bool setStatusOption(const std::string& value); - /** - * Get the argument of response message - * @param[in] removeEscapeCharacters Whether non-alphanumerical characters should be removed or not - * @return std::string Value of argument - */ + /// Get the argument of response message + /// @param[in] removeEscapeCharacters Whether non-alphanumerical characters should be removed or not + /// @return std::string Value of argument std::string getStatusOption(bool removeEscapeCharacters = true) const; - /** - * Convert the status code to readable string - * @param[in] code Status code to convert - * @return std::string Returns the status info as readable string - */ + /// Convert the status code to readable string + /// @param[in] code Status code to convert + /// @return std::string Returns the status info as readable string static std::string getStatusCodeAsString(FtpStatusCode code); // overridden methods - /** - * @return Returns the protocol info as readable string - */ + /// @return Returns the protocol info as readable string std::string toString() const override; }; - /** - * Class for representing the data of FTP Layer - */ + /// Class for representing the data of FTP Layer class FtpDataLayer : public PayloadLayer { public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in FtpDataLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : PayloadLayer(data, dataLen, prevLayer, packet) { m_Protocol = FTP; }; - /** - * @return Returns the protocol info as readable string - */ + /// @return Returns the protocol info as readable string std::string toString() const override; }; } // namespace pcpp diff --git a/Packet++/header/GreLayer.h b/Packet++/header/GreLayer.h index 487cfd845d..b08f11ba49 100644 --- a/Packet++/header/GreLayer.h +++ b/Packet++/header/GreLayer.h @@ -4,156 +4,133 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct gre_basic_header - * Represents GRE basic protocol header (common for GREv0 and GREv1) - */ + /// @struct gre_basic_header + /// Represents GRE basic protocol header (common for GREv0 and GREv1) #pragma pack(push, 1) struct gre_basic_header { #if (BYTE_ORDER == LITTLE_ENDIAN) - /** Number of additional encapsulations which are permitted. 0 is the default value */ + /// Number of additional encapsulations which are permitted. 0 is the default value uint8_t recursionControl : 3, - /** Strict source routing bit (GRE v0 only) */ + /// Strict source routing bit (GRE v0 only) strictSourceRouteBit : 1, - /** Set if sequence number exists */ + /// Set if sequence number exists sequenceNumBit : 1, - /** Set if key exists */ + /// Set if key exists keyBit : 1, - /** Set if routing exists (GRE v0 only) */ + /// Set if routing exists (GRE v0 only) routingBit : 1, - /** Set if checksum exists (GRE v0 only) */ + /// Set if checksum exists (GRE v0 only) checksumBit : 1; #else - /** Set if checksum exists (GRE v0 only) */ + /// Set if checksum exists (GRE v0 only) uint8_t checksumBit : 1, - /** Set if routing exists (GRE v0 only) */ + /// Set if routing exists (GRE v0 only) routingBit : 1, - /** Set if key exists */ + /// Set if key exists keyBit : 1, - /** Set if sequence number exists */ + /// Set if sequence number exists sequenceNumBit : 1, - /** Strict source routing bit (GRE v0 only) */ + /// Strict source routing bit (GRE v0 only) strictSourceRouteBit : 1, - /** Number of additional encapsulations which are permitted. 0 is the default value */ + /// Number of additional encapsulations which are permitted. 0 is the default value recursionControl : 3; #endif #if (BYTE_ORDER == LITTLE_ENDIAN) - /** GRE version - can be 0 or 1 */ + /// GRE version - can be 0 or 1 uint8_t version : 3, - /** Reserved */ + /// Reserved flags : 4, - /** Set if acknowledgment number is set (GRE v1 only) */ + /// Set if acknowledgment number is set (GRE v1 only) ackSequenceNumBit : 1; #else - /** Set if acknowledgment number is set (GRE v1 only) */ + /// Set if acknowledgment number is set (GRE v1 only) uint8_t ackSequenceNumBit : 1, - /** Reserved */ + /// Reserved flags : 4, - /** GRE version - can be 0 or 1 */ + /// GRE version - can be 0 or 1 version : 3; #endif - /** Protocol type of the next layer */ + /// Protocol type of the next layer uint16_t protocol; }; #pragma pack(pop) static_assert(sizeof(gre_basic_header) == 4, "gre_basic_header size is not 4 bytes"); - /** - * @struct gre1_header - * Represents GREv1 protocol header - */ + /// @struct gre1_header + /// Represents GREv1 protocol header #pragma pack(push, 1) struct gre1_header : gre_basic_header { - /** Size of the payload not including the GRE header */ + /// Size of the payload not including the GRE header uint16_t payloadLength; - /** Contains the Peer's Call ID for the session to which this packet belongs */ + /// Contains the Peer's Call ID for the session to which this packet belongs uint16_t callID; }; #pragma pack(pop) static_assert(sizeof(gre1_header) == 8, "gre1_header size is not 8 bytes"); - /** - * @struct ppp_pptp_header - * Represents PPP layer that comes after GREv1 as part of PPTP protocol - */ + /// @struct ppp_pptp_header + /// Represents PPP layer that comes after GREv1 as part of PPTP protocol #pragma pack(push, 1) struct ppp_pptp_header { - /** Broadcast address */ + /// Broadcast address uint8_t address; - /** Control byte */ + /// Control byte uint8_t control; - /** Protocol type of the next layer (see PPP_* macros at PPPoELayer.h) */ + /// Protocol type of the next layer (see PPP_* macros at PPPoELayer.h) uint16_t protocol; }; #pragma pack(pop) static_assert(sizeof(ppp_pptp_header) == 4, "ppp_pptp_header size is not 4 bytes"); - /** - * @class GreLayer - * Abstract base class for GRE layers (GREv0Layer and GREv1Layer). Cannot be instantiated and contains common logic - * for derived classes - */ + /// @class GreLayer + /// Abstract base class for GRE layers (GREv0Layer and GREv1Layer). Cannot be instantiated and contains common logic + /// for derived classes class GreLayer : public Layer { public: ~GreLayer() override = default; - /** - * A static method that determines the GRE version of GRE layer raw data by looking at the - * gre_basic_header#version field - * @param[in] greData GRE layer raw data - * @param[in] greDataLen Size of raw data - * @return ::GREv0 or ::GREv1 values if raw data is GREv0 or GREv1 (accordingly) or ::UnknownProtocol otherwise - */ + /// A static method that determines the GRE version of GRE layer raw data by looking at the + /// gre_basic_header#version field + /// @param[in] greData GRE layer raw data + /// @param[in] greDataLen Size of raw data + /// @return ::GREv0 or ::GREv1 values if raw data is GREv0 or GREv1 (accordingly) or ::UnknownProtocol otherwise static ProtocolType getGREVersion(uint8_t* greData, size_t greDataLen); - /** - * Get sequence number value if field exists in layer - * @param[out] seqNumber The returned sequence number value if exists in layer. Else remain unchanged - * @return True if sequence number field exists in layer. In this case seqNumber will be filled with the value. - * Or false if sequence number field doesn't exist in layer - */ + /// Get sequence number value if field exists in layer + /// @param[out] seqNumber The returned sequence number value if exists in layer. Else remain unchanged + /// @return True if sequence number field exists in layer. In this case seqNumber will be filled with the value. + /// Or false if sequence number field doesn't exist in layer bool getSequenceNumber(uint32_t& seqNumber) const; - /** - * Set sequence number value. If field already exists (gre_basic_header#sequenceNumBit is set) then only the new - * value is set. If field doesn't exist it will be added to the layer, gre_basic_header#sequenceNumBit will be - * set and the new value will be set - * @param[in] seqNumber The sequence number value to set - * @return True if managed to set the value successfully, or false otherwise (if couldn't extend the layer) - */ + /// Set sequence number value. If field already exists (gre_basic_header#sequenceNumBit is set) then only the + /// new value is set. If field doesn't exist it will be added to the layer, gre_basic_header#sequenceNumBit will + /// be set and the new value will be set + /// @param[in] seqNumber The sequence number value to set + /// @return True if managed to set the value successfully, or false otherwise (if couldn't extend the layer) bool setSequenceNumber(uint32_t seqNumber); - /** - * Unset sequence number and remove it from the layer - * @return True if managed to unset successfully or false (and error log) if sequence number wasn't set in the - * first place or if didn't manage to remove it from the layer - */ + /// Unset sequence number and remove it from the layer + /// @return True if managed to unset successfully or false (and error log) if sequence number wasn't set in the + /// first place or if didn't manage to remove it from the layer bool unsetSequenceNumber(); // implement abstract methods - /** - * Currently identifies the following next layers: - * IPv4Layer, IPv6Layer, VlanLayer, MplsLayer, PPP_PPTPLayer, EthLayer, EthDot3Layer - * Otherwise sets PayloadLayer - */ + /// Currently identifies the following next layers: + /// IPv4Layer, IPv6Layer, VlanLayer, MplsLayer, PPP_PPTPLayer, EthLayer, EthDot3Layer + /// Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * @return Size of GRE header (may change if optional fields are added or removed) - */ + /// @return Size of GRE header (may change if optional fields are added or removed) size_t getHeaderLen() const override; OsiModelLayer getOsiModelLayer() const override @@ -182,114 +159,91 @@ namespace pcpp void computeCalculateFieldsInner(); }; - /** - * @class GREv0Layer - * Represents a GRE version 0 protocol. Limitation: currently this layer doesn't support GRE routing information - * parsing and editing. So if a GREv0 packet includes routing information it won't be parse correctly. I didn't add - * it because of lack of time, but if you need it please tell me and I'll add it - */ + /// @class GREv0Layer + /// Represents a GRE version 0 protocol. Limitation: currently this layer doesn't support GRE routing information + /// parsing and editing. So if a GREv0 packet includes routing information it won't be parse correctly. I didn't add + /// it because of lack of time, but if you need it please tell me and I'll add it class GREv0Layer : public GreLayer { public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in GREv0Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : GreLayer(data, dataLen, prevLayer, packet, GREv0) {} - /** - * A constructor that creates a new GREv0 header and allocates the data - */ + /// A constructor that creates a new GREv0 header and allocates the data GREv0Layer(); ~GREv0Layer() override = default; - /** - * Get a pointer to the basic GRE header containing only non-optional fields. Notice this points directly to the - * data, so every change will change the actual packet data. Also please notice that changing the set bits - * (gre_basic_header#strictSourceRouteBit, gre_basic_header#sequenceNumBit, gre_basic_header#keyBit, - * gre_basic_header#routingBit, gre_basic_header#checksumBit, gre_basic_header#ackSequenceNumBit) without using - * the proper set or unset methods (such as setChecksum(), unsetChecksum(), etc.) may result to wrong - * calculation of header length and really weird bugs. Please avoid doing so - * @return A pointer to the gre_basic_header - */ + /// Get a pointer to the basic GRE header containing only non-optional fields. Notice this points directly to + /// the data, so every change will change the actual packet data. Also please notice that changing the set bits + /// (gre_basic_header#strictSourceRouteBit, gre_basic_header#sequenceNumBit, gre_basic_header#keyBit, + /// gre_basic_header#routingBit, gre_basic_header#checksumBit, gre_basic_header#ackSequenceNumBit) without using + /// the proper set or unset methods (such as setChecksum(), unsetChecksum(), etc.) may result to wrong + /// calculation of header length and really weird bugs. Please avoid doing so + /// @return A pointer to the gre_basic_header gre_basic_header* getGreHeader() const { return reinterpret_cast(m_Data); } - /** - * Get checksum value if field exists in layer - * @param[out] checksum The returned checksum value if exists in layer. Else remain unchanged - * @return True if checksum field exists in layer. In this case checksum parameter will be filled with the - * value. Or false if checksum field doesn't exist in layer - */ + /// Get checksum value if field exists in layer + /// @param[out] checksum The returned checksum value if exists in layer. Else remain unchanged + /// @return True if checksum field exists in layer. In this case checksum parameter will be filled with the + /// value. Or false if checksum field doesn't exist in layer bool getChecksum(uint16_t& checksum); - /** - * Set checksum value. If checksum or offset fields already exist (gre_basic_header#checksumBit or - * gre_basic_header#routingBit are set) then only the new value is set. If both fields don't exist a new 4-byte - * value will be added to the layer, gre_basic_header#checksumBit will be set (gre_basic_header#routingBit will - * remain unset), the new checksum value will be set and offset value will be set to 0. The reason both fields - * are added is that GREv0 protocol states both of them or none of them should exist on packet (even if only one - * of the bits are set) - * @param[in] checksum The checksum value to set - * @return True if managed to set the value/s successfully, or false otherwise (if couldn't extend the layer) - */ + /// Set checksum value. If checksum or offset fields already exist (gre_basic_header#checksumBit or + /// gre_basic_header#routingBit are set) then only the new value is set. If both fields don't exist a new 4-byte + /// value will be added to the layer, gre_basic_header#checksumBit will be set (gre_basic_header#routingBit will + /// remain unset), the new checksum value will be set and offset value will be set to 0. The reason both fields + /// are added is that GREv0 protocol states both of them or none of them should exist on packet (even if only + /// one of the bits are set) + /// @param[in] checksum The checksum value to set + /// @return True if managed to set the value/s successfully, or false otherwise (if couldn't extend the layer) bool setChecksum(uint16_t checksum); - /** - * Unset checksum and possibly remove it from the layer. It will be removed from the layer only if - * gre_basic_header#routingBit is not set as well. Otherwise checksum field will remain on packet with value of - * 0 - * @return True if managed to unset successfully or false (and error log) if checksum wasn't set in the first - * place or if didn't manage to remove it from the layer - */ + /// Unset checksum and possibly remove it from the layer. It will be removed from the layer only if + /// gre_basic_header#routingBit is not set as well. Otherwise checksum field will remain on packet with value of + /// 0 + /// @return True if managed to unset successfully or false (and error log) if checksum wasn't set in the first + /// place or if didn't manage to remove it from the layer bool unsetChecksum(); - /** - * Get offset value if field exists in layer. Notice there is no setOffset() method as GRE routing information - * isn't supported yet (see comment on class description) - * @param[out] offset The returned offset value if exists in layer. Else remain unchanged - * @return True if offset field exists in layer. In this case offset parameter will be filled with the value. - * Or false if offset field doesn't exist in layer - */ + /// Get offset value if field exists in layer. Notice there is no setOffset() method as GRE routing information + /// isn't supported yet (see comment on class description) + /// @param[out] offset The returned offset value if exists in layer. Else remain unchanged + /// @return True if offset field exists in layer. In this case offset parameter will be filled with the value. + /// Or false if offset field doesn't exist in layer bool getOffset(uint16_t& offset) const; - /** - * Get key value if field exists in layer - * @param[out] key The returned key value if exists in layer. Else remain unchanged - * @return True if key field exists in layer. In this case key parameter will be filled with the value. - * Or false if key field doesn't exist in layer - */ + /// Get key value if field exists in layer + /// @param[out] key The returned key value if exists in layer. Else remain unchanged + /// @return True if key field exists in layer. In this case key parameter will be filled with the value. + /// Or false if key field doesn't exist in layer bool getKey(uint32_t& key) const; - /** - * Set key value. If field already exists (gre_basic_header#keyBit is set) then only the new value is set. - * If field doesn't exist it will be added to the layer, gre_basic_header#keyBit will be set - * and the new value will be set - * @param[in] key The key value to set - * @return True if managed to set the value successfully, or false otherwise (if couldn't extend the layer) - */ + /// Set key value. If field already exists (gre_basic_header#keyBit is set) then only the new value is set. + /// If field doesn't exist it will be added to the layer, gre_basic_header#keyBit will be set + /// and the new value will be set + /// @param[in] key The key value to set + /// @return True if managed to set the value successfully, or false otherwise (if couldn't extend the layer) bool setKey(uint32_t key); - /** - * Unset key and remove it from the layer - * @return True if managed to unset successfully or false (and error log) if key wasn't set in the first - * place or if didn't manage to remove it from the layer - */ + /// Unset key and remove it from the layer + /// @return True if managed to unset successfully or false (and error log) if key wasn't set in the first + /// place or if didn't manage to remove it from the layer bool unsetKey(); - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of an GREv0 layer - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent an GREv0 layer - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of an GREv0 layer + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent an GREv0 layer static inline bool isDataValid(const uint8_t* data, size_t dataLen) { return data && dataLen >= sizeof(gre_basic_header); @@ -297,86 +251,69 @@ namespace pcpp // implement abstract methods - /** - * Calculate the following fields: - * - gre_basic_header#protocol - * - GRE checksum field (if exists in packet) - */ + /// Calculate the following fields: + /// - gre_basic_header#protocol + /// - GRE checksum field (if exists in packet) void computeCalculateFields() override; std::string toString() const override; }; - /** - * @class GREv1Layer - * Represents a GRE version 1 protocol - */ + /// @class GREv1Layer + /// Represents a GRE version 1 protocol class GREv1Layer : public GreLayer { public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in GREv1Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : GreLayer(data, dataLen, prevLayer, packet, GREv1) {} - /** - * A constructor that creates a new GREv1 header and allocates the data - * @param[in] callID The call ID to set - */ + /// A constructor that creates a new GREv1 header and allocates the data + /// @param[in] callID The call ID to set explicit GREv1Layer(uint16_t callID); ~GREv1Layer() override = default; - /** - * Get a pointer to the basic GREv1 header containing all non-optional fields. Notice this points directly to - * the data, so every change will change the actual packet data. Also please notice that changing the set bits - * (gre_basic_header#strictSourceRouteBit, gre_basic_header#sequenceNumBit, gre_basic_header#keyBit, - * gre_basic_header#routingBit, gre_basic_header#checksumBit, gre_basic_header#ackSequenceNumBit) without using - * the proper set or unset methods (such as setAcknowledgmentNum(), unsetSequenceNumber(), etc.) may result to - * wrong calculation of header length or illegal GREv1 packet and to some really weird bugs. Please avoid doing - * so - * @return A pointer to the gre1_header - */ + /// Get a pointer to the basic GREv1 header containing all non-optional fields. Notice this points directly to + /// the data, so every change will change the actual packet data. Also please notice that changing the set bits + /// (gre_basic_header#strictSourceRouteBit, gre_basic_header#sequenceNumBit, gre_basic_header#keyBit, + /// gre_basic_header#routingBit, gre_basic_header#checksumBit, gre_basic_header#ackSequenceNumBit) without using + /// the proper set or unset methods (such as setAcknowledgmentNum(), unsetSequenceNumber(), etc.) may result to + /// wrong calculation of header length or illegal GREv1 packet and to some really weird bugs. Please avoid doing + /// so + /// @return A pointer to the gre1_header gre1_header* getGreHeader() const { return reinterpret_cast(m_Data); } - /** - * Get acknowledgment (ack) number value if field exists in layer - * @param[out] ackNum The returned ack number value if exists in layer. Else remain unchanged - * @return True if ack number field exists in layer. In this case ackNum will be filled with the value. - * Or false if ack number field doesn't exist in layer - */ + /// Get acknowledgment (ack) number value if field exists in layer + /// @param[out] ackNum The returned ack number value if exists in layer. Else remain unchanged + /// @return True if ack number field exists in layer. In this case ackNum will be filled with the value. + /// Or false if ack number field doesn't exist in layer bool getAcknowledgmentNum(uint32_t& ackNum) const; - /** - * Set acknowledgment (ack) number value. If field already exists (gre_basic_header#ackSequenceNumBit is set) - * then only the new value is set. If field doesn't exist it will be added to the layer, - * gre_basic_header#ackSequenceNumBit will be set and the new value will be set - * @param[in] ackNum The ack number value to set - * @return True if managed to set the value successfully, or false otherwise (if couldn't extend the layer) - */ + /// Set acknowledgment (ack) number value. If field already exists (gre_basic_header#ackSequenceNumBit is set) + /// then only the new value is set. If field doesn't exist it will be added to the layer, + /// gre_basic_header#ackSequenceNumBit will be set and the new value will be set + /// @param[in] ackNum The ack number value to set + /// @return True if managed to set the value successfully, or false otherwise (if couldn't extend the layer) bool setAcknowledgmentNum(uint32_t ackNum); - /** - * Unset acknowledgment (ack) number and remove it from the layer - * @return True if managed to unset successfully or false (and error log) if ack number wasn't set in the first - * place or if didn't manage to remove it from the layer - */ + /// Unset acknowledgment (ack) number and remove it from the layer + /// @return True if managed to unset successfully or false (and error log) if ack number wasn't set in the first + /// place or if didn't manage to remove it from the layer bool unsetAcknowledgmentNum(); - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of an GREv1 layer - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent an GREv1 layer - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of an GREv1 layer + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent an GREv1 layer static inline bool isDataValid(const uint8_t* data, size_t dataLen) { return data && dataLen >= sizeof(gre1_header); @@ -384,49 +321,39 @@ namespace pcpp // implement abstract methods - /** - * Calculate the following fields: - * - gre1_header#payloadLength - * - gre_basic_header#protocol - */ + /// Calculate the following fields: + /// - gre1_header#payloadLength + /// - gre_basic_header#protocol void computeCalculateFields() override; std::string toString() const override; }; - /** - * @class PPP_PPTPLayer - * Represent a PPP (point-to-point) protocol header that comes after GREv1 header, as part of PPTP - Point-to-Point - * Tunneling Protocol - */ + /// @class PPP_PPTPLayer + /// Represent a PPP (point-to-point) protocol header that comes after GREv1 header, as part of PPTP - Point-to-Point + /// Tunneling Protocol class PPP_PPTPLayer : public Layer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to @ref ppp_pptp_header) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to @ref ppp_pptp_header) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in PPP_PPTPLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, PPP_PPTP) {} - /** - * A constructor that allocates a new PPP-PPTP header - * @param[in] address Address field - * @param[in] control Control field - */ + /// A constructor that allocates a new PPP-PPTP header + /// @param[in] address Address field + /// @param[in] control Control field PPP_PPTPLayer(uint8_t address, uint8_t control); ~PPP_PPTPLayer() override = default; - /** - * Get a pointer to the PPP-PPTP header. Notice this points directly to the data, so every change will change - * the actual packet data - * @return A pointer to the @ref ppp_pptp_header - */ + /// Get a pointer to the PPP-PPTP header. Notice this points directly to the data, so every change will change + /// the actual packet data + /// @return A pointer to the @ref ppp_pptp_header ppp_pptp_header* getPPP_PPTPHeader() const { return reinterpret_cast(m_Data); @@ -434,23 +361,17 @@ namespace pcpp // implement abstract methods - /** - * Currently identifies the following next layers: IPv4Layer, IPv6Layer. Otherwise sets PayloadLayer - */ + /// Currently identifies the following next layers: IPv4Layer, IPv6Layer. Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * @return The size of @ref ppp_pptp_header - */ + /// @return The size of @ref ppp_pptp_header size_t getHeaderLen() const override { return sizeof(ppp_pptp_header); } - /** - * Calculate the following fields: - * - ppp_pptp_header#protocol - */ + /// Calculate the following fields: + /// - ppp_pptp_header#protocol void computeCalculateFields() override; std::string toString() const override diff --git a/Packet++/header/GtpLayer.h b/Packet++/header/GtpLayer.h index 27ce036c18..91428fb3df 100644 --- a/Packet++/header/GtpLayer.h +++ b/Packet++/header/GtpLayer.h @@ -7,212 +7,204 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { #pragma pack(push, 1) - /** - * @struct gtpv1_header - * GTP v1 common message header - */ + /// @struct gtpv1_header + /// GTP v1 common message header struct gtpv1_header { #if (BYTE_ORDER == LITTLE_ENDIAN) - /** A 1-bit value that states whether there is a N-PDU number optional field */ + /// A 1-bit value that states whether there is a N-PDU number optional field uint8_t npduNumberFlag : 1, - /** A 1-bit value that states whether there is a Sequence Number optional field */ + /// A 1-bit value that states whether there is a Sequence Number optional field sequenceNumberFlag : 1, - /** A 1-bit value that states whether there is an extension header optional field */ + /// A 1-bit value that states whether there is an extension header optional field extensionHeaderFlag : 1, - /** Reserved bit */ + /// Reserved bit reserved : 1, - /** A 1-bit value that differentiates GTP (value 1) from GTP' (value 0) */ + /// A 1-bit value that differentiates GTP (value 1) from GTP' (value 0) protocolType : 1, - /** GTP version */ + /// GTP version version : 3; #else - /** GTP version */ + /// GTP version uint8_t version : 3, - /** A 1-bit value that differentiates GTP (value 1) from GTP' (value 0) */ + /// A 1-bit value that differentiates GTP (value 1) from GTP' (value 0) protocolType : 1, - /** Reserved bit */ + /// Reserved bit reserved : 1, - /** A 1-bit value that states whether there is an extension header optional field */ + /// A 1-bit value that states whether there is an extension header optional field extensionHeaderFlag : 1, - /** A 1-bit value that states whether there is a Sequence Number optional field */ + /// A 1-bit value that states whether there is a Sequence Number optional field sequenceNumberFlag : 1, - /** A 1-bit value that states whether there is a N-PDU number optional field */ + /// A 1-bit value that states whether there is a N-PDU number optional field npduNumberFlag : 1; #endif - /** An 8-bit field that indicates the type of GTP message */ + /// An 8-bit field that indicates the type of GTP message uint8_t messageType; - /** A 16-bit field that indicates the length of the payload in bytes (rest of the packet following the mandatory - * 8-byte GTP header). Includes the optional fields */ + /// A 16-bit field that indicates the length of the payload in bytes (rest of the packet following the mandatory + /// 8-byte GTP header). Includes the optional fields uint16_t messageLength; - /** Tunnel endpoint identifier - A 32-bit(4-octet) field used to multiplex different connections in the same GTP - * tunnel */ + /// Tunnel endpoint identifier - A 32-bit(4-octet) field used to multiplex different connections in the same GTP + /// tunnel uint32_t teid; }; #pragma pack(pop) static_assert(sizeof(gtpv1_header) == 8, "gtpv1_header size is not 8 bytes"); - /** - * An enum representing the possible GTP v1 message types. - * All of the message types except for #GtpV1_GPDU are considered GTP-C messages. #GtpV1_GPDU is considered a GTP-U - * message - */ + /// An enum representing the possible GTP v1 message types. + /// All of the message types except for #GtpV1_GPDU are considered GTP-C messages. #GtpV1_GPDU is considered a GTP-U + /// message enum GtpV1MessageType { - /** GTPv1 Message Type Unknown */ + /// GTPv1 Message Type Unknown GtpV1_MessageTypeUnknown = 0, - /** Echo Request */ + /// Echo Request GtpV1_EchoRequest = 1, - /** Echo Response */ + /// Echo Response GtpV1_EchoResponse = 2, - /** Version Not Supported */ + /// Version Not Supported GtpV1_VersionNotSupported = 3, - /** Node Alive Request */ + /// Node Alive Request GtpV1_NodeAliveRequest = 4, - /** Node Alive Response */ + /// Node Alive Response GtpV1_NodeAliveResponse = 5, - /** Redirection Request */ + /// Redirection Request GtpV1_RedirectionRequest = 6, - /** Create PDP Context Request */ + /// Create PDP Context Request GtpV1_CreatePDPContextRequest = 7, - /** Create PDP Context Response */ + /// Create PDP Context Response GtpV1_CreatePDPContextResponse = 16, - /** Update PDP Context Request */ + /// Update PDP Context Request GtpV1_UpdatePDPContextRequest = 17, - /** Update PDP Context Response */ + /// Update PDP Context Response GtpV1_UpdatePDPContextResponse = 18, - /** Delete PDP Context Request */ + /// Delete PDP Context Request GtpV1_DeletePDPContextRequest = 19, - /** Delete PDP Context Response */ + /// Delete PDP Context Response GtpV1_DeletePDPContextResponse = 20, - /** Initiate PDP Context Activation Request */ + /// Initiate PDP Context Activation Request GtpV1_InitiatePDPContextActivationRequest = 22, - /** Initiate PDP Context Activation Response */ + /// Initiate PDP Context Activation Response GtpV1_InitiatePDPContextActivationResponse = 23, - /** Error Indication */ + /// Error Indication GtpV1_ErrorIndication = 26, - /** PDU Notification Request */ + /// PDU Notification Request GtpV1_PDUNotificationRequest = 27, - /** PDU Notification Response */ + /// PDU Notification Response GtpV1_PDUNotificationResponse = 28, - /** PDU Notification Reject Request */ + /// PDU Notification Reject Request GtpV1_PDUNotificationRejectRequest = 29, - /** PDU Notification Reject Response */ + /// PDU Notification Reject Response GtpV1_PDUNotificationRejectResponse = 30, - /** Supported Extensions Header Notification */ + /// Supported Extensions Header Notification GtpV1_SupportedExtensionsHeaderNotification = 31, - /** Send Routing for GPRS Request */ + /// Send Routing for GPRS Request GtpV1_SendRoutingforGPRSRequest = 32, - /** Send Routing for GPRS Response */ + /// Send Routing for GPRS Response GtpV1_SendRoutingforGPRSResponse = 33, - /** Failure Report Request */ + /// Failure Report Request GtpV1_FailureReportRequest = 34, - /** Failure Report Response */ + /// Failure Report Response GtpV1_FailureReportResponse = 35, - /** Note MS Present Request */ + /// Note MS Present Request GtpV1_NoteMSPresentRequest = 36, - /** Note MS Present Response */ + /// Note MS Present Response GtpV1_NoteMSPresentResponse = 37, - /** Identification Request */ + /// Identification Request GtpV1_IdentificationRequest = 38, - /** Identification Response */ + /// Identification Response GtpV1_IdentificationResponse = 39, - /** SGSN Context Request */ + /// SGSN Context Request GtpV1_SGSNContextRequest = 50, - /** SGSN Context Response */ + /// SGSN Context Response GtpV1_SGSNContextResponse = 51, - /** SGSN Context Acknowledge */ + /// SGSN Context Acknowledge GtpV1_SGSNContextAcknowledge = 52, - /** Forward Relocation Request */ + /// Forward Relocation Request GtpV1_ForwardRelocationRequest = 53, - /** Forward Relocation Response */ + /// Forward Relocation Response GtpV1_ForwardRelocationResponse = 54, - /** Forward Relocation Complete */ + /// Forward Relocation Complete GtpV1_ForwardRelocationComplete = 55, - /** Relocation Cancel Request */ + /// Relocation Cancel Request GtpV1_RelocationCancelRequest = 56, - /** Relocation Cancel Response */ + /// Relocation Cancel Response GtpV1_RelocationCancelResponse = 57, - /** Forward SRNS Context */ + /// Forward SRNS Context GtpV1_ForwardSRNSContext = 58, - /** Forward Relocation Complete Acknowledge */ + /// Forward Relocation Complete Acknowledge GtpV1_ForwardRelocationCompleteAcknowledge = 59, - /** Forward SRNS Context Acknowledge */ + /// Forward SRNS Context Acknowledge GtpV1_ForwardSRNSContextAcknowledge = 60, - /** UE Registration Request */ + /// UE Registration Request GtpV1_UERegistrationRequest = 61, - /** UE Registration Response */ + /// UE Registration Response GtpV1_UERegistrationResponse = 62, - /** RAN Information Relay */ + /// RAN Information Relay GtpV1_RANInformationRelay = 70, - /** MBMS Notification Request */ + /// MBMS Notification Request GtpV1_MBMSNotificationRequest = 96, - /** MBMS Notification Response */ + /// MBMS Notification Response GtpV1_MBMSNotificationResponse = 97, - /** MBMS Notification Reject Request */ + /// MBMS Notification Reject Request GtpV1_MBMSNotificationRejectRequest = 98, - /** MBMS Notification Reject Response */ + /// MBMS Notification Reject Response GtpV1_MBMSNotificationRejectResponse = 99, - /** Create MBMS Notification Request */ + /// Create MBMS Notification Request GtpV1_CreateMBMSNotificationRequest = 100, - /** Create MBMS Notification Response */ + /// Create MBMS Notification Response GtpV1_CreateMBMSNotificationResponse = 101, - /** Update MBMS Notification Request */ + /// Update MBMS Notification Request GtpV1_UpdateMBMSNotificationRequest = 102, - /** Update MBMS Notification Response */ + /// Update MBMS Notification Response GtpV1_UpdateMBMSNotificationResponse = 103, - /** Delete MBMS Notification Request */ + /// Delete MBMS Notification Request GtpV1_DeleteMBMSNotificationRequest = 104, - /** Delete MBMS Notification Response */ + /// Delete MBMS Notification Response GtpV1_DeleteMBMSNotificationResponse = 105, - /** MBMS Registration Request */ + /// MBMS Registration Request GtpV1_MBMSRegistrationRequest = 112, - /** MBMS Registration Response */ + /// MBMS Registration Response GtpV1_MBMSRegistrationResponse = 113, - /** MBMS De-Registration Request */ + /// MBMS De-Registration Request GtpV1_MBMSDeRegistrationRequest = 114, - /** MBMS De-Registration Response */ + /// MBMS De-Registration Response GtpV1_MBMSDeRegistrationResponse = 115, - /** MBMS Session Start Request */ + /// MBMS Session Start Request GtpV1_MBMSSessionStartRequest = 116, - /** MBMS Session Start Response */ + /// MBMS Session Start Response GtpV1_MBMSSessionStartResponse = 117, - /** MBMS Session Stop Request */ + /// MBMS Session Stop Request GtpV1_MBMSSessionStopRequest = 118, - /** MBMS Session Stop Response */ + /// MBMS Session Stop Response GtpV1_MBMSSessionStopResponse = 119, - /** MBMS Session Update Request */ + /// MBMS Session Update Request GtpV1_MBMSSessionUpdateRequest = 120, - /** MBMS Session Update Response */ + /// MBMS Session Update Response GtpV1_MBMSSessionUpdateResponse = 121, - /** MS Info Change Request */ + /// MS Info Change Request GtpV1_MSInfoChangeRequest = 128, - /** MS Info Change Response */ + /// MS Info Change Response GtpV1_MSInfoChangeResponse = 129, - /** Data Record Transfer Request */ + /// Data Record Transfer Request GtpV1_DataRecordTransferRequest = 240, - /** Data Record Transfer Response */ + /// Data Record Transfer Response GtpV1_DataRecordTransferResponse = 241, - /** End Marker */ + /// End Marker GtpV1_EndMarker = 254, - /** G-PDU */ + /// G-PDU GtpV1_GPDU = 255 }; - /** - * @class GtpV1Layer - * A class representing the [GTP v1](https://en.wikipedia.org/wiki/GPRS_Tunnelling_Protocol) protocol. - */ + /// @class GtpV1Layer + /// A class representing the [GTP v1](https://en.wikipedia.org/wiki/GPRS_Tunnelling_Protocol) protocol. class GtpV1Layer : public Layer { private: @@ -229,10 +221,8 @@ namespace pcpp uint8_t npduNum); public: - /** - * @class GtpExtension - * A class that represents [GTP header extensions](https://en.wikipedia.org/wiki/GPRS_Tunnelling_Protocol) - */ + /// @class GtpExtension + /// A class that represents [GTP header extensions](https://en.wikipedia.org/wiki/GPRS_Tunnelling_Protocol) class GtpExtension { friend class GtpV1Layer; @@ -249,203 +239,150 @@ namespace pcpp static GtpExtension createGtpExtension(uint8_t* data, size_t dataLen, uint8_t extType, uint16_t content); public: - /** - * An empty c'tor that creates an empty object, meaning one that isNull() returns "true") - */ + /// An empty c'tor that creates an empty object, meaning one that isNull() returns "true") GtpExtension(); - /** - * A copy c'tor for this class - * @param[in] other The GTP extension to copy from - */ + /// A copy c'tor for this class + /// @param[in] other The GTP extension to copy from GtpExtension(const GtpExtension& other); - /** - * An assignment operator for this class - * @param[in] other The extension to assign from - * @return A reference to the assignee - */ + /// An assignment operator for this class + /// @param[in] other The extension to assign from + /// @return A reference to the assignee GtpExtension& operator=(const GtpExtension& other); - /** - * @return Instances of this class may be initialized as empty, meaning they don't contain any data. In - * these cases this method returns true - */ + /// @return Instances of this class may be initialized as empty, meaning they don't contain any data. In + /// these cases this method returns true bool isNull() const; - /** - * @return The extension type. If the object is empty a value of zero is returned - */ + /// @return The extension type. If the object is empty a value of zero is returned uint8_t getExtensionType() const; - /** - * @return The total length of the extension including the length and next extension type fields. - * If the object is empty a value of zero is returned - */ + /// @return The total length of the extension including the length and next extension type fields. + /// If the object is empty a value of zero is returned size_t getTotalLength() const; - /** - * @return The length of the extension's content, excluding the extension length and next extension type - * fields. If the object is empty a value of zero is returned - */ + /// @return The length of the extension's content, excluding the extension length and next extension type + /// fields. If the object is empty a value of zero is returned size_t getContentLength() const; - /** - * @return A byte array that includes the extension's content. The length of this array can be determined by - * getContentLength(). If the object is empty a null value is returned - */ + /// @return A byte array that includes the extension's content. The length of this array can be determined + /// by getContentLength(). If the object is empty a null value is returned uint8_t* getContent() const; - /** - * @return The extension type of the next header. If there are no more header extensions or if this object - * is empty a value of zero is returned - */ + /// @return The extension type of the next header. If there are no more header extensions or if this object + /// is empty a value of zero is returned uint8_t getNextExtensionHeaderType() const; - /** - * @return An instance of this class representing the next extension header, if exists in the message. If - * there are no more header extensions or if this object is empty an empty instance of GtpExtension is - * returned, meaning one that GtpExtension#isNull() returns "true" - */ + /// @return An instance of this class representing the next extension header, if exists in the message. If + /// there are no more header extensions or if this object is empty an empty instance of GtpExtension is + /// returned, meaning one that GtpExtension#isNull() returns "true" GtpExtension getNextExtension() const; }; // GtpExtension ~GtpV1Layer() override = default; - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in GtpV1Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, GTPv1) {} - /** - * A constructor that creates a new GTPv1 layer and sets the message type and the TEID value - * @param[in] messageType The GTPv1 message type to be set in the newly created layer - * @param[in] teid The TEID value to be set in the newly created layer - */ + /// A constructor that creates a new GTPv1 layer and sets the message type and the TEID value + /// @param[in] messageType The GTPv1 message type to be set in the newly created layer + /// @param[in] teid The TEID value to be set in the newly created layer GtpV1Layer(GtpV1MessageType messageType, uint32_t teid); - /** - * A constructor that creates a new GTPv1 layer and sets various parameters - * @param[in] messageType The GTPv1 message type to be set in the newly created layer - * @param[in] teid The TEID value to be set in the newly created layer - * @param[in] setSeqNum A flag indicating whether to set a sequence number. If set to "false" then the parameter - * "seqNum" will be ignored - * @param[in] seqNum The sequence number to be set in the newly created later. If "setSeqNum" is set to false - * this parameter will be ignored - * @param[in] setNpduNum A flag indicating whether to set the N-PDU number. If set to "false" then the parameter - * "npduNum" will be ignored - * @param[in] npduNum The N-PDU number to be set in the newly created later. If "setNpduNum" is set to false - * this parameter will be ignored - */ + /// A constructor that creates a new GTPv1 layer and sets various parameters + /// @param[in] messageType The GTPv1 message type to be set in the newly created layer + /// @param[in] teid The TEID value to be set in the newly created layer + /// @param[in] setSeqNum A flag indicating whether to set a sequence number. If set to "false" then the + /// parameter "seqNum" will be ignored + /// @param[in] seqNum The sequence number to be set in the newly created later. If "setSeqNum" is set to false + /// this parameter will be ignored + /// @param[in] setNpduNum A flag indicating whether to set the N-PDU number. If set to "false" then the + /// parameter "npduNum" will be ignored + /// @param[in] npduNum The N-PDU number to be set in the newly created later. If "setNpduNum" is set to false + /// this parameter will be ignored GtpV1Layer(GtpV1MessageType messageType, uint32_t teid, bool setSeqNum, uint16_t seqNum, bool setNpduNum, uint8_t npduNum); - /** - * A static method that takes a byte array and detects whether it is a GTP v1 message - * @param[in] data A byte array - * @param[in] dataSize The byte array size (in bytes) - * @return True if the data is identified as GTP v1 message (GTP-C or GTP-U) - */ + /// A static method that takes a byte array and detects whether it is a GTP v1 message + /// @param[in] data A byte array + /// @param[in] dataSize The byte array size (in bytes) + /// @return True if the data is identified as GTP v1 message (GTP-C or GTP-U) static bool isGTPv1(const uint8_t* data, size_t dataSize); - /** - * @return The GTP v1 common header structure. Notice this points directly to the data, so every change will - * change the actual packet data - */ + /// @return The GTP v1 common header structure. Notice this points directly to the data, so every change will + /// change the actual packet data gtpv1_header* getHeader() const { return reinterpret_cast(m_Data); } - /** - * Get the sequence number if exists on the message (sequence number is an optional field in GTP messages) - * @param[out] seqNumber Set with the sequence number value if exists in the layer. Otherwise remains unchanged - * @return True if the sequence number field exists in layer, in which case seqNumber is set with the value. - * Or false otherwise - */ + /// Get the sequence number if exists on the message (sequence number is an optional field in GTP messages) + /// @param[out] seqNumber Set with the sequence number value if exists in the layer. Otherwise remains unchanged + /// @return True if the sequence number field exists in layer, in which case seqNumber is set with the value. + /// Or false otherwise bool getSequenceNumber(uint16_t& seqNumber) const; - /** - * Set a sequence number - * @param[in] seqNumber The sequence number to set - * @return True if the value was set successfully, false otherwise. In case of failure a corresponding error - * message will be written to log - */ + /// Set a sequence number + /// @param[in] seqNumber The sequence number to set + /// @return True if the value was set successfully, false otherwise. In case of failure a corresponding error + /// message will be written to log bool setSequenceNumber(uint16_t seqNumber); - /** - * Get the N-PDU number if exists on the message (N-PDU number is an optional field in GTP messages) - * @param[out] npduNum Set with the N-PDU number value if exists in the layer. Otherwise remains unchanged - * @return True if the N-PDU number field exists in layer, in which case npduNum is set with the value. - * Or false otherwise - */ + /// Get the N-PDU number if exists on the message (N-PDU number is an optional field in GTP messages) + /// @param[out] npduNum Set with the N-PDU number value if exists in the layer. Otherwise remains unchanged + /// @return True if the N-PDU number field exists in layer, in which case npduNum is set with the value. + /// Or false otherwise bool getNpduNumber(uint8_t& npduNum) const; - /** - * Set an N-PDU number - * @param[in] npduNum The N-PDU number to set - * @return True if the value was set successfully, false otherwise. In case of failure a corresponding error - * message will be written to log - */ + /// Set an N-PDU number + /// @param[in] npduNum The N-PDU number to set + /// @return True if the value was set successfully, false otherwise. In case of failure a corresponding error + /// message will be written to log bool setNpduNumber(uint8_t npduNum); - /** - * Get the type of the next header extension if exists on the message (extensions are optional in GTP messages) - * @param[out] nextExtType Set with the next header extension type if exists in layer. Otherwise remains - * unchanged - * @return True if the message contains header extensions, in which case nextExtType is set to the next - * header extension type. If there are no header extensions false is returned and nextExtType remains unchanged - */ + /// Get the type of the next header extension if exists on the message (extensions are optional in GTP messages) + /// @param[out] nextExtType Set with the next header extension type if exists in layer. Otherwise remains + /// unchanged + /// @return True if the message contains header extensions, in which case nextExtType is set to the next + /// header extension type. If there are no header extensions false is returned and nextExtType remains unchanged bool getNextExtensionHeaderType(uint8_t& nextExtType) const; - /** - * @return An object that represents the next extension header, if exists in the message. If there are no - * extensions an empty object is returned, meaning an object which GtpExtension#isNull() returns "true" - */ + /// @return An object that represents the next extension header, if exists in the message. If there are no + /// extensions an empty object is returned, meaning an object which GtpExtension#isNull() returns "true" GtpExtension getNextExtension() const; - /** - * Add a GTPv1 header extension. It is assumed that the extension is 4 bytes in length and its content is 2 - * bytes in length. If you need a different content size please reach out to me. This method takes care of - * extending the layer to make room for the new extension and also sets the relevant flags and fields - * @param[in] extensionType The type of the new extension - * @param[in] extensionContent A 2-byte long content - * @return An object representing the newly added extension. If there was an error adding the extension a null - * object will be returned (meaning GtpExtension#isNull() will return "true") and a corresponding error message - * will be written to log - */ + /// Add a GTPv1 header extension. It is assumed that the extension is 4 bytes in length and its content is 2 + /// bytes in length. If you need a different content size please reach out to me. This method takes care of + /// extending the layer to make room for the new extension and also sets the relevant flags and fields + /// @param[in] extensionType The type of the new extension + /// @param[in] extensionContent A 2-byte long content + /// @return An object representing the newly added extension. If there was an error adding the extension a null + /// object will be returned (meaning GtpExtension#isNull() will return "true") and a corresponding error message + /// will be written to log GtpExtension addExtension(uint8_t extensionType, uint16_t extensionContent); - /** - * @return The message type of this GTP packet - */ + /// @return The message type of this GTP packet GtpV1MessageType getMessageType() const; - /** - * @return A string representation of the packet's message type - */ + /// @return A string representation of the packet's message type std::string getMessageTypeAsString() const; - /** - * @return True if this is a GTP-U message, false otherwise - */ + /// @return True if this is a GTP-U message, false otherwise bool isGTPUMessage() const; - /** - * @return True if this is a GTP-C message, false otherwise - */ + /// @return True if this is a GTP-C message, false otherwise bool isGTPCMessage() const; - /** - * A static method that checks whether the port is considered as GTPv1 - * @param[in] port The port number to be checked - * @return True if the port matches those associated with the GTPv1 protocol - */ + /// A static method that checks whether the port is considered as GTPv1 + /// @param[in] port The port number to be checked + /// @return True if the port matches those associated with the GTPv1 protocol static bool isGTPv1Port(uint16_t port) { return port == 2152 /* GTP-U */ || port == 2123 /* GTP-C */; @@ -453,23 +390,17 @@ namespace pcpp // implement abstract methods - /** - * Identifies the following next layers for GTP-U packets: IPv4Layer, IPv6Layer. Otherwise sets PayloadLayer - */ + /// Identifies the following next layers for GTP-U packets: IPv4Layer, IPv6Layer. Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * @return The size of the GTP header. For GTP-C packets the size is determined by the value of - * gtpv1_header#messageLength and for GTP-U the size only includes the GTP header itself (meaning - * the size of gtpv1_header plus the size of the optional fields such as sequence number, N-PDU - * or extensions if exist) - */ + /// @return The size of the GTP header. For GTP-C packets the size is determined by the value of + /// gtpv1_header#messageLength and for GTP-U the size only includes the GTP header itself (meaning + /// the size of gtpv1_header plus the size of the optional fields such as sequence number, N-PDU + /// or extensions if exist) size_t getHeaderLen() const override; - /** - * Calculate the following fields: - * - gtpv1_header#messageLength - */ + /// Calculate the following fields: + /// - gtpv1_header#messageLength void computeCalculateFields() override; std::string toString() const override; @@ -480,207 +411,197 @@ namespace pcpp } }; - /** - * @class GtpV2MessageType - * The enum wrapper class of GTPv2 message type - */ + /// @class GtpV2MessageType + /// The enum wrapper class of GTPv2 message type class GtpV2MessageType { public: - /** - * Define enum types and the corresponding int values - */ + /// Define enum types and the corresponding int values enum Value : uint8_t { - /** Unknown message */ + /// Unknown message Unknown = 0, - /** Echo Request message */ + /// Echo Request message EchoRequest = 1, - /** Echo Response message */ + /// Echo Response message EchoResponse = 2, - /** Version Not Supported message */ + /// Version Not Supported message VersionNotSupported = 3, - /** Create Session Request message */ + /// Create Session Request message CreateSessionRequest = 32, - /** Create Session Response message */ + /// Create Session Response message CreateSessionResponse = 33, - /** Modify Bearer Request message */ + /// Modify Bearer Request message ModifyBearerRequest = 34, - /** Modify Bearer Response message */ + /// Modify Bearer Response message ModifyBearerResponse = 35, - /** Delete Session Request message */ + /// Delete Session Request message DeleteSessionRequest = 36, - /** Delete Session Response message */ + /// Delete Session Response message DeleteSessionResponse = 37, - /** Change Notification Request message */ + /// Change Notification Request message ChangeNotificationRequest = 38, - /** Change Notification Response message */ + /// Change Notification Response message ChangeNotificationResponse = 39, - /** Remote UE Report Notifications message */ + /// Remote UE Report Notifications message RemoteUEReportNotifications = 40, - /** Remote UE Report Acknowledge message */ + /// Remote UE Report Acknowledge message RemoteUEReportAcknowledge = 41, - /** Modify Bearer Command message */ + /// Modify Bearer Command message ModifyBearerCommand = 64, - /** Modify Bearer Failure message */ + /// Modify Bearer Failure message ModifyBearerFailure = 65, - /** Delete Bearer Command message */ + /// Delete Bearer Command message DeleteBearerCommand = 66, - /** Delete Bearer Failure message */ + /// Delete Bearer Failure message DeleteBearerFailure = 67, - /** Bearer Resource Command message */ + /// Bearer Resource Command message BearerResourceCommand = 68, - /** Bearer Resource Failure message */ + /// Bearer Resource Failure message BearerResourceFailure = 69, - /** Downlink Data Notification Failure message */ + /// Downlink Data Notification Failure message DownlinkDataNotificationFailure = 70, - /** Trace Session Activation message */ + /// Trace Session Activation message TraceSessionActivation = 71, - /** Trace Session Deactivation message */ + /// Trace Session Deactivation message TraceSessionDeactivation = 72, - /** Stop Paging Indication message */ + /// Stop Paging Indication message StopPagingIndication = 73, - /** Create Bearer Request message */ + /// Create Bearer Request message CreateBearerRequest = 95, - /** Create Bearer Response message */ + /// Create Bearer Response message CreateBearerResponse = 96, - /** Update Bearer Request message */ + /// Update Bearer Request message UpdateBearerRequest = 97, - /** Update Bearer Response message */ + /// Update Bearer Response message UpdateBearerResponse = 98, - /** Delete Bearer Request message */ + /// Delete Bearer Request message DeleteBearerRequest = 99, - /** Delete Bearer Response message */ + /// Delete Bearer Response message DeleteBearerResponse = 100, - /** Delete PDN Request message */ + /// Delete PDN Request message DeletePDNRequest = 101, - /** Delete PDN Response message */ + /// Delete PDN Response message DeletePDNResponse = 102, - /** PGW Downlink Notification message */ + /// PGW Downlink Notification message PGWDownlinkNotification = 103, - /** PGW Downlink Acknowledge message */ + /// PGW Downlink Acknowledge message PGWDownlinkAcknowledge = 104, - /** Identification Request message */ + /// Identification Request message IdentificationRequest = 128, - /** Identification Response message */ + /// Identification Response message IdentificationResponse = 129, - /** Context Request message */ + /// Context Request message ContextRequest = 130, - /** Context Response message */ + /// Context Response message ContextResponse = 131, - /** Context Acknowledge message */ + /// Context Acknowledge message ContextAcknowledge = 132, - /** Forward Relocation Request message */ + /// Forward Relocation Request message ForwardRelocationRequest = 133, - /** Forward Relocation Response message */ + /// Forward Relocation Response message ForwardRelocationResponse = 134, - /** Forward Relocation Notification message */ + /// Forward Relocation Notification message ForwardRelocationNotification = 135, - /** Forward Relocation Acknowledge message */ + /// Forward Relocation Acknowledge message ForwardRelocationAcknowledge = 136, - /** Forward Access Notification message */ + /// Forward Access Notification message ForwardAccessNotification = 137, - /** Forward Access Acknowledge message */ + /// Forward Access Acknowledge message ForwardAccessAcknowledge = 138, - /** Relocation Cancel Request message */ + /// Relocation Cancel Request message RelocationCancelRequest = 139, - /** Relocation Cancel Response message */ + /// Relocation Cancel Response message RelocationCancelResponse = 140, - /** Configuration Transfer Tunnel message */ + /// Configuration Transfer Tunnel message ConfigurationTransferTunnel = 141, - /** Detach Notification message */ + /// Detach Notification message DetachNotification = 149, - /** Detach Acknowledge message */ + /// Detach Acknowledge message DetachAcknowledge = 150, - /** CS Paging message */ + /// CS Paging message CSPaging = 151, - /** RAN Information Relay message */ + /// RAN Information Relay message RANInformationRelay = 152, - /** Alert MME Notification message */ + /// Alert MME Notification message AlertMMENotification = 153, - /** Alert MME Acknowledge message */ + /// Alert MME Acknowledge message AlertMMEAcknowledge = 154, - /** UE Activity Notification message */ + /// UE Activity Notification message UEActivityNotification = 155, - /** UE Activity Acknowledge message */ + /// UE Activity Acknowledge message UEActivityAcknowledge = 156, - /** ISR Status message */ + /// ISR Status message ISRStatus = 157, - /** Create Forwarding Request message */ + /// Create Forwarding Request message CreateForwardingRequest = 160, - /** Create Forwarding Response message */ + /// Create Forwarding Response message CreateForwardingResponse = 161, - /** Suspend Notification message */ + /// Suspend Notification message SuspendNotification = 162, - /** Suspend Acknowledge message */ + /// Suspend Acknowledge message SuspendAcknowledge = 163, - /** Resume Notification message */ + /// Resume Notification message ResumeNotification = 164, - /** Resume Acknowledge message */ + /// Resume Acknowledge message ResumeAcknowledge = 165, - /** Create Indirect Data Tunnel Request message */ + /// Create Indirect Data Tunnel Request message CreateIndirectDataTunnelRequest = 166, - /** Create Indirect Data Tunnel Response message */ + /// Create Indirect Data Tunnel Response message CreateIndirectDataTunnelResponse = 167, - /** Delete Indirect Data Tunnel Request message */ + /// Delete Indirect Data Tunnel Request message DeleteIndirectDataTunnelRequest = 168, - /** Delete Indirect Data Tunnel Response message */ + /// Delete Indirect Data Tunnel Response message DeleteIndirectDataTunnelResponse = 169, - /** Release Access Bearers Request message */ + /// Release Access Bearers Request message ReleaseAccessBearersRequest = 170, - /** Release Access Bearers Response message */ + /// Release Access Bearers Response message ReleaseAccessBearersResponse = 171, - /** Downlink Data Notification message */ + /// Downlink Data Notification message DownlinkDataNotification = 176, - /** Downlink Data Acknowledge message */ + /// Downlink Data Acknowledge message DownlinkDataAcknowledge = 177, - /** PGW Restart Notification message */ + /// PGW Restart Notification message PGWRestartNotification = 179, - /** PGW Restart Acknowledge message */ + /// PGW Restart Acknowledge message PGWRestartAcknowledge = 180, - /** Update PDN Connection Request message */ + /// Update PDN Connection Request message UpdatePDNConnectionRequest = 200, - /** Update PDN Connection Response message */ + /// Update PDN Connection Response message UpdatePDNConnectionResponse = 201, - /** Modify Access Bearers Request message */ + /// Modify Access Bearers Request message ModifyAccessBearersRequest = 211, - /** Modify Access Bearers Response message */ + /// Modify Access Bearers Response message ModifyAccessBearersResponse = 212, - /** MMBS Session Start Request message */ + /// MMBS Session Start Request message MMBSSessionStartRequest = 231, - /** MMBS Session Start Response message */ + /// MMBS Session Start Response message MMBSSessionStartResponse = 232, - /** MMBS Session Update Request message */ + /// MMBS Session Update Request message MMBSSessionUpdateRequest = 233, - /** MMBS Session Update Response message */ + /// MMBS Session Update Response message MMBSSessionUpdateResponse = 234, - /** MMBS Session Stop Request message */ + /// MMBS Session Stop Request message MMBSSessionStopRequest = 235, - /** MMBS Session Stop Response message */ + /// MMBS Session Stop Response message MMBSSessionStopResponse = 236 }; GtpV2MessageType() = default; // cppcheck-suppress noExplicitConstructor - /** - * Construct GtpV2MessageType from Value enum - * @param[in] value the message type enum value - */ + /// Construct GtpV2MessageType from Value enum + /// @param[in] value the message type enum value constexpr GtpV2MessageType(Value value) : m_Value(value) {} - /** - * @return A string representation of the message type - */ + /// @return A string representation of the message type std::string toString() const; - /** - * A static method that creates GtpV2MessageType from an integer value - * @param[in] value The message type integer value - * @return The message type that corresponds to the integer value. If the integer value - * doesn't corresponds to any message type, GtpV2MessageType::Unknown is returned - */ + /// A static method that creates GtpV2MessageType from an integer value + /// @param[in] value The message type integer value + /// @return The message type that corresponds to the integer value. If the integer value + /// doesn't corresponds to any message type, GtpV2MessageType::Unknown is returned static GtpV2MessageType fromUintValue(uint8_t value); // Allow switch and comparisons. @@ -696,327 +617,315 @@ namespace pcpp Value m_Value = GtpV2MessageType::Unknown; }; - /** - * @class GtpV2InformationElement - * A wrapper class for GTPv2 information elements (IE). This class does not create or modify IEs, but rather - * serves as a wrapper and provides useful methods for retrieving data from them - */ + /// @class GtpV2InformationElement + /// A wrapper class for GTPv2 information elements (IE). This class does not create or modify IEs, but rather + /// serves as a wrapper and provides useful methods for retrieving data from them class GtpV2InformationElement : public TLVRecord { public: - /** - * GTPv2 Information Element (IE) types as defined in 3GPP TS 29.274 - */ + /// GTPv2 Information Element (IE) types as defined in 3GPP TS 29.274 enum class Type : uint8_t { - /** Unknown or reserved value */ + /// Unknown or reserved value Unknown = 0, - /** International Mobile Subscriber Identity */ + /// International Mobile Subscriber Identity Imsi = 1, - /** Indicates the result of a procedure */ + /// Indicates the result of a procedure Cause = 2, - /** Recovery counter for GTP path management */ + /// Recovery counter for GTP path management Recovery = 3, - /** Session Transfer Number for SRVCC */ + /// Session Transfer Number for SRVCC StnSr = 51, - /** Access Point Name */ + /// Access Point Name Apn = 71, - /** Aggregate Maximum Bit Rate */ + /// Aggregate Maximum Bit Rate Ambr = 72, - /** EPS Bearer ID */ + /// EPS Bearer ID Ebi = 73, - /** IPv4/IPv6 Address */ + /// IPv4/IPv6 Address IpAddress = 74, - /** Mobile Equipment Identity (IMEI or IMEISV) */ + /// Mobile Equipment Identity (IMEI or IMEISV) Mei = 75, - /** Mobile Station International Subscriber Directory Number */ + /// Mobile Station International Subscriber Directory Number Msisdn = 76, - /** Indication flags for various features and capabilities */ + /// Indication flags for various features and capabilities Indication = 77, - /** Protocol Configuration Options */ + /// Protocol Configuration Options Pco = 78, - /** PDN Address Allocation */ + /// PDN Address Allocation Paa = 79, - /** Bearer Level Quality of Service */ + /// Bearer Level Quality of Service BearerQos = 80, - /** Flow Level Quality of Service */ + /// Flow Level Quality of Service FlowQos = 81, - /** Radio Access Technology Type */ + /// Radio Access Technology Type RatType = 82, - /** Current PLMN and MME identifier */ + /// Current PLMN and MME identifier ServingNetwork = 83, - /** Bearer Traffic Flow Template */ + /// Bearer Traffic Flow Template BearerTft = 84, - /** Traffic Aggregation Description */ + /// Traffic Aggregation Description Tad = 85, - /** User Location Information */ + /// User Location Information Uli = 86, - /** Fully Qualified TEID */ + /// Fully Qualified TEID FTeid = 87, - /** Temporary Mobile Subscriber Identity */ + /// Temporary Mobile Subscriber Identity Tmsi = 88, - /** Global Core Network ID */ + /// Global Core Network ID GlobalCnId = 89, - /** S103 PDN Data Forwarding Info */ + /// S103 PDN Data Forwarding Info S103PdnDataForwardingInfo = 90, - /** S1-U Data Forwarding Info */ + /// S1-U Data Forwarding Info S1UDataForwardingInfo = 91, - /** Delay Value in integer multiples of 50 milliseconds */ + /// Delay Value in integer multiples of 50 milliseconds DelayValue = 92, - /** Bearer Context */ + /// Bearer Context BearerContext = 93, - /** Charging ID for this PDP context */ + /// Charging ID for this PDP context ChargingId = 94, - /** Charging Characteristics */ + /// Charging Characteristics ChargingCharacteristics = 95, - /** Trace Information */ + /// Trace Information TraceInformation = 96, - /** Bearer Flags */ + /// Bearer Flags BearerFlags = 97, - /** PDN Type (IPv4, IPv6, IPv4v6) */ + /// PDN Type (IPv4, IPv6, IPv4v6) PdnType = 99, - /** Procedure Transaction ID */ + /// Procedure Transaction ID Pti = 100, - /** MM Context (GSM Key and Triplets) */ + /// MM Context (GSM Key and Triplets) MmContext1 = 103, - /** MM Context (UMTS Key, Used Cipher and Quintuplets) */ + /// MM Context (UMTS Key, Used Cipher and Quintuplets) MmContext2 = 104, - /** MM Context (GSM Key, Used Cipher and Quintuplets) */ + /// MM Context (GSM Key, Used Cipher and Quintuplets) MmContext3 = 105, - /** MM Context (UMTS Key and Quintuplets) */ + /// MM Context (UMTS Key and Quintuplets) MmContext4 = 106, - /** MM Context (EPS Security Context, Quadruplets and Quintuplets) */ + /// MM Context (EPS Security Context, Quadruplets and Quintuplets) MmContext5 = 107, - /** MM Context (UMTS Key, Quadruplets and Quintuplets) */ + /// MM Context (UMTS Key, Quadruplets and Quintuplets) MmContext6 = 108, - /** PDN Connection */ + /// PDN Connection PdnConnection = 109, - /** PDU Numbers */ + /// PDU Numbers PduNumbers = 110, - /** Packet TMSI */ + /// Packet TMSI PTmsi = 111, - /** P-TMSI Signature */ + /// P-TMSI Signature PTmsiSignature = 112, - /** Hop Counter */ + /// Hop Counter HopCounter = 113, - /** UE Time Zone */ + /// UE Time Zone UeTimeZone = 114, - /** Trace Reference */ + /// Trace Reference TraceReference = 115, - /** Complete Request Message */ + /// Complete Request Message CompleteRequestMessage = 116, - /** Globally Unique Temporary Identity */ + /// Globally Unique Temporary Identity Guti = 117, - /** F-Container */ + /// F-Container FContainer = 118, - /** F-Cause */ + /// F-Cause FCause = 119, - /** PLMN Identity */ + /// PLMN Identity PlmnId = 120, - /** Target Identification */ + /// Target Identification TargetIdentification = 121, - /** Packet Flow ID */ + /// Packet Flow ID PacketFlowId = 123, - /** RAB Context */ + /// RAB Context RabContext = 124, - /** Source RNC PDCP Context Info */ + /// Source RNC PDCP Context Info SourceRncPdcpContextInfo = 125, - /** Port Number */ + /// Port Number PortNumber = 126, - /** APN Restriction */ + /// APN Restriction ApnRestriction = 127, - /** Selection Mode */ + /// Selection Mode SelectionMode = 128, - /** Source Identification */ + /// Source Identification SourceIdentification = 129, - /** Change Reporting Action */ + /// Change Reporting Action ChangeReportingAction = 131, - /** Fully Qualified PDN Connection Set Identifier */ + /// Fully Qualified PDN Connection Set Identifier FqCsid = 132, - /** Channel Needed */ + /// Channel Needed ChannelNeeded = 133, - /** eMLPP Priority */ + /// eMLPP Priority EmlppPriority = 134, - /** Node Type */ + /// Node Type NodeType = 135, - /** Fully Qualified Domain Name */ + /// Fully Qualified Domain Name Fqdn = 136, - /** Transaction Identifier */ + /// Transaction Identifier Ti = 137, - /** MBMS Session Duration */ + /// MBMS Session Duration MbmsSessionDuration = 138, - /** MBMS Service Area */ + /// MBMS Service Area MbmsServiceArea = 139, - /** MBMS Session Identifier */ + /// MBMS Session Identifier MbmsSessionIdentifier = 140, - /** MBMS Flow Identifier */ + /// MBMS Flow Identifier MbmsFlowIdentifier = 141, - /** MBMS IP Multicast Distribution */ + /// MBMS IP Multicast Distribution MbmsIpMulticastDistribution = 142, - /** MBMS Distribution Acknowledge */ + /// MBMS Distribution Acknowledge MbmsDistributionAcknowledge = 143, - /** RF Selection Priority Index */ + /// RF Selection Priority Index RfspIndex = 144, - /** User CSG Information */ + /// User CSG Information Uci = 145, - /** CSG Information Reporting Action */ + /// CSG Information Reporting Action CsgInformationReportingAction = 146, - /** CSG ID */ + /// CSG ID CsgId = 147, - /** CSG Membership Indication */ + /// CSG Membership Indication Cmi = 148, - /** Service Indicator */ + /// Service Indicator ServiceIndicator = 149, - /** Detach Type */ + /// Detach Type DetachType = 150, - /** Local Distinguished Name */ + /// Local Distinguished Name Ldn = 151, - /** Node Features */ + /// Node Features NodeFeatures = 152, - /** MBMS Time To Data Transfer */ + /// MBMS Time To Data Transfer MbmsTimeToDataTransfer = 153, - /** Throttling */ + /// Throttling Throttling = 154, - /** Allocation Retention Priority */ + /// Allocation Retention Priority Arp = 155, - /** EPC Timer */ + /// EPC Timer EpcTimer = 156, - /** Signalling Priority Indication */ + /// Signalling Priority Indication SignallingPriorityIndication = 157, - /** Temporary Mobile Group Identity */ + /// Temporary Mobile Group Identity Tmgi = 158, - /** Additional MM Context For SRVCC */ + /// Additional MM Context For SRVCC AdditionalMmContextForSrvcc = 159, - /** Additional Flags For SRVCC */ + /// Additional Flags For SRVCC AdditionalFlagsForSrvcc = 160, - /** MDT Configuration */ + /// MDT Configuration MdtConfiguration = 162, - /** Additional Protocol Configuration Options */ + /// Additional Protocol Configuration Options Apco = 163, - /** Absolute Time of MBMS Data Transfer */ + /// Absolute Time of MBMS Data Transfer AbsoluteTimeOfMbmsDataTransfer = 164, - /** H(e)NB Information Reporting */ + /// H(e)NB Information Reporting HenbInformationReporting = 165, - /** IPv4 Configuration Parameters */ + /// IPv4 Configuration Parameters Ipv4ConfigurationParameters = 166, - /** Change To Report Flags */ + /// Change To Report Flags ChangeToReportFlags = 167, - /** Action Indication */ + /// Action Indication ActionIndication = 168, - /** TWAN Identifier */ + /// TWAN Identifier TwanIdentifier = 169, - /** ULI Timestamp */ + /// ULI Timestamp UliTimestamp = 170, - /** MBMS Flags */ + /// MBMS Flags MbmsFlags = 171, - /** RAN/NAS Cause */ + /// RAN/NAS Cause RanNasCause = 172, - /** CN Operator Selection Entity */ + /// CN Operator Selection Entity CnOperatorSelectionEntity = 173, - /** Trusted WLAN Mode Indication */ + /// Trusted WLAN Mode Indication Twmi = 174, - /** Node Number */ + /// Node Number NodeNumber = 175, - /** Node Identifier */ + /// Node Identifier NodeIdentifier = 176, - /** Presence Reporting Area Action */ + /// Presence Reporting Area Action PresenceReportingAreaAction = 177, - /** Presence Reporting Area Information */ + /// Presence Reporting Area Information PresenceReportingAreaInformation = 178, - /** TWAN Identifier Timestamp */ + /// TWAN Identifier Timestamp TwanIdentifierTimestamp = 179, - /** Overload Control Information */ + /// Overload Control Information OverloadControlInformation = 180, - /** Load Control Information */ + /// Load Control Information LoadControlInformation = 181, - /** Metric */ + /// Metric Metric = 182, - /** Sequence Number */ + /// Sequence Number SequenceNumber = 183, - /** APN and Relative Capacity */ + /// APN and Relative Capacity ApnAndRelativeCapacity = 184, - /** WLAN Offloadability Indication */ + /// WLAN Offloadability Indication WlanOffloadabilityIndication = 185, - /** Paging and Service Information */ + /// Paging and Service Information PagingAndServiceInformation = 186, - /** Integer Number */ + /// Integer Number IntegerNumber = 187, - /** Millisecond Time Stamp */ + /// Millisecond Time Stamp MillisecondTimeStamp = 188, - /** Monitoring Event Information */ + /// Monitoring Event Information MonitoringEventInformation = 189, - /** ECGI List */ + /// ECGI List EcgiList = 190, - /** Remote UE Context */ + /// Remote UE Context RemoteUeContext = 191, - /** Remote User ID */ + /// Remote User ID RemoteUserId = 192, - /** Remote UE IP Information */ + /// Remote UE IP Information RemoteUeIpInformation = 193, - /** CIoT Optimizations Support Indication */ + /// CIoT Optimizations Support Indication CiotOptimizationsSupportIndication = 194, - /** SCEF PDN Connection */ + /// SCEF PDN Connection ScefPdnConnection = 195, - /** Header Compression Configuration */ + /// Header Compression Configuration HeaderCompressionConfiguration = 196, - /** Extended Protocol Configuration Options */ + /// Extended Protocol Configuration Options ExtendedPco = 197, - /** Serving PLMN Rate Control */ + /// Serving PLMN Rate Control ServingPlmnRateControl = 198, - /** Counter */ + /// Counter Counter = 199, - /** Mapped UE Usage Type */ + /// Mapped UE Usage Type MappedUeUsageType = 200, - /** Secondary RAT Usage Data Report */ + /// Secondary RAT Usage Data Report SecondaryRatUsageDataReport = 201, - /** UP Function Selection Indication Flags */ + /// UP Function Selection Indication Flags UpFunctionSelectionIndicationFlags = 202, - /** Maximum Packet Loss Rate */ + /// Maximum Packet Loss Rate MaximumPacketLossRate = 203, - /** APN Rate Control Status */ + /// APN Rate Control Status ApnRateControlStatus = 204, - /** Extended Trace Information */ + /// Extended Trace Information ExtendedTraceInformation = 205, - /** Monitoring Event Extension Information */ + /// Monitoring Event Extension Information MonitoringEventExtensionInformation = 206, - /** Additional RRM Policy Index */ + /// Additional RRM Policy Index AdditionalRrmPolicyIndex = 207, - /** V2X Context */ + /// V2X Context V2xContext = 208, - /** PC5 QoS Parameters */ + /// PC5 QoS Parameters Pc5QosParameters = 209, - /** Services Authorized */ + /// Services Authorized ServicesAuthorized = 210, - /** Bit Rate */ + /// Bit Rate BitRate = 211, - /** PC5 QoS Flow */ + /// PC5 QoS Flow Pc5QosFlow = 212, - /** SGi PtP Tunnel Address */ + /// SGi PtP Tunnel Address SgiPtpTunnelAddress = 213 }; - /** - * A c'tor for this class that gets a pointer to the IE raw data (byte array) - * @param[in] infoElementRawData A pointer to the IE raw data - */ + /// A c'tor for this class that gets a pointer to the IE raw data (byte array) + /// @param[in] infoElementRawData A pointer to the IE raw data explicit GtpV2InformationElement(uint8_t* infoElementRawData) : TLVRecord(infoElementRawData) {} ~GtpV2InformationElement() override = default; - /** - * @return The information element (IE) type - */ + /// @return The information element (IE) type GtpV2InformationElement::Type getIEType(); - /** - * @return The IE CR flag - */ + /// @return The IE CR flag uint8_t getCRFlag(); - /** - * @return The IE instance value - */ + /// @return The IE instance value uint8_t getInstance(); // implement abstract methods @@ -1031,29 +940,23 @@ namespace pcpp size_t getDataSize() const override; }; - /** - * @class GtpV2InformationElementBuilder - * A class for building GTPv2 information elements (IE). This builder receives the IE parameters in its c'tor, - * builds the IE raw buffer and provides a build() method to get a GtpV2InformationElement object out of it - */ + /// @class GtpV2InformationElementBuilder + /// A class for building GTPv2 information elements (IE). This builder receives the IE parameters in its c'tor, + /// builds the IE raw buffer and provides a build() method to get a GtpV2InformationElement object out of it class GtpV2InformationElementBuilder : public TLVRecordBuilder { public: - /** - * A c'tor for building information elements (IE) which their value is a byte array. The GtpV2InformationElement - * object can be later retrieved by calling build(). - * @param[in] infoElementType Information elements (IE) type - * @param[in] crFlag CR flag value - * @param[in] instance Instance value - * @param[in] infoElementValue A byte array of the IE value - */ + /// A c'tor for building information elements (IE) which their value is a byte array. The + /// GtpV2InformationElement object can be later retrieved by calling build(). + /// @param[in] infoElementType Information elements (IE) type + /// @param[in] crFlag CR flag value + /// @param[in] instance Instance value + /// @param[in] infoElementValue A byte array of the IE value GtpV2InformationElementBuilder(GtpV2InformationElement::Type infoElementType, const std::bitset<4>& crFlag, const std::bitset<4>& instance, const std::vector& infoElementValue); - /** - * Build the GtpV2InformationElement object out of the parameters defined in the c'tor - * @return The GtpV2InformationElement object - */ + /// Build the GtpV2InformationElement object out of the parameters defined in the c'tor + /// @return The GtpV2InformationElement object GtpV2InformationElement build() const; private: @@ -1061,203 +964,147 @@ namespace pcpp std::bitset<4> m_Instance; }; - /** - * @class GtpV2Layer - * A class representing the GTPv2 defined in 3GPP TS 29.274 - */ + /// @class GtpV2Layer + /// A class representing the GTPv2 defined in 3GPP TS 29.274 class GtpV2Layer : public Layer { public: ~GtpV2Layer() override = default; - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in GtpV2Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, GTPv2) {} - /** - * A constructor that creates a new GTPv2 message - * @param messageType GTPv2 message type - * @param sequenceNumber Message sequence number - * @param setTeid Whether or not to set Tunnel Endpoint Identifier in this message - * @param teid Tunnel Endpoint Identifier value. Only used if setTeid is set to true - * @param setMessagePriority Whether or not to set Message Priority in this message - * @param messagePriority Message Priority. Only used if setMessagePriority to true - */ + /// A constructor that creates a new GTPv2 message + /// @param messageType GTPv2 message type + /// @param sequenceNumber Message sequence number + /// @param setTeid Whether or not to set Tunnel Endpoint Identifier in this message + /// @param teid Tunnel Endpoint Identifier value. Only used if setTeid is set to true + /// @param setMessagePriority Whether or not to set Message Priority in this message + /// @param messagePriority Message Priority. Only used if setMessagePriority to true GtpV2Layer(GtpV2MessageType messageType, uint32_t sequenceNumber, bool setTeid = false, uint32_t teid = 0, bool setMessagePriority = false, std::bitset<4> messagePriority = 0); - /** - * A static method that checks whether the port is considered as GTPv2 - * @param[in] port The port number to be checked - * @return True if the port matches those associated with the GTPv2 protocol - */ + /// A static method that checks whether the port is considered as GTPv2 + /// @param[in] port The port number to be checked + /// @return True if the port matches those associated with the GTPv2 protocol static bool isGTPv2Port(uint16_t port) { return port == 2123; } - /** - * A static method that takes a byte array and detects whether it is a GTPv2 message - * @param[in] data A byte array - * @param[in] dataSize The byte array size (in bytes) - * @return True if the data is identified as GTPv2 message - */ + /// A static method that takes a byte array and detects whether it is a GTPv2 message + /// @param[in] data A byte array + /// @param[in] dataSize The byte array size (in bytes) + /// @return True if the data is identified as GTPv2 message static bool isDataValid(const uint8_t* data, size_t dataSize); - /** - * @return The message type - */ + /// @return The message type GtpV2MessageType getMessageType() const; - /** - * Set message type - * @param type The message type to set - */ + /// Set message type + /// @param type The message type to set void setMessageType(const GtpV2MessageType& type); - /** - * @return The message length as set in the layer. Note it is different from getHeaderLen() because the later - * refers to the entire layers length, and this property excludes the mandatory part of the GTP-C header - * (the first 4 octets) - */ + /// @return The message length as set in the layer. Note it is different from getHeaderLen() because the later + /// refers to the entire layers length, and this property excludes the mandatory part of the GTP-C header + /// (the first 4 octets) uint16_t getMessageLength() const; - /** - * @return True if there is another GTPv2 message piggybacking on this message (will appear as another - * GtpV2Layer after this layer) - */ + /// @return True if there is another GTPv2 message piggybacking on this message (will appear as another + /// GtpV2Layer after this layer) bool isPiggybacking() const; - /** - * Get the Tunnel Endpoint Identifier (TEID) if exists - * @return A pair of 2 values; the first value states whether TEID exists, and if it's true the second value - * contains the TEID value - */ + /// Get the Tunnel Endpoint Identifier (TEID) if exists + /// @return A pair of 2 values; the first value states whether TEID exists, and if it's true the second value + /// contains the TEID value std::pair getTeid() const; - /** - * Set Tunnel Endpoint Identifier (TEID) - * @param teid The TEID value to set - */ + /// Set Tunnel Endpoint Identifier (TEID) + /// @param teid The TEID value to set void setTeid(uint32_t teid); - /** - * Unset Tunnel Endpoint Identifier (TEID) if exists in the layer (otherwise does nothing) - */ + /// Unset Tunnel Endpoint Identifier (TEID) if exists in the layer (otherwise does nothing) void unsetTeid(); - /** - * @return The sequence number - */ + /// @return The sequence number uint32_t getSequenceNumber() const; - /** - * Set the sequence number - * @param sequenceNumber The sequence number value to set - */ + /// Set the sequence number + /// @param sequenceNumber The sequence number value to set void setSequenceNumber(uint32_t sequenceNumber); - /** - * Get the Message Property if exists - * @return A pair of 2 values; the first value states whether Message Priority exists, and if it's true - * the second value contains the Message Priority value - */ + /// Get the Message Property if exists + /// @return A pair of 2 values; the first value states whether Message Priority exists, and if it's true + /// the second value contains the Message Priority value std::pair getMessagePriority() const; - /** - * Set Message Priority - * @param messagePriority The Message Priority value to set - */ + /// Set Message Priority + /// @param messagePriority The Message Priority value to set void setMessagePriority(const std::bitset<4>& messagePriority); - /** - * Unset Message Priority if exists in the layer (otherwise does nothing) - */ + /// Unset Message Priority if exists in the layer (otherwise does nothing) void unsetMessagePriority(); - /** - * @return The first GTPv2 Information Element (IE). If there are no IEs the returned value will contain - * a logical null (GtpV2InformationElement#isNull() == true) - */ + /// @return The first GTPv2 Information Element (IE). If there are no IEs the returned value will contain + /// a logical null (GtpV2InformationElement#isNull() == true) GtpV2InformationElement getFirstInformationElement() const; - /** - * Get the GTPv2 Information Element (IE) that comes after a given IE. If the given IE was the last one, the - * returned value will contain a logical null (GtpV2InformationElement#isNull() == true) - * @param[in] infoElement A given GTPv2 Information Element - * @return A GtpV2InformationElement object containing the IE that comes next, or logical null if the given - * IE: (1) is the last one; (2) contains a logical null or (3) doesn't belong to this packet - */ + /// Get the GTPv2 Information Element (IE) that comes after a given IE. If the given IE was the last one, the + /// returned value will contain a logical null (GtpV2InformationElement#isNull() == true) + /// @param[in] infoElement A given GTPv2 Information Element + /// @return A GtpV2InformationElement object containing the IE that comes next, or logical null if the given + /// IE: (1) is the last one; (2) contains a logical null or (3) doesn't belong to this packet GtpV2InformationElement getNextInformationElement(GtpV2InformationElement infoElement) const; - /** - * Get a GTPv2 Information Element (IE) by type - * @param[in] infoElementType GTPv2 Information Element (IE) type - * @return A GtpV2InformationElement object containing the first IE that matches this type, or logical - * null (GtpV2InformationElement#isNull() == true) if no such IE found - */ + /// Get a GTPv2 Information Element (IE) by type + /// @param[in] infoElementType GTPv2 Information Element (IE) type + /// @return A GtpV2InformationElement object containing the first IE that matches this type, or logical + /// null (GtpV2InformationElement#isNull() == true) if no such IE found GtpV2InformationElement getInformationElement(GtpV2InformationElement::Type infoElementType) const; - /** - * @return The number of GTPv2 Information Elements (IEs) in this layer - */ + /// @return The number of GTPv2 Information Elements (IEs) in this layer size_t getInformationElementCount() const; - /** - * Add a new Information Element (IE) at the end of the layer - * @param[in] infoElementBuilder A GtpV2InformationElementBuilder object that contains the requested - * IE data to add - * @return A GtpV2InformationElement object containing the newly added IE data or logical null - * (GtpV2InformationElement#isNull() == true) if addition failed - */ + /// Add a new Information Element (IE) at the end of the layer + /// @param[in] infoElementBuilder A GtpV2InformationElementBuilder object that contains the requested + /// IE data to add + /// @return A GtpV2InformationElement object containing the newly added IE data or logical null + /// (GtpV2InformationElement#isNull() == true) if addition failed GtpV2InformationElement addInformationElement(const GtpV2InformationElementBuilder& infoElementBuilder); - /** - * Add a new Information Element (IE) after an existing one - * @param[in] infoElementBuilder A GtpV2InformationElementBuilder object that contains the requested - * IE data to add - * @param[in] infoElementType The IE type which the newly added option will come after - * @return A GtpV2InformationElement object containing the newly added IE data or logical null - * (GtpV2InformationElement#isNull() == true) if addition failed - */ + /// Add a new Information Element (IE) after an existing one + /// @param[in] infoElementBuilder A GtpV2InformationElementBuilder object that contains the requested + /// IE data to add + /// @param[in] infoElementType The IE type which the newly added option will come after + /// @return A GtpV2InformationElement object containing the newly added IE data or logical null + /// (GtpV2InformationElement#isNull() == true) if addition failed GtpV2InformationElement addInformationElementAfter(const GtpV2InformationElementBuilder& infoElementBuilder, GtpV2InformationElement::Type infoElementType); - /** - * Remove an existing Information Element (IE) from the layer - * @param[in] infoElementType The IE type to remove - * @return True if the IE was successfully removed or false if type wasn't found or if removal failed - */ + /// Remove an existing Information Element (IE) from the layer + /// @param[in] infoElementType The IE type to remove + /// @return True if the IE was successfully removed or false if type wasn't found or if removal failed bool removeInformationElement(GtpV2InformationElement::Type infoElementType); - /** - * Remove all Information Elements (IE) in this layer - * @return True if all IEs were successfully removed or false if removal failed for some reason - */ + /// Remove all Information Elements (IE) in this layer + /// @return True if all IEs were successfully removed or false if removal failed for some reason bool removeAllInformationElements(); // implement abstract methods - /** - * Identifies if the next layer is GTPv2 piggyback. Otherwise sets PayloadLayer - */ + /// Identifies if the next layer is GTPv2 piggyback. Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * @return The size of the GTPv2 header including its Information Elements (IE) - */ + /// @return The size of the GTPv2 header including its Information Elements (IE) size_t getHeaderLen() const override; - /** - * Computes the piggybacking flag by checking if the next layer is also a GTPv2 message - */ + /// Computes the piggybacking flag by checking if the next layer is also a GTPv2 message void computeCalculateFields() override; std::string toString() const override; diff --git a/Packet++/header/HttpLayer.h b/Packet++/header/HttpLayer.h index cc22499b44..fa5a2c1dcd 100644 --- a/Packet++/header/HttpLayer.h +++ b/Packet++/header/HttpLayer.h @@ -7,55 +7,50 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * An enum for HTTP version - */ + /// An enum for HTTP version enum HttpVersion { - /** HTTP/0.9 */ + /// HTTP/0.9 ZeroDotNine, - /** HTTP/1.0 */ + /// HTTP/1.0 OneDotZero, - /** HTTP/1.1 */ + /// HTTP/1.1 OneDotOne, - /** Unknown HTTP version */ + /// Unknown HTTP version HttpVersionUnknown }; // some popular HTTP fields - /** Host field */ + /// Host field #define PCPP_HTTP_HOST_FIELD "Host" - /** Connection field */ + /// Connection field #define PCPP_HTTP_CONNECTION_FIELD "Connection" - /** User-Agent field */ + /// User-Agent field #define PCPP_HTTP_USER_AGENT_FIELD "User-Agent" - /** Referer field */ + /// Referer field #define PCPP_HTTP_REFERER_FIELD "Referer" - /** Accept field */ + /// Accept field #define PCPP_HTTP_ACCEPT_FIELD "Accept" - /** Accept-Encoding field */ + /// Accept-Encoding field #define PCPP_HTTP_ACCEPT_ENCODING_FIELD "Accept-Encoding" - /** Accept-Language field */ + /// Accept-Language field #define PCPP_HTTP_ACCEPT_LANGUAGE_FIELD "Accept-Language" - /** Cookie field */ + /// Cookie field #define PCPP_HTTP_COOKIE_FIELD "Cookie" - /** Content-Length field */ + /// Content-Length field #define PCPP_HTTP_CONTENT_LENGTH_FIELD "Content-Length" - /** Content-Encoding field */ + /// Content-Encoding field #define PCPP_HTTP_CONTENT_ENCODING_FIELD "Content-Encoding" - /** Content-Type field */ + /// Content-Type field #define PCPP_HTTP_CONTENT_TYPE_FIELD "Content-Type" - /** Transfer-Encoding field */ + /// Transfer-Encoding field #define PCPP_HTTP_TRANSFER_ENCODING_FIELD "Transfer-Encoding" - /** Server field */ + /// Server field #define PCPP_HTTP_SERVER_FIELD "Server" // -------- classes to be defined later ----------------- @@ -65,21 +60,17 @@ namespace pcpp // -------- Class HttpMessage ----------------- - /** - * @class HttpMessage - * Represents a general HTTP message. It's an abstract class and cannot be instantiated. It's inherited by - * HttpRequestLayer and HttpResponseLayer - */ + /// @class HttpMessage + /// Represents a general HTTP message. It's an abstract class and cannot be instantiated. It's inherited by + /// HttpRequestLayer and HttpResponseLayer class HttpMessage : public TextBasedProtocolMessage { public: ~HttpMessage() override = default; - /** - * A static method that checks whether the port is considered as HTTP - * @param[in] port The port number to be checked - * @return True if the port matches those associated with the HTTP protocol - */ + /// A static method that checks whether the port is considered as HTTP + /// @param[in] port The port number to be checked + /// @return True if the port matches those associated with the HTTP protocol static bool isHttpPort(uint16_t port) { return port == 80 || port == 8080; @@ -125,99 +116,85 @@ namespace pcpp // -------- Class HttpRequestLayer ----------------- - /** - * @class HttpRequestLayer - * Represents an HTTP request header and inherits all basic functionality of HttpMessage and - * TextBasedProtocolMessage. The functionality that is added for this class is the HTTP first line concept. An HTTP - * request has the following first line: GET /bla/blabla.asp HTTP/1.1 Since it's not an "ordinary" HTTP - * field, it requires a special treatment and gets a class of it's own: HttpRequestFirstLine. Unlike most L2-4 - * protocols, an HTTP request header can spread over more than 1 packet. PcapPlusPlus currently doesn't support a - * header that is spread over more than 1 packet so in such cases: 1) only the first packet will be parsed as - * HttpRequestLayer (the other packets won't be recognized as HttpRequestLayer) and 2) the HTTP header for the first - * packet won't be complete (as it continues in the following packets), this why PcapPlusPlus can indicate that HTTP - * request header is complete or not(doesn't end with "\r\n\r\n" or "\n\n") using HttpMessage#isHeaderComplete() - */ + /// @class HttpRequestLayer + /// Represents an HTTP request header and inherits all basic functionality of HttpMessage and + /// TextBasedProtocolMessage. The functionality that is added for this class is the HTTP first line concept. An HTTP + /// request has the following first line: GET /bla/blabla.asp HTTP/1.1 Since it's not an "ordinary" HTTP + /// field, it requires a special treatment and gets a class of it's own: HttpRequestFirstLine. Unlike most L2-4 + /// protocols, an HTTP request header can spread over more than 1 packet. PcapPlusPlus currently doesn't support a + /// header that is spread over more than 1 packet so in such cases: 1) only the first packet will be parsed as + /// HttpRequestLayer (the other packets won't be recognized as HttpRequestLayer) and 2) the HTTP header for the + /// first packet won't be complete (as it continues in the following packets), this why PcapPlusPlus can indicate + /// that HTTP request header is complete or not(doesn't end with "\r\n\r\n" or "\n\n") using + /// HttpMessage#isHeaderComplete() class HttpRequestLayer : public HttpMessage { friend class HttpRequestFirstLine; public: - /** - * HTTP request methods - */ + /// HTTP request methods enum HttpMethod { - /** GET */ + /// GET HttpGET, - /** HEAD */ + /// HEAD HttpHEAD, - /** POST */ + /// POST HttpPOST, - /** PUT */ + /// PUT HttpPUT, - /** DELETE */ + /// DELETE HttpDELETE, - /** TRACE */ + /// TRACE HttpTRACE, - /** OPTIONS */ + /// OPTIONS HttpOPTIONS, - /** CONNECT */ + /// CONNECT HttpCONNECT, - /** PATCH */ + /// PATCH HttpPATCH, - /** Unknown HTTP method */ + /// Unknown HTTP method HttpMethodUnknown }; - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in HttpRequestLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * A constructor that allocates a new HTTP request header with only the first line filled. Object will be - * created without further fields. The user can then add fields using addField() methods - * @param[in] method The HTTP method used in this HTTP request - * @param[in] uri The URI of the first line - * @param[in] version HTTP version to be used in this request - */ + /// A constructor that allocates a new HTTP request header with only the first line filled. Object will be + /// created without further fields. The user can then add fields using addField() methods + /// @param[in] method The HTTP method used in this HTTP request + /// @param[in] uri The URI of the first line + /// @param[in] version HTTP version to be used in this request HttpRequestLayer(HttpMethod method, const std::string& uri, HttpVersion version); ~HttpRequestLayer() override; - /** - * A copy constructor for this layer. This copy constructor inherits base copy constructor - * HttpMessage#HttpMessage() and add the functionality of copying the first line as well - * @param[in] other The instance to copy from - */ + /// A copy constructor for this layer. This copy constructor inherits base copy constructor + /// HttpMessage#HttpMessage() and add the functionality of copying the first line as well + /// @param[in] other The instance to copy from HttpRequestLayer(const HttpRequestLayer& other); - /** - * An assignment operator overload for this layer. This method inherits base assignment operator - * HttpMessage#operator=() and add the functionality of copying the first line as well - * @param[in] other The instance to copy from - * @return A reference to the assignee - */ + /// An assignment operator overload for this layer. This method inherits base assignment operator + /// HttpMessage#operator=() and add the functionality of copying the first line as well + /// @param[in] other The instance to copy from + /// @return A reference to the assignee HttpRequestLayer& operator=(const HttpRequestLayer& other); - /** - * @return A pointer to the first line instance for this message - */ + /// @return A pointer to the first line instance for this message HttpRequestFirstLine* getFirstLine() const { return m_FirstLine; } - /** - * The URL is hostname+uri. So given the following URL, for example: "www.cnn.com/main.html", the hostname is - * "www.cnn.com" and the URI is "/.main.html". URI and hostname are split to 2 different places inside the HTTP - * request packet: URI is in the first line and hostname is in "HOST" field. This methods concatenates the - * hostname and URI to the full URL - * @return The URL of the HTTP request message - */ + /// The URL is hostname+uri. So given the following URL, for example: "www.cnn.com/main.html", the hostname is + /// "www.cnn.com" and the URI is "/.main.html". URI and hostname are split to 2 different places inside the HTTP + /// request packet: URI is in the first line and hostname is in "HOST" field. This methods concatenates the + /// hostname and URI to the full URL + /// @return The URL of the HTTP request message std::string getUrl() const; // implement Layer's abstract methods @@ -229,203 +206,199 @@ namespace pcpp // -------- Class HttpResponseStatusCode ----------------- - /** - * @struct HttpResponseStatusCode - * @brief The enum wrapper class of HTTP response status codes - */ + /// @struct HttpResponseStatusCode + /// @brief The enum wrapper class of HTTP response status codes class HttpResponseStatusCode { public: - /** - * @brief Define enum types and the corresponding int values - */ + /// @brief Define enum types and the corresponding int values enum Value : int { - /** 100 Continue*/ + /// 100 Continue Http100Continue = 100, - /** 101 Switching Protocols*/ + /// 101 Switching Protocols Http101SwitchingProtocols = 101, - /** 102 Processing */ + /// 102 Processing Http102Processing = 102, - /** 103 Early Hints */ + /// 103 Early Hints Http103EarlyHints = 103, - /** 104-199 Unassigned */ + /// 104-199 Unassigned - /** 200 OK */ + /// 200 OK Http200OK = 200, - /** 201 Created */ + /// 201 Created Http201Created = 201, - /** 202 Accepted */ + /// 202 Accepted Http202Accepted = 202, - /** 203 Non-Authoritative Information */ + /// 203 Non-Authoritative Information Http203NonAuthoritativeInformation = 203, - /** 204 No Content*/ + /// 204 No Content Http204NoContent = 204, - /** 205 Reset Content*/ + /// 205 Reset Content Http205ResetContent = 205, - /** 206 Partial Content */ + /// 206 Partial Content Http206PartialContent = 206, - /** 207 Multi-Status */ + /// 207 Multi-Status Http207MultiStatus = 207, - /** 208 Already Reported */ + /// 208 Already Reported Http208AlreadyReported = 208, - /** 209-225 Unassigned */ - /** 226 IM Used */ + /// 209-225 Unassigned + /// 226 IM Used Http226IMUsed = 226, - /** 227-299 Unassigned */ + /// 227-299 Unassigned - /** 300 Multiple Choices */ + /// 300 Multiple Choices Http300MultipleChoices = 300, - /** 301 Moved Permanently */ + /// 301 Moved Permanently Http301MovedPermanently = 301, - /** 302 (various messages) */ + /// 302 (various messages) Http302 = 302, - /** 303 See Other */ + /// 303 See Other Http303SeeOther = 303, - /** 304 Not Modified */ + /// 304 Not Modified Http304NotModified = 304, - /** 305 Use Proxy */ + /// 305 Use Proxy Http305UseProxy = 305, - /** 306 Switch Proxy */ + /// 306 Switch Proxy Http306SwitchProxy = 306, - /** 307 Temporary Redirect */ + /// 307 Temporary Redirect Http307TemporaryRedirect = 307, - /** 308 Permanent Redirect, */ + /// 308 Permanent Redirect, Http308PermanentRedirect = 308, - /** 309-399 Unassigned */ + /// 309-399 Unassigned - /** 400 Bad Request */ + /// 400 Bad Request Http400BadRequest = 400, - /** 401 Unauthorized */ + /// 401 Unauthorized Http401Unauthorized = 401, - /** 402 Payment Required */ + /// 402 Payment Required Http402PaymentRequired = 402, - /** 403 Forbidden */ + /// 403 Forbidden Http403Forbidden = 403, - /** 404 Not Found */ + /// 404 Not Found Http404NotFound = 404, - /** 405 Method Not Allowed */ + /// 405 Method Not Allowed Http405MethodNotAllowed = 405, - /** 406 Not Acceptable */ + /// 406 Not Acceptable Http406NotAcceptable = 406, - /** 407 Proxy Authentication Required */ + /// 407 Proxy Authentication Required Http407ProxyAuthenticationRequired = 407, - /** 408 Request Timeout */ + /// 408 Request Timeout Http408RequestTimeout = 408, - /** 409 Conflict */ + /// 409 Conflict Http409Conflict = 409, - /** 410 Gone */ + /// 410 Gone Http410Gone = 410, - /** 411 Length Required */ + /// 411 Length Required Http411LengthRequired = 411, - /** 412 Precondition Failed */ + /// 412 Precondition Failed Http412PreconditionFailed = 412, - /** 413 RequestEntity Too Large */ + /// 413 RequestEntity Too Large Http413RequestEntityTooLarge = 413, - /** 414 Request-URI Too Long */ + /// 414 Request-URI Too Long Http414RequestURITooLong = 414, - /** 415 Unsupported Media Type */ + /// 415 Unsupported Media Type Http415UnsupportedMediaType = 415, - /** 416 Requested Range Not Satisfiable */ + /// 416 Requested Range Not Satisfiable Http416RequestedRangeNotSatisfiable = 416, - /** 417 Expectation Failed */ + /// 417 Expectation Failed Http417ExpectationFailed = 417, - /** 418 I'm a teapot */ + /// 418 I'm a teapot Http418ImATeapot = 418, - /** 419 Authentication Timeout */ + /// 419 Authentication Timeout Http419AuthenticationTimeout = 419, - /** 420 (various messages) */ + /// 420 (various messages) Http420 = 420, - /** 421 Misdirected Request */ + /// 421 Misdirected Request Http421MisdirectedRequest = 421, - /** 422 Unprocessable Entity */ + /// 422 Unprocessable Entity Http422UnprocessableEntity = 422, - /** 423 Locked */ + /// 423 Locked Http423Locked = 423, - /** 424 Failed Dependency */ + /// 424 Failed Dependency Http424FailedDependency = 424, - /** 425 Too Early */ + /// 425 Too Early Http425TooEarly = 425, - /** 426 Upgrade Required */ + /// 426 Upgrade Required Http426UpgradeRequired = 426, - /** 427 Unassigned */ - /** 428 Precondition Required */ + /// 427 Unassigned + /// 428 Precondition Required Http428PreconditionRequired = 428, - /** 429 Too Many Requests */ + /// 429 Too Many Requests Http429TooManyRequests = 429, - /** 430 Unassigned */ - /** 431 Request Header Fields Too Large */ + /// 430 Unassigned + /// 431 Request Header Fields Too Large Http431RequestHeaderFieldsTooLarge = 431, - /** 432-439 unassigned */ - /** 440 Login Timeout */ + /// 432-439 unassigned + /// 440 Login Timeout Http440LoginTimeout = 440, - /** 441-443 unassigned */ - /** 444 No Response */ + /// 441-443 unassigned + /// 444 No Response Http444NoResponse = 444, - /** 445-448 unassigned */ - /** 449 Retry With */ + /// 445-448 unassigned + /// 449 Retry With Http449RetryWith = 449, - /** 450 Blocked by Windows Parental Controls */ + /// 450 Blocked by Windows Parental Controls Http450BlockedByWindowsParentalControls = 450, - /** 451 (various messages) */ + /// 451 (various messages) Http451 = 451, - /** 452-493 unassigned */ - /** 494 Request Header Too Large */ + /// 452-493 unassigned + /// 494 Request Header Too Large Http494RequestHeaderTooLarge = 494, - /** 495 Cert Error */ + /// 495 Cert Error Http495CertError = 495, - /** 496 No Cert */ + /// 496 No Cert Http496NoCert = 496, - /** 497 HTTP to HTTPS */ + /// 497 HTTP to HTTPS Http497HTTPtoHTTPS = 497, - /** 498 Token expired/invalid */ + /// 498 Token expired/invalid Http498TokenExpiredInvalid = 498, - /** 499 (various messages) */ + /// 499 (various messages) Http499 = 499, - /** 500 Internal Server Error */ + /// 500 Internal Server Error Http500InternalServerError = 500, - /** 501 Not Implemented */ + /// 501 Not Implemented Http501NotImplemented = 501, - /** 502 Bad Gateway */ + /// 502 Bad Gateway Http502BadGateway = 502, - /** 503 Service Unavailable */ + /// 503 Service Unavailable Http503ServiceUnavailable = 503, - /** 504 Gateway Timeout */ + /// 504 Gateway Timeout Http504GatewayTimeout = 504, - /** 505 HTTP Version Not Supported */ + /// 505 HTTP Version Not Supported Http505HTTPVersionNotSupported = 505, - /** 506 Variant Also Negotiates */ + /// 506 Variant Also Negotiates Http506VariantAlsoNegotiates = 506, - /** 507 Insufficient Storage */ + /// 507 Insufficient Storage Http507InsufficientStorage = 507, - /** 508 Loop Detected */ + /// 508 Loop Detected Http508LoopDetected = 508, - /** 509 Bandwidth Limit Exceeded */ + /// 509 Bandwidth Limit Exceeded Http509BandwidthLimitExceeded = 509, - /** 510 Not Extended */ + /// 510 Not Extended Http510NotExtended = 510, - /** 511 Network Authentication Required */ + /// 511 Network Authentication Required Http511NetworkAuthenticationRequired = 511, - /** 512-519 unassigned */ - /** 520 Origin Error */ + /// 512-519 unassigned + /// 520 Origin Error Http520OriginError = 520, - /** 521 Web server is down */ + /// 521 Web server is down Http521WebServerIsDown = 521, - /** 522 Connection timed out */ + /// 522 Connection timed out Http522ConnectionTimedOut = 522, - /** 523 Proxy Declined Request */ + /// 523 Proxy Declined Request Http523ProxyDeclinedRequest = 523, - /** 524 A timeout occurred */ + /// 524 A timeout occurred Http524aTimeoutOccurred = 524, - /** 525-597 unassigned */ - /** 598 Network read timeout error */ + /// 525-597 unassigned + /// 598 Network read timeout error Http598NetworkReadTimeoutError = 598, - /** 599 Network connect timeout error */ + /// 599 Network connect timeout error Http599NetworkConnectTimeoutError = 599, // clang-format off - /** Unknown status code */ + /// Unknown status code HttpStatus1xxCodeUnknown = 900001, // 1xx: Informational - Request received, continuing process HttpStatus2xxCodeUnknown = 900002, // 2xx: Success - The action was successfully received, understood, and accepted HttpStatus3xxCodeUnknown = 900003, // 3xx: Redirection - Further action must be taken in order to complete the request @@ -438,25 +411,19 @@ namespace pcpp HttpResponseStatusCode() = default; // cppcheck-suppress noExplicitConstructor - /** - * @brief Construct HttpResponseStatusCode from Value enum - * @param[in] statusCode the status code enum - */ + /// @brief Construct HttpResponseStatusCode from Value enum + /// @param[in] statusCode the status code enum HttpResponseStatusCode(Value statusCode) : m_Value(statusCode) {} - /** - * @brief Construct HttpResponseStatusCode from the code number and the customized message - * @param[in] statusCodeNumber the status code in number, e.g. 200, 404 - * @param[in] statusMessage the status message, optional, leave empty to use a default message - */ + /// @brief Construct HttpResponseStatusCode from the code number and the customized message + /// @param[in] statusCodeNumber the status code in number, e.g. 200, 404 + /// @param[in] statusMessage the status message, optional, leave empty to use a default message explicit HttpResponseStatusCode(const int& statusCodeNumber, const std::string& statusMessage = ""); - /** - * @brief Construct HttpResponseStatusCode from Value enum and the customized message - * @param[in] statusCode the status code enum - * @param[in] statusMessage the customized status message, optional - */ + /// @brief Construct HttpResponseStatusCode from Value enum and the customized message + /// @param[in] statusCode the status code enum + /// @param[in] statusMessage the customized status message, optional explicit HttpResponseStatusCode(const Value& statusCode, const std::string& statusMessage); // Allow switch and comparisons. @@ -467,30 +434,22 @@ namespace pcpp // Prevent usage: if(httpResponseStatusCode) explicit operator bool() const = delete; - /** - * @brief get status code number as string - */ + /// @brief get status code number as string std::string toString() const { return std::to_string(m_Value); } - /** - * @brief get status code number as int - */ + /// @brief get status code number as int int toInt() const { return static_cast(m_Value); } - /** - * @brief get status code message, e.g. "OK", "Not Found" - */ + /// @brief get status code message, e.g. "OK", "Not Found" std::string getMessage() const; - /** - * @return If this HttpResponseStatusCode a valid code - * @note Any unknown or error code has an extreme large enum value - */ + /// @return If this HttpResponseStatusCode a valid code + /// @note Any unknown or error code has an extreme large enum value bool isUnsupportedCode() const { return m_Value > 599; @@ -503,18 +462,16 @@ namespace pcpp // -------- Class HttpResponseLayer ----------------- - /** - * @class HttpResponseLayer - * Represents an HTTP response header and inherits all basic functionality of HttpMessage and - * TextBasedProtocolMessage. The functionality that is added for this class is the HTTP first line concept. An HTTP - * response has the following first line: 200 OK HTTP/1.1 Since it's not an "ordinary" HTTP field, it - * requires a special treatment and gets a class of it's own: HttpResponseFirstLine. Unlike most L2-4 protocols, an - * HTTP response header can spread over more than 1 packet. PcapPlusPlus currently doesn't support a header that is - * spread over more than 1 packet so in such cases: 1) only the first packet will be parsed as HttpResponseLayer - * (the other packets won't be recognized as HttpResponseLayer) and 2) the HTTP header for the first packet won't be - * complete (as it continues in the following packets), this why PcapPlusPlus can indicate that HTTP response header - * is complete or not (doesn't end with "\r\n\r\n" or "\n\n") using HttpMessage#isHeaderComplete() - */ + /// @class HttpResponseLayer + /// Represents an HTTP response header and inherits all basic functionality of HttpMessage and + /// TextBasedProtocolMessage. The functionality that is added for this class is the HTTP first line concept. An HTTP + /// response has the following first line: 200 OK HTTP/1.1 Since it's not an "ordinary" HTTP field, it + /// requires a special treatment and gets a class of it's own: HttpResponseFirstLine. Unlike most L2-4 protocols, an + /// HTTP response header can spread over more than 1 packet. PcapPlusPlus currently doesn't support a header that is + /// spread over more than 1 packet so in such cases: 1) only the first packet will be parsed as HttpResponseLayer + /// (the other packets won't be recognized as HttpResponseLayer) and 2) the HTTP header for the first packet won't + /// be complete (as it continues in the following packets), this why PcapPlusPlus can indicate that HTTP response + /// header is complete or not (doesn't end with "\r\n\r\n" or "\n\n") using HttpMessage#isHeaderComplete() class HttpResponseLayer : public HttpMessage { friend class HttpResponseFirstLine; @@ -523,84 +480,70 @@ namespace pcpp // backward compatibility using HttpResponseStatusCode = pcpp::HttpResponseStatusCode; - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in HttpResponseLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * A constructor that allocates a new HTTP response header with only the first line filled. Object will be - * created without further fields. The user can then add fields using addField() methods - * @param[in] version HTTP version to be used - * @param[in] statusCode Status code to be used - * @param[in] statusCodeString Most status codes have their default string, e.g 200 is usually "OK", 404 is - * usually "Not Found", etc. But the user can set a non-default status code string and it will be written in the - * header first line. Empty string ("") means using the default status code string - * @deprecated Use other constructors instead. - */ + /// A constructor that allocates a new HTTP response header with only the first line filled. Object will be + /// created without further fields. The user can then add fields using addField() methods + /// @param[in] version HTTP version to be used + /// @param[in] statusCode Status code to be used + /// @param[in] statusCodeString Most status codes have their default string, e.g 200 is usually "OK", 404 is + /// usually "Not Found", etc. But the user can set a non-default status code string and it will be written in + /// the header first line. Empty string ("") means using the default status code string + /// @deprecated Use other constructors instead. PCPP_DEPRECATED("Use other constructors instead") explicit HttpResponseLayer(HttpVersion version, const HttpResponseStatusCode& statusCode, const std::string& statusCodeString); - /** - * A constructor that allocates a new HTTP response header with only the first line filled. Object will be - * created without further fields. The user can then add fields using addField() methods - * @param[in] version HTTP version to be used - * @param[in] statusCode Status code to be used - */ + /// A constructor that allocates a new HTTP response header with only the first line filled. Object will be + /// created without further fields. The user can then add fields using addField() methods + /// @param[in] version HTTP version to be used + /// @param[in] statusCode Status code to be used explicit HttpResponseLayer(HttpVersion version, const HttpResponseStatusCode& statusCode); ~HttpResponseLayer() override; - /** - * A copy constructor for this layer. This copy constructor inherits base copy constructor - * HttpMessage#HttpMessage() and adds the functionality of copying the first line as well - * @param[in] other The instance to copy from - */ + /// A copy constructor for this layer. This copy constructor inherits base copy constructor + /// HttpMessage#HttpMessage() and adds the functionality of copying the first line as well + /// @param[in] other The instance to copy from HttpResponseLayer(const HttpResponseLayer& other); - /** - * An assignment operator overload for this layer. This method inherits base assignment operator - * HttpMessage#operator=() and adds the functionality of copying the first line as well - * @param[in] other The instance to copy from - * @return A reference to the assignee - */ + /// An assignment operator overload for this layer. This method inherits base assignment operator + /// HttpMessage#operator=() and adds the functionality of copying the first line as well + /// @param[in] other The instance to copy from + /// @return A reference to the assignee HttpResponseLayer& operator=(const HttpResponseLayer& other); - /** - * @return A pointer to the first line instance for this message - */ + /// @return A pointer to the first line instance for this message HttpResponseFirstLine* getFirstLine() const { return m_FirstLine; } - /** - * The length of the body of many HTTP response messages is determined by a HTTP header field called - * "Content-Length". This method sets The content-length field value. The method supports several cases: - * - If the "Content-Length" field exists - the method will only replace the existing value with the new value - * - If the "Content-Length" field doesn't exist - the method will create this field and put the value in it. - * Here are also 2 cases: - * - If prevFieldName is specified - the new "Content-Length" field will be created after it - * - If prevFieldName isn't specified or doesn't exist - the new "Content-Length" field will be created as the - * last field before end-of-header field - * - * @param[in] contentLength The content length value to set - * @param[in] prevFieldName Optional field, if specified and "Content-Length" field doesn't exist, it will be - * created after it - * @return A pointer to the "Content-Length" field, or nullptr if creation failed for some reason - */ + /// The length of the body of many HTTP response messages is determined by a HTTP header field called + /// "Content-Length". This method sets The content-length field value. The method supports several cases: + /// - If the "Content-Length" field exists - the method will only replace the existing value with the new + /// value + /// - If the "Content-Length" field doesn't exist - the method will create this field and put the value in it. + /// Here are also 2 cases: + /// - If prevFieldName is specified - the new "Content-Length" field will be created after it + /// - If prevFieldName isn't specified or doesn't exist - the new "Content-Length" field will be created as + /// the last field before end-of-header field + /// + /// @param[in] contentLength The content length value to set + /// @param[in] prevFieldName Optional field, if specified and "Content-Length" field doesn't exist, it will be + /// created after it + /// @return A pointer to the "Content-Length" field, or nullptr if creation failed for some reason HeaderField* setContentLength(int contentLength, const std::string& prevFieldName = ""); - /** - * The length of the body of many HTTP response messages is determined by a HTTP header field called - * "Content-Length". This method parses this field, extracts its value and return it. If this field doesn't - * exist the method will return 0 - * @return HTTP response body length determined by "Content-Length" field - */ + /// The length of the body of many HTTP response messages is determined by a HTTP header field called + /// "Content-Length". This method parses this field, extracts its value and return it. If this field doesn't + /// exist the method will return 0 + /// @return HTTP response body length determined by "Content-Length" field int getContentLength() const; // implement Layer's abstract methods @@ -613,99 +556,77 @@ namespace pcpp // -------- Class HttpRequestFirstLine ----------------- - /** - * @class HttpRequestFirstLine - * Represents an HTTP request header first line. The first line includes 3 parameters: HTTP method (e.g GET, POST, - * etc.), URI (e.g /main/index.html) and HTTP version (e.g HTTP/1.1). All these parameters are included in this - * class, and the user can retrieve or set them. This class cannot be instantiated by users, it's created inside - * HttpRequestLayer and user can get a pointer to an instance of it. All "get" methods of this class will retrieve - * the actual data of the HTTP request and the "set" methods will change the packet data. Since HTTP is a textual - * protocol, most fields aren't of fixed size and this also applies to the first line parameters. So most "set" - * methods of this class need in most cases to shorten or extend the data in HttpRequestLayer. These methods will - * return a false value if this action failed - */ + /// @class HttpRequestFirstLine + /// Represents an HTTP request header first line. The first line includes 3 parameters: HTTP method (e.g GET, POST, + /// etc.), URI (e.g /main/index.html) and HTTP version (e.g HTTP/1.1). All these parameters are included in this + /// class, and the user can retrieve or set them. This class cannot be instantiated by users, it's created inside + /// HttpRequestLayer and user can get a pointer to an instance of it. All "get" methods of this class will retrieve + /// the actual data of the HTTP request and the "set" methods will change the packet data. Since HTTP is a textual + /// protocol, most fields aren't of fixed size and this also applies to the first line parameters. So most "set" + /// methods of this class need in most cases to shorten or extend the data in HttpRequestLayer. These methods will + /// return a false value if this action failed class HttpRequestFirstLine { friend class HttpRequestLayer; public: - /** - * @return The HTTP method - */ + /// @return The HTTP method HttpRequestLayer::HttpMethod getMethod() const { return m_Method; } - /** - * Set the HTTP method - * @param[in] newMethod The method to set - * @return False if newMethod is HttpRequestLayer#HttpMethodUnknown or if shortening/extending the - * HttpRequestLayer data failed. True otherwise - */ + /// Set the HTTP method + /// @param[in] newMethod The method to set + /// @return False if newMethod is HttpRequestLayer#HttpMethodUnknown or if shortening/extending the + /// HttpRequestLayer data failed. True otherwise bool setMethod(HttpRequestLayer::HttpMethod newMethod); - /** - * @return A copied version of the URI (notice changing the return value won't change the actual data of the - * packet) - */ + /// @return A copied version of the URI (notice changing the return value won't change the actual data of the + /// packet) std::string getUri() const; - /** - * Set the URI - * @param[in] newUri The URI to set - * @return False if shortening/extending the HttpRequestLayer data failed. True otherwise - */ + /// Set the URI + /// @param[in] newUri The URI to set + /// @return False if shortening/extending the HttpRequestLayer data failed. True otherwise bool setUri(std::string newUri); - /** - * @return The HTTP version - */ + /// @return The HTTP version HttpVersion getVersion() const { return m_Version; } - /** - * Set the HTTP version. This method doesn't return a value since all supported HTTP versions are of the same - * size (HTTP/0.9, HTTP/1.0, HTTP/1.1) - * @param[in] newVersion The HTTP version to set - */ + /// Set the HTTP version. This method doesn't return a value since all supported HTTP versions are of the same + /// size (HTTP/0.9, HTTP/1.0, HTTP/1.1) + /// @param[in] newVersion The HTTP version to set void setVersion(HttpVersion newVersion); - /** - * A static method for parsing the HTTP method out of raw data - * @param[in] data The raw data - * @param[in] dataLen The raw data length - * @return The parsed HTTP method - */ + /// A static method for parsing the HTTP method out of raw data + /// @param[in] data The raw data + /// @param[in] dataLen The raw data length + /// @return The parsed HTTP method static HttpRequestLayer::HttpMethod parseMethod(const char* data, size_t dataLen); - /** - * @return The size in bytes of the HTTP first line - */ + /// @return The size in bytes of the HTTP first line int getSize() const { return m_FirstLineEndOffset; } - /** - * As explained in HttpRequestLayer, an HTTP header can spread over more than 1 packet, so when looking at a - * single packet the header can be partial. Same goes for the first line - it can spread over more than 1 - * packet. This method returns an indication whether the first line is partial - * @return False if the first line is partial, true if it's complete - */ + /// As explained in HttpRequestLayer, an HTTP header can spread over more than 1 packet, so when looking at a + /// single packet the header can be partial. Same goes for the first line - it can spread over more than 1 + /// packet. This method returns an indication whether the first line is partial + /// @return False if the first line is partial, true if it's complete bool isComplete() const { return m_IsComplete; } - /** - * @class HttpRequestFirstLineException - * This exception can be thrown while constructing HttpRequestFirstLine (the constructor is private, so the - * construction happens only in HttpRequestLayer). This kind of exception will be thrown if trying to construct - * with HTTP method of HttpRequestLayer#HttpMethodUnknown or with undefined HTTP version ::HttpVersionUnknown - */ + /// @class HttpRequestFirstLineException + /// This exception can be thrown while constructing HttpRequestFirstLine (the constructor is private, so the + /// construction happens only in HttpRequestLayer). This kind of exception will be thrown if trying to construct + /// with HTTP method of HttpRequestLayer#HttpMethodUnknown or with undefined HTTP version ::HttpVersionUnknown class HttpRequestFirstLineException : public std::exception { public: @@ -743,116 +664,90 @@ namespace pcpp // -------- Class HttpResponseFirstLine ----------------- - /** - * @class HttpResponseFirstLine - * Represents an HTTP response header first line. The first line includes 2 parameters: status code (e.g 200 OK, 404 - * Not Found, etc.), and HTTP version (e.g HTTP/1.1). These 2 parameters are included in this class, and the user - * can retrieve or set them. This class cannot be instantiated by users, it's created inside HttpResponseLayer and - * user can get a pointer to an instance of it. The "get" methods of this class will retrieve the actual data of the - * HTTP response and the "set" methods will change the packet data. Since HTTP is a textual protocol, most fields - * aren't of fixed size and this also applies to the first line parameters. So most "set" methods of this class need - * in most cases to shorten or extend the data in HttpResponseLayer. These methods will return a false value if this - * action failed - */ + /// @class HttpResponseFirstLine + /// Represents an HTTP response header first line. The first line includes 2 parameters: status code (e.g 200 OK, + /// 404 Not Found, etc.), and HTTP version (e.g HTTP/1.1). These 2 parameters are included in this class, and the + /// user can retrieve or set them. This class cannot be instantiated by users, it's created inside HttpResponseLayer + /// and user can get a pointer to an instance of it. The "get" methods of this class will retrieve the actual data + /// of the HTTP response and the "set" methods will change the packet data. Since HTTP is a textual protocol, most + /// fields aren't of fixed size and this also applies to the first line parameters. So most "set" methods of this + /// class need in most cases to shorten or extend the data in HttpResponseLayer. These methods will return a false + /// value if this action failed class HttpResponseFirstLine { friend class HttpResponseLayer; public: - /** - * @return The status code as HttpResponseStatusCode enum - */ + /// @return The status code as HttpResponseStatusCode enum HttpResponseStatusCode getStatusCode() const { return m_StatusCode; } - /** - * @return The status code number as integer (e.g 200, 404, etc.) - */ + /// @return The status code number as integer (e.g 200, 404, etc.) int getStatusCodeAsInt() const; - /** - * @return The status code message (e.g "OK", "Not Found", etc.) - */ + /// @return The status code message (e.g "OK", "Not Found", etc.) std::string getStatusCodeString() const; - /** - * Set the status code - * @param[in] newStatusCode The new status code to set - * @param[in] statusCodeString An optional parameter: set a non-default status code message (e.g "Bla Bla" - * instead of "Not Found"). If this parameter isn't supplied or supplied as empty string (""), the default - * message for the status code will be set - * @return True if setting the status code was completed successfully, false otherwise - * @deprecated Use the other overload instead. - */ + /// Set the status code + /// @param[in] newStatusCode The new status code to set + /// @param[in] statusCodeString An optional parameter: set a non-default status code message (e.g "Bla Bla" + /// instead of "Not Found"). If this parameter isn't supplied or supplied as empty string (""), the default + /// message for the status code will be set + /// @return True if setting the status code was completed successfully, false otherwise + /// @deprecated Use the other overload instead. PCPP_DEPRECATED("Use the other overload instead") bool setStatusCode(const HttpResponseStatusCode& newStatusCode, const std::string& statusCodeString); - /** - * Set the status code - * @param[in] newStatusCode The new status code to set - * @return True if setting the status code was completed successfully, false otherwise - */ + /// Set the status code + /// @param[in] newStatusCode The new status code to set + /// @return True if setting the status code was completed successfully, false otherwise bool setStatusCode(const HttpResponseStatusCode& newStatusCode); - /** - * @return The HTTP version - */ + /// @return The HTTP version HttpVersion getVersion() const { return m_Version; } - /** - * Set the HTTP version. This method doesn't return a value since all supported HTTP versions are of the same - * size (HTTP/0.9, HTTP/1.0, HTTP/1.1) - * @param[in] newVersion The HTTP version to set - */ + /// Set the HTTP version. This method doesn't return a value since all supported HTTP versions are of the same + /// size (HTTP/0.9, HTTP/1.0, HTTP/1.1) + /// @param[in] newVersion The HTTP version to set void setVersion(HttpVersion newVersion); - /** - * A static method for parsing the HTTP status code out of raw data - * @param[in] data The raw data - * @param[in] dataLen The raw data length - * @return The parsed HTTP status code as enum - */ + /// A static method for parsing the HTTP status code out of raw data + /// @param[in] data The raw data + /// @param[in] dataLen The raw data length + /// @return The parsed HTTP status code as enum static HttpResponseStatusCode parseStatusCode(const char* data, size_t dataLen); - /** - * A static method for parsing the HTTP version out of raw first line data (e.g "HTTP/x.y") - * @param[in] data The raw data - * @param[in] dataLen The raw data length - * @return The parsed HTTP status code as enum - */ + /// A static method for parsing the HTTP version out of raw first line data (e.g "HTTP/x.y") + /// @param[in] data The raw data + /// @param[in] dataLen The raw data length + /// @return The parsed HTTP status code as enum static HttpVersion parseVersion(const char* data, size_t dataLen); - /** - * @return The size in bytes of the HTTP first line - */ + /// @return The size in bytes of the HTTP first line int getSize() const { return m_FirstLineEndOffset; } - /** - * As explained in HttpResponseLayer, an HTTP header can spread over more than 1 packet, so when looking at a - * single packet the header can be partial. Same goes for the first line - it can spread over more than 1 - * packet. This method returns an indication whether the first line is partial - * @return False if the first line is partial, true if it's complete - */ + /// As explained in HttpResponseLayer, an HTTP header can spread over more than 1 packet, so when looking at a + /// single packet the header can be partial. Same goes for the first line - it can spread over more than 1 + /// packet. This method returns an indication whether the first line is partial + /// @return False if the first line is partial, true if it's complete bool isComplete() const { return m_IsComplete; } - /** - * @class HttpResponseFirstLineException - * This exception can be thrown while constructing HttpResponseFirstLine (the constructor is private, so the - * construction happens only in HttpResponseLayer). This kind of exception will be thrown if trying to construct - * with a HTTP status code that is not in HttpResponseStatusCode or with undefined HTTP version - * ::HttpVersionUnknown - */ + /// @class HttpResponseFirstLineException + /// This exception can be thrown while constructing HttpResponseFirstLine (the constructor is private, so the + /// construction happens only in HttpResponseLayer). This kind of exception will be thrown if trying to + /// construct with a HTTP status code that is not in HttpResponseStatusCode or with undefined HTTP version + /// ::HttpVersionUnknown class HttpResponseFirstLineException : public std::exception { public: diff --git a/Packet++/header/IPLayer.h b/Packet++/header/IPLayer.h index 187f4e439e..9e87eff0a6 100644 --- a/Packet++/header/IPLayer.h +++ b/Packet++/header/IPLayer.h @@ -5,40 +5,30 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @class IPLayer - * This is an interface (abstract class) implemented in the IP layers (IPv4Layer and IPv6Layer). - * It provides methods to fetch the source and destination IP addresses in an abdtract way - * that hides the IP type (IPv4 or IPv6). This is useful for use-cases in which the IP type doesn't matter. - * For example: if you're only interested in printing the IP address the IP type shouldn't matter. - */ + /// @class IPLayer + /// This is an interface (abstract class) implemented in the IP layers (IPv4Layer and IPv6Layer). + /// It provides methods to fetch the source and destination IP addresses in an abdtract way + /// that hides the IP type (IPv4 or IPv6). This is useful for use-cases in which the IP type doesn't matter. + /// For example: if you're only interested in printing the IP address the IP type shouldn't matter. class IPLayer { protected: IPLayer() = default; public: - /** - * An abstract method to get the source IP address - * @return An IPAddress object containing the source address - */ + /// An abstract method to get the source IP address + /// @return An IPAddress object containing the source address virtual IPAddress getSrcIPAddress() const = 0; - /** - * An abstract method to get the destination IP address - * @return An IPAddress object containing the destination address - */ + /// An abstract method to get the destination IP address + /// @return An IPAddress object containing the destination address virtual IPAddress getDstIPAddress() const = 0; - /** - * An empty destructor - */ + /// An empty destructor virtual ~IPLayer() = default; }; } // namespace pcpp diff --git a/Packet++/header/IPReassembly.h b/Packet++/header/IPReassembly.h index 54571ebd5c..7edca76003 100644 --- a/Packet++/header/IPReassembly.h +++ b/Packet++/header/IPReassembly.h @@ -6,94 +6,78 @@ #include "PointerVector.h" #include -/** - * @file - * This file includes an implementation of IP reassembly mechanism (a.k.a IP de-fragmentation), which is the mechanism - * of assembling IPv4 or IPv6 fragments back into one whole packet. As the previous sentence imply, this module supports - * both IPv4 and IPv6 reassembly which means the same pcpp#IPReassembly instance can reassemble both IPv4 and IPv6 - * fragments. You can read more about IP fragmentation here: https://en.wikipedia.org/wiki/IP_fragmentation.
The API - * is rather simple and contains one main method: pcpp#IPReassembly#processPacket() which gets a fragment packet as a - * parameter, does the reassembly and returns a fully reassembled packet when done.
- * - * The logic works as follows: - * - There is an internal map that stores the reassembly data for each packet. The key to this map, meaning the way to - * uniquely associate a fragment to a (reassembled) packet is the triplet of source IP, destination IP and IP ID (for - * IPv4) or Fragment ID (for IPv6) - * - When the first fragment arrives a new record is created in the map and the fragment data is copied - * - With each fragment arriving the fragment data is copied right after the previous fragment and the reassembled - * packet is gradually being built - * - When the last fragment arrives the packet is fully reassembled and returned to the user. Since all fragment data is - * copied, the packet pointer returned to the user has to be freed by the user when done using it - * - The logic supports out-of-order fragments, meaning that a fragment which arrives out-of-order, its data will be - * copied to a list of out-of-order fragments where it waits for its turn. This list is observed each time a new - * fragment arrives to see if the next fragment(s) wait(s) in this list - * - If a non-IP packet arrives it's returned as is to the user - * - If a non-fragment packet arrives it's returned as is to the user - * - * In order to limit the amount of memory used by this mechanism there is a limit to the number of concurrent packets - * being reassembled. The default limit is #PCPP_IP_REASSEMBLY_DEFAULT_MAX_PACKETS_TO_STORE but the user can set any - * value (determined in pcpp#IPReassembly c'tor). Once capacity (the number of concurrent reassembled packets) exceeds - * this number, the packet that was least recently used will be dropped from the map along with all the data that was - * reassembled so far. This means that if the next fragment from this packet suddenly appears it will be treated as a - * new reassembled packet (which will create another record in the map). The user can be notified when reassembled - * packets are removed from the map by registering to the pcpp#IPReassembly#OnFragmentsClean callback in - * pcpp#IPReassembly c'tor - */ - -/** - * @namespace pcpp - * @brief The main namespace for the PcapPlusPlus lib - */ +/// @file +/// This file includes an implementation of IP reassembly mechanism (a.k.a IP de-fragmentation), which is the mechanism +/// of assembling IPv4 or IPv6 fragments back into one whole packet. As the previous sentence imply, this module +/// supports both IPv4 and IPv6 reassembly which means the same pcpp#IPReassembly instance can reassemble both IPv4 and +/// IPv6 fragments. You can read more about IP fragmentation here: https://en.wikipedia.org/wiki/IP_fragmentation.
+/// The API is rather simple and contains one main method: pcpp#IPReassembly#processPacket() which gets a fragment +/// packet as a parameter, does the reassembly and returns a fully reassembled packet when done.
+/// +/// The logic works as follows: +/// - There is an internal map that stores the reassembly data for each packet. The key to this map, meaning the way to +/// uniquely associate a fragment to a (reassembled) packet is the triplet of source IP, destination IP and IP ID (for +/// IPv4) or Fragment ID (for IPv6) +/// - When the first fragment arrives a new record is created in the map and the fragment data is copied +/// - With each fragment arriving the fragment data is copied right after the previous fragment and the reassembled +/// packet is gradually being built +/// - When the last fragment arrives the packet is fully reassembled and returned to the user. Since all fragment data +/// is +/// copied, the packet pointer returned to the user has to be freed by the user when done using it +/// - The logic supports out-of-order fragments, meaning that a fragment which arrives out-of-order, its data will be +/// copied to a list of out-of-order fragments where it waits for its turn. This list is observed each time a new +/// fragment arrives to see if the next fragment(s) wait(s) in this list +/// - If a non-IP packet arrives it's returned as is to the user +/// - If a non-fragment packet arrives it's returned as is to the user +/// +/// In order to limit the amount of memory used by this mechanism there is a limit to the number of concurrent packets +/// being reassembled. The default limit is #PCPP_IP_REASSEMBLY_DEFAULT_MAX_PACKETS_TO_STORE but the user can set any +/// value (determined in pcpp#IPReassembly c'tor). Once capacity (the number of concurrent reassembled packets) exceeds +/// this number, the packet that was least recently used will be dropped from the map along with all the data that was +/// reassembled so far. This means that if the next fragment from this packet suddenly appears it will be treated as a +/// new reassembled packet (which will create another record in the map). The user can be notified when reassembled +/// packets are removed from the map by registering to the pcpp#IPReassembly#OnFragmentsClean callback in +/// pcpp#IPReassembly c'tor + +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { -/** IP reassembly mechanism default capacity. If concurrent packet volume exceeds this numbers, packets will start to be - * dropped in a LRU manner - */ +/// IP reassembly mechanism default capacity. If concurrent packet volume exceeds this numbers, packets will start to be +/// dropped in a LRU manner #define PCPP_IP_REASSEMBLY_DEFAULT_MAX_PACKETS_TO_STORE 500000 - /** - * @class IPReassembly - * Contains the IP reassembly (a.k.a IP de-fragmentation) mechanism. Encapsulates both IPv4 and IPv6 reassembly. - * Please refer to the documentation at the top of IPReassembly.h - * to understand how this mechanism works. The main APIs are: - * - IPReassembly#processPacket() - process a fragment. This is the main method which should be called whenever a - * new fragment arrives. This method processes the fragment, runs the reassembly logic and returns the result - * packet when it's fully reassembled - * - IPReassembly#getCurrentPacket() - get the reassembled data that is currently available, even if reassembly - * process is not yet completed - * - IPReassembly#removePacket() - remove all data that is currently stored for a packet, including the reassembled - * data that was gathered so far - */ + /// @class IPReassembly + /// Contains the IP reassembly (a.k.a IP de-fragmentation) mechanism. Encapsulates both IPv4 and IPv6 reassembly. + /// Please refer to the documentation at the top of IPReassembly.h + /// to understand how this mechanism works. The main APIs are: + /// - IPReassembly#processPacket() - process a fragment. This is the main method which should be called whenever a + /// new fragment arrives. This method processes the fragment, runs the reassembly logic and returns the result + /// packet when it's fully reassembled + /// - IPReassembly#getCurrentPacket() - get the reassembled data that is currently available, even if reassembly + /// process is not yet completed + /// - IPReassembly#removePacket() - remove all data that is currently stored for a packet, including the reassembled + /// data that was gathered so far class IPReassembly { public: - /** - * @class PacketKey - * An abstract class that represents a key that can uniquely identify an IP packet. This class cannot be - * instantiated or copied, only its derived classes can - */ + /// @class PacketKey + /// An abstract class that represents a key that can uniquely identify an IP packet. This class cannot be + /// instantiated or copied, only its derived classes can class PacketKey { public: - /** - * A default virtual d'tor - */ + /// A default virtual d'tor virtual ~PacketKey() = default; - /** - * @return A 4-byte hash value of the packet key - */ + /// @return A 4-byte hash value of the packet key virtual uint32_t getHashValue() const = 0; - /** - * @return The IP protocol this key represents (pcpp#IPv4 or pcpp#IPv6) - */ + /// @return The IP protocol this key represents (pcpp#IPv4 or pcpp#IPv6) virtual ProtocolType getProtocolType() const = 0; - /** - * @return A pointer to a new instance which is a clone of the current instance - */ + /// @return A pointer to a new instance which is a clone of the current instance virtual PacketKey* clone() const = 0; protected: @@ -104,42 +88,32 @@ namespace pcpp PacketKey(const PacketKey& other) = default; }; - /** - * @class IPv4PacketKey - * Represents a key that can uniquely identify IPv4 packets. The key comprises of source IPv4 address, dest IPv4 - * address and IP ID - */ + /// @class IPv4PacketKey + /// Represents a key that can uniquely identify IPv4 packets. The key comprises of source IPv4 address, dest + /// IPv4 address and IP ID class IPv4PacketKey : public PacketKey { public: - /** - * A default c'tor which zeros all members - */ + /// A default c'tor which zeros all members IPv4PacketKey() : m_IpID(0), m_SrcIP(IPv4Address::Zero), m_DstIP(IPv4Address::Zero) {} - /** - * A c'tor that sets values in each one of the members - * @param[in] ipid IP ID value - * @param[in] srcip Source IPv4 address - * @param[in] dstip Dest IPv4 address - */ + /// A c'tor that sets values in each one of the members + /// @param[in] ipid IP ID value + /// @param[in] srcip Source IPv4 address + /// @param[in] dstip Dest IPv4 address IPv4PacketKey(uint16_t ipid, IPv4Address srcip, IPv4Address dstip) : m_IpID(ipid), m_SrcIP(srcip), m_DstIP(dstip) {} - /** - * A copy c'tor for this class - * @param[in] other The instance to copy from - */ + /// A copy c'tor for this class + /// @param[in] other The instance to copy from IPv4PacketKey(const IPv4PacketKey& other) : PacketKey(other), m_IpID(other.m_IpID), m_SrcIP(other.m_SrcIP), m_DstIP(other.m_DstIP) {} - /** - * Assignment operator for this class - * @param[in] other The instance to assign from - */ + /// Assignment operator for this class + /// @param[in] other The instance to assign from IPv4PacketKey& operator=(const IPv4PacketKey& other) { m_IpID = other.m_IpID; @@ -148,52 +122,40 @@ namespace pcpp return *this; } - /** - * @return IP ID value - */ + /// @return IP ID value uint16_t getIpID() const { return m_IpID; } - /** - * @return Source IP address - */ + /// @return Source IP address IPv4Address getSrcIP() const { return m_SrcIP; } - /** - * @return Dest IP address - */ + /// @return Dest IP address IPv4Address getDstIP() const { return m_DstIP; } - /** - * Set IP ID - * @param[in] ipID IP ID value to set - */ + /// Set IP ID + /// @param[in] ipID IP ID value to set void setIpID(uint16_t ipID) { m_IpID = ipID; } - /** - * Set source IPv4 address - * @param[in] srcIP Source IP to set - */ + /// Set source IPv4 address + /// @param[in] srcIP Source IP to set void setSrcIP(const IPv4Address& srcIP) { m_SrcIP = srcIP; } - /** - * Set dest IPv4 address - * @param[in] dstIP Dest IP to set - */ + /// Set dest IPv4 address + /// @param[in] dstIP Dest IP to set void setDstIP(const IPv4Address& dstIP) { m_DstIP = dstIP; @@ -203,9 +165,7 @@ namespace pcpp uint32_t getHashValue() const override; - /** - * @return pcpp#IPv4 protocol - */ + /// @return pcpp#IPv4 protocol ProtocolType getProtocolType() const override { return IPv4; @@ -222,42 +182,32 @@ namespace pcpp IPv4Address m_DstIP; }; - /** - * @class IPv6PacketKey - * Represents a key that can uniquely identify IPv6 fragment packets. The key comprises of source IPv6 address, - * dest IPv6 address and fragment ID (which resides in the IPv6 fragmentation extension) - */ + /// @class IPv6PacketKey + /// Represents a key that can uniquely identify IPv6 fragment packets. The key comprises of source IPv6 address, + /// dest IPv6 address and fragment ID (which resides in the IPv6 fragmentation extension) class IPv6PacketKey : public PacketKey { public: - /** - * A default c'tor which zeros all members - */ + /// A default c'tor which zeros all members IPv6PacketKey() : m_FragmentID(0), m_SrcIP(IPv6Address::Zero), m_DstIP(IPv6Address::Zero) {} - /** - * A c'tor that sets values in each one of the members - * @param[in] fragmentID Fragment ID value - * @param[in] srcip Source IPv6 address - * @param[in] dstip Dest IPv6 address - */ + /// A c'tor that sets values in each one of the members + /// @param[in] fragmentID Fragment ID value + /// @param[in] srcip Source IPv6 address + /// @param[in] dstip Dest IPv6 address IPv6PacketKey(uint32_t fragmentID, IPv6Address srcip, IPv6Address dstip) : m_FragmentID(fragmentID), m_SrcIP(srcip), m_DstIP(dstip) {} - /** - * A copy c'tor for this class - * @param[in] other The instance to copy from - */ + /// A copy c'tor for this class + /// @param[in] other The instance to copy from IPv6PacketKey(const IPv6PacketKey& other) : PacketKey(other), m_FragmentID(other.m_FragmentID), m_SrcIP(other.m_SrcIP), m_DstIP(other.m_DstIP) {} - /** - * Assignment operator for this class - * @param[in] other The instance to assign from - */ + /// Assignment operator for this class + /// @param[in] other The instance to assign from IPv6PacketKey& operator=(const IPv6PacketKey& other) { m_FragmentID = other.m_FragmentID; @@ -266,52 +216,40 @@ namespace pcpp return *this; } - /** - * @return Fragment ID value - */ + /// @return Fragment ID value uint32_t getFragmentID() const { return m_FragmentID; } - /** - * @return Source IP address - */ + /// @return Source IP address IPv6Address getSrcIP() const { return m_SrcIP; } - /** - * @return Dest IP address - */ + /// @return Dest IP address IPv6Address getDstIP() const { return m_DstIP; } - /** - * Set fragment ID - * @param[in] fragID Fragment ID value to set - */ + /// Set fragment ID + /// @param[in] fragID Fragment ID value to set void setFragmentID(uint32_t fragID) { m_FragmentID = fragID; } - /** - * Set source IPv6 address - * @param[in] srcIP Source IP to set - */ + /// Set source IPv6 address + /// @param[in] srcIP Source IP to set void setSrcIP(const IPv6Address& srcIP) { m_SrcIP = srcIP; } - /** - * Set dest IPv6 address - * @param[in] dstIP Dest IP to set - */ + /// Set dest IPv6 address + /// @param[in] dstIP Dest IP to set void setDstIP(const IPv6Address& dstIP) { m_DstIP = dstIP; @@ -321,9 +259,7 @@ namespace pcpp uint32_t getHashValue() const override; - /** - * @return pcpp#IPv6 protocol - */ + /// @return pcpp#IPv6 protocol ProtocolType getProtocolType() const override { return IPv6; @@ -340,172 +276,154 @@ namespace pcpp IPv6Address m_DstIP; }; - /** - * @typedef OnFragmentsClean - * The IP reassembly mechanism has a certain capacity of concurrent packets it can handle. This capacity is - * determined in its c'tor (default value is #PCPP_IP_REASSEMBLY_DEFAULT_MAX_PACKETS_TO_STORE). When traffic - * volume exceeds this capacity the mechanism starts dropping packets in a LRU manner (least recently used are - * dropped first). Whenever a packet is dropped this callback is fired - * @param[in] key A pointer to the identifier of the packet that is being dropped - * @param[in] userCookie A pointer to the cookie provided by the user in IPReassemby c'tor (or nullptr if no - * cookie provided) - */ + /// @typedef OnFragmentsClean + /// The IP reassembly mechanism has a certain capacity of concurrent packets it can handle. This capacity is + /// determined in its c'tor (default value is #PCPP_IP_REASSEMBLY_DEFAULT_MAX_PACKETS_TO_STORE). When traffic + /// volume exceeds this capacity the mechanism starts dropping packets in a LRU manner (least recently used are + /// dropped first). Whenever a packet is dropped this callback is fired + /// @param[in] key A pointer to the identifier of the packet that is being dropped + /// @param[in] userCookie A pointer to the cookie provided by the user in IPReassemby c'tor (or nullptr if no + /// cookie provided) typedef void (*OnFragmentsClean)(const PacketKey* key, void* userCookie); - /** - * An enum representing the status returned from processing a fragment - */ + /// An enum representing the status returned from processing a fragment enum ReassemblyStatus { - /** The processed packet isn't of type IPv4 or IPv6 */ + /// The processed packet isn't of type IPv4 or IPv6 NON_IP_PACKET = 0x00, - /** The processed packet isn't a fragment */ + /// The processed packet isn't a fragment NON_FRAGMENT = 0x01, - /** The processed fragment is the first fragment */ + /// The processed fragment is the first fragment FIRST_FRAGMENT = 0x02, - /** The processed fragment is a fragment (but not the first one) */ + /// The processed fragment is a fragment (but not the first one) FRAGMENT = 0x04, - /** The processed fragment is not the fragment that was expected at this time */ + /// The processed fragment is not the fragment that was expected at this time OUT_OF_ORDER_FRAGMENT = 0x08, - /** The processed fragment is malformed, meaning a fragment which has offset of zero but isn't the first - * fragment */ + /// The processed fragment is malformed, meaning a fragment which has offset of zero but isn't the first + /// fragment MALFORMED_FRAGMENT = 0x10, - /** Packet is now fully reassembled */ + /// Packet is now fully reassembled REASSEMBLED = 0x20 }; - /** - * A c'tor for this class. - * @param[in] onFragmentsCleanCallback The callback to be called when packets are dropped due to capacity limit. - * Please read more about capacity limit in IPReassembly.h file description. This parameter is optional, default - * value is nullptr (no callback) - * @param[in] callbackUserCookie A pointer to an object provided by the user. This pointer will be returned when - * invoking the onFragmentsCleanCallback. This parameter is optional, default cookie is nullptr - * @param[in] maxPacketsToStore Set the capacity limit of the IP reassembly mechanism. Default capacity is - * #PCPP_IP_REASSEMBLY_DEFAULT_MAX_PACKETS_TO_STORE - */ + /// A c'tor for this class. + /// @param[in] onFragmentsCleanCallback The callback to be called when packets are dropped due to capacity + /// limit. Please read more about capacity limit in IPReassembly.h file description. This parameter is optional, + /// default value is nullptr (no callback) + /// @param[in] callbackUserCookie A pointer to an object provided by the user. This pointer will be returned + /// when invoking the onFragmentsCleanCallback. This parameter is optional, default cookie is nullptr + /// @param[in] maxPacketsToStore Set the capacity limit of the IP reassembly mechanism. Default capacity is + /// #PCPP_IP_REASSEMBLY_DEFAULT_MAX_PACKETS_TO_STORE explicit IPReassembly(OnFragmentsClean onFragmentsCleanCallback = nullptr, void* callbackUserCookie = nullptr, size_t maxPacketsToStore = PCPP_IP_REASSEMBLY_DEFAULT_MAX_PACKETS_TO_STORE) : m_PacketLRU(maxPacketsToStore), m_OnFragmentsCleanCallback(onFragmentsCleanCallback), m_CallbackUserCookie(callbackUserCookie) {} - /** - * A d'tor for this class - */ + /// A d'tor for this class ~IPReassembly(); - /** - * The main API that drives IPReassembly. This method should be called whenever a fragment arrives. This method - * finds the relevant packet this fragment belongs to and runs the IP reassembly logic that is described in - * IPReassembly.h. - * @param[in] fragment The fragment to process (IPv4 or IPv6). Please notice that the reassembly logic doesn't - * change or manipulate this object in any way. All of its data is copied to internal structures and manipulated - * there - * @param[out] status An indication of the packet reassembly status following the processing of this fragment. - * Possible values are: - * - The input fragment is not a IPv4 or IPv6 packet - * - The input fragment is not a IPv4 or IPv6 fragment packet - * - The input fragment is the first fragment of the packet - * - The input fragment is not the first or last fragment - * - The input fragment came out-of-order, meaning that wasn't the fragment that was currently expected (it's - * data is copied to the out-of-order fragment list) - * - The input fragment is malformed and will be ignored - * - The input fragment is the last one and the packet is now fully reassembled. In this case the return value - * will contain a pointer to the reassembled packet - * @param[in] parseUntil Optional parameter. Parse the reassembled packet until you reach a certain protocol - * (inclusive). Can be useful for cases when you need to parse only up to a certain layer and want to avoid the - * performance impact and memory consumption of parsing the whole packet. Note that setting this to a protocol - * which doesn't include the IP-Layer will result in IPReassembly not finding the IP-Layer and thus failing to - * work properly. Default value is ::UnknownProtocol which means don't take this parameter into account - * @param[in] parseUntilLayer Optional parameter. Parse the reassembled packet until you reach a certain layer - * in the OSI model (inclusive). Can be useful for cases when you need to parse only up to a certain OSI layer - * (for example transport layer) and want to avoid the performance impact and memory consumption of parsing the - * whole packet. Note that setting this value to OsiModelPhysicalLayer will result in IPReassembly not finding - * the IP-layer and thus failing to work properly. Default value is ::OsiModelLayerUnknown which means don't - * take this parameter into account - * @return - * - If the input fragment isn't an IPv4/IPv6 packet or if it isn't an IPv4/IPv6 fragment, the return value is a - * pointer to the input fragment - * - If the input fragment is the last one and the reassembled packet is ready - a pointer to the reassembled - * packet is returned. Notice it's the user's responsibility to free this pointer when done using it - * - If the reassembled packet isn't ready then nullptr is returned - */ + /// The main API that drives IPReassembly. This method should be called whenever a fragment arrives. This method + /// finds the relevant packet this fragment belongs to and runs the IP reassembly logic that is described in + /// IPReassembly.h. + /// @param[in] fragment The fragment to process (IPv4 or IPv6). Please notice that the reassembly logic doesn't + /// change or manipulate this object in any way. All of its data is copied to internal structures and + /// manipulated there + /// @param[out] status An indication of the packet reassembly status following the processing of this fragment. + /// Possible values are: + /// - The input fragment is not a IPv4 or IPv6 packet + /// - The input fragment is not a IPv4 or IPv6 fragment packet + /// - The input fragment is the first fragment of the packet + /// - The input fragment is not the first or last fragment + /// - The input fragment came out-of-order, meaning that wasn't the fragment that was currently expected (it's + /// data is copied to the out-of-order fragment list) + /// - The input fragment is malformed and will be ignored + /// - The input fragment is the last one and the packet is now fully reassembled. In this case the return value + /// will contain a pointer to the reassembled packet + /// @param[in] parseUntil Optional parameter. Parse the reassembled packet until you reach a certain protocol + /// (inclusive). Can be useful for cases when you need to parse only up to a certain layer and want to avoid the + /// performance impact and memory consumption of parsing the whole packet. Note that setting this to a protocol + /// which doesn't include the IP-Layer will result in IPReassembly not finding the IP-Layer and thus failing to + /// work properly. Default value is ::UnknownProtocol which means don't take this parameter into account + /// @param[in] parseUntilLayer Optional parameter. Parse the reassembled packet until you reach a certain layer + /// in the OSI model (inclusive). Can be useful for cases when you need to parse only up to a certain OSI layer + /// (for example transport layer) and want to avoid the performance impact and memory consumption of parsing the + /// whole packet. Note that setting this value to OsiModelPhysicalLayer will result in IPReassembly not finding + /// the IP-layer and thus failing to work properly. Default value is ::OsiModelLayerUnknown which means don't + /// take this parameter into account + /// @return + /// - If the input fragment isn't an IPv4/IPv6 packet or if it isn't an IPv4/IPv6 fragment, the return value is + /// a + /// pointer to the input fragment + /// - If the input fragment is the last one and the reassembled packet is ready - a pointer to the reassembled + /// packet is returned. Notice it's the user's responsibility to free this pointer when done using it + /// - If the reassembled packet isn't ready then nullptr is returned Packet* processPacket(Packet* fragment, ReassemblyStatus& status, ProtocolType parseUntil = UnknownProtocol, OsiModelLayer parseUntilLayer = OsiModelLayerUnknown); - /** - * The main API that drives IPReassembly. This method should be called whenever a fragment arrives. This method - * finds the relevant packet this fragment belongs to and runs the IPv4 reassembly logic that is described in - * IPReassembly.h. - * @param[in] fragment The fragment to process (IPv4 or IPv6). Please notice that the reassembly logic doesn't - * change or manipulate this object in any way. All of its data is copied to internal structures and manipulated - * there - * @param[out] status An indication of the packet reassembly status following the processing of this fragment. - * Possible values are: - * - The input fragment is not a IPv4 or IPv6 packet - * - The input fragment is not a IPv4 or IPv6 fragment packet - * - The input fragment is the first fragment of the packet - * - The input fragment is not the first or last fragment - * - The input fragment came out-of-order, meaning that wasn't the fragment that was currently expected (it's - * data is copied to the out-of-order fragment list) - * - The input fragment is malformed and will be ignored - * - The input fragment is the last one and the packet is now fully reassembled. In this case the return value - * will contain a pointer to the reassembled packet - * @param[in] parseUntil Optional parameter. Parse the raw and reassembled packets until you reach a certain - * protocol (inclusive). Can be useful for cases when you need to parse only up to a certain layer and want to - * avoid the performance impact and memory consumption of parsing the whole packet. Note that setting this to a - * protocol which doesn't include the IP-Layer will result in IPReassembly not finding the IP-Layer and thus - * failing to work properly. Default value is ::UnknownProtocol which means don't take this parameter into - * account - * @param[in] parseUntilLayer Optional parameter. Parse the raw and reassembled packets until you reach a - * certain layer in the OSI model (inclusive). Can be useful for cases when you need to parse only up to a - * certain OSI layer (for example transport layer) and want to avoid the performance impact and memory - * consumption of parsing the whole packet. Note that setting this value to OsiModelPhysicalLayer will result in - * IPReassembly not finding the IP-layer and thus failing to work properly. Default value is ::UnknownProtocol - * which means don't take this parameter into account Default value is ::OsiModelLayerUnknown which means don't - * take this parameter into account - * @return - * - If the input fragment isn't an IPv4/IPv6 packet or if it isn't an IPv4/IPv6 fragment, the return value is a - * pointer to a Packet object wrapping the input fragment RawPacket object. It's the user responsibility to - * free this instance - * - If the input fragment is the last one and the reassembled packet is ready - a pointer to the reassembled - * packet is returned. Notice it's the user's responsibility to free this pointer when done using it - * - If the reassembled packet isn't ready then nullptr is returned - */ + /// The main API that drives IPReassembly. This method should be called whenever a fragment arrives. This method + /// finds the relevant packet this fragment belongs to and runs the IPv4 reassembly logic that is described in + /// IPReassembly.h. + /// @param[in] fragment The fragment to process (IPv4 or IPv6). Please notice that the reassembly logic doesn't + /// change or manipulate this object in any way. All of its data is copied to internal structures and + /// manipulated there + /// @param[out] status An indication of the packet reassembly status following the processing of this fragment. + /// Possible values are: + /// - The input fragment is not a IPv4 or IPv6 packet + /// - The input fragment is not a IPv4 or IPv6 fragment packet + /// - The input fragment is the first fragment of the packet + /// - The input fragment is not the first or last fragment + /// - The input fragment came out-of-order, meaning that wasn't the fragment that was currently expected (it's + /// data is copied to the out-of-order fragment list) + /// - The input fragment is malformed and will be ignored + /// - The input fragment is the last one and the packet is now fully reassembled. In this case the return value + /// will contain a pointer to the reassembled packet + /// @param[in] parseUntil Optional parameter. Parse the raw and reassembled packets until you reach a certain + /// protocol (inclusive). Can be useful for cases when you need to parse only up to a certain layer and want to + /// avoid the performance impact and memory consumption of parsing the whole packet. Note that setting this to a + /// protocol which doesn't include the IP-Layer will result in IPReassembly not finding the IP-Layer and thus + /// failing to work properly. Default value is ::UnknownProtocol which means don't take this parameter into + /// account + /// @param[in] parseUntilLayer Optional parameter. Parse the raw and reassembled packets until you reach a + /// certain layer in the OSI model (inclusive). Can be useful for cases when you need to parse only up to a + /// certain OSI layer (for example transport layer) and want to avoid the performance impact and memory + /// consumption of parsing the whole packet. Note that setting this value to OsiModelPhysicalLayer will result + /// in IPReassembly not finding the IP-layer and thus failing to work properly. Default value is + /// ::UnknownProtocol which means don't take this parameter into account Default value is ::OsiModelLayerUnknown + /// which means don't take this parameter into account + /// @return + /// - If the input fragment isn't an IPv4/IPv6 packet or if it isn't an IPv4/IPv6 fragment, the return value is + /// a + /// pointer to a Packet object wrapping the input fragment RawPacket object. It's the user responsibility to + /// free this instance + /// - If the input fragment is the last one and the reassembled packet is ready - a pointer to the reassembled + /// packet is returned. Notice it's the user's responsibility to free this pointer when done using it + /// - If the reassembled packet isn't ready then nullptr is returned Packet* processPacket(RawPacket* fragment, ReassemblyStatus& status, ProtocolType parseUntil = UnknownProtocol, OsiModelLayer parseUntilLayer = OsiModelLayerUnknown); - /** - * Get a partially reassembled packet. This method returns all the reassembled data that was gathered so far - * which is obviously not a fully reassembled packet (otherwise it would have returned by processPacket()). - * Notice all data is being copied so the user is responsible to free the returned Packet object when done using - * it. Notice#2 - calling this method doesn't interfere with the reassembly of this packet - all internal - * structures and data remain - * @param[in] key The identifiers of the packet to return - * @return A pointer to a Packet object containing the partially reassembled packet. Notice the user is - * responsible to free this object when done using it - */ + /// Get a partially reassembled packet. This method returns all the reassembled data that was gathered so far + /// which is obviously not a fully reassembled packet (otherwise it would have returned by processPacket()). + /// Notice all data is being copied so the user is responsible to free the returned Packet object when done + /// using it. Notice#2 - calling this method doesn't interfere with the reassembly of this packet - all internal + /// structures and data remain + /// @param[in] key The identifiers of the packet to return + /// @return A pointer to a Packet object containing the partially reassembled packet. Notice the user is + /// responsible to free this object when done using it Packet* getCurrentPacket(const PacketKey& key); - /** - * Remove a partially reassembled packet from all internal structures. That means that if another fragment of - * this packet appears it will be treated as a new packet - * @param[in] key The identifiers of the packet to remove - */ + /// Remove a partially reassembled packet from all internal structures. That means that if another fragment of + /// this packet appears it will be treated as a new packet + /// @param[in] key The identifiers of the packet to remove void removePacket(const PacketKey& key); - /** - * Get the maximum capacity as determined in the c'tor - */ + /// Get the maximum capacity as determined in the c'tor size_t getMaxCapacity() const { return m_PacketLRU.getMaxSize(); } - /** - * Get the current number of packets being processed - */ + /// Get the current number of packets being processed size_t getCurrentCapacity() const { return m_FragmentMap.size(); diff --git a/Packet++/header/IPSecLayer.h b/Packet++/header/IPSecLayer.h index 77a8be2af9..b38cd3a54f 100644 --- a/Packet++/header/IPSecLayer.h +++ b/Packet++/header/IPSecLayer.h @@ -4,127 +4,98 @@ #include "Layer.h" -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @struct ipsec_authentication_header - * Represents IPSec AuthenticationHeader (AH) structure - */ + /// @struct ipsec_authentication_header + /// Represents IPSec AuthenticationHeader (AH) structure #pragma pack(push, 1) struct ipsec_authentication_header { - /** Type of the next header */ + /// Type of the next header uint8_t nextHeader; - /** The length of the Authentication Header in 4-octet units, minus 2 */ + /// The length of the Authentication Header in 4-octet units, minus 2 uint8_t payloadLen; - /** Reserved */ + /// Reserved uint16_t reserved; - /** Security Parameters Index */ + /// Security Parameters Index uint32_t spi; - /** Sequence Number */ + /// Sequence Number uint32_t sequenceNumber; }; #pragma pack(pop) static_assert(sizeof(ipsec_authentication_header) == 12, "ipsec_authentication_header size is not 12 bytes"); - /** - * @struct ipsec_esp - * Represents IPSec Encapsulating Security Payload (ESP) structure - */ + /// @struct ipsec_esp + /// Represents IPSec Encapsulating Security Payload (ESP) structure #pragma pack(push, 1) struct ipsec_esp { - /** Security Parameters Index */ + /// Security Parameters Index uint32_t spi; - /** Sequence Number */ + /// Sequence Number uint32_t sequenceNumber; }; #pragma pack(pop) static_assert(sizeof(ipsec_esp) == 8, "ipsec_esp size is not 8 bytes"); - /** - * @class AuthenticationHeaderLayer - * Represents an IPSec AuthenticationHeader (AH) layer - */ + /// @class AuthenticationHeaderLayer + /// Represents an IPSec AuthenticationHeader (AH) layer class AuthenticationHeaderLayer : public Layer { public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in AuthenticationHeaderLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, AuthenticationHeader) {} - /** - * Get a pointer to the raw AH header. Notice this points directly to the data, so every change will change the - * actual packet data - * @return A pointer to the ipsec_authentication_header - */ + /// Get a pointer to the raw AH header. Notice this points directly to the data, so every change will change the + /// actual packet data + /// @return A pointer to the ipsec_authentication_header ipsec_authentication_header* getAHHeader() const { return reinterpret_cast(m_Data); } - /** - * @return The Security Parameters Index (SPI) field value - */ + /// @return The Security Parameters Index (SPI) field value uint32_t getSPI() const; - /** - * @return The sequence number value - */ + /// @return The sequence number value uint32_t getSequenceNumber() const; - /** - * @return The size of the Integrity Check Value (ICV) - */ + /// @return The size of the Integrity Check Value (ICV) size_t getICVLength() const; - /** - * @return A pointer to the raw data of the Integrity Check Value (ICV) - */ + /// @return A pointer to the raw data of the Integrity Check Value (ICV) uint8_t* getICVBytes() const; - /** - * @return The value of the Integrity Check Value (ICV) as a hex string - */ + /// @return The value of the Integrity Check Value (ICV) as a hex string std::string getICVHexStream() const; - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of a AuthenticationHeader layer - * @param[in] dataLen The length of byte stream - * @return True if the data is valid and can represent an AuthenticationHeader layer - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of a AuthenticationHeader layer + /// @param[in] dataLen The length of byte stream + /// @return True if the data is valid and can represent an AuthenticationHeader layer static inline bool isDataValid(const uint8_t* data, size_t dataLen); // implement abstract methods - /** - * @return The size of the AH header - */ + /// @return The size of the AH header size_t getHeaderLen() const override { return static_cast(4) * (getAHHeader()->payloadLen + 2); } - /** - * Currently identifies the following next layers: UdpLayer, TcpLayer, IPv4Layer, IPv6Layer and ESPLayer. - * Otherwise sets PayloadLayer - */ + /// Currently identifies the following next layers: UdpLayer, TcpLayer, IPv4Layer, IPv6Layer and ESPLayer. + /// Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * Does nothing for this layer - */ + /// Does nothing for this layer void computeCalculateFields() override {} @@ -141,19 +112,16 @@ namespace pcpp {} }; - /** - * @class ESPLayer - * Represents an IPSec Encapsulating Security Payload (ESP) layer - */ + /// @class ESPLayer + /// Represents an IPSec Encapsulating Security Payload (ESP) layer class ESPLayer : public Layer { public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in ESPLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, ESP) {} @@ -163,42 +131,30 @@ namespace pcpp return reinterpret_cast(m_Data); } - /** - * @return The Security Parameters Index (SPI) field value - */ + /// @return The Security Parameters Index (SPI) field value uint32_t getSPI() const; - /** - * @return The sequence number value - */ + /// @return The sequence number value uint32_t getSequenceNumber() const; - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of a ESP layer - * @param[in] dataLen The length of byte stream - * @return True if the data is valid and can represent an ESP layer - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of a ESP layer + /// @param[in] dataLen The length of byte stream + /// @return True if the data is valid and can represent an ESP layer static inline bool isDataValid(const uint8_t* data, size_t dataLen); // implement abstract methods - /** - * @return The size of the ESP header (8 bytes) - */ + /// @return The size of the ESP header (8 bytes) size_t getHeaderLen() const override { return sizeof(ipsec_esp); } - /** - * The payload of an ESP layer is encrypted, hence the next layer is always a generic payload (PayloadLayer) - */ + /// The payload of an ESP layer is encrypted, hence the next layer is always a generic payload (PayloadLayer) void parseNextLayer() override; - /** - * Does nothing for this layer - */ + /// Does nothing for this layer void computeCalculateFields() override {} diff --git a/Packet++/header/IPv4Layer.h b/Packet++/header/IPv4Layer.h index 3159ff0284..ec89dcf9ee 100644 --- a/Packet++/header/IPv4Layer.h +++ b/Packet++/header/IPv4Layer.h @@ -9,198 +9,183 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct iphdr - * Represents an IPv4 protocol header - */ + /// @struct iphdr + /// Represents an IPv4 protocol header #pragma pack(push, 1) struct iphdr { #if (BYTE_ORDER == LITTLE_ENDIAN) - /** IP header length, has the value of 5 for IPv4 */ + /// IP header length, has the value of 5 for IPv4 uint8_t internetHeaderLength : 4, - /** IP version number, has the value of 4 for IPv4 */ + /// IP version number, has the value of 4 for IPv4 ipVersion : 4; #else - /** IP version number, has the value of 4 for IPv4 */ + /// IP version number, has the value of 4 for IPv4 uint8_t ipVersion : 4, - /** IP header length, has the value of 5 for IPv4 */ + /// IP header length, has the value of 5 for IPv4 internetHeaderLength : 4; #endif - /** type of service, same as Differentiated Services Code Point (DSCP)*/ + /// type of service, same as Differentiated Services Code Point (DSCP) uint8_t typeOfService; - /** Entire packet (fragment) size, including header and data, in bytes */ + /// Entire packet (fragment) size, including header and data, in bytes uint16_t totalLength; - /** Identification field. Primarily used for uniquely identifying the group of fragments of a single IP - * datagram*/ + /// Identification field. Primarily used for uniquely identifying the group of fragments of a single IP + /// datagram uint16_t ipId; - /** Fragment offset field, measured in units of eight-byte blocks (64 bits) */ + /// Fragment offset field, measured in units of eight-byte blocks (64 bits) uint16_t fragmentOffset; - /** An eight-bit time to live field helps prevent datagrams from persisting (e.g. going in circles) on an - * internet. In practice, the field has become a hop count */ + /// An eight-bit time to live field helps prevent datagrams from persisting (e.g. going in circles) on an + /// internet. In practice, the field has become a hop count uint8_t timeToLive; - /** Defines the protocol used in the data portion of the IP datagram. Must be one of ::IPProtocolTypes */ + /// Defines the protocol used in the data portion of the IP datagram. Must be one of ::IPProtocolTypes uint8_t protocol; - /** Error-checking of the header */ + /// Error-checking of the header uint16_t headerChecksum; - /** IPv4 address of the sender of the packet */ + /// IPv4 address of the sender of the packet uint32_t ipSrc; - /** IPv4 address of the receiver of the packet */ + /// IPv4 address of the receiver of the packet uint32_t ipDst; - /*The options start here. */ + // The options start here. }; #pragma pack(pop) static_assert(sizeof(iphdr) == 20, "iphdr size is not 20 bytes"); - /** - * An enum for all possible IPv4 and IPv6 protocol types - */ + /// An enum for all possible IPv4 and IPv6 protocol types enum IPProtocolTypes { - /** Dummy protocol for TCP */ + /// Dummy protocol for TCP PACKETPP_IPPROTO_IP = 0, - /** IPv6 Hop-by-Hop options */ + /// IPv6 Hop-by-Hop options PACKETPP_IPPROTO_HOPOPTS = 0, - /** Internet Control Message Protocol */ + /// Internet Control Message Protocol PACKETPP_IPPROTO_ICMP = 1, - /** Internet Gateway Management Protocol */ + /// Internet Gateway Management Protocol PACKETPP_IPPROTO_IGMP = 2, - /** IPIP tunnels (older KA9Q tunnels use 94) */ + /// IPIP tunnels (older KA9Q tunnels use 94) PACKETPP_IPPROTO_IPIP = 4, - /** Transmission Control Protocol */ + /// Transmission Control Protocol PACKETPP_IPPROTO_TCP = 6, - /** Exterior Gateway Protocol */ + /// Exterior Gateway Protocol PACKETPP_IPPROTO_EGP = 8, - /** PUP protocol */ + /// PUP protocol PACKETPP_IPPROTO_PUP = 12, - /** User Datagram Protocol */ + /// User Datagram Protocol PACKETPP_IPPROTO_UDP = 17, - /** XNS IDP protocol */ + /// XNS IDP protocol PACKETPP_IPPROTO_IDP = 22, - /** IPv6 header */ + /// IPv6 header PACKETPP_IPPROTO_IPV6 = 41, - /** IPv6 Routing header */ + /// IPv6 Routing header PACKETPP_IPPROTO_ROUTING = 43, - /** IPv6 fragmentation header */ + /// IPv6 fragmentation header PACKETPP_IPPROTO_FRAGMENT = 44, - /** GRE protocol */ + /// GRE protocol PACKETPP_IPPROTO_GRE = 47, - /** encapsulating security payload */ + /// encapsulating security payload PACKETPP_IPPROTO_ESP = 50, - /** authentication header */ + /// authentication header PACKETPP_IPPROTO_AH = 51, - /** ICMPv6 */ + /// ICMPv6 PACKETPP_IPPROTO_ICMPV6 = 58, - /** IPv6 no next header */ + /// IPv6 no next header PACKETPP_IPPROTO_NONE = 59, - /** IPv6 Destination options */ + /// IPv6 Destination options PACKETPP_IPPROTO_DSTOPTS = 60, - /** VRRP protocol */ + /// VRRP protocol PACKETPP_IPPROTO_VRRP = 112, - /** Raw IP packets */ + /// Raw IP packets PACKETPP_IPPROTO_RAW = 255, - /** Maximum value */ + /// Maximum value PACKETPP_IPPROTO_MAX }; - /** - * An enum for supported IPv4 option types - */ + /// An enum for supported IPv4 option types enum IPv4OptionTypes { - /** End of Options List */ + /// End of Options List IPV4OPT_EndOfOptionsList = 0, - /** No Operation */ + /// No Operation IPV4OPT_NOP = 1, - /** Record Route */ + /// Record Route IPV4OPT_RecordRoute = 7, - /** MTU Probe */ + /// MTU Probe IPV4OPT_MTUProbe = 11, - /** MTU Reply */ + /// MTU Reply IPV4OPT_MTUReply = 12, - /** Quick-Start */ + /// Quick-Start IPV4OPT_QuickStart = 25, - /** Timestamp */ + /// Timestamp IPV4OPT_Timestamp = 68, - /** Traceroute */ + /// Traceroute IPV4OPT_Traceroute = 82, - /** Security */ + /// Security IPV4OPT_Security = 130, - /** Loose Source Route */ + /// Loose Source Route IPV4OPT_LooseSourceRoute = 131, - /** Extended Security */ + /// Extended Security IPV4OPT_ExtendedSecurity = 133, - /** Commercial Security */ + /// Commercial Security IPV4OPT_CommercialSecurity = 134, - /** Stream ID */ + /// Stream ID IPV4OPT_StreamID = 136, - /** Strict Source Route */ + /// Strict Source Route IPV4OPT_StrictSourceRoute = 137, - /** Extended Internet Protocol */ + /// Extended Internet Protocol IPV4OPT_ExtendedInternetProtocol = 145, - /** Address Extension */ + /// Address Extension IPV4OPT_AddressExtension = 147, - /** Router Alert */ + /// Router Alert IPV4OPT_RouterAlert = 148, - /** Selective Directed Broadcast */ + /// Selective Directed Broadcast IPV4OPT_SelectiveDirectedBroadcast = 149, - /** Dynamic Packet State */ + /// Dynamic Packet State IPV4OPT_DynamicPacketState = 151, - /** Upstream Multicast Pkt. */ + /// Upstream Multicast Pkt. IPV4OPT_UpstreamMulticastPkt = 152, - /** Unknown IPv4 option */ + /// Unknown IPv4 option IPV4OPT_Unknown }; #define PCPP_IP_DONT_FRAGMENT 0x40 #define PCPP_IP_MORE_FRAGMENTS 0x20 - /** - * @struct IPv4TimestampOptionValue - * A struct representing a parsed value of the IPv4 timestamp option. This struct is used returned in - * IPv4OptionData#getTimestampOptionValue() method - */ + /// @struct IPv4TimestampOptionValue + /// A struct representing a parsed value of the IPv4 timestamp option. This struct is used returned in + /// IPv4OptionData#getTimestampOptionValue() method struct IPv4TimestampOptionValue { - /** - * An enum for IPv4 timestamp option types - */ + /// An enum for IPv4 timestamp option types enum TimestampType { - /** Value containing only timestamps */ + /// Value containing only timestamps TimestampOnly = 0, - /** Value containing both timestamps and IPv4 addresses */ + /// Value containing both timestamps and IPv4 addresses TimestampAndIP = 1, - /** The IPv4 addresses are prespecified */ + /// The IPv4 addresses are prespecified TimestampsForPrespecifiedIPs = 2, - /** Invalid or unknown value type */ + /// Invalid or unknown value type Unknown = 3 }; - /** The timestamp value type */ + /// The timestamp value type TimestampType type; - /** A list of timestamps parsed from the IPv4 timestamp option value */ + /// A list of timestamps parsed from the IPv4 timestamp option value std::vector timestamps; - /** A list of IPv4 addresses parsed from the IPv4 timestamp option value */ + /// A list of IPv4 addresses parsed from the IPv4 timestamp option value std::vector ipAddresses; - /** The default constructor */ + /// The default constructor IPv4TimestampOptionValue() : type(IPv4TimestampOptionValue::Unknown) {} - /** - * Clear the structure. Clean the timestamps and IP addresses vectors and set the type as - * IPv4TimestampOptionValue#Unknown - */ + /// Clear the structure. Clean the timestamps and IP addresses vectors and set the type as + /// IPv4TimestampOptionValue#Unknown void clear() { type = IPv4TimestampOptionValue::Unknown; @@ -209,34 +194,26 @@ namespace pcpp } }; - /** - * @class IPv4Option - * A wrapper class for IPv4 options. This class does not create or modify IPv4 option records, but rather - * serves as a wrapper and provides useful methods for retrieving data from them - */ + /// @class IPv4Option + /// A wrapper class for IPv4 options. This class does not create or modify IPv4 option records, but rather + /// serves as a wrapper and provides useful methods for retrieving data from them class IPv4Option : public TLVRecord { public: - /** - * A c'tor for this class that gets a pointer to the option raw data (byte array) - * @param[in] optionRawData A pointer to the IPv4 option raw data - */ + /// A c'tor for this class that gets a pointer to the option raw data (byte array) + /// @param[in] optionRawData A pointer to the IPv4 option raw data explicit IPv4Option(uint8_t* optionRawData) : TLVRecord(optionRawData) {} - /** - * A d'tor for this class, currently does nothing - */ + /// A d'tor for this class, currently does nothing ~IPv4Option() override = default; - /** - * A method for parsing the IPv4 option value as a list of IPv4 addresses. This method is relevant only for - * certain types of IPv4 options which their value is a list of IPv4 addresses such as ::IPV4OPT_RecordRoute, - * ::IPV4OPT_StrictSourceRoute, ::IPV4OPT_LooseSourceRoute, etc. This method returns a vector of the IPv4 - * addresses. Blank IP addresses (meaning zeroed addresses - 0.0.0.0) will not be added to the returned list. If - * some error occurs during the parsing or the value is invalid an empty vector is returned - * @return A vector of IPv4 addresses parsed from the IPv4 option value - */ + /// A method for parsing the IPv4 option value as a list of IPv4 addresses. This method is relevant only for + /// certain types of IPv4 options which their value is a list of IPv4 addresses such as ::IPV4OPT_RecordRoute, + /// ::IPV4OPT_StrictSourceRoute, ::IPV4OPT_LooseSourceRoute, etc. This method returns a vector of the IPv4 + /// addresses. Blank IP addresses (meaning zeroed addresses - 0.0.0.0) will not be added to the returned list. + /// If some error occurs during the parsing or the value is invalid an empty vector is returned + /// @return A vector of IPv4 addresses parsed from the IPv4 option value std::vector getValueAsIpList() const { std::vector res; @@ -265,15 +242,13 @@ namespace pcpp return res; } - /** - * A method for parsing the IPv4 timestamp option value. This method is relevant only for IPv4 timestamp option. - * For other option types an empty result will be returned. The returned structure contains the timestamp value - * type (timestamp only, timestamp + IP addresses, etc.) as well as 2 vectors containing the list of timestamps - * and the list of IP addresses (if applicable for the timestamp value type). Blank timestamps or IP addresses - * (meaning zeroed values - timestamp=0 or IP address=0.0.0.0) will not be added to the lists. If some error - * occurs during the parsing or the value is invalid an empty result is returned - * @return A structured containing the IPv4 timestamp value - */ + /// A method for parsing the IPv4 timestamp option value. This method is relevant only for IPv4 timestamp + /// option. For other option types an empty result will be returned. The returned structure contains the + /// timestamp value type (timestamp only, timestamp + IP addresses, etc.) as well as 2 vectors containing the + /// list of timestamps and the list of IP addresses (if applicable for the timestamp value type). Blank + /// timestamps or IP addresses (meaning zeroed values - timestamp=0 or IP address=0.0.0.0) will not be added to + /// the lists. If some error occurs during the parsing or the value is invalid an empty result is returned + /// @return A structured containing the IPv4 timestamp value IPv4TimestampOptionValue getTimestampOptionValue() const { IPv4TimestampOptionValue res; @@ -315,20 +290,16 @@ namespace pcpp return res; } - /** - * @return IPv4 option type casted as pcpp::IPv4OptionTypes enum - */ + /// @return IPv4 option type casted as pcpp::IPv4OptionTypes enum IPv4OptionTypes getIPv4OptionType() const { return getIPv4OptionType(m_Data); } - /** - * Check if a pointer can be assigned to the TLV record data - * @param[in] recordRawData A pointer to the TLV record raw data - * @param[in] tlvDataLen The size of the TLV record raw data - * @return True if data is valid and can be assigned - */ + /// Check if a pointer can be assigned to the TLV record data + /// @param[in] recordRawData A pointer to the TLV record raw data + /// @param[in] tlvDataLen The size of the TLV record raw data + /// @return True if data is valid and can be assigned static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen) { auto data = reinterpret_cast(recordRawData); @@ -372,9 +343,7 @@ namespace pcpp } private: - /** - * @return IPv4 option type casted as pcpp::IPv4OptionTypes enum - */ + /// @return IPv4 option type casted as pcpp::IPv4OptionTypes enum static IPv4OptionTypes getIPv4OptionType(const TLVRawData* data) { if (data == nullptr) @@ -384,314 +353,243 @@ namespace pcpp } }; - /** - * @class IPv4OptionBuilder - * A class for building IPv4 option records. This builder receives the IPv4 option parameters in its c'tor, - * builds the IPv4 option raw buffer and provides a build() method to get a IPv4Option object out of it - */ + /// @class IPv4OptionBuilder + /// A class for building IPv4 option records. This builder receives the IPv4 option parameters in its c'tor, + /// builds the IPv4 option raw buffer and provides a build() method to get a IPv4Option object out of it class IPv4OptionBuilder : public TLVRecordBuilder { private: bool m_BuilderParamsValid; public: - /** - * A c'tor for building IPv4 options which their value is a byte array. The IPv4Option object can be later - * retrieved by calling build() - * @param[in] optionType IPv4 option type - * @param[in] optionValue A buffer containing the option value. This buffer is read-only and isn't modified in - * any way. For option types ::IPV4OPT_NOP and ::IPV4OPT_EndOfOptionsList this parameter is ignored (expected to - * be nullptr) as these option types don't contain any data - * @param[in] optionValueLen Option value length in bytes - */ + /// A c'tor for building IPv4 options which their value is a byte array. The IPv4Option object can be later + /// retrieved by calling build() + /// @param[in] optionType IPv4 option type + /// @param[in] optionValue A buffer containing the option value. This buffer is read-only and isn't modified in + /// any way. For option types ::IPV4OPT_NOP and ::IPV4OPT_EndOfOptionsList this parameter is ignored (expected + /// to be nullptr) as these option types don't contain any data + /// @param[in] optionValueLen Option value length in bytes IPv4OptionBuilder(IPv4OptionTypes optionType, const uint8_t* optionValue, uint8_t optionValueLen) : TLVRecordBuilder((uint8_t)optionType, optionValue, optionValueLen) { m_BuilderParamsValid = true; } - /** - * A c'tor for building IPv4 options which have a 2-byte value. The IPv4Option object can be later retrieved - * by calling build() - * @param[in] optionType IPv4 option type - * @param[in] optionValue A 2-byte option value - */ + /// A c'tor for building IPv4 options which have a 2-byte value. The IPv4Option object can be later retrieved + /// by calling build() + /// @param[in] optionType IPv4 option type + /// @param[in] optionValue A 2-byte option value IPv4OptionBuilder(IPv4OptionTypes optionType, uint16_t optionValue) : TLVRecordBuilder((uint8_t)optionType, optionValue) { m_BuilderParamsValid = true; } - /** - * A c'tor for building IPv4 options which their value is a list of IPv4 addresses, for example: - * ::IPV4OPT_RecordRoute, ::IPV4OPT_StrictSourceRoute, ::IPV4OPT_LooseSourceRoute. The IPv4Option object can be - * later retrieved by calling build() - * @param[in] optionType IPv4 option type - * @param[in] ipList A vector of IPv4 addresses that will be used as the option value - */ + /// A c'tor for building IPv4 options which their value is a list of IPv4 addresses, for example: + /// ::IPV4OPT_RecordRoute, ::IPV4OPT_StrictSourceRoute, ::IPV4OPT_LooseSourceRoute. The IPv4Option object can be + /// later retrieved by calling build() + /// @param[in] optionType IPv4 option type + /// @param[in] ipList A vector of IPv4 addresses that will be used as the option value IPv4OptionBuilder(IPv4OptionTypes optionType, const std::vector& ipList); - /** - * A c'tor for building IPv4 timestamp option (::IPV4OPT_Timestamp). The IPv4Option object can be later - * retrieved by calling build() - * @param[in] timestampValue The timestamp value to build the IPv4 option with - */ + /// A c'tor for building IPv4 timestamp option (::IPV4OPT_Timestamp). The IPv4Option object can be later + /// retrieved by calling build() + /// @param[in] timestampValue The timestamp value to build the IPv4 option with explicit IPv4OptionBuilder(const IPv4TimestampOptionValue& timestampValue); - /** - * Build the IPv4Option object out of the parameters defined in the c'tor - * @return The IPv4Option object - */ + /// Build the IPv4Option object out of the parameters defined in the c'tor + /// @return The IPv4Option object IPv4Option build() const; }; - /** - * @class IPv4Layer - * Represents an IPv4 protocol layer - */ + /// @class IPv4Layer + /// Represents an IPv4 protocol layer class IPv4Layer : public Layer, public IPLayer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to @ref iphdr) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to @ref iphdr) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to @ref iphdr) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - * @param[in] setTotalLenAsDataLen When setting this value to "true" or when using the other c'tor, the layer - * data length is calculated from iphdr#totalLength field. When setting to "false" the data length is set as the - * value of dataLen parameter. Please notice that if iphdr#totalLength is equal to zero (which can happen in TCP - * Segmentation Offloading), this flag is ignored and the layer data length is calculated by the actual data - * captured on the wire - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to @ref iphdr) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in + /// @param[in] setTotalLenAsDataLen When setting this value to "true" or when using the other c'tor, the layer + /// data length is calculated from iphdr#totalLength field. When setting to "false" the data length is set as + /// the value of dataLen parameter. Please notice that if iphdr#totalLength is equal to zero (which can happen + /// in TCP Segmentation Offloading), this flag is ignored and the layer data length is calculated by the actual + /// data captured on the wire IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, bool setTotalLenAsDataLen); - /** - * A constructor that allocates a new IPv4 header with empty fields - */ + /// A constructor that allocates a new IPv4 header with empty fields IPv4Layer(); - /** - * A constructor that allocates a new IPv4 header with source and destination IPv4 addresses - * @param[in] srcIP Source IPv4 address - * @param[in] dstIP Destination IPv4 address - */ + /// A constructor that allocates a new IPv4 header with source and destination IPv4 addresses + /// @param[in] srcIP Source IPv4 address + /// @param[in] dstIP Destination IPv4 address IPv4Layer(const IPv4Address& srcIP, const IPv4Address& dstIP); - /** - * A copy constructor that copy the entire header from the other IPv4Layer (including IPv4 options) - */ + /// A copy constructor that copy the entire header from the other IPv4Layer (including IPv4 options) IPv4Layer(const IPv4Layer& other); - /** - * An assignment operator that first delete all data from current layer and then copy the entire header from the - * other IPv4Layer (including IPv4 options) - */ + /// An assignment operator that first delete all data from current layer and then copy the entire header from + /// the other IPv4Layer (including IPv4 options) IPv4Layer& operator=(const IPv4Layer& other); - /** - * Get a pointer to the IPv4 header. Notice this points directly to the data, so every change will change the - * actual packet data - * @return A pointer to the @ref iphdr - */ + /// Get a pointer to the IPv4 header. Notice this points directly to the data, so every change will change the + /// actual packet data + /// @return A pointer to the @ref iphdr iphdr* getIPv4Header() const { return reinterpret_cast(m_Data); } - /** - * Get the source IP address in the form of IPAddress. This method is very similar to getSrcIPv4Address(), - * but adds a level of abstraction because IPAddress can be used for both IPv4 and IPv6 addresses - * @return An IPAddress containing the source address - */ + /// Get the source IP address in the form of IPAddress. This method is very similar to getSrcIPv4Address(), + /// but adds a level of abstraction because IPAddress can be used for both IPv4 and IPv6 addresses + /// @return An IPAddress containing the source address IPAddress getSrcIPAddress() const override { return getSrcIPv4Address(); } - /** - * Get the source IP address in the form of IPv4Address - * @return An IPv4Address containing the source address - */ + /// Get the source IP address in the form of IPv4Address + /// @return An IPv4Address containing the source address IPv4Address getSrcIPv4Address() const { return getIPv4Header()->ipSrc; } - /** - * Set the source IP address - * @param[in] ipAddr The IP address to set - */ + /// Set the source IP address + /// @param[in] ipAddr The IP address to set void setSrcIPv4Address(const IPv4Address& ipAddr) { getIPv4Header()->ipSrc = ipAddr.toInt(); } - /** - * Get the destination IP address in the form of IPAddress. This method is very similar to getDstIPv4Address(), - * but adds a level of abstraction because IPAddress can be used for both IPv4 and IPv6 addresses - * @return An IPAddress containing the destination address - */ + /// Get the destination IP address in the form of IPAddress. This method is very similar to getDstIPv4Address(), + /// but adds a level of abstraction because IPAddress can be used for both IPv4 and IPv6 addresses + /// @return An IPAddress containing the destination address IPAddress getDstIPAddress() const override { return getDstIPv4Address(); } - /** - * Get the destination IP address in the form of IPv4Address - * @return An IPv4Address containing the destination address - */ + /// Get the destination IP address in the form of IPv4Address + /// @return An IPv4Address containing the destination address IPv4Address getDstIPv4Address() const { return getIPv4Header()->ipDst; } - /** - * Set the dest IP address - * @param[in] ipAddr The IP address to set - */ + /// Set the dest IP address + /// @param[in] ipAddr The IP address to set void setDstIPv4Address(const IPv4Address& ipAddr) { getIPv4Header()->ipDst = ipAddr.toInt(); } - /** - * @return True if this packet is a fragment (in sense of IP fragmentation), false otherwise - */ + /// @return True if this packet is a fragment (in sense of IP fragmentation), false otherwise bool isFragment() const; - /** - * @return True if this packet is a fragment (in sense of IP fragmentation) and is the first fragment - * (which usually contains the L4 header). Return false otherwise (not a fragment or not the first fragment) - */ + /// @return True if this packet is a fragment (in sense of IP fragmentation) and is the first fragment + /// (which usually contains the L4 header). Return false otherwise (not a fragment or not the first fragment) bool isFirstFragment() const; - /** - * @return True if this packet is a fragment (in sense of IP fragmentation) and is the last fragment. - * Return false otherwise (not a fragment or not the last fragment) - */ + /// @return True if this packet is a fragment (in sense of IP fragmentation) and is the last fragment. + /// Return false otherwise (not a fragment or not the last fragment) bool isLastFragment() const; - /** - * @return A bitmask containing the fragmentation flags (e.g IP_DONT_FRAGMENT or IP_MORE_FRAGMENTS) - */ + /// @return A bitmask containing the fragmentation flags (e.g IP_DONT_FRAGMENT or IP_MORE_FRAGMENTS) uint8_t getFragmentFlags() const; - /** - * @return The fragment offset in case this packet is a fragment, 0 otherwise - */ + /// @return The fragment offset in case this packet is a fragment, 0 otherwise uint16_t getFragmentOffset() const; - /** - * Get an IPv4 option by type. - * @param[in] option IPv4 option type - * @return An IPv4Option object that contains the first option that matches this type, or logical null - * (IPv4Option#isNull() == true) if no such option found - */ + /// Get an IPv4 option by type. + /// @param[in] option IPv4 option type + /// @return An IPv4Option object that contains the first option that matches this type, or logical null + /// (IPv4Option#isNull() == true) if no such option found IPv4Option getOption(IPv4OptionTypes option) const; - /** - * @return The first IPv4 option in the packet. If the current layer contains no options the returned value will - * contain a logical null (IPv4Option#isNull() == true) - */ + /// @return The first IPv4 option in the packet. If the current layer contains no options the returned value + /// will contain a logical null (IPv4Option#isNull() == true) IPv4Option getFirstOption() const; - /** - * Get the IPv4 option that comes after a given option. If the given option was the last one, the - * returned value will contain a logical null (IPv4Option#isNull() == true) - * @param[in] option An IPv4 option object that exists in the current layer - * @return A IPv4Option object that contains the IPv4 option data that comes next, or logical null if the - * given IPv4 option: (1) was the last one; or (2) contains a logical null; or (3) doesn't belong to this - * packet - */ + /// Get the IPv4 option that comes after a given option. If the given option was the last one, the + /// returned value will contain a logical null (IPv4Option#isNull() == true) + /// @param[in] option An IPv4 option object that exists in the current layer + /// @return A IPv4Option object that contains the IPv4 option data that comes next, or logical null if the + /// given IPv4 option: (1) was the last one; or (2) contains a logical null; or (3) doesn't belong to this + /// packet IPv4Option getNextOption(IPv4Option& option) const; - /** - * @return The number of IPv4 options in this layer - */ + /// @return The number of IPv4 options in this layer size_t getOptionCount() const; - /** - * Add a new IPv4 option at the end of the layer (after the last IPv4 option) - * @param[in] optionBuilder An IPv4OptionBuilder object that contains the IPv4 option data to be added - * @return A IPv4Option object that contains the newly added IPv4 option data or logical null - * (IPv4Option#isNull() == true) if addition failed. In case of a failure a corresponding error message will be - * printed to log - */ + /// Add a new IPv4 option at the end of the layer (after the last IPv4 option) + /// @param[in] optionBuilder An IPv4OptionBuilder object that contains the IPv4 option data to be added + /// @return A IPv4Option object that contains the newly added IPv4 option data or logical null + /// (IPv4Option#isNull() == true) if addition failed. In case of a failure a corresponding error message will be + /// printed to log IPv4Option addOption(const IPv4OptionBuilder& optionBuilder); - /** - * Add a new IPv4 option after an existing one - * @param[in] optionBuilder An IPv4OptionBuilder object that contains the requested IPv4 option data to be added - * @param[in] prevOptionType The IPv4 option which the newly added option should come after. This is an optional - * parameter which gets a default value of ::IPV4OPT_Unknown if omitted, which means the new option will be - * added as the first option in the layer - * @return A IPv4Option object containing the newly added IPv4 option data or logical null - * (IPv4Option#isNull() == true) if addition failed. In case of a failure a corresponding error message will be - * printed to log - */ + /// Add a new IPv4 option after an existing one + /// @param[in] optionBuilder An IPv4OptionBuilder object that contains the requested IPv4 option data to be + /// added + /// @param[in] prevOptionType The IPv4 option which the newly added option should come after. This is an + /// optional parameter which gets a default value of ::IPV4OPT_Unknown if omitted, which means the new option + /// will be added as the first option in the layer + /// @return A IPv4Option object containing the newly added IPv4 option data or logical null + /// (IPv4Option#isNull() == true) if addition failed. In case of a failure a corresponding error message will be + /// printed to log IPv4Option addOptionAfter(const IPv4OptionBuilder& optionBuilder, IPv4OptionTypes prevOptionType = IPV4OPT_Unknown); - /** - * Remove an IPv4 option - * @param[in] option The option type to remove - * @return True if option was removed successfully or false if option type wasn't found or failed to shorten the - * layer. If an option appears twice in the layer, its first instance will be removed - */ + /// Remove an IPv4 option + /// @param[in] option The option type to remove + /// @return True if option was removed successfully or false if option type wasn't found or failed to shorten + /// the layer. If an option appears twice in the layer, its first instance will be removed bool removeOption(IPv4OptionTypes option); - /** - * Remove all IPv4 options from the layer - * @return True if options removed successfully or false if some error occurred (an appropriate error message - * will be printed to log) - */ + /// Remove all IPv4 options from the layer + /// @return True if options removed successfully or false if some error occurred (an appropriate error message + /// will be printed to log) bool removeAllOptions(); // implement abstract methods - /** - * Currently identifies the following next layers: - * - UdpLayer - * - TcpLayer - * - IcmpLayer - * - IPv4Layer (IP-in-IP) - * - IPv6Layer (IP-in-IP) - * - GreLayer - * - IgmpLayer - * - AuthenticationHeaderLayer (IPSec) - * - ESPLayer (IPSec) - * - * Otherwise sets PayloadLayer - */ + /// Currently identifies the following next layers: + /// - UdpLayer + /// - TcpLayer + /// - IcmpLayer + /// - IPv4Layer (IP-in-IP) + /// - IPv6Layer (IP-in-IP) + /// - GreLayer + /// - IgmpLayer + /// - AuthenticationHeaderLayer (IPSec) + /// - ESPLayer (IPSec) + /// + /// Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * @return Size of IPv4 header (including IPv4 options if exist) - */ + /// @return Size of IPv4 header (including IPv4 options if exist) size_t getHeaderLen() const override { return static_cast(static_cast(getIPv4Header()->internetHeaderLength) * 4) + m_TempHeaderExtension; } - /** - * Calculate the following fields: - * - iphdr#ipVersion = 4; - * - iphdr#totalLength = total packet length - * - iphdr#headerChecksum = calculated - * - iphdr#protocol = calculated if next layer is known: ::PACKETPP_IPPROTO_TCP for TCP, ::PACKETPP_IPPROTO_UDP - * for UDP, ::PACKETPP_IPPROTO_ICMP for ICMP - */ + /// Calculate the following fields: + /// - iphdr#ipVersion = 4; + /// - iphdr#totalLength = total packet length + /// - iphdr#headerChecksum = calculated + /// - iphdr#protocol = calculated if next layer is known: ::PACKETPP_IPPROTO_TCP for TCP, ::PACKETPP_IPPROTO_UDP + /// for UDP, ::PACKETPP_IPPROTO_ICMP for ICMP void computeCalculateFields() override; std::string toString() const override; @@ -701,12 +599,10 @@ namespace pcpp return OsiModelNetworkLayer; } - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of IP packet - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent an IPv4 packet - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of IP packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent an IPv4 packet static inline bool isDataValid(const uint8_t* data, size_t dataLen); private: diff --git a/Packet++/header/IPv6Extensions.h b/Packet++/header/IPv6Extensions.h index b459f30d8b..e03d32837d 100644 --- a/Packet++/header/IPv6Extensions.h +++ b/Packet++/header/IPv6Extensions.h @@ -7,66 +7,51 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @class IPv6Extension - * A base class for all supported IPv6 extensions. This class is abstract, meaning it cannot be instantiated or - * copied (has private c'tor and copy c'tor) - */ + /// @class IPv6Extension + /// A base class for all supported IPv6 extensions. This class is abstract, meaning it cannot be instantiated or + /// copied (has private c'tor and copy c'tor) class IPv6Extension { friend class IPv6Layer; public: - /** - * An enum representing all supported IPv6 extension types - */ + /// An enum representing all supported IPv6 extension types enum IPv6ExtensionType { - /** Hop-By-Hop extension type */ + /// Hop-By-Hop extension type IPv6HopByHop = 0, - /** Routing extension type */ + /// Routing extension type IPv6Routing = 43, - /** IPv6 fragmentation extension type */ + /// IPv6 fragmentation extension type IPv6Fragmentation = 44, - /** Authentication Header extension type */ + /// Authentication Header extension type IPv6AuthenticationHdr = 51, - /** Destination extension type */ + /// Destination extension type IPv6Destination = 60, - /** Unknown or unsupported extension type */ + /// Unknown or unsupported extension type IPv6ExtensionUnknown = 255 }; - /** - * @return The size of extension in bytes, meaning (for most extensions): 8 * ([headerLen field] + 1) - */ + /// @return The size of extension in bytes, meaning (for most extensions): 8 * ([headerLen field] + 1) virtual size_t getExtensionLen() const { return 8 * (getBaseHeader()->headerLen + 1); } - /** - * @return The type of the extension - */ + /// @return The type of the extension IPv6ExtensionType getExtensionType() const { return m_ExtType; } - /** - * A destructor for this class - */ + /// A destructor for this class virtual ~IPv6Extension(); - /** - * @return A pointer to the next header or nullptr if the extension is the last one - */ + /// @return A pointer to the next header or nullptr if the extension is the last one IPv6Extension* getNextHeader() const { return m_NextHeader; @@ -117,69 +102,53 @@ namespace pcpp uint8_t* m_ShadowData; }; - /** - * @class IPv6FragmentationHeader - * Represents an IPv6 fragmentation extension header and allows easy access to all fragmentation parameters - */ + /// @class IPv6FragmentationHeader + /// Represents an IPv6 fragmentation extension header and allows easy access to all fragmentation parameters class IPv6FragmentationHeader : public IPv6Extension { friend class IPv6Layer; public: - /** - * @struct ipv6_frag_header - * A struct representing IPv6 fragmentation header - */ + /// @struct ipv6_frag_header + /// A struct representing IPv6 fragmentation header struct ipv6_frag_header { - /** Next header type */ + /// Next header type uint8_t nextHeader; - /** Fragmentation header size is fixed 8 bytes, so len is always zero */ + /// Fragmentation header size is fixed 8 bytes, so len is always zero uint8_t headerLen; - /** Offset, in 8-octet units, relative to the start of the fragmentable part of the original packet - * plus 1-bit indicating if more fragments will follow */ + /// Offset, in 8-octet units, relative to the start of the fragmentable part of the original packet + /// plus 1-bit indicating if more fragments will follow uint16_t fragOffsetAndFlags; - /** packet identification value. Needed for reassembly of the original packet */ + /// packet identification value. Needed for reassembly of the original packet uint32_t id; }; - /** - * A c'tor for creating a new IPv6 fragmentation extension object not bounded to a packet. Useful for adding new - * extensions to an IPv6 layer with IPv6Layer#addExtension() - * @param[in] fragId Fragmentation ID - * @param[in] fragOffset Fragmentation offset - * @param[in] lastFragment Indicates whether this fragment is the last one - */ + /// A c'tor for creating a new IPv6 fragmentation extension object not bounded to a packet. Useful for adding + /// new extensions to an IPv6 layer with IPv6Layer#addExtension() + /// @param[in] fragId Fragmentation ID + /// @param[in] fragOffset Fragmentation offset + /// @param[in] lastFragment Indicates whether this fragment is the last one IPv6FragmentationHeader(uint32_t fragId, uint16_t fragOffset, bool lastFragment); - /** - * Get a pointer to the fragmentation header. Notice the returned pointer points directly to the data, so every - * change will modify the actual packet data - * @return A pointer to the @ref ipv6_frag_header - */ + /// Get a pointer to the fragmentation header. Notice the returned pointer points directly to the data, so every + /// change will modify the actual packet data + /// @return A pointer to the @ref ipv6_frag_header ipv6_frag_header* getFragHeader() const { return (ipv6_frag_header*)getDataPtr(); } - /** - * @return True if this is the first fragment (which usually contains the L4 header), false otherwise - */ + /// @return True if this is the first fragment (which usually contains the L4 header), false otherwise bool isFirstFragment() const; - /** - * @return True if this is the last fragment, false otherwise - */ + /// @return True if this is the last fragment, false otherwise bool isLastFragment() const; - /** - * @return True if the "more fragments" bit is set, meaning more fragments are expected to follow this fragment - */ + /// @return True if the "more fragments" bit is set, meaning more fragments are expected to follow this fragment bool isMoreFragments() const; - /** - * @return The fragment offset - */ + /// @return The fragment offset uint16_t getFragmentOffset() const; private: @@ -189,47 +158,37 @@ namespace pcpp } }; - /** - * An abstract base class for Hop-By-Hop and Destination IPv6 extensions which their structure contains - * Type-Length-Value (TLV) options. This class provides access to these options and their data as well as methods to - * create new options. Notice this class is abstract and cannot be instantiated - */ + /// An abstract base class for Hop-By-Hop and Destination IPv6 extensions which their structure contains + /// Type-Length-Value (TLV) options. This class provides access to these options and their data as well as methods + /// to create new options. Notice this class is abstract and cannot be instantiated class IPv6TLVOptionHeader : public IPv6Extension { friend class IPv6Layer; public: - /** - * @class IPv6Option - * A class representing a Type-Length-Value (TLV) options that are used inside Hop-By-Hop and Destinations IPv6 - * extensions. This class does not create or modify IPv6 option records, but rather serves as a wrapper and - * provides useful methods for retrieving data from them - */ + /// @class IPv6Option + /// A class representing a Type-Length-Value (TLV) options that are used inside Hop-By-Hop and Destinations IPv6 + /// extensions. This class does not create or modify IPv6 option records, but rather serves as a wrapper and + /// provides useful methods for retrieving data from them class IPv6Option : public TLVRecord { public: static const uint8_t Pad0OptionType = 0; static const uint8_t PadNOptionType = 1; - /** - * A c'tor for this class that gets a pointer to the option raw data (byte array) - * @param[in] optionRawData A pointer to the attribute raw data - */ + /// A c'tor for this class that gets a pointer to the option raw data (byte array) + /// @param[in] optionRawData A pointer to the attribute raw data explicit IPv6Option(uint8_t* optionRawData) : TLVRecord(optionRawData) {} - /** - * A d'tor for this class, currently does nothing - */ + /// A d'tor for this class, currently does nothing ~IPv6Option() {} - /** - * Check if a pointer can be assigned to the TLV record data - * @param[in] recordRawData A pointer to the TLV record raw data - * @param[in] tlvDataLen The size of the TLV record raw data - * @return True if data is valid and can be assigned - */ + /// Check if a pointer can be assigned to the TLV record data + /// @param[in] recordRawData A pointer to the TLV record raw data + /// @param[in] tlvDataLen The size of the TLV record raw data + /// @return True if data is valid and can be assigned static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen) { auto data = (TLVRawData*)recordRawData; @@ -267,99 +226,77 @@ namespace pcpp } }; - /** - * @class IPv6TLVOptionBuilder - * A class for building IPv6 Type-Length-Value (TLV) options. This builder receives the option parameters in its - * c'tor, builds the option raw buffer and provides a method to build a IPv6Option object out of it - */ + /// @class IPv6TLVOptionBuilder + /// A class for building IPv6 Type-Length-Value (TLV) options. This builder receives the option parameters in + /// its c'tor, builds the option raw buffer and provides a method to build a IPv6Option object out of it class IPv6TLVOptionBuilder : public TLVRecordBuilder { public: - /** - * A c'tor for building IPv6 TLV options which their value is a byte array. The IPv6Option object can later - * be retrieved by calling build() - * @param[in] optType IPv6 option type - * @param[in] optValue A buffer containing the option value. This buffer is read-only and isn't modified in - * any way - * @param[in] optValueLen Option value length in bytes - */ + /// A c'tor for building IPv6 TLV options which their value is a byte array. The IPv6Option object can later + /// be retrieved by calling build() + /// @param[in] optType IPv6 option type + /// @param[in] optValue A buffer containing the option value. This buffer is read-only and isn't modified in + /// any way + /// @param[in] optValueLen Option value length in bytes IPv6TLVOptionBuilder(uint8_t optType, const uint8_t* optValue, uint8_t optValueLen) : TLVRecordBuilder(optType, optValue, optValueLen) {} - /** - * A c'tor for building IPv6 TLV options which have a 1-byte value. The IPv6Option object can later be - * retrieved by calling build() - * @param[in] optType IPv6 option type - * @param[in] optValue A 1-byte option value - */ + /// A c'tor for building IPv6 TLV options which have a 1-byte value. The IPv6Option object can later be + /// retrieved by calling build() + /// @param[in] optType IPv6 option type + /// @param[in] optValue A 1-byte option value IPv6TLVOptionBuilder(uint8_t optType, uint8_t optValue) : TLVRecordBuilder(optType, optValue) {} - /** - * A c'tor for building IPv6 TLV options which have a 2-byte value. The IPv6Option object can later be - * retrieved by calling build() - * @param[in] optType IPv6 option type - * @param[in] optValue A 2-byte option value - */ + /// A c'tor for building IPv6 TLV options which have a 2-byte value. The IPv6Option object can later be + /// retrieved by calling build() + /// @param[in] optType IPv6 option type + /// @param[in] optValue A 2-byte option value IPv6TLVOptionBuilder(uint8_t optType, uint16_t optValue) : TLVRecordBuilder(optType, optValue) {} - /** - * A copy c'tor that creates an instance of this class out of another instance and copies all the data from - * it - * @param[in] other The instance to copy data from - */ + /// A copy c'tor that creates an instance of this class out of another instance and copies all the data from + /// it + /// @param[in] other The instance to copy data from IPv6TLVOptionBuilder(const IPv6TLVOptionBuilder& other) : TLVRecordBuilder(other) {} - /** - * Assignment operator that copies all data from another instance of IPv6TLVOptionBuilder - * @param[in] other The instance to assign from - */ + /// Assignment operator that copies all data from another instance of IPv6TLVOptionBuilder + /// @param[in] other The instance to assign from IPv6TLVOptionBuilder& operator=(const IPv6TLVOptionBuilder& other) { TLVRecordBuilder::operator=(other); return *this; } - /** - * Build the IPv6Option object out of the parameters defined in the c'tor - * @return The IPv6Option object - */ + /// Build the IPv6Option object out of the parameters defined in the c'tor + /// @return The IPv6Option object IPv6Option build() const; }; - /** - * Retrieve an option by its type - * @param[in] optionType Option type - * @return An IPv6Option object that wraps the option data. If option isn't found a logical null is returned - * (IPv6Option#isNull() == true) - */ + /// Retrieve an option by its type + /// @param[in] optionType Option type + /// @return An IPv6Option object that wraps the option data. If option isn't found a logical null is returned + /// (IPv6Option#isNull() == true) IPv6Option getOption(uint8_t optionType) const; - /** - * @return An IPv6Option that wraps the first option data or logical null (IPv6Option#isNull() == true) if no - * options exist - */ + /// @return An IPv6Option that wraps the first option data or logical null (IPv6Option#isNull() == true) if no + /// options exist IPv6Option getFirstOption() const; - /** - * Returns a pointer to the option that comes after the option given as the parameter - * @param[in] option A pointer to an option instance - * @return An IPv6Option object that wraps the option data. In the following cases logical null - * (IPv6Option#isNull() == true) is returned: (1) input parameter is out-of-bounds for this extension or (2) the - * next option doesn't exist or (3) the input option is nullptr - */ + /// Returns a pointer to the option that comes after the option given as the parameter + /// @param[in] option A pointer to an option instance + /// @return An IPv6Option object that wraps the option data. In the following cases logical null + /// (IPv6Option#isNull() == true) is returned: (1) input parameter is out-of-bounds for this extension or (2) + /// the next option doesn't exist or (3) the input option is nullptr IPv6Option getNextOption(IPv6Option& option) const; - /** - * @returns The number of options this IPv6 extension contains - */ + /// @returns The number of options this IPv6 extension contains size_t getOptionCount() const; protected: - /** A private c'tor to keep this object from being constructed */ + /// A private c'tor to keep this object from being constructed explicit IPv6TLVOptionHeader(const std::vector& options); IPv6TLVOptionHeader(IDataContainer* dataContainer, size_t offset); @@ -368,22 +305,18 @@ namespace pcpp TLVRecordReader m_OptionReader; }; - /** - * @class IPv6HopByHopHeader - * Represents IPv6 Hop-By-Hop extension header and allows easy access to all of its data including the TLV options - * stored - */ + /// @class IPv6HopByHopHeader + /// Represents IPv6 Hop-By-Hop extension header and allows easy access to all of its data including the TLV options + /// stored class IPv6HopByHopHeader : public IPv6TLVOptionHeader { friend class IPv6Layer; public: - /** - * A c'tor for creating a new IPv6 Hop-By-Hop extension object not bounded to a packet. Useful for adding new - * extensions to an IPv6 layer with IPv6Layer#addExtension() - * @param[in] options A vector of IPv6TLVOptionHeader#TLVOptionBuilder instances which define the options that - * will be stored in the extension data. Notice this vector is read-only and its content won't be modified - */ + /// A c'tor for creating a new IPv6 Hop-By-Hop extension object not bounded to a packet. Useful for adding new + /// extensions to an IPv6 layer with IPv6Layer#addExtension() + /// @param[in] options A vector of IPv6TLVOptionHeader#TLVOptionBuilder instances which define the options that + /// will be stored in the extension data. Notice this vector is read-only and its content won't be modified explicit IPv6HopByHopHeader(const std::vector& options) : IPv6TLVOptionHeader(options) { m_ExtType = IPv6HopByHop; @@ -396,22 +329,18 @@ namespace pcpp } }; - /** - * @class IPv6DestinationHeader - * Represents IPv6 destination extension header and allows easy access to all of its data including the TLV options - * stored in it - */ + /// @class IPv6DestinationHeader + /// Represents IPv6 destination extension header and allows easy access to all of its data including the TLV options + /// stored in it class IPv6DestinationHeader : public IPv6TLVOptionHeader { friend class IPv6Layer; public: - /** - * A c'tor for creating a new IPv6 destination extension object not bounded to a packet. Useful for adding new - * extensions to an IPv6 layer with IPv6Layer#addExtension() - * @param[in] options A vector of IPv6TLVOptionHeader#TLVOptionBuilder instances which define the options that - * will be stored in the extension data. Notice this vector is read-only and its content won't be modified - */ + /// A c'tor for creating a new IPv6 destination extension object not bounded to a packet. Useful for adding new + /// extensions to an IPv6 layer with IPv6Layer#addExtension() + /// @param[in] options A vector of IPv6TLVOptionHeader#TLVOptionBuilder instances which define the options that + /// will be stored in the extension data. Notice this vector is read-only and its content won't be modified explicit IPv6DestinationHeader(const std::vector& options) : IPv6TLVOptionHeader(options) { m_ExtType = IPv6Destination; @@ -424,76 +353,62 @@ namespace pcpp } }; - /** - * @class IPv6RoutingHeader - * Represents IPv6 routing extension header and allows easy access to all of its data - */ + /// @class IPv6RoutingHeader + /// Represents IPv6 routing extension header and allows easy access to all of its data class IPv6RoutingHeader : public IPv6Extension { friend class IPv6Layer; public: - /** - * @struct ipv6_routing_header - * A struct representing the fixed part of the IPv6 routing extension header - */ + /// @struct ipv6_routing_header + /// A struct representing the fixed part of the IPv6 routing extension header struct ipv6_routing_header { - /** Next header type */ + /// Next header type uint8_t nextHeader; - /** The length of this header, in multiples of 8 octets, not including the first 8 octets */ + /// The length of this header, in multiples of 8 octets, not including the first 8 octets uint8_t headerLen; - /** A value representing the routing type */ + /// A value representing the routing type uint8_t routingType; - /** Number of nodes this packet still has to visit before reaching its final destination */ + /// Number of nodes this packet still has to visit before reaching its final destination uint8_t segmentsLeft; }; - /** - * A c'tor for creating a new IPv6 routing extension object not bounded to a packet. Useful for adding new - * extensions to an IPv6 layer with IPv6Layer#addExtension() - * @param[in] routingType Routing type value (will be written to ipv6_routing_header#routingType field) - * @param[in] segmentsLeft Segments left value (will be written to ipv6_routing_header#segmentsLeft field) - * @param[in] additionalRoutingData A pointer to a buffer containing the additional routing data for this - * extension. Notice this buffer is read-only and its content isn't modified - * @param[in] additionalRoutingDataLen The length of the additional routing data buffer - */ + /// A c'tor for creating a new IPv6 routing extension object not bounded to a packet. Useful for adding new + /// extensions to an IPv6 layer with IPv6Layer#addExtension() + /// @param[in] routingType Routing type value (will be written to ipv6_routing_header#routingType field) + /// @param[in] segmentsLeft Segments left value (will be written to ipv6_routing_header#segmentsLeft field) + /// @param[in] additionalRoutingData A pointer to a buffer containing the additional routing data for this + /// extension. Notice this buffer is read-only and its content isn't modified + /// @param[in] additionalRoutingDataLen The length of the additional routing data buffer IPv6RoutingHeader(uint8_t routingType, uint8_t segmentsLeft, const uint8_t* additionalRoutingData, size_t additionalRoutingDataLen); - /** - * Get a pointer to the fixed part of the routing header. Notice the return pointer points directly to the data, - * so every change will modify the actual packet data - * @return A pointer to the @ref ipv6_routing_header - */ + /// Get a pointer to the fixed part of the routing header. Notice the return pointer points directly to the + /// data, so every change will modify the actual packet data + /// @return A pointer to the @ref ipv6_routing_header ipv6_routing_header* getRoutingHeader() const { return (ipv6_routing_header*)getDataPtr(); } - /** - * @return A pointer to the buffer containing the additional routing data for this extension. Notice that any - * change in this buffer will lead to a change in the extension data - */ + /// @return A pointer to the buffer containing the additional routing data for this extension. Notice that any + /// change in this buffer will lead to a change in the extension data uint8_t* getRoutingAdditionalData() const; - /** - * @return The length of the additional routing parameters buffer - */ + /// @return The length of the additional routing parameters buffer size_t getRoutingAdditionalDataLength() const; - /** - * In many cases the additional routing data is actually IPv6 address(es). This method converts the raw buffer - * data into an IPv6 address - * @param[in] offset An offset in the additional routing buffer pointing to where the IPv6 address begins. In - * some cases there are multiple IPv6 addresses in the additional routing data buffer so this offset points to - * where the request IPv6 address begins. Also, even if there is only one IPv6 address in this buffer, sometimes - * it isn't written in the beginning of the buffer, so the offset points to where the IPv6 address begins. This - * is an optional parameter and the default offset is 0 - * @return The IPv6 address stored in the additional routing data buffer from the offset defined by the user. If - * offset is out-of-bounds of the extension of doesn't have 16 bytes (== the length of IPv6 address) until the - * end of the buffer - IPv6Address#Zero is returned - */ + /// In many cases the additional routing data is actually IPv6 address(es). This method converts the raw buffer + /// data into an IPv6 address + /// @param[in] offset An offset in the additional routing buffer pointing to where the IPv6 address begins. In + /// some cases there are multiple IPv6 addresses in the additional routing data buffer so this offset points to + /// where the request IPv6 address begins. Also, even if there is only one IPv6 address in this buffer, + /// sometimes it isn't written in the beginning of the buffer, so the offset points to where the IPv6 address + /// begins. This is an optional parameter and the default offset is 0 + /// @return The IPv6 address stored in the additional routing data buffer from the offset defined by the user. + /// If offset is out-of-bounds of the extension of doesn't have 16 bytes (== the length of IPv6 address) until + /// the end of the buffer - IPv6Address#Zero is returned IPv6Address getRoutingAdditionalDataAsIPv6Address(size_t offset = 0) const; private: @@ -503,79 +418,65 @@ namespace pcpp } }; - /** - * @class IPv6AuthenticationHeader - * Represents IPv6 authentication header extension (used in IPSec protocol) and allows easy access to all of its - * data - */ + /// @class IPv6AuthenticationHeader + /// Represents IPv6 authentication header extension (used in IPSec protocol) and allows easy access to all of its + /// data class IPv6AuthenticationHeader : public IPv6Extension { friend class IPv6Layer; public: - /** - * @struct ipv6_authentication_header - * A struct representing the fixed part of the IPv6 authentication header extension - */ + /// @struct ipv6_authentication_header + /// A struct representing the fixed part of the IPv6 authentication header extension struct ipv6_authentication_header { - /** Next header type */ + /// Next header type uint8_t nextHeader; - /** The length of this Authentication Header in 4-octet units, minus 2. For example, an AH value of 4 - * equals: [ 3×(32-bit fixed-length AH fields) + 3×(32-bit ICV fields) − 2 ] and thus an AH value of 4 means - * 24 octets */ + /// The length of this Authentication Header in 4-octet units, minus 2. For example, an AH value of 4 + /// equals: [ 3×(32-bit fixed-length AH fields) + 3×(32-bit ICV fields) − 2 ] and thus an AH value of 4 + /// means 24 octets uint8_t headerLen; - /** Reserved bytes, all zeros */ + /// Reserved bytes, all zeros uint16_t reserved; - /** Arbitrary value which is used (together with the destination IP address) to identify the security - * association of the receiving party */ + /// Arbitrary value which is used (together with the destination IP address) to identify the security + /// association of the receiving party uint32_t securityParametersIndex; - /** A monotonic strictly increasing sequence number (incremented by 1 for every packet sent) */ + /// A monotonic strictly increasing sequence number (incremented by 1 for every packet sent) uint32_t sequenceNumber; }; - /** - * A c'tor for creating a new IPv6 authentication header extension object not bounded to a packet. Useful for - * adding new extensions to an IPv6 layer with IPv6Layer#addExtension() - * @param[in] securityParametersIndex Security Parameters Index (SPI) value (will be written to - * ipv6_authentication_header#securityParametersIndex field) - * @param[in] sequenceNumber Sequence number value (will be written to ipv6_authentication_header#sequenceNumber - * field) - * @param[in] integrityCheckValue A pointer to a buffer containing the integrity check value (ICV) data for this - * extension. Notice this pointer is read-only and its content isn't modified in any way - * @param[in] integrityCheckValueLen The length of the integrity check value (ICV) buffer - */ + /// A c'tor for creating a new IPv6 authentication header extension object not bounded to a packet. Useful for + /// adding new extensions to an IPv6 layer with IPv6Layer#addExtension() + /// @param[in] securityParametersIndex Security Parameters Index (SPI) value (will be written to + /// ipv6_authentication_header#securityParametersIndex field) + /// @param[in] sequenceNumber Sequence number value (will be written to + /// ipv6_authentication_header#sequenceNumber field) + /// @param[in] integrityCheckValue A pointer to a buffer containing the integrity check value (ICV) data for + /// this extension. Notice this pointer is read-only and its content isn't modified in any way + /// @param[in] integrityCheckValueLen The length of the integrity check value (ICV) buffer IPv6AuthenticationHeader(uint32_t securityParametersIndex, uint32_t sequenceNumber, const uint8_t* integrityCheckValue, size_t integrityCheckValueLen); - /** - * Get a pointer to the fixed part of the authentication header. Notice the return pointer points directly to - * the data, so every change will modify the actual packet data - * @return A pointer to the @ref ipv6_authentication_header - */ + /// Get a pointer to the fixed part of the authentication header. Notice the return pointer points directly to + /// the data, so every change will modify the actual packet data + /// @return A pointer to the @ref ipv6_authentication_header ipv6_authentication_header* getAuthHeader() const { return (ipv6_authentication_header*)getDataPtr(); } - /** - * @return A pointer to the buffer containing the integrity check value (ICV) for this extension. Notice that - * any change in this buffer will lead to a change in the extension data - */ + /// @return A pointer to the buffer containing the integrity check value (ICV) for this extension. Notice that + /// any change in this buffer will lead to a change in the extension data uint8_t* getIntegrityCheckValue() const; - /** - * @return The length of the integrity check value (ICV) buffer - */ + /// @return The length of the integrity check value (ICV) buffer size_t getIntegrityCheckValueLength() const; // overridden methods - /** - * In the authentication header the extension length is calculated in a different way than other extensions. The - * calculation is: [ 4 * (ipv6_authentication_header#headerLen + 2) ] - * @return The length of this extension - */ + /// In the authentication header the extension length is calculated in a different way than other extensions. + /// The calculation is: [ 4 * (ipv6_authentication_header#headerLen + 2) ] + /// @return The length of this extension size_t getExtensionLen() const override { return 4 * (getBaseHeader()->headerLen + 2); diff --git a/Packet++/header/IPv6Layer.h b/Packet++/header/IPv6Layer.h index 2316181f99..2d78473753 100644 --- a/Packet++/header/IPv6Layer.h +++ b/Packet++/header/IPv6Layer.h @@ -7,230 +7,180 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @struct ip6_hdr - * Represents IPv6 protocol header - */ + /// @struct ip6_hdr + /// Represents IPv6 protocol header #pragma pack(push, 1) struct ip6_hdr { #if (BYTE_ORDER == LITTLE_ENDIAN) - /** Traffic class */ + /// Traffic class uint8_t trafficClass : 4, - /** IP version number, has the value of 6 for IPv6 */ + /// IP version number, has the value of 6 for IPv6 ipVersion : 4; #else - /** IP version number, has the value of 6 for IPv6 */ + /// IP version number, has the value of 6 for IPv6 uint8_t ipVersion : 4, - /** Traffic class */ + /// Traffic class trafficClass : 4; #endif - /** Flow label */ + /// Flow label uint8_t flowLabel[3]; - /** The size of the payload in octets, including any extension headers */ + /// The size of the payload in octets, including any extension headers uint16_t payloadLength; - /** Specifies the type of the next header (protocol). Must be one of ::IPProtocolTypes */ + /// Specifies the type of the next header (protocol). Must be one of ::IPProtocolTypes uint8_t nextHeader; - /** Replaces the time to live field of IPv4 */ + /// Replaces the time to live field of IPv4 uint8_t hopLimit; - /** Source address */ + /// Source address uint8_t ipSrc[16]; - /** Destination address */ + /// Destination address uint8_t ipDst[16]; }; #pragma pack(pop) static_assert(sizeof(ip6_hdr) == 40, "ip6_hdr size is not 40 bytes"); - /** - * @class IPv6Layer - * Represents an IPv6 protocol layer - */ + /// @class IPv6Layer + /// Represents an IPv6 protocol layer class IPv6Layer : public Layer, public IPLayer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to @ref ip6_hdr) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to @ref ip6_hdr) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in IPv6Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * A constructor that allocates a new IPv6 header with empty fields - */ + /// A constructor that allocates a new IPv6 header with empty fields IPv6Layer(); - /** - * A constructor that allocates a new IPv6 header with source and destination IPv6 addresses - * @param[in] srcIP Source IPv6 address - * @param[in] dstIP Destination IPv6 address - */ + /// A constructor that allocates a new IPv6 header with source and destination IPv6 addresses + /// @param[in] srcIP Source IPv6 address + /// @param[in] dstIP Destination IPv6 address IPv6Layer(const IPv6Address& srcIP, const IPv6Address& dstIP); - /** - * A copy constructor that copies the entire header from the other IPv6Layer (including IPv6 extensions) - */ + /// A copy constructor that copies the entire header from the other IPv6Layer (including IPv6 extensions) IPv6Layer(const IPv6Layer& other); - /** - * A destructor for this layer - */ + /// A destructor for this layer ~IPv6Layer() override; - /** - * An assignment operator that first delete all data from current layer and then copy the entire header from the - * other IPv6Layer (including IPv6 extensions) - */ + /// An assignment operator that first delete all data from current layer and then copy the entire header from + /// the other IPv6Layer (including IPv6 extensions) IPv6Layer& operator=(const IPv6Layer& other); - /** - * Get a pointer to the IPv6 header. Notice this points directly to the data, so every change will change the - * actual packet data - * @return A pointer to the @ref ip6_hdr - */ + /// Get a pointer to the IPv6 header. Notice this points directly to the data, so every change will change the + /// actual packet data + /// @return A pointer to the @ref ip6_hdr ip6_hdr* getIPv6Header() const { return reinterpret_cast(m_Data); } - /** - * Get the source IP address in the form of IPAddress. This method is very similar to getSrcIPv6Address(), - * but adds a level of abstraction because IPAddress can be used for both IPv4 and IPv6 addresses - * @return An IPAddress containing the source address - */ + /// Get the source IP address in the form of IPAddress. This method is very similar to getSrcIPv6Address(), + /// but adds a level of abstraction because IPAddress can be used for both IPv4 and IPv6 addresses + /// @return An IPAddress containing the source address IPAddress getSrcIPAddress() const override { return getSrcIPv6Address(); } - /** - * Get the source IP address in the form of IPv6Address - * @return An IPv6Address containing the source address - */ + /// Get the source IP address in the form of IPv6Address + /// @return An IPv6Address containing the source address IPv6Address getSrcIPv6Address() const { return getIPv6Header()->ipSrc; } - /** - * Set the source IP address - * @param[in] ipAddr The IP address to set - */ + /// Set the source IP address + /// @param[in] ipAddr The IP address to set void setSrcIPv6Address(const IPv6Address& ipAddr) { ipAddr.copyTo(getIPv6Header()->ipSrc); } - /** - * Set the dest IP address - * @param[in] ipAddr The IP address to set - */ + /// Set the dest IP address + /// @param[in] ipAddr The IP address to set void setDstIPv6Address(const IPv6Address& ipAddr) { ipAddr.copyTo(getIPv6Header()->ipDst); } - /** - * Get the destination IP address in the form of IPAddress. This method is very similar to getDstIPv6Address(), - * but adds a level of abstraction because IPAddress can be used for both IPv4 and IPv6 addresses - * @return An IPAddress containing the destination address - */ + /// Get the destination IP address in the form of IPAddress. This method is very similar to getDstIPv6Address(), + /// but adds a level of abstraction because IPAddress can be used for both IPv4 and IPv6 addresses + /// @return An IPAddress containing the destination address IPAddress getDstIPAddress() const override { return getDstIPv6Address(); } - /** - * Get the destination IP address in the form of IPv6Address - * @return An IPv6Address containing the destination address - */ + /// Get the destination IP address in the form of IPv6Address + /// @return An IPv6Address containing the destination address IPv6Address getDstIPv6Address() const { return getIPv6Header()->ipDst; } - /** - * @return Number of IPv6 extensions in this layer - */ + /// @return Number of IPv6 extensions in this layer size_t getExtensionCount() const; - /** - * A templated getter for an IPv6 extension of a type TIPv6Extension. TIPv6Extension has to be one of the - * supported IPv6 extensions, meaning a class that inherits IPv6Extension. If the requested extension type isn't - * found nullptr is returned - * @return A pointer to the extension instance or nullptr if the requested extension type isn't found - */ + /// A templated getter for an IPv6 extension of a type TIPv6Extension. TIPv6Extension has to be one of the + /// supported IPv6 extensions, meaning a class that inherits IPv6Extension. If the requested extension type + /// isn't found nullptr is returned + /// @return A pointer to the extension instance or nullptr if the requested extension type isn't found template TIPv6Extension* getExtensionOfType() const; - /** - * Add a new extension of type TIPv6Extension to the layer. This is a templated method and TIPv6Extension has to - * be one of the supported IPv6 extensions, meaning a class that inherits IPv6Extension. If the extension is - * added successfully a pointer to the newly added extension object is returned, otherwise nullptr is returned - * @param[in] extensionHeader The extension object to add. Notice the object passed here is read-only, meaning - * its data is copied but the object itself isn't modified - * @return If the extension is added successfully a pointer to the newly added extension object is returned. - * Otherwise nullptr is returned - */ + /// Add a new extension of type TIPv6Extension to the layer. This is a templated method and TIPv6Extension has + /// to be one of the supported IPv6 extensions, meaning a class that inherits IPv6Extension. If the extension is + /// added successfully a pointer to the newly added extension object is returned, otherwise nullptr is returned + /// @param[in] extensionHeader The extension object to add. Notice the object passed here is read-only, meaning + /// its data is copied but the object itself isn't modified + /// @return If the extension is added successfully a pointer to the newly added extension object is returned. + /// Otherwise nullptr is returned template TIPv6Extension* addExtension(const TIPv6Extension& extensionHeader); - /** - * Remove all IPv6 extensions in this layer - */ + /// Remove all IPv6 extensions in this layer void removeAllExtensions(); - /** - * @return True if this packet is an IPv6 fragment, meaning if it has an IPv6FragmentationHeader extension - */ + /// @return True if this packet is an IPv6 fragment, meaning if it has an IPv6FragmentationHeader extension bool isFragment() const; - /** - * The static method makes validation of input data - * @param[in] data The pointer to the beginning of byte stream of IP packet - * @param[in] dataLen The length of byte stream - * @return True if the data is valid and can represent the IPv6 packet - */ + /// The static method makes validation of input data + /// @param[in] data The pointer to the beginning of byte stream of IP packet + /// @param[in] dataLen The length of byte stream + /// @return True if the data is valid and can represent the IPv6 packet static inline bool isDataValid(const uint8_t* data, size_t dataLen); // implement abstract methods - /** - * Currently identifies the following next layers: - * - UdpLayer - * - TcpLayer - * - IPv4Layer (IP-in-IP) - * - IPv6Layer (IP-in-IP) - * - GreLayer - * - AuthenticationHeaderLayer (IPSec) - * - ESPLayer (IPSec) - * - * Otherwise sets PayloadLayer - */ + /// Currently identifies the following next layers: + /// - UdpLayer + /// - TcpLayer + /// - IPv4Layer (IP-in-IP) + /// - IPv6Layer (IP-in-IP) + /// - GreLayer + /// - AuthenticationHeaderLayer (IPSec) + /// - ESPLayer (IPSec) + /// + /// Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * @return Size of @ref ip6_hdr - */ + /// @return Size of @ref ip6_hdr size_t getHeaderLen() const override { return sizeof(ip6_hdr) + m_ExtensionsLen; } - /** - * Calculate the following fields: - * - ip6_hdr#payloadLength = size of payload (all data minus header size) - * - ip6_hdr#ipVersion = 6 - * - ip6_hdr#nextHeader = calculated if next layer is known: ::PACKETPP_IPPROTO_TCP for TCP, - * ::PACKETPP_IPPROTO_UDP for UDP, ::PACKETPP_IPPROTO_ICMP for ICMP - */ + /// Calculate the following fields: + /// - ip6_hdr#payloadLength = size of payload (all data minus header size) + /// - ip6_hdr#ipVersion = 6 + /// - ip6_hdr#nextHeader = calculated if next layer is known: ::PACKETPP_IPPROTO_TCP for TCP, + /// ::PACKETPP_IPPROTO_UDP for UDP, ::PACKETPP_IPPROTO_ICMP for ICMP void computeCalculateFields() override; std::string toString() const override; diff --git a/Packet++/header/IcmpLayer.h b/Packet++/header/IcmpLayer.h index dacfbcaebd..0f629ef3b6 100644 --- a/Packet++/header/IcmpLayer.h +++ b/Packet++/header/IcmpLayer.h @@ -11,277 +11,238 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @struct icmphdr - * Represents ICMP basic protocol header (common for all ICMP message types) - */ + /// @struct icmphdr + /// Represents ICMP basic protocol header (common for all ICMP message types) #pragma pack(push, 1) typedef struct icmphdr { - /** message type */ + /// message type uint8_t type; - /** message code */ + /// message code uint8_t code; - /** message checksum */ + /// message checksum uint16_t checksum; } icmphdr; #pragma pack(pop) static_assert(sizeof(icmphdr) == 4, "icmphdr size is not 4 bytes"); - /** - * An enum of all supported ICMP message types - */ + /// An enum of all supported ICMP message types enum IcmpMessageType { - /** ICMP echo (ping) reply message */ + /// ICMP echo (ping) reply message ICMP_ECHO_REPLY = 0, - /** ICMP destination unreachable message */ + /// ICMP destination unreachable message ICMP_DEST_UNREACHABLE = 3, - /** ICMP source quench message */ + /// ICMP source quench message ICMP_SOURCE_QUENCH = 4, - /** ICMP redirect message */ + /// ICMP redirect message ICMP_REDIRECT = 5, - /** ICMP echo (ping) request message */ + /// ICMP echo (ping) request message ICMP_ECHO_REQUEST = 8, - /** ICMP router advertisement message */ + /// ICMP router advertisement message ICMP_ROUTER_ADV = 9, - /** ICMP router soliciatation message */ + /// ICMP router soliciatation message ICMP_ROUTER_SOL = 10, - /** ICMP time-to-live excceded message */ + /// ICMP time-to-live excceded message ICMP_TIME_EXCEEDED = 11, - /** ICMP parameter problem message */ + /// ICMP parameter problem message ICMP_PARAM_PROBLEM = 12, - /** ICMP timestamp request message */ + /// ICMP timestamp request message ICMP_TIMESTAMP_REQUEST = 13, - /** ICMP timestamp reply message */ + /// ICMP timestamp reply message ICMP_TIMESTAMP_REPLY = 14, - /** ICMP information request message */ + /// ICMP information request message ICMP_INFO_REQUEST = 15, - /** ICMP information reply message */ + /// ICMP information reply message ICMP_INFO_REPLY = 16, - /** ICMP address mask request message */ + /// ICMP address mask request message ICMP_ADDRESS_MASK_REQUEST = 17, - /** ICMP address mask reply message */ + /// ICMP address mask reply message ICMP_ADDRESS_MASK_REPLY = 18, - /** ICMP message type unsupported by PcapPlusPlus */ + /// ICMP message type unsupported by PcapPlusPlus ICMP_UNSUPPORTED = 255 }; - /** - * An enum for all possible codes for a destination unreachable message type - * Documentation is taken from Wikipedia: https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol - */ + /// An enum for all possible codes for a destination unreachable message type + /// Documentation is taken from Wikipedia: https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol enum IcmpDestUnreachableCodes { - /** Network unreachable error */ + /// Network unreachable error IcmpNetworkUnreachable = 0, - /** Host unreachable error */ + /// Host unreachable error IcmpHostUnreachable = 1, - /** Protocol unreachable error (the designated transport protocol is not supported) */ + /// Protocol unreachable error (the designated transport protocol is not supported) IcmpProtocolUnreachable = 2, - /** Port unreachable error (the designated protocol is unable to inform the host of the incoming message) */ + /// Port unreachable error (the designated protocol is unable to inform the host of the incoming message) IcmpPortUnreachable = 3, - /** The datagram is too big. Packet fragmentation is required but the 'don't fragment' (DF) flag is on */ + /// The datagram is too big. Packet fragmentation is required but the 'don't fragment' (DF) flag is on IcmpDatagramTooBig = 4, - /** Source route failed error */ + /// Source route failed error IcmpSourceRouteFailed = 5, - /** Destination network unknown error */ + /// Destination network unknown error IcmpDestinationNetworkUnknown = 6, - /** Destination host unknown error */ + /// Destination host unknown error IcmpDestinationHostUnknown = 7, - /** Source host isolated error */ + /// Source host isolated error IcmpSourceHostIsolated = 8, - /** The destination network is administratively prohibited */ + /// The destination network is administratively prohibited IcmpDestinationNetworkProhibited = 9, - /** The destination host is administratively prohibited */ + /// The destination host is administratively prohibited IcmpDestinationHostProhibited = 10, - /** The network is unreachable for Type Of Service */ + /// The network is unreachable for Type Of Service IcmpNetworkUnreachableForTypeOfService = 11, - /** The host is unreachable for Type Of Service */ + /// The host is unreachable for Type Of Service IcmpHostUnreachableForTypeOfService = 12, - /** Communication administratively prohibited (administrative filtering prevents - * packet from being forwarded) - */ + /// Communication administratively prohibited (administrative filtering prevents + /// packet from being forwarded) IcmpCommunicationProhibited = 13, - /** Host precedence violation (indicates the requested precedence is not permitted for - * the combination of host or network and port) - */ + /// Host precedence violation (indicates the requested precedence is not permitted for + /// the combination of host or network and port) IcmpHostPrecedenceViolation = 14, - /** Precedence cutoff in effect (precedence of datagram is below the level set by - * the network administrators) - */ + /// Precedence cutoff in effect (precedence of datagram is below the level set by + /// the network administrators) IcmpPrecedenceCutoff = 15 }; - /** - * @struct icmp_echo_hdr - * ICMP echo (ping) request/reply message structure - */ + /// @struct icmp_echo_hdr + /// ICMP echo (ping) request/reply message structure #pragma pack(push, 1) typedef struct icmp_echo_hdr : icmphdr { - /** the echo (ping) request identifier */ + /// the echo (ping) request identifier uint16_t id; - /** the echo (ping) request sequence number */ + /// the echo (ping) request sequence number uint16_t sequence; - /** a timestamp of when the message was sent */ + /// a timestamp of when the message was sent uint64_t timestamp; } icmp_echo_hdr; #pragma pack(pop) static_assert(sizeof(icmp_echo_hdr) == 16, "icmp_echo_hdr size is not 16 bytes"); - /** - * @struct icmp_echo_request - * ICMP echo (ping) request/reply message structure - */ + /// @struct icmp_echo_request + /// ICMP echo (ping) request/reply message structure typedef struct icmp_echo_request { - /** a pointer to the header data */ + /// a pointer to the header data icmp_echo_hdr* header; - /** most echo requests/replies contain some payload data. This is the data length */ + /// most echo requests/replies contain some payload data. This is the data length size_t dataLength; - /** most echo requests/replies contain some payload data. This is a pointer to this data */ + /// most echo requests/replies contain some payload data. This is a pointer to this data uint8_t* data; } icmp_echo_request; - /** - * @typedef icmp_echo_reply - * ICMP echo (ping) reply message structure, same as icmp_echo_request - */ + /// @typedef icmp_echo_reply + /// ICMP echo (ping) reply message structure, same as icmp_echo_request typedef icmp_echo_request icmp_echo_reply; - /** - * @struct icmp_timestamp_request - * ICMP timestamp request message structure - */ + /// @struct icmp_timestamp_request + /// ICMP timestamp request message structure #pragma pack(push, 1) typedef struct icmp_timestamp_request : icmphdr { - /** the timestamp request identifier */ + /// the timestamp request identifier uint16_t id; - /** the timestamp request sequence number */ + /// the timestamp request sequence number uint16_t sequence; - /** the time (in milliseconds since midnight) the sender last touched the packet */ + /// the time (in milliseconds since midnight) the sender last touched the packet uint32_t originateTimestamp; - /** relevant for timestamp reply only - the time the echoer first touched it on receipt */ + /// relevant for timestamp reply only - the time the echoer first touched it on receipt uint32_t receiveTimestamp; - /** relevant for timestamp reply only - the time the echoer last touched the message on sending it */ + /// relevant for timestamp reply only - the time the echoer last touched the message on sending it uint32_t transmitTimestamp; } icmp_timestamp_request; #pragma pack(pop) static_assert(sizeof(icmp_timestamp_request) == 20, "icmp_timestamp_request size is not 20 bytes"); - /** - * @typedef icmp_timestamp_reply - * ICMP timestamp reply message structure, same as icmp_timestamp_request - */ + /// @typedef icmp_timestamp_reply + /// ICMP timestamp reply message structure, same as icmp_timestamp_request typedef icmp_timestamp_request icmp_timestamp_reply; static_assert(sizeof(icmp_timestamp_reply) == 20, "icmp_timestamp_reply size is not 20 bytes"); - /** - * @struct icmp_destination_unreachable - * ICMP destination unreachable message structure - */ + /// @struct icmp_destination_unreachable + /// ICMP destination unreachable message structure #pragma pack(push, 1) typedef struct icmp_destination_unreachable : icmphdr { - /** unused 2 bytes */ + /// unused 2 bytes uint16_t unused; - /** contains the MTU of the next-hop network if a code 4 error occurs */ + /// contains the MTU of the next-hop network if a code 4 error occurs uint16_t nextHopMTU; } icmp_destination_unreachable; #pragma pack(pop) static_assert(sizeof(icmp_destination_unreachable) == 8, "icmp_destination_unreachable size is not 8 bytes"); - /** - * @struct icmp_time_exceeded - * ICMP time-to-live exceeded message structure - */ + /// @struct icmp_time_exceeded + /// ICMP time-to-live exceeded message structure #pragma pack(push, 1) typedef struct icmp_time_exceeded : icmphdr { - /** unused 4 bytes */ + /// unused 4 bytes uint32_t unused; } icmp_time_exceeded; #pragma pack(pop) static_assert(sizeof(icmp_time_exceeded) == 8, "icmp_time_exceeded size is not 8 bytes"); - /** - * @typedef icmp_source_quench - * ICMP source quence message structure, same as icmp_time_exceeded - */ + /// @typedef icmp_source_quench + /// ICMP source quence message structure, same as icmp_time_exceeded typedef icmp_time_exceeded icmp_source_quench; static_assert(sizeof(icmp_source_quench) == 8, "icmp_source_quench size is not 8 bytes"); - /** - * @struct icmp_param_problem - * ICMP parameter problem message structure - */ + /// @struct icmp_param_problem + /// ICMP parameter problem message structure #pragma pack(push, 1) typedef struct icmp_param_problem : icmphdr { - /** in the case of an invalid IP header (Code 0), this field indicates the byte offset of the error in the - * header */ + /// in the case of an invalid IP header (Code 0), this field indicates the byte offset of the error in the + /// header uint8_t pointer; - /** unused 1 byte */ + /// unused 1 byte uint8_t unused1; - /** unused 2 bytes */ + /// unused 2 bytes uint16_t unused2; } icmp_param_problem; #pragma pack(pop) static_assert(sizeof(icmp_param_problem) == 8, "icmp_param_problem size is not 8 bytes"); - /** - * @typedef icmp_router_solicitation - * ICMP router solicitation message structure, same as icmphdr - */ + /// @typedef icmp_router_solicitation + /// ICMP router solicitation message structure, same as icmphdr typedef icmphdr icmp_router_solicitation; static_assert(sizeof(icmp_router_solicitation) == 4, "icmp_router_solicitation size is not 4 bytes"); - /** - * @struct icmp_redirect - * ICMP redirect message structure - */ + /// @struct icmp_redirect + /// ICMP redirect message structure #pragma pack(push, 1) typedef struct icmp_redirect : icmphdr { - /** an IPv4 address of the gateway to which the redirection should be sent */ + /// an IPv4 address of the gateway to which the redirection should be sent uint32_t gatewayAddress; } icmp_redirect; #pragma pack(pop) static_assert(sizeof(icmp_redirect) == 8, "icmp_redirect size is not 8 bytes"); - /** - * @struct icmp_router_address_structure - * Router address structure, relevant for ICMP router advertisement message type (icmp_router_advertisement) - */ + /// @struct icmp_router_address_structure + /// Router address structure, relevant for ICMP router advertisement message type (icmp_router_advertisement) #pragma pack(push, 1) struct icmp_router_address_structure { - /** the IPv4 address of the advertised router */ + /// the IPv4 address of the advertised router uint32_t routerAddress; - /** The preferability of the router address as a default router address, relative to other router addresses - * on the same subnet. This is a twos-complement value where higher values indicate that the route is - * more preferable */ + /// The preferability of the router address as a default router address, relative to other router addresses + /// on the same subnet. This is a twos-complement value where higher values indicate that the route is + /// more preferable uint32_t preferenceLevel; - /** - * Set router address structure from a given IPv4 address and preference level - * @param[in] addr IPv4 address to set - * @param[in] preference Preference level to set - */ + /// Set router address structure from a given IPv4 address and preference level + /// @param[in] addr IPv4 address to set + /// @param[in] preference Preference level to set void setRouterAddress(IPv4Address addr, uint32_t preference); - /** - * @return The IPv4 address extracted from icmp_router_address_structure#routerAddress field - */ + /// @return The IPv4 address extracted from icmp_router_address_structure#routerAddress field IPv4Address getAddress() const { return routerAddress; @@ -290,93 +251,77 @@ namespace pcpp #pragma pack(pop) static_assert(sizeof(icmp_router_address_structure) == 8, "icmp_router_address_structure size is not 8 bytes"); - /** - * @struct icmp_router_advertisement_hdr - * ICMP router advertisement message structure - */ + /// @struct icmp_router_advertisement_hdr + /// ICMP router advertisement message structure #pragma pack(push, 1) typedef struct icmp_router_advertisement_hdr : icmphdr { - /** the number of router advertisements in this message. Each advertisement contains one router - * address/preference level pair */ + /// the number of router advertisements in this message. Each advertisement contains one router + /// address/preference level pair uint8_t advertisementCount; - /** the number of 32-bit words of information for each router address entry in the list. The value is normally - * set to 2 (router address + preference level) */ + /// the number of 32-bit words of information for each router address entry in the list. The value is normally + /// set to 2 (router address + preference level) uint8_t addressEntrySize; - /** the maximum number of seconds that the router addresses in this list may be considered valid */ + /// the maximum number of seconds that the router addresses in this list may be considered valid uint16_t lifetime; } icmp_router_advertisement_hdr; #pragma pack(pop) static_assert(sizeof(icmp_router_advertisement_hdr) == 8, "icmp_router_advertisement_hdr size is not 8 bytes"); - /** - * @struct icmp_router_advertisement - * ICMP router advertisement message structure - */ + /// @struct icmp_router_advertisement + /// ICMP router advertisement message structure struct icmp_router_advertisement { - /** a pointer to the header data on the packet */ + /// a pointer to the header data on the packet icmp_router_advertisement_hdr* header; - /** - * Extract router advertisement at a given index - * @param[in] index The index of the router advertisement - * @return A pointer to the router advertisement on the packet or null if index is out of range (less than zero - * or greater than the number of router advertisement records on this message, determined by advertisementCount - * field) - */ + /// Extract router advertisement at a given index + /// @param[in] index The index of the router advertisement + /// @return A pointer to the router advertisement on the packet or null if index is out of range (less than zero + /// or greater than the number of router advertisement records on this message, determined by advertisementCount + /// field) icmp_router_address_structure* getRouterAddress(int index) const; }; - /** - * @struct icmp_address_mask_request - * ICMP address mask request message structure - */ + /// @struct icmp_address_mask_request + /// ICMP address mask request message structure #pragma pack(push, 1) typedef struct icmp_address_mask_request : icmphdr { - /** the address mask request identifier */ + /// the address mask request identifier uint16_t id; - /** the address mask request sequence */ + /// the address mask request sequence uint16_t sequence; - /** the subnet mask of the requesting host */ + /// the subnet mask of the requesting host uint32_t addressMask; } icmp_address_mask_request; #pragma pack(pop) static_assert(sizeof(icmp_address_mask_request) == 12, "icmp_address_mask_request size is not 12 bytes"); - /** - * @typedef icmp_address_mask_reply - * ICMP address mask reply message structure, same as icmp_address_mask_request - */ + /// @typedef icmp_address_mask_reply + /// ICMP address mask reply message structure, same as icmp_address_mask_request typedef icmp_address_mask_request icmp_address_mask_reply; - /** - * @struct icmp_info_request - * ICMP information request message structure - */ + /// @struct icmp_info_request + /// ICMP information request message structure #pragma pack(push, 1) typedef struct icmp_info_request : icmphdr { - /** the information request identifier */ + /// the information request identifier uint16_t id; - /** the information request sequence */ + /// the information request sequence uint16_t sequence; } icmp_info_request; #pragma pack(pop) static_assert(sizeof(icmp_info_request) == 8, "icmp_info_request size is not 8 bytes"); - /** - * @typedef icmp_info_reply - * ICMP information reply message structure, same as icmp_info_request - */ + /// @typedef icmp_info_reply + /// ICMP information reply message structure, same as icmp_info_request typedef icmp_info_request icmp_info_reply; static_assert(sizeof(icmp_info_reply) == 8, "icmp_info_reply size is not 8 bytes"); - /** - * @class IcmpLayer - * Represents an ICMP protocol layer (for IPv4 only) - */ + /// @class IcmpLayer + /// Represents an ICMP protocol layer (for IPv4 only) class IcmpLayer : public Layer { private: @@ -391,347 +336,274 @@ namespace pcpp bool setIpAndL4Layers(IPv4Layer* ipLayer, Layer* l4Layer); public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to @ref arphdr) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to @ref arphdr) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in // cppcheck-suppress uninitMemberVar IcmpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, ICMP) {} - /** - * An empty constructor that creates a new layer with an empty ICMP header without setting the ICMP type or ICMP - * data. Call the set*Data() methods to set ICMP type and data - */ + /// An empty constructor that creates a new layer with an empty ICMP header without setting the ICMP type or + /// ICMP data. Call the set*Data() methods to set ICMP type and data IcmpLayer(); ~IcmpLayer() override = default; - /** - * Get a pointer to the basic ICMP header. Notice this points directly to the data, so every change will change - * the actual packet data - * @return A pointer to the @ref icmphdr - */ + /// Get a pointer to the basic ICMP header. Notice this points directly to the data, so every change will change + /// the actual packet data + /// @return A pointer to the @ref icmphdr icmphdr* getIcmpHeader() const { return reinterpret_cast(m_Data); } - /** - * @return The ICMP message type - */ + /// @return The ICMP message type IcmpMessageType getMessageType() const; - /** - * @param[in] type Type to check - * @return True if the layer if of the given type, false otherwise - */ + /// @param[in] type Type to check + /// @return True if the layer if of the given type, false otherwise bool isMessageOfType(IcmpMessageType type) const { return getMessageType() == type; } - /** - * @return ICMP echo (ping) request data. If the layer isn't of type ICMP echo request nullptr is returned - */ + /// @return ICMP echo (ping) request data. If the layer isn't of type ICMP echo request nullptr is returned icmp_echo_request* getEchoRequestData(); - /** - * Set echo (ping) request message data - * @param[in] id Echo (ping) request identifier - * @param[in] sequence Echo (ping) request sequence - * @param[in] timestamp Echo (ping) request timestamp - * @param[in] data A pointer to echo (ping) request payload to set - * @param[in] dataLen The length of the echo (ping) request payload - * @return A pointer to the echo (ping) request data that have been set or nullptr if something went wrong - * (an appropriate error log is printed in such cases) - */ + /// Set echo (ping) request message data + /// @param[in] id Echo (ping) request identifier + /// @param[in] sequence Echo (ping) request sequence + /// @param[in] timestamp Echo (ping) request timestamp + /// @param[in] data A pointer to echo (ping) request payload to set + /// @param[in] dataLen The length of the echo (ping) request payload + /// @return A pointer to the echo (ping) request data that have been set or nullptr if something went wrong + /// (an appropriate error log is printed in such cases) icmp_echo_request* setEchoRequestData(uint16_t id, uint16_t sequence, uint64_t timestamp, const uint8_t* data, size_t dataLen); - /** - * @return ICMP echo reply data. If the layer isn't of type ICMP echo reply nullptr is returned - */ + /// @return ICMP echo reply data. If the layer isn't of type ICMP echo reply nullptr is returned icmp_echo_reply* getEchoReplyData(); - /** - * Set echo (ping) reply message data - * @param[in] id Echo (ping) reply identifier - * @param[in] sequence Echo (ping) reply sequence - * @param[in] timestamp Echo (ping) reply timestamp - * @param[in] data A pointer to echo (ping) reply payload to set - * @param[in] dataLen The length of the echo (ping) reply payload - * @return A pointer to the echo (ping) reply data that have been set or nullptr if something went wrong - * (an appropriate error log is printed in such cases) - */ + /// Set echo (ping) reply message data + /// @param[in] id Echo (ping) reply identifier + /// @param[in] sequence Echo (ping) reply sequence + /// @param[in] timestamp Echo (ping) reply timestamp + /// @param[in] data A pointer to echo (ping) reply payload to set + /// @param[in] dataLen The length of the echo (ping) reply payload + /// @return A pointer to the echo (ping) reply data that have been set or nullptr if something went wrong + /// (an appropriate error log is printed in such cases) icmp_echo_reply* setEchoReplyData(uint16_t id, uint16_t sequence, uint64_t timestamp, const uint8_t* data, size_t dataLen); - /** - * @return ICMP timestamp request data. If the layer isn't of type ICMP timestamp request nullptr is returned - */ + /// @return ICMP timestamp request data. If the layer isn't of type ICMP timestamp request nullptr is returned icmp_timestamp_request* getTimestampRequestData(); - /** - * Set timestamp request message data - * @param[in] id Timestamp request identifier - * @param[in] sequence Timestamp request sequence - * @param[in] originateTimestamp Time (in milliseconds since midnight) the sender last touched the packet - * @return A pointer to the timestamp request data that have been set or nullptr if something went wrong - * (an appropriate error log is printed in such cases) - */ + /// Set timestamp request message data + /// @param[in] id Timestamp request identifier + /// @param[in] sequence Timestamp request sequence + /// @param[in] originateTimestamp Time (in milliseconds since midnight) the sender last touched the packet + /// @return A pointer to the timestamp request data that have been set or nullptr if something went wrong + /// (an appropriate error log is printed in such cases) icmp_timestamp_request* setTimestampRequestData(uint16_t id, uint16_t sequence, timeval originateTimestamp); - /** - * @return ICMP timestamp reply data. If the layer isn't of type ICMP timestamp reply nullptr is returned - */ + /// @return ICMP timestamp reply data. If the layer isn't of type ICMP timestamp reply nullptr is returned icmp_timestamp_reply* getTimestampReplyData(); - /** - * Set timestamp reply message data - * @param[in] id Timestamp reply identifier - * @param[in] sequence Timestamp reply sequence - * @param[in] originateTimestamp Time (in milliseconds since midnight) the sender last touched the packet - * @param[in] receiveTimestamp The time the echoer first touched it on receipt - * @param[in] transmitTimestamp The time the echoer last touched the message on sending it - * @return A pointer to the timestamp reply data that have been set or nullptr if something went wrong - * (an appropriate error log is printed in such cases) - */ + /// Set timestamp reply message data + /// @param[in] id Timestamp reply identifier + /// @param[in] sequence Timestamp reply sequence + /// @param[in] originateTimestamp Time (in milliseconds since midnight) the sender last touched the packet + /// @param[in] receiveTimestamp The time the echoer first touched it on receipt + /// @param[in] transmitTimestamp The time the echoer last touched the message on sending it + /// @return A pointer to the timestamp reply data that have been set or nullptr if something went wrong + /// (an appropriate error log is printed in such cases) icmp_timestamp_reply* setTimestampReplyData(uint16_t id, uint16_t sequence, timeval originateTimestamp, timeval receiveTimestamp, timeval transmitTimestamp); - /** - * @return ICMP destination unreachable data. If the layer isn't of type ICMP destination unreachable nullptr is - * returned. The IP and L4 (ICMP/TCP/UDP) headers of the destination unreachable data are parsed as separate - * layers and can be retrieved via this->getNextLayer() - */ + /// @return ICMP destination unreachable data. If the layer isn't of type ICMP destination unreachable nullptr + /// is returned. The IP and L4 (ICMP/TCP/UDP) headers of the destination unreachable data are parsed as separate + /// layers and can be retrieved via this->getNextLayer() icmp_destination_unreachable* getDestUnreachableData(); - /** - * Set destination unreachable message data. This method only works if IcmpLayer is already part of a packet - * (not a standalone layer). The reason is the Internet and L4 headers given as parameters are added as separate - * layers and need a packet to be added to - * @param[in] code Destination unreachable code - * @param[in] nextHopMTU The MTU of the next-hop network if a code 4 error occurs - * @param[in] ipHeader The Internet header of the original data. This layer is added as a separate layer on the - * packet - * @param[in] l4Header The L4 header of the original data. This layer is added as a separate layer on the packet - * @return A pointer to the destination unreachable data that have been set or nullptr if something went wrong - * (an appropriate error log is printed in such cases) - */ + /// Set destination unreachable message data. This method only works if IcmpLayer is already part of a packet + /// (not a standalone layer). The reason is the Internet and L4 headers given as parameters are added as + /// separate layers and need a packet to be added to + /// @param[in] code Destination unreachable code + /// @param[in] nextHopMTU The MTU of the next-hop network if a code 4 error occurs + /// @param[in] ipHeader The Internet header of the original data. This layer is added as a separate layer on the + /// packet + /// @param[in] l4Header The L4 header of the original data. This layer is added as a separate layer on the + /// packet + /// @return A pointer to the destination unreachable data that have been set or nullptr if something went wrong + /// (an appropriate error log is printed in such cases) icmp_destination_unreachable* setDestUnreachableData(IcmpDestUnreachableCodes code, uint16_t nextHopMTU, IPv4Layer* ipHeader, Layer* l4Header); - /** - * @return ICMP source quench data. If the layer isn't of type ICMP source quench nullptr is returned. - * The IP and L4 (ICMP/TCP/UDP) headers of the source quench data are parsed as separate layers and can be - * retrieved via this->getNextLayer() - */ + /// @return ICMP source quench data. If the layer isn't of type ICMP source quench nullptr is returned. + /// The IP and L4 (ICMP/TCP/UDP) headers of the source quench data are parsed as separate layers and can be + /// retrieved via this->getNextLayer() icmp_source_quench* getSourceQuenchdata(); - /** - * Set source quench message data. This method only works if IcmpLayer is already part of a packet (not - * a standalone layer). The reason is the Internet and L4 headers given as parameters are added as separate - * layers and need a packet to be added to - * @param[in] ipHeader The Internet header of the original data. This layer is added as a separate layer on the - * packet - * @param[in] l4Header The L4 header of the original data. This layer is added as a separate layer on the packet - * @return A pointer to the source quench data that have been set or nullptr if something went wrong - * (an appropriate error log is printed in such cases) - */ + /// Set source quench message data. This method only works if IcmpLayer is already part of a packet (not + /// a standalone layer). The reason is the Internet and L4 headers given as parameters are added as separate + /// layers and need a packet to be added to + /// @param[in] ipHeader The Internet header of the original data. This layer is added as a separate layer on the + /// packet + /// @param[in] l4Header The L4 header of the original data. This layer is added as a separate layer on the + /// packet + /// @return A pointer to the source quench data that have been set or nullptr if something went wrong + /// (an appropriate error log is printed in such cases) icmp_source_quench* setSourceQuenchdata(IPv4Layer* ipHeader, Layer* l4Header); - /** - * @return ICMP redirect data. If the layer isn't of type ICMP redirect nullptr is returned. - * The IP and L4 (ICMP/TCP/UDP) headers of the redirect data are parsed as separate layers and can be - * retrieved via this->getNextLayer() - */ + /// @return ICMP redirect data. If the layer isn't of type ICMP redirect nullptr is returned. + /// The IP and L4 (ICMP/TCP/UDP) headers of the redirect data are parsed as separate layers and can be + /// retrieved via this->getNextLayer() icmp_redirect* getRedirectData(); - /** - * Set redirect message data. This method only works if IcmpLayer is already part of a packet (not - * a standalone layer). The reason is the Internet and L4 headers given as parameters are added as separate - * layers and need a packet to be added to - * @param[in] code The redirect message code. Only values between 0 and 3 are legal, the rest will cause the - * method to fail - * @param[in] gatewayAddress An IPv4 address of the gateway to which the redirection should be sent - * @param[in] ipHeader The Internet header of the original data. This layer is added as a separate layer on the - * packet - * @param[in] l4Header The L4 header of the original data. This layer is added as a separate layer on the packet - * @return A pointer to the redirect data that have been set or nullptr if something went wrong - * (an appropriate error log is printed in such cases) - */ + /// Set redirect message data. This method only works if IcmpLayer is already part of a packet (not + /// a standalone layer). The reason is the Internet and L4 headers given as parameters are added as separate + /// layers and need a packet to be added to + /// @param[in] code The redirect message code. Only values between 0 and 3 are legal, the rest will cause the + /// method to fail + /// @param[in] gatewayAddress An IPv4 address of the gateway to which the redirection should be sent + /// @param[in] ipHeader The Internet header of the original data. This layer is added as a separate layer on the + /// packet + /// @param[in] l4Header The L4 header of the original data. This layer is added as a separate layer on the + /// packet + /// @return A pointer to the redirect data that have been set or nullptr if something went wrong + /// (an appropriate error log is printed in such cases) icmp_redirect* setRedirectData(uint8_t code, IPv4Address gatewayAddress, IPv4Layer* ipHeader, Layer* l4Header); - /** - * @return ICMP router advertisement data. If the layer isn't of type ICMP router advertisement nullptr is - * returned - */ + /// @return ICMP router advertisement data. If the layer isn't of type ICMP router advertisement nullptr is + /// returned icmp_router_advertisement* getRouterAdvertisementData() const; - /** - * Set router advertisement message data - * @param[in] code The router advertisement message code. Only codes 0 or 16 are legal, the rest will fail the - * method - * @param[in] lifetimeInSeconds The maximum number of seconds that the router addresses in this list may be - * considered valid - * @param[in] routerAddresses A vector of router advertisements to set - * @return A pointer to the router advertisement data that have been set or nullptr if something went wrong - * (an appropriate error log is printed in such cases) - */ + /// Set router advertisement message data + /// @param[in] code The router advertisement message code. Only codes 0 or 16 are legal, the rest will fail the + /// method + /// @param[in] lifetimeInSeconds The maximum number of seconds that the router addresses in this list may be + /// considered valid + /// @param[in] routerAddresses A vector of router advertisements to set + /// @return A pointer to the router advertisement data that have been set or nullptr if something went wrong + /// (an appropriate error log is printed in such cases) icmp_router_advertisement* setRouterAdvertisementData( uint8_t code, uint16_t lifetimeInSeconds, const std::vector& routerAddresses); - /** - * @return ICMP router solicitation data. If the layer isn't of type ICMP router solicitation nullptr is - * returned - */ + /// @return ICMP router solicitation data. If the layer isn't of type ICMP router solicitation nullptr is + /// returned icmp_router_solicitation* getRouterSolicitationData(); - /** - * Set router solicitation message data. This message accepts no parameters as there are no parameters to this - * type of message (code is always zero) - * @return A pointer to the router solicitation data that have been set or nullptr if something went wrong - * (an appropriate error log is printed in such cases) - */ + /// Set router solicitation message data. This message accepts no parameters as there are no parameters to this + /// type of message (code is always zero) + /// @return A pointer to the router solicitation data that have been set or nullptr if something went wrong + /// (an appropriate error log is printed in such cases) icmp_router_solicitation* setRouterSolicitationData(); - /** - * @return ICMP time-to-live exceeded data. If the layer isn't of type ICMP time-to-live exceeded nullptr is - * returned. The IP and L4 (ICMP/TCP/UDP) headers of the time exceeded data are parsed as separate layers and - * can be retrieved via this->getNextLayer() - */ + /// @return ICMP time-to-live exceeded data. If the layer isn't of type ICMP time-to-live exceeded nullptr is + /// returned. The IP and L4 (ICMP/TCP/UDP) headers of the time exceeded data are parsed as separate layers and + /// can be retrieved via this->getNextLayer() icmp_time_exceeded* getTimeExceededData(); - /** - * Set time-to-live exceeded message data. This method only works if IcmpLayer is already part of a packet (not - * a standalone layer). The reason is the Internet and L4 headers given as parameters are added as separate - * layers and need a packet to be added to - * @param[in] code Time-to-live exceeded message code. Only codes 0 or 1 are legal, the rest will fail the - * method - * @param[in] ipHeader The Internet header of the original data. This layer is added as a separate layer on the - * packet - * @param[in] l4Header The L4 header of the original data. This layer is added as a separate layer on the packet - * @return A pointer to the time-to-live exceeded data that have been set or nullptr if something went wrong - * (an appropriate error log is printed in such cases) - */ + /// Set time-to-live exceeded message data. This method only works if IcmpLayer is already part of a packet (not + /// a standalone layer). The reason is the Internet and L4 headers given as parameters are added as separate + /// layers and need a packet to be added to + /// @param[in] code Time-to-live exceeded message code. Only codes 0 or 1 are legal, the rest will fail the + /// method + /// @param[in] ipHeader The Internet header of the original data. This layer is added as a separate layer on the + /// packet + /// @param[in] l4Header The L4 header of the original data. This layer is added as a separate layer on the + /// packet + /// @return A pointer to the time-to-live exceeded data that have been set or nullptr if something went wrong + /// (an appropriate error log is printed in such cases) icmp_time_exceeded* setTimeExceededData(uint8_t code, IPv4Layer* ipHeader, Layer* l4Header); - /** - * @return ICMP parameter problem data. If the layer isn't of type ICMP parameter problem nullptr is returned - */ + /// @return ICMP parameter problem data. If the layer isn't of type ICMP parameter problem nullptr is returned icmp_param_problem* getParamProblemData(); - /** - * Set parameter problem message data. This method only works if IcmpLayer is already part of a packet (not - * a standalone layer). The reason is the Internet and L4 headers given as parameters are added as separate - * layers and need a packet to be added to - * @param[in] code Parameter problem message code. Only code between 0 and 2 are legal, the rest will fail the - * method - * @param[in] errorOctetPointer In the case of an invalid IP header (Code 0), indicate the byte offset of the - * error in the header - * @param[in] ipHeader The Internet header of the original data. This layer is added as a separate layer on the - * packet - * @param[in] l4Header The L4 header of the original data. This layer is added as a separate layer on the packet - * @return A pointer to the parameter problem data that have been set or nullptr if something went wrong - * (an appropriate error log is printed in such cases) - */ + /// Set parameter problem message data. This method only works if IcmpLayer is already part of a packet (not + /// a standalone layer). The reason is the Internet and L4 headers given as parameters are added as separate + /// layers and need a packet to be added to + /// @param[in] code Parameter problem message code. Only code between 0 and 2 are legal, the rest will fail the + /// method + /// @param[in] errorOctetPointer In the case of an invalid IP header (Code 0), indicate the byte offset of the + /// error in the header + /// @param[in] ipHeader The Internet header of the original data. This layer is added as a separate layer on the + /// packet + /// @param[in] l4Header The L4 header of the original data. This layer is added as a separate layer on the + /// packet + /// @return A pointer to the parameter problem data that have been set or nullptr if something went wrong + /// (an appropriate error log is printed in such cases) icmp_param_problem* setParamProblemData(uint8_t code, uint8_t errorOctetPointer, IPv4Layer* ipHeader, Layer* l4Header); - /** - * @return ICMP address mask request data. If the layer isn't of type ICMP address mask request nullptr is - * returned - */ + /// @return ICMP address mask request data. If the layer isn't of type ICMP address mask request nullptr is + /// returned icmp_address_mask_request* getAddressMaskRequestData(); - /** - * Set address mask request message data - * @param[in] id Address mask request identifier - * @param[in] sequence Address mask request sequence - * @param[in] mask The subnet mask of the requesting host - * @return A pointer to the address mask request data that have been set or nullptr if something went wrong - * (an appropriate error log is printed in such cases) - */ + /// Set address mask request message data + /// @param[in] id Address mask request identifier + /// @param[in] sequence Address mask request sequence + /// @param[in] mask The subnet mask of the requesting host + /// @return A pointer to the address mask request data that have been set or nullptr if something went wrong + /// (an appropriate error log is printed in such cases) icmp_address_mask_request* setAddressMaskRequestData(uint16_t id, uint16_t sequence, IPv4Address mask); - /** - * @return ICMP address mask reply data. If the layer isn't of type ICMP address mask reply nullptr is returned - */ + /// @return ICMP address mask reply data. If the layer isn't of type ICMP address mask reply nullptr is returned icmp_address_mask_reply* getAddressMaskReplyData(); - /** - * Set address mask reply message data - * @param[in] id Address mask reply identifier - * @param[in] sequence Address mask reply sequence - * @param[in] mask The subnet mask of the requesting host - * @return A pointer to the address mask reply data that have been set or nullptr if something went wrong - * (an appropriate error log is printed in such cases) - */ + /// Set address mask reply message data + /// @param[in] id Address mask reply identifier + /// @param[in] sequence Address mask reply sequence + /// @param[in] mask The subnet mask of the requesting host + /// @return A pointer to the address mask reply data that have been set or nullptr if something went wrong + /// (an appropriate error log is printed in such cases) icmp_address_mask_reply* setAddressMaskReplyData(uint16_t id, uint16_t sequence, IPv4Address mask); - /** - * @return ICMP address information request data. If the layer isn't of type ICMP information request nullptr is - * returned - */ + /// @return ICMP address information request data. If the layer isn't of type ICMP information request nullptr + /// is returned icmp_info_request* getInfoRequestData(); - /** - * Set information request message data - * @param[in] id Information request identifier - * @param[in] sequence Information request sequence - * @return A pointer to the information request data that have been set or nullptr if something went wrong - * (an appropriate error log is printed in such cases) - */ + /// Set information request message data + /// @param[in] id Information request identifier + /// @param[in] sequence Information request sequence + /// @return A pointer to the information request data that have been set or nullptr if something went wrong + /// (an appropriate error log is printed in such cases) icmp_info_request* setInfoRequestData(uint16_t id, uint16_t sequence); - /** - * @return ICMP address information reply data. If the layer isn't of type ICMP information reply nullptr is - * returned - */ + /// @return ICMP address information reply data. If the layer isn't of type ICMP information reply nullptr is + /// returned icmp_info_reply* getInfoReplyData(); - /** - * Set information reply message data - * @param[in] id Information reply identifier - * @param[in] sequence Information reply sequence - * @return A pointer to the information reply data that have been set or nullptr if something went wrong - * (an appropriate error log is printed in such cases) - */ + /// Set information reply message data + /// @param[in] id Information reply identifier + /// @param[in] sequence Information reply sequence + /// @return A pointer to the information reply data that have been set or nullptr if something went wrong + /// (an appropriate error log is printed in such cases) icmp_info_reply* setInfoReplyData(uint16_t id, uint16_t sequence); - /** - * The static method makes validation of input data - * @param[in] data The pointer to the beginning of byte stream of ICMP packet - * @param[in] dataLen The length of byte stream - * @return True if the data is valid and can represent an ICMP packet - */ + /// The static method makes validation of input data + /// @param[in] data The pointer to the beginning of byte stream of ICMP packet + /// @param[in] dataLen The length of byte stream + /// @return True if the data is valid and can represent an ICMP packet static inline bool isDataValid(const uint8_t* data, size_t dataLen); // implement abstract methods - /** - * ICMP messages of types: ICMP_DEST_UNREACHABLE, ICMP_SOURCE_QUENCH, ICMP_TIME_EXCEEDED, ICMP_REDIRECT, - * ICMP_PARAM_PROBLEM have data that contains IPv4 header and some L4 header (TCP/UDP/ICMP). This method parses - * these headers as separate layers on top of the ICMP layer - */ + /// ICMP messages of types: ICMP_DEST_UNREACHABLE, ICMP_SOURCE_QUENCH, ICMP_TIME_EXCEEDED, ICMP_REDIRECT, + /// ICMP_PARAM_PROBLEM have data that contains IPv4 header and some L4 header (TCP/UDP/ICMP). This method parses + /// these headers as separate layers on top of the ICMP layer void parseNextLayer() override; - /** - * @return The ICMP header length. This length varies according to the ICMP message type. This length doesn't - * include IPv4 and L4 headers in case ICMP message type are: ICMP_DEST_UNREACHABLE, ICMP_SOURCE_QUENCH, - * ICMP_TIME_EXCEEDED, ICMP_REDIRECT, ICMP_PARAM_PROBLEM - */ + /// @return The ICMP header length. This length varies according to the ICMP message type. This length doesn't + /// include IPv4 and L4 headers in case ICMP message type are: ICMP_DEST_UNREACHABLE, ICMP_SOURCE_QUENCH, + /// ICMP_TIME_EXCEEDED, ICMP_REDIRECT, ICMP_PARAM_PROBLEM size_t getHeaderLen() const override; - /** - * Calculate ICMP checksum field - */ + /// Calculate ICMP checksum field void computeCalculateFields() override; std::string toString() const override; diff --git a/Packet++/header/IcmpV6Layer.h b/Packet++/header/IcmpV6Layer.h index 2fbf1f07fe..4038b5e2f2 100644 --- a/Packet++/header/IcmpV6Layer.h +++ b/Packet++/header/IcmpV6Layer.h @@ -4,209 +4,178 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * An enum representing the available ICMPv6 message types - */ + /// An enum representing the available ICMPv6 message types enum class ICMPv6MessageType : int { - /** Unknown ICMPv6 message */ + /// Unknown ICMPv6 message ICMPv6_UNKNOWN_MESSAGE = 0, - /** Destination Unreachable Message */ + /// Destination Unreachable Message ICMPv6_DESTINATION_UNREACHABLE = 1, - /** Packet Too Big Message */ + /// Packet Too Big Message ICMPv6_PACKET_TOO_BIG = 2, - /** Time Exceeded Message */ + /// Time Exceeded Message ICMPv6_TIME_EXCEEDED = 3, - /** Parameter Problem Message */ + /// Parameter Problem Message ICMPv6_PARAMETER_PROBLEM = 4, - /** Private Experimentation Message */ + /// Private Experimentation Message ICMPv6_PRIVATE_EXPERIMENTATION1 = 100, - /** Private Experimentation Message */ + /// Private Experimentation Message ICMPv6_PRIVATE_EXPERIMENTATION2 = 101, - /** Reserved for expansion of ICMPv6 error messages */ + /// Reserved for expansion of ICMPv6 error messages ICMPv6_RESERVED_EXPANSION_ERROR = 127, - /** Echo Request Message */ + /// Echo Request Message ICMPv6_ECHO_REQUEST = 128, - /** Echo Reply Message */ + /// Echo Reply Message ICMPv6_ECHO_REPLY = 129, - /** Multicast Listener Query Message */ + /// Multicast Listener Query Message ICMPv6_MULTICAST_LISTENER_QUERY = 130, - /** Multicast Listener Report Message */ + /// Multicast Listener Report Message ICMPv6_MULTICAST_LISTENER_REPORT = 131, - /** Multicast Listener Done Message */ + /// Multicast Listener Done Message ICMPv6_MULTICAST_LISTENER_DONE = 132, - /** Router Solicitation Message */ + /// Router Solicitation Message ICMPv6_ROUTER_SOLICITATION = 133, - /** Router Advertisement Message */ + /// Router Advertisement Message ICMPv6_ROUTER_ADVERTISEMENT = 134, - /** Neighbor Solicitation Message */ + /// Neighbor Solicitation Message ICMPv6_NEIGHBOR_SOLICITATION = 135, - /** Neighbor Advertisement Message */ + /// Neighbor Advertisement Message ICMPv6_NEIGHBOR_ADVERTISEMENT = 136, - /** Redirect Message */ + /// Redirect Message ICMPv6_REDIRECT_MESSAGE = 137, - /** Router Renumbering Message */ + /// Router Renumbering Message ICMPv6_ROUTER_RENUMBERING = 138, - /** Node Information Query Message */ + /// Node Information Query Message ICMPv6_ICMP_NODE_INFORMATION_QUERY = 139, - /** Node Information Reply Message*/ + /// Node Information Reply Message ICMPv6_ICMP_NODE_INFORMATION_RESPONSE = 140, - /** Inverse Neighbor Discovery Solicitation Message */ + /// Inverse Neighbor Discovery Solicitation Message ICMPv6_INVERSE_NEIGHBOR_DISCOVERY_SOLICITATION_MESSAGE = 141, - /** Inverse Neighbor Discovery Advertisement Message */ + /// Inverse Neighbor Discovery Advertisement Message ICMPv6_INVERSE_NEIGHBOR_DISCOVERY_ADVERTISEMENT_MESSAGE = 142, - /** Multicast Listener Report Message */ + /// Multicast Listener Report Message ICMPv6_MULTICAST_LISTENER_DISCOVERY_REPORTS = 143, - /** Home Agent Address Discovery Request Message */ + /// Home Agent Address Discovery Request Message ICMPv6_HOME_AGENT_ADDRESS_DISCOVERY_REQUEST_MESSAGE = 144, - /** Home Agent Address Discovery Reply Message */ + /// Home Agent Address Discovery Reply Message ICMPv6_HOME_AGENT_ADDRESS_DISCOVERY_REPLY_MESSAGE = 145, - /** Mobile Prefix Solicitation Message */ + /// Mobile Prefix Solicitation Message ICMPv6_MOBILE_PREFIX_SOLICITATION = 146, - /** Mobile Prefix Advertisement Message */ + /// Mobile Prefix Advertisement Message ICMPv6_MOBILE_PREFIX_ADVERTISEMENT = 147, - /** Certification Path Solicitation Message */ + /// Certification Path Solicitation Message ICMPv6_CERTIFICATION_PATH_SOLICITATION = 148, - /** Certification Path Advertisement Message */ + /// Certification Path Advertisement Message ICMPv6_CERTIFICATION_PATH_ADVERTISEMENT = 149, - /** ICMP Experimental Mobility Subtype Format and Registry Message */ + /// ICMP Experimental Mobility Subtype Format and Registry Message ICMPv6_EXPERIMENTAL_MOBILITY = 150, - /** Multicast Router Advertisement Message */ + /// Multicast Router Advertisement Message ICMPv6_MULTICAST_ROUTER_ADVERTISEMENT = 151, - /** Multicast Router Solicitation Message */ + /// Multicast Router Solicitation Message ICMPv6_MULTICAST_ROUTER_SOLICITATION = 152, - /** Multicast Router Termination Message*/ + /// Multicast Router Termination Message ICMPv6_MULTICAST_ROUTER_TERMINATION = 153, - /** RPL Control Message */ + /// RPL Control Message ICMPv6_RPL_CONTROL_MESSAGE = 155, - /** Private Experimentation Message */ + /// Private Experimentation Message ICMPv6_PRIVATE_EXPERIMENTATION3 = 200, - /** Private Experimentation Message */ + /// Private Experimentation Message ICMPv6_PRIVATE_EXPERIMENTATION4 = 201, - /** Reserved for expansion of ICMPv6 informational messages */ + /// Reserved for expansion of ICMPv6 informational messages ICMPv6_RESERVED_EXPANSION_INFORMATIONAL = 255 }; -/** - * @struct icmpv6hdr - * Represents an ICMPv6 protocol header - */ + /// @struct icmpv6hdr + /// Represents an ICMPv6 protocol header #pragma pack(push, 1) struct icmpv6hdr { - /** Type of the message. Values in the range from 0 to 127 (high-order bit is 0) indicate an error message, - while values in the range from 128 to 255 (high-order bit is 1) indicate an information message. */ + /// Type of the message. Values in the range from 0 to 127 (high-order bit is 0) indicate an error message, + /// while values in the range from 128 to 255 (high-order bit is 1) indicate an information message. uint8_t type; - /** The code field value depends on the message type and provides an additional level of message granularity */ + /// The code field value depends on the message type and provides an additional level of message granularity uint8_t code; - /** The checksum field provides a minimal level of integrity verification for the ICMP message */ + /// The checksum field provides a minimal level of integrity verification for the ICMP message uint16_t checksum; }; #pragma pack(pop) static_assert(sizeof(icmpv6hdr) == 4, "icmpv6hdr size is not 4 bytes"); -/** - * @struct icmpv6_echo_hdr - * ICMP echo request/reply message structure - */ + /// @struct icmpv6_echo_hdr + /// ICMP echo request/reply message structure #pragma pack(push, 1) typedef struct icmpv6_echo_hdr : icmpv6hdr { - /** the echo request identifier */ + /// the echo request identifier uint16_t id; - /** the echo request sequence number */ + /// the echo request sequence number uint16_t sequence; } icmpv6_echo_hdr; #pragma pack(pop) static_assert(sizeof(icmpv6_echo_hdr) == 8, "icmpv6_echo_hdr size is not 8 bytes"); - /** - * @class IcmpV6Layer - * Base class for ICMPv6 protocol layers which provides common logic for ICMPv6 messages. - */ + /// @class IcmpV6Layer + /// Base class for ICMPv6 protocol layers which provides common logic for ICMPv6 messages. class IcmpV6Layer : public Layer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param data A pointer to the raw data - * @param dataLen Size of the data in bytes - * @param prevLayer A pointer to the previous layer - * @param packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param data A pointer to the raw data + /// @param dataLen Size of the data in bytes + /// @param prevLayer A pointer to the previous layer + /// @param packet A pointer to the Packet instance where layer will be stored in IcmpV6Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, ICMPv6) {} - /** - * A constructor that allocates a new ICMPv6 layer with type, code and data - * @param[in] msgType Message type of the ICMPv6 layer - * @param[in] code Code field of the ICMPv6 layer - * @param[in] data A pointer to the payload to set - * @param[in] dataLen The length of the payload - */ + /// A constructor that allocates a new ICMPv6 layer with type, code and data + /// @param[in] msgType Message type of the ICMPv6 layer + /// @param[in] code Code field of the ICMPv6 layer + /// @param[in] data A pointer to the payload to set + /// @param[in] dataLen The length of the payload IcmpV6Layer(ICMPv6MessageType msgType, uint8_t code, const uint8_t* data, size_t dataLen); ~IcmpV6Layer() override = default; - /** - * A static method that creates an ICMPv6 layer from packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored - * @return Layer* A newly allocated ICMPv6 layer - */ + /// A static method that creates an ICMPv6 layer from packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored + /// @return Layer* A newly allocated ICMPv6 layer static Layer* parseIcmpV6Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * @param[in] type Type to check - * @return True if the layer if of the given type, false otherwise - */ + /// @param[in] type Type to check + /// @return True if the layer if of the given type, false otherwise bool isMessageOfType(ICMPv6MessageType type) const { return getMessageType() == type; } - /** - * @return Get the ICMPv6 Message Type - */ + /// @return Get the ICMPv6 Message Type ICMPv6MessageType getMessageType() const; - /** - * @return Get the code header field - */ + /// @return Get the code header field uint8_t getCode() const; - /** - * @return Get the checksum header field in host representation - */ + /// @return Get the checksum header field in host representation uint16_t getChecksum() const; - /** - * Does nothing for this layer. ICMPv6 is the last layer. - */ + /// Does nothing for this layer. ICMPv6 is the last layer. void parseNextLayer() override {} - /** - * @return The size of the ICMPv6 message - */ + /// @return The size of the ICMPv6 message size_t getHeaderLen() const override { return m_DataLen; } - /** - * Calculate ICMPv6 checksum field - */ + /// Calculate ICMPv6 checksum field void computeCalculateFields() override; OsiModelLayer getOsiModelLayer() const override @@ -227,68 +196,52 @@ namespace pcpp } }; - /** - * @class ICMPv6EchoLayer - * Represents an ICMPv6 echo request/reply protocol layer - */ + /// @class ICMPv6EchoLayer + /// Represents an ICMPv6 echo request/reply protocol layer class ICMPv6EchoLayer : public IcmpV6Layer { public: - /** - * An enum representing ICMPv6 echo message types - */ + /// An enum representing ICMPv6 echo message types enum ICMPv6EchoType { - /** Echo Request Type */ + /// Echo Request Type REQUEST, - /** Echo Reply Type */ + /// Echo Reply Type REPLY }; - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in ICMPv6EchoLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : IcmpV6Layer(data, dataLen, prevLayer, packet) {} - /** - * A constructor for a new echo request/reply layer - * @param[in] echoType The type of the echo message - * @param[in] id Echo request identifier - * @param[in] sequence Echo request sequence number - * @param[in] data A pointer to echo request payload to set - * @param[in] dataLen The length of the echo request payload - */ + /// A constructor for a new echo request/reply layer + /// @param[in] echoType The type of the echo message + /// @param[in] id Echo request identifier + /// @param[in] sequence Echo request sequence number + /// @param[in] data A pointer to echo request payload to set + /// @param[in] dataLen The length of the echo request payload ICMPv6EchoLayer(ICMPv6EchoType echoType, uint16_t id, uint16_t sequence, const uint8_t* data, size_t dataLen); ~ICMPv6EchoLayer() override = default; - /** - * @return Identifier in host representation - */ + /// @return Identifier in host representation uint16_t getIdentifier() const; - /** - * @return Sequence number in host representation - */ + /// @return Sequence number in host representation uint16_t getSequenceNr() const; - /** - * @return Size of the data in bytes - */ + /// @return Size of the data in bytes size_t getEchoDataLen() const { return m_DataLen - sizeof(icmpv6_echo_hdr); } - /** - * @return Pointer to the beginning of the data - */ + /// @return Pointer to the beginning of the data uint8_t* getEchoDataPtr() const { return m_Data + sizeof(icmpv6_echo_hdr); diff --git a/Packet++/header/IgmpLayer.h b/Packet++/header/IgmpLayer.h index 68ecc59140..c6418cc865 100644 --- a/Packet++/header/IgmpLayer.h +++ b/Packet++/header/IgmpLayer.h @@ -6,161 +6,135 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct igmp_header - * IGMPv1 and IGMPv2 basic protocol header - */ + /// @struct igmp_header + /// IGMPv1 and IGMPv2 basic protocol header struct igmp_header { - /** Indicates the message type. The enum for message type is pcpp::IgmpType */ + /// Indicates the message type. The enum for message type is pcpp::IgmpType uint8_t type; - /** Specifies the time limit for the corresponding report. The field has a resolution of 100 milliseconds */ + /// Specifies the time limit for the corresponding report. The field has a resolution of 100 milliseconds uint8_t maxResponseTime; - /** This is the 16-bit one's complement of the one's complement sum of the entire IGMP message */ + /// This is the 16-bit one's complement of the one's complement sum of the entire IGMP message uint16_t checksum; - /** This is the multicast address being queried when sending a Group-Specific or Group-and-Source-Specific Query - */ + /// This is the multicast address being queried when sending a Group-Specific or Group-and-Source-Specific Query uint32_t groupAddress; }; static_assert(sizeof(igmp_header) == 8, "igmp_header size is not 8 bytes"); - /** - * @struct igmpv3_query_header - * IGMPv3 membership query basic header - */ + /// @struct igmpv3_query_header + /// IGMPv3 membership query basic header struct igmpv3_query_header { - /** IGMP message type. Should always have value of membership query (::IgmpType_MembershipQuery) */ + /// IGMP message type. Should always have value of membership query (::IgmpType_MembershipQuery) uint8_t type; - /** This field specifies the maximum time (in 1/10 second) allowed before sending a responding report */ + /// This field specifies the maximum time (in 1/10 second) allowed before sending a responding report uint8_t maxResponseTime; - /** This is the 16-bit one's complement of the one's complement sum of the entire IGMP message */ + /// This is the 16-bit one's complement of the one's complement sum of the entire IGMP message uint16_t checksum; - /** This is the multicast address being queried when sending a Group-Specific or Group-and-Source-Specific Query - */ + /// This is the multicast address being queried when sending a Group-Specific or Group-and-Source-Specific Query uint32_t groupAddress; - /** Suppress Router-side Processing Flag + Querier's Robustness Variable */ + /// Suppress Router-side Processing Flag + Querier's Robustness Variable uint8_t s_qrv; - /** Querier's Query Interval Code */ + /// Querier's Query Interval Code uint8_t qqic; - /** This field specifies the number of source addresses present in the Query */ + /// This field specifies the number of source addresses present in the Query uint16_t numOfSources; }; static_assert(sizeof(igmpv3_query_header) == 12, "igmpv3_query_header size is not 12 bytes"); - /** - * @struct igmpv3_report_header - * IGMPv3 membership report basic header - */ + /// @struct igmpv3_report_header + /// IGMPv3 membership report basic header struct igmpv3_report_header { - /** IGMP message type. Should always have value of IGMPv3 membership report (::IgmpType_MembershipReportV3) */ + /// IGMP message type. Should always have value of IGMPv3 membership report (::IgmpType_MembershipReportV3) uint8_t type; - /** Unused byte */ + /// Unused byte uint8_t reserved1; - /** This is the 16-bit one's complement of the one's complement sum of the entire IGMP message */ + /// This is the 16-bit one's complement of the one's complement sum of the entire IGMP message uint16_t checksum; - /** Unused bytes */ + /// Unused bytes uint16_t reserved2; - /** This field specifies the number of group records present in the Report */ + /// This field specifies the number of group records present in the Report uint16_t numOfGroupRecords; }; static_assert(sizeof(igmpv3_report_header) == 8, "igmpv3_report_header size is not 8 bytes"); - /** - * @struct igmpv3_group_record - * A block of fields containing information pertaining to the sender's membership in a single multicast group on the - * interface from which the Report is sent. Relevant only for IGMPv3 membership report messages - */ + /// @struct igmpv3_group_record + /// A block of fields containing information pertaining to the sender's membership in a single multicast group on + /// the interface from which the Report is sent. Relevant only for IGMPv3 membership report messages struct igmpv3_group_record { - /** Group record type */ + /// Group record type uint8_t recordType; - /** Contains the length of the Auxiliary Data field in this Group Record. A value other than 0 isn't supported - */ + /// Contains the length of the Auxiliary Data field in this Group Record. A value other than 0 isn't supported uint8_t auxDataLen; - /** Specifies how many source addresses are present in this Group Record */ + /// Specifies how many source addresses are present in this Group Record uint16_t numOfSources; - /** Contains the IP multicast address to which this Group Record pertains */ + /// Contains the IP multicast address to which this Group Record pertains uint32_t multicastAddress; - /** A vector of n IP unicast addresses, where n is the value in this record's Number of Sources field */ + /// A vector of n IP unicast addresses, where n is the value in this record's Number of Sources field uint8_t sourceAddresses[]; - /** - * @return The multicast address in igmpv3_group_record#multicastAddress as IPv4Address instance - */ + /// @return The multicast address in igmpv3_group_record#multicastAddress as IPv4Address instance IPv4Address getMulticastAddress() const { return multicastAddress; } - /** - * @return The number of source addresses in this group record - */ + /// @return The number of source addresses in this group record uint16_t getSourceAddressCount() const; - /** - * Get the source address at a certain index - * @param[in] index The index of the source address in the group record - * @return The source address in the requested index. If index is negative or higher than the number of source - * addresses in this group record the value if IPv4Address#Zero is returned - */ + /// Get the source address at a certain index + /// @param[in] index The index of the source address in the group record + /// @return The source address in the requested index. If index is negative or higher than the number of source + /// addresses in this group record the value if IPv4Address#Zero is returned IPv4Address getSourceAddressAtIndex(int index) const; - /** - * @return The total size in bytes of the group record - */ + /// @return The total size in bytes of the group record size_t getRecordLen() const; }; - /** - * IGMP message types - */ + /// IGMP message types enum IgmpType { - /** Unknown message type */ + /// Unknown message type IgmpType_Unknown = 0, - /** IGMP Membership Query */ + /// IGMP Membership Query IgmpType_MembershipQuery = 0x11, - /** IGMPv1 Membership Report */ + /// IGMPv1 Membership Report IgmpType_MembershipReportV1 = 0x12, - /** DVMRP */ + /// DVMRP IgmpType_DVMRP = 0x13, - /** PIM version 1 */ + /// PIM version 1 IgmpType_P1Mv1 = 0x14, - /** Cisco Trace Messages */ + /// Cisco Trace Messages IgmpType_CiscoTrace = 0x15, - /** IGMPv2 Membership Report */ + /// IGMPv2 Membership Report IgmpType_MembershipReportV2 = 0x16, - /** IGMPv2 Leave Group */ + /// IGMPv2 Leave Group IgmpType_LeaveGroup = 0x17, - /** Multicast Traceroute Response */ + /// Multicast Traceroute Response IgmpType_MulticastTracerouteResponse = 0x1e, - /** Multicast Traceroute */ + /// Multicast Traceroute IgmpType_MulticastTraceroute = 0x1f, - /** IGMPv3 Membership Report */ + /// IGMPv3 Membership Report IgmpType_MembershipReportV3 = 0x22, - /** MRD, Multicast Router Advertisement */ + /// MRD, Multicast Router Advertisement IgmpType_MulticastRouterAdvertisement = 0x30, - /** MRD, Multicast Router Solicitation */ + /// MRD, Multicast Router Solicitation IgmpType_MulticastRouterSolicitation = 0x31, - /** MRD, Multicast Router Termination */ + /// MRD, Multicast Router Termination IgmpType_MulticastRouterTermination = 0x32, }; - /** - * @class IgmpLayer - * A base class for all IGMP (Internet Group Management Protocol) protocol classes. This is an abstract class and - * cannot be instantiated, only its child classes can be instantiated. The inherited classes represent the different - * versions of the protocol: IGMPv1, IGMPv2 and IGMPv3 - */ + /// @class IgmpLayer + /// A base class for all IGMP (Internet Group Management Protocol) protocol classes. This is an abstract class and + /// cannot be instantiated, only its child classes can be instantiated. The inherited classes represent the + /// different versions of the protocol: IGMPv1, IGMPv2 and IGMPv3 class IgmpLayer : public Layer { protected: @@ -177,63 +151,47 @@ namespace pcpp public: ~IgmpLayer() override = default; - /** - * Get a pointer to the raw IGMPv1/IGMPv2 header. Notice this points directly to the data, so every change will - * change the actual packet data - * @return A pointer to the @ref igmp_header - */ + /// Get a pointer to the raw IGMPv1/IGMPv2 header. Notice this points directly to the data, so every change will + /// change the actual packet data + /// @return A pointer to the @ref igmp_header igmp_header* getIgmpHeader() const { return reinterpret_cast(m_Data); } - /** - * @return The IPv4 multicast address stored igmp_header#groupAddress - */ + /// @return The IPv4 multicast address stored igmp_header#groupAddress IPv4Address getGroupAddress() const { return getIgmpHeader()->groupAddress; } - /** - * Set the IPv4 multicast address - * @param[in] groupAddr The IPv4 address to set - */ + /// Set the IPv4 multicast address + /// @param[in] groupAddr The IPv4 address to set void setGroupAddress(const IPv4Address& groupAddr); - /** - * @return IGMP type set in igmp_header#type as ::IgmpType enum. Notice that if igmp_header#type contains a - * value that doesn't appear in the ::IgmpType enum, ::IgmpType_Unknown will be returned - */ + /// @return IGMP type set in igmp_header#type as ::IgmpType enum. Notice that if igmp_header#type contains a + /// value that doesn't appear in the ::IgmpType enum, ::IgmpType_Unknown will be returned IgmpType getType() const; - /** - * Set IGMP type (will be written to igmp_header#type field) - * @param[in] type The type to set - */ + /// Set IGMP type (will be written to igmp_header#type field) + /// @param[in] type The type to set void setType(IgmpType type); - /** - * A static method that gets raw IGMP data (byte stream) and returns the IGMP version of this IGMP message - * @param[in] data The IGMP raw data (byte stream) - * @param[in] dataLen Raw data length - * @param[out] isQuery Return true if IGMP message type is ::IgmpType_MembershipQuery and false otherwise - * @return One of the values ::IGMPv1, ::IGMPv2, ::IGMPv3 according to detected IGMP version or - * ::UnknownProtocol if couldn't detect IGMP version - */ + /// A static method that gets raw IGMP data (byte stream) and returns the IGMP version of this IGMP message + /// @param[in] data The IGMP raw data (byte stream) + /// @param[in] dataLen Raw data length + /// @param[out] isQuery Return true if IGMP message type is ::IgmpType_MembershipQuery and false otherwise + /// @return One of the values ::IGMPv1, ::IGMPv2, ::IGMPv3 according to detected IGMP version or + /// ::UnknownProtocol if couldn't detect IGMP version static ProtocolType getIGMPVerFromData(uint8_t* data, size_t dataLen, bool& isQuery); // implement abstract methods - /** - * Does nothing for this layer (IGMP layer is always last) - */ + /// Does nothing for this layer (IGMP layer is always last) void parseNextLayer() override {} - /** - * @return Size of IGMP header = 8B - */ + /// @return Size of IGMP header = 8B size_t getHeaderLen() const override { return sizeof(igmp_header); @@ -247,195 +205,152 @@ namespace pcpp } }; - /** - * @class IgmpV1Layer - * Represents IGMPv1 (Internet Group Management Protocol ver 1) layer. This class represents all the different - * messages of IGMPv1 - */ + /// @class IgmpV1Layer + /// Represents IGMPv1 (Internet Group Management Protocol ver 1) layer. This class represents all the different + /// messages of IGMPv1 class IgmpV1Layer : public IgmpLayer { public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in IgmpV1Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : IgmpLayer(data, dataLen, prevLayer, packet, IGMPv1) {} - /** - * A constructor that allocates a new IGMPv1 header - * @param[in] type The message type to set - * @param[in] groupAddr The multicast address to set. This is an optional parameter and has a default value of - * IPv4Address#Zero if not provided - */ + /// A constructor that allocates a new IGMPv1 header + /// @param[in] type The message type to set + /// @param[in] groupAddr The multicast address to set. This is an optional parameter and has a default value of + /// IPv4Address#Zero if not provided explicit IgmpV1Layer(IgmpType type, const IPv4Address& groupAddr = IPv4Address()) : IgmpLayer(type, groupAddr, 0, IGMPv1) {} - /** - * A destructor for this layer (does nothing) - */ + /// A destructor for this layer (does nothing) ~IgmpV1Layer() override = default; // implement abstract methods - /** - * Calculate the IGMP checksum and set igmp_header#maxResponseTime to 0 (this field is unused in IGMPv1) - */ + /// Calculate the IGMP checksum and set igmp_header#maxResponseTime to 0 (this field is unused in IGMPv1) void computeCalculateFields() override; }; - /** - * @class IgmpV2Layer - * Represents IGMPv2 (Internet Group Management Protocol ver 2) layer. This class represents all the different - * messages of IGMPv2 - */ + /// @class IgmpV2Layer + /// Represents IGMPv2 (Internet Group Management Protocol ver 2) layer. This class represents all the different + /// messages of IGMPv2 class IgmpV2Layer : public IgmpLayer { public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in IgmpV2Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : IgmpLayer(data, dataLen, prevLayer, packet, IGMPv2) {} - /** - * A constructor that allocates a new IGMPv2 header - * @param[in] type The message type to set - * @param[in] groupAddr The multicast address to set. This is an optional parameter and has a default value of - * unspecified/zero IPv4 address - * @param[in] maxResponseTime The max response time to set. This is an optional parameter and has a default - * value of 0 if not provided - */ + /// A constructor that allocates a new IGMPv2 header + /// @param[in] type The message type to set + /// @param[in] groupAddr The multicast address to set. This is an optional parameter and has a default value of + /// unspecified/zero IPv4 address + /// @param[in] maxResponseTime The max response time to set. This is an optional parameter and has a default + /// value of 0 if not provided explicit IgmpV2Layer(IgmpType type, const IPv4Address& groupAddr = IPv4Address(), uint8_t maxResponseTime = 0) : IgmpLayer(type, groupAddr, maxResponseTime, IGMPv2) {} - /** - * A destructor for this layer (does nothing) - */ + /// A destructor for this layer (does nothing) ~IgmpV2Layer() override = default; // implement abstract methods - /** - * Calculate the IGMP checksum - */ + /// Calculate the IGMP checksum void computeCalculateFields() override; }; - /** - * @class IgmpV3QueryLayer - * Represents an IGMPv3 (Internet Group Management Protocol ver 3) membership query message - */ + /// @class IgmpV3QueryLayer + /// Represents an IGMPv3 (Internet Group Management Protocol ver 3) membership query message class IgmpV3QueryLayer : public IgmpLayer { public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in IgmpV3QueryLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * A constructor that allocates a new IGMPv3 membership query - * @param[in] multicastAddr The multicast address to set. This is an optional parameter and has a default value - * of unspecified/zero IPv4 address if not provided - * @param[in] maxResponseTime The max response time to set. This is an optional parameter and has a default - * value of 0 if not provided - * @param[in] s_qrv A 1-byte value representing the value in Suppress Router-side Processing Flag + Querier's - * Robustness Variable (igmpv3_query_header#s_qrv field). This is an optional parameter and has a default value - * of 0 if not provided - */ + /// A constructor that allocates a new IGMPv3 membership query + /// @param[in] multicastAddr The multicast address to set. This is an optional parameter and has a default value + /// of unspecified/zero IPv4 address if not provided + /// @param[in] maxResponseTime The max response time to set. This is an optional parameter and has a default + /// value of 0 if not provided + /// @param[in] s_qrv A 1-byte value representing the value in Suppress Router-side Processing Flag + Querier's + /// Robustness Variable (igmpv3_query_header#s_qrv field). This is an optional parameter and has a default value + /// of 0 if not provided explicit IgmpV3QueryLayer(const IPv4Address& multicastAddr = IPv4Address(), uint8_t maxResponseTime = 0, uint8_t s_qrv = 0); - /** - * Get a pointer to the raw IGMPv3 membership query header. Notice this points directly to the data, so every - * change will change the actual packet data - * @return A pointer to the @ref igmpv3_query_header - */ + /// Get a pointer to the raw IGMPv3 membership query header. Notice this points directly to the data, so every + /// change will change the actual packet data + /// @return A pointer to the @ref igmpv3_query_header igmpv3_query_header* getIgmpV3QueryHeader() const { return reinterpret_cast(m_Data); } - /** - * @return The number of source addresses in this message (as extracted from the - * igmpv3_query_header#numOfSources field) - */ + /// @return The number of source addresses in this message (as extracted from the + /// igmpv3_query_header#numOfSources field) uint16_t getSourceAddressCount() const; - /** - * Get the IPV4 source address in a certain index - * @param[in] index The requested index of the source address - * @return The IPv4 source address, or IPv4Address#Zero if index is out of bounds (of the message or of the - * layer) - */ + /// Get the IPV4 source address in a certain index + /// @param[in] index The requested index of the source address + /// @return The IPv4 source address, or IPv4Address#Zero if index is out of bounds (of the message or of the + /// layer) IPv4Address getSourceAddressAtIndex(int index) const; - /** - * Add a new source address at the end of the source address list. The igmpv3_query_header#numOfSources field - * will be incremented accordingly - * @param[in] addr The IPv4 source address to add - * @return True if source address was added successfully or false otherwise. If false is returned an appropriate - * error message will be printed to log - */ + /// Add a new source address at the end of the source address list. The igmpv3_query_header#numOfSources field + /// will be incremented accordingly + /// @param[in] addr The IPv4 source address to add + /// @return True if source address was added successfully or false otherwise. If false is returned an + /// appropriate error message will be printed to log bool addSourceAddress(const IPv4Address& addr); - /** - * Add a new source address at a certain index of the source address list. The igmpv3_query_header#numOfSources - * field will be incremented accordingly - * @param[in] addr The IPv4 source address to add - * @param[in] index The index to add the new source address at - * @return True if source address was added successfully or false otherwise. If false is returned an appropriate - * error message will be printed to log - */ + /// Add a new source address at a certain index of the source address list. The igmpv3_query_header#numOfSources + /// field will be incremented accordingly + /// @param[in] addr The IPv4 source address to add + /// @param[in] index The index to add the new source address at + /// @return True if source address was added successfully or false otherwise. If false is returned an + /// appropriate error message will be printed to log bool addSourceAddressAtIndex(const IPv4Address& addr, int index); - /** - * Remove a source address at a certain index. The igmpv3_query_header#numOfSources field will be decremented - * accordingly - * @param[in] index The index of the source address to be removed - * @return True if source address was removed successfully or false otherwise. If false is returned an - * appropriate error message will be printed to log - */ + /// Remove a source address at a certain index. The igmpv3_query_header#numOfSources field will be decremented + /// accordingly + /// @param[in] index The index of the source address to be removed + /// @return True if source address was removed successfully or false otherwise. If false is returned an + /// appropriate error message will be printed to log bool removeSourceAddressAtIndex(int index); - /** - * Remove all source addresses in the message. The igmpv3_query_header#numOfSources field will be set to 0 - * @return True if all source addresses were cleared successfully or false otherwise. If false is returned an - * appropriate error message will be printed to log - */ + /// Remove all source addresses in the message. The igmpv3_query_header#numOfSources field will be set to 0 + /// @return True if all source addresses were cleared successfully or false otherwise. If false is returned an + /// appropriate error message will be printed to log bool removeAllSourceAddresses(); // implement abstract methods - /** - * Calculate the IGMP checksum - */ + /// Calculate the IGMP checksum void computeCalculateFields() override; - /** - * @return The message size in bytes which include the size of the basic header + the size of the source address - * list - */ + /// @return The message size in bytes which include the size of the basic header + the size of the source + /// address list size_t getHeaderLen() const override; }; - /** - * @class IgmpV3ReportLayer - * Represents an IGMPv3 (Internet Group Management Protocol ver 3) membership report message - */ + /// @class IgmpV3ReportLayer + /// Represents an IGMPv3 (Internet Group Management Protocol ver 3) membership report message class IgmpV3ReportLayer : public IgmpLayer { private: @@ -443,108 +358,85 @@ namespace pcpp const std::vector& sourceAddresses, int offset); public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in IgmpV3ReportLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : IgmpLayer(data, dataLen, prevLayer, packet, IGMPv3) {} - /** - * A constructor that allocates a new IGMPv3 membership report with 0 group addresses - */ + /// A constructor that allocates a new IGMPv3 membership report with 0 group addresses IgmpV3ReportLayer() : IgmpLayer(IgmpType_MembershipReportV3, IPv4Address(), 0, IGMPv3) {} - /** - * Get a pointer to the raw IGMPv3 membership report header. Notice this points directly to the data, so every - * change will change the actual packet data - * @return A pointer to the @ref igmpv3_report_header - */ + /// Get a pointer to the raw IGMPv3 membership report header. Notice this points directly to the data, so every + /// change will change the actual packet data + /// @return A pointer to the @ref igmpv3_report_header igmpv3_report_header* getReportHeader() const { return reinterpret_cast(m_Data); } - /** - * @return The number of group records in this message (as extracted from the - * igmpv3_report_header#numOfGroupRecords field) - */ + /// @return The number of group records in this message (as extracted from the + /// igmpv3_report_header#numOfGroupRecords field) uint16_t getGroupRecordCount() const; - /** - * @return A pointer to the first group record or nullptr if no group records exist. Notice the return value is - * a pointer to the real data, so changes in the return value will affect the packet data - */ + /// @return A pointer to the first group record or nullptr if no group records exist. Notice the return value is + /// a pointer to the real data, so changes in the return value will affect the packet data igmpv3_group_record* getFirstGroupRecord() const; - /** - * Get the group record that comes next to a given group record. If "groupRecord" is nullptr then nullptr will - * be returned. If "groupRecord" is the last group record or if it is out of layer bounds nullptr will be - * returned also. Notice the return value is a pointer to the real data casted to igmpv3_group_record type (as - * opposed to a copy of the option data). So changes in the return value will affect the packet data - * @param[in] groupRecord The group record to start searching from - * @return The next group record or nullptr if "groupRecord" is nullptr, last or out of layer bounds - */ + /// Get the group record that comes next to a given group record. If "groupRecord" is nullptr then nullptr will + /// be returned. If "groupRecord" is the last group record or if it is out of layer bounds nullptr will be + /// returned also. Notice the return value is a pointer to the real data casted to igmpv3_group_record type (as + /// opposed to a copy of the option data). So changes in the return value will affect the packet data + /// @param[in] groupRecord The group record to start searching from + /// @return The next group record or nullptr if "groupRecord" is nullptr, last or out of layer bounds igmpv3_group_record* getNextGroupRecord(igmpv3_group_record* groupRecord) const; - /** - * Add a new group record at a the end of the group record list. The igmpv3_report_header#numOfGroupRecords - * field will be incremented accordingly - * @param[in] recordType The type of the new group record - * @param[in] multicastAddress The multicast address of the new group record - * @param[in] sourceAddresses A vector containing all the source addresses of the new group record - * @return The method constructs a new group record, adds it to the end of the group record list of IGMPv3 - * report message and returns a pointer to the new message. If something went wrong in creating or adding the - * new group record a nullptr value is returned and an appropriate error message is printed to log - */ + /// Add a new group record at a the end of the group record list. The igmpv3_report_header#numOfGroupRecords + /// field will be incremented accordingly + /// @param[in] recordType The type of the new group record + /// @param[in] multicastAddress The multicast address of the new group record + /// @param[in] sourceAddresses A vector containing all the source addresses of the new group record + /// @return The method constructs a new group record, adds it to the end of the group record list of IGMPv3 + /// report message and returns a pointer to the new message. If something went wrong in creating or adding the + /// new group record a nullptr value is returned and an appropriate error message is printed to log igmpv3_group_record* addGroupRecord(uint8_t recordType, const IPv4Address& multicastAddress, const std::vector& sourceAddresses); - /** - * Add a new group record at a certain index of the group record list. The - * igmpv3_report_header#numOfGroupRecords field will be incremented accordingly - * @param[in] recordType The type of the new group record - * @param[in] multicastAddress The multicast address of the new group record - * @param[in] sourceAddresses A vector containing all the source addresses of the new group record - * @param[in] index The index to add the new group address at - * @return The method constructs a new group record, adds it to the IGMPv3 report message and returns a pointer - * to the new message. If something went wrong in creating or adding the new group record a nullptr value is - * returned and an appropriate error message is printed to log - */ + /// Add a new group record at a certain index of the group record list. The + /// igmpv3_report_header#numOfGroupRecords field will be incremented accordingly + /// @param[in] recordType The type of the new group record + /// @param[in] multicastAddress The multicast address of the new group record + /// @param[in] sourceAddresses A vector containing all the source addresses of the new group record + /// @param[in] index The index to add the new group address at + /// @return The method constructs a new group record, adds it to the IGMPv3 report message and returns a pointer + /// to the new message. If something went wrong in creating or adding the new group record a nullptr value is + /// returned and an appropriate error message is printed to log igmpv3_group_record* addGroupRecordAtIndex(uint8_t recordType, const IPv4Address& multicastAddress, const std::vector& sourceAddresses, int index); - /** - * Remove a group record at a certain index. The igmpv3_report_header#numOfGroupRecords field will be - * decremented accordingly - * @param[in] index The index of the group record to be removed - * @return True if group record was removed successfully or false otherwise. If false is returned an appropriate - * error message will be printed to log - */ + /// Remove a group record at a certain index. The igmpv3_report_header#numOfGroupRecords field will be + /// decremented accordingly + /// @param[in] index The index of the group record to be removed + /// @return True if group record was removed successfully or false otherwise. If false is returned an + /// appropriate error message will be printed to log bool removeGroupRecordAtIndex(int index); - /** - * Remove all group records in the message. The igmpv3_report_header#numOfGroupRecords field will be set to 0 - * @return True if all group records were cleared successfully or false otherwise. If false is returned an - * appropriate error message will be printed to log - */ + /// Remove all group records in the message. The igmpv3_report_header#numOfGroupRecords field will be set to 0 + /// @return True if all group records were cleared successfully or false otherwise. If false is returned an + /// appropriate error message will be printed to log bool removeAllGroupRecords(); // implement abstract methods - /** - * Calculate the IGMP checksum - */ + /// Calculate the IGMP checksum void computeCalculateFields() override; - /** - * @return The message size in bytes which include the size of the basic header + the size of the group record - * list - */ + /// @return The message size in bytes which include the size of the basic header + the size of the group record + /// list size_t getHeaderLen() const override { return m_DataLen; diff --git a/Packet++/header/LLCLayer.h b/Packet++/header/LLCLayer.h index d5a5793ffc..ddaf7a99ad 100644 --- a/Packet++/header/LLCLayer.h +++ b/Packet++/header/LLCLayer.h @@ -4,17 +4,13 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { #pragma pack(push, 1) - /** - * @struct llc_header - * Logical Link Control (LLC) header - */ + /// @struct llc_header + /// Logical Link Control (LLC) header struct llc_header { /// Destination Service Access Point @@ -27,36 +23,28 @@ namespace pcpp #pragma pack(pop) static_assert(sizeof(llc_header) == 3, "llc_header size is not 3 bytes"); - /** - * @class LLCLayer - * Represents Logical Link Control layer messages - */ + /// @class LLCLayer + /// Represents Logical Link Control layer messages class LLCLayer : public Layer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to llc_header) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to llc_header) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in LLCLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, LLC) {} - /** - * A constructor that creates the LLC layer from provided values - * @param[in] dsap Destination Service Access Point - * @param[in] ssap Source Service Access Point - * @param[in] control Control Field - */ + /// A constructor that creates the LLC layer from provided values + /// @param[in] dsap Destination Service Access Point + /// @param[in] ssap Source Service Access Point + /// @param[in] control Control Field LLCLayer(uint8_t dsap, uint8_t ssap, uint8_t control); - /** - * Get a pointer to Logical Link Control (LLC) layer header - * @return Pointer to LLC header - */ + /// Get a pointer to Logical Link Control (LLC) layer header + /// @return Pointer to LLC header inline llc_header* getLlcHeader() const { return reinterpret_cast(m_Data); @@ -71,33 +59,25 @@ namespace pcpp void computeCalculateFields() override {} - /** - * @return Get the size of the LLC header - */ + /// @return Get the size of the LLC header size_t getHeaderLen() const override { return sizeof(llc_header); } - /** - * @return Returns the protocol info as readable string - */ + /// @return Returns the protocol info as readable string std::string toString() const override; - /** - * @return The OSI layer level of LLC (Data Link Layer). - */ + /// @return The OSI layer level of LLC (Data Link Layer). OsiModelLayer getOsiModelLayer() const override { return OsiModelDataLinkLayer; } - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of an LLC packet - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent an LLC packet - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of an LLC packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent an LLC packet static bool isDataValid(const uint8_t* data, size_t dataLen); }; diff --git a/Packet++/header/Layer.h b/Packet++/header/Layer.h index f2e1755e14..a6c22be5f6 100644 --- a/Packet++/header/Layer.h +++ b/Packet++/header/Layer.h @@ -7,26 +7,20 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @class IDataContainer - * An interface (virtual abstract class) that indicates an object that holds a pointer to a buffer data. The Layer - * class is an example of such object, hence it inherits this interface - */ + /// @class IDataContainer + /// An interface (virtual abstract class) that indicates an object that holds a pointer to a buffer data. The Layer + /// class is an example of such object, hence it inherits this interface class IDataContainer { public: - /** - * Get a pointer to the data - * @param[in] offset Get a pointer in a certain offset. Default is 0 - get a pointer to start of data - * @return A pointer to the data - */ + /// Get a pointer to the data + /// @param[in] offset Get a pointer in a certain offset. Default is 0 - get a pointer to start of data + /// @return A pointer to the data virtual uint8_t* getDataPtr(size_t offset = 0) const = 0; virtual ~IDataContainer() = default; @@ -34,131 +28,106 @@ namespace pcpp class Packet; - /** - * @class Layer - * Layer is the base class for all protocol layers. Each protocol supported in PcapPlusPlus has a class that - * inherits Layer. - * The protocol layer class expose all properties and methods relevant for viewing and editing protocol fields. - * For example: a pointer to a structured header (e.g tcphdr, iphdr, etc.), protocol header size, payload size, - * compute fields that can be automatically computed, print protocol data to string, etc. - * Each protocol instance is obviously part of a protocol stack (which construct a packet). This protocol stack is - * represented in PcapPlusPlus in a linked list, and each layer is an element in this list. That's why each layer - * has properties to the next and previous layer in the protocol stack. The Layer class, as a base class, is - * abstract and the user can't create an instance of it (it has a private constructor). Each layer holds a pointer - * to the relevant place in the packet. The layer sees all the data from this pointer forward until the end of the - * packet. Here is an example packet showing this concept: - * - * @verbatim - * ==================================================== - * |Eth |IPv4 |TCP |Packet | - * |Header |Header |Header |Payload | - * ==================================================== - * - * |--------------------------------------------------| - * EthLayer data - * |---------------------------------------| - * IPv4Layer data - * |---------------------------| - * TcpLayer data - * |----------------| - * PayloadLayer data - * @endverbatim - * - */ + /// @class Layer + /// Layer is the base class for all protocol layers. Each protocol supported in PcapPlusPlus has a class that + /// inherits Layer. + /// The protocol layer class expose all properties and methods relevant for viewing and editing protocol fields. + /// For example: a pointer to a structured header (e.g tcphdr, iphdr, etc.), protocol header size, payload size, + /// compute fields that can be automatically computed, print protocol data to string, etc. + /// Each protocol instance is obviously part of a protocol stack (which construct a packet). This protocol stack is + /// represented in PcapPlusPlus in a linked list, and each layer is an element in this list. That's why each layer + /// has properties to the next and previous layer in the protocol stack. The Layer class, as a base class, is + /// abstract and the user can't create an instance of it (it has a private constructor). Each layer holds a pointer + /// to the relevant place in the packet. The layer sees all the data from this pointer forward until the end of the + /// packet. Here is an example packet showing this concept: + /// + /// @code{.unparsed} + /// ==================================================== + /// |Eth |IPv4 |TCP |Packet | + /// |Header |Header |Header |Payload | + /// ==================================================== + /// + /// |--------------------------------------------------| + /// EthLayer data + /// |---------------------------------------| + /// IPv4Layer data + /// |---------------------------| + /// TcpLayer data + /// |----------------| + /// PayloadLayer data + /// @endcode class Layer : public IDataContainer { friend class Packet; public: - /** - * A destructor for this class. Frees the data if it was allocated by the layer constructor (see - * isAllocatedToPacket() for more info) - */ + /// A destructor for this class. Frees the data if it was allocated by the layer constructor (see + /// isAllocatedToPacket() for more info) ~Layer() override; - /** - * @return A pointer to the next layer in the protocol stack or nullptr if the layer is the last one - */ + /// @return A pointer to the next layer in the protocol stack or nullptr if the layer is the last one Layer* getNextLayer() const { return m_NextLayer; } - /** - * @return A pointer to the previous layer in the protocol stack or nullptr if the layer is the first one - */ + /// @return A pointer to the previous layer in the protocol stack or nullptr if the layer is the first one Layer* getPrevLayer() const { return m_PrevLayer; } - /** - * @return The protocol enum - */ + /// @return The protocol enum ProtocolType getProtocol() const { return m_Protocol; } - /** - * Check if the layer's protocol matches a protocol family - * @param protocolTypeFamily The protocol family to check - * @return True if the layer's protocol matches the protocol family, false otherwise - */ + /// Check if the layer's protocol matches a protocol family + /// @param protocolTypeFamily The protocol family to check + /// @return True if the layer's protocol matches the protocol family, false otherwise bool isMemberOfProtocolFamily(ProtocolTypeFamily protocolTypeFamily) const; - /** - * @return A pointer to the layer raw data. In most cases it'll be a pointer to the first byte of the header - */ + /// @return A pointer to the layer raw data. In most cases it'll be a pointer to the first byte of the header uint8_t* getData() const { return m_Data; } - /** - * @return The length in bytes of the data from the first byte of the header until the end of the packet - */ + /// @return The length in bytes of the data from the first byte of the header until the end of the packet size_t getDataLen() const { return m_DataLen; } - /** - * @return A pointer for the layer payload, meaning the first byte after the header - */ + /// @return A pointer for the layer payload, meaning the first byte after the header uint8_t* getLayerPayload() const { return m_Data + getHeaderLen(); } - /** - * @return The size in bytes of the payload - */ + /// @return The size in bytes of the payload size_t getLayerPayloadSize() const { return m_DataLen - getHeaderLen(); } - /** - * Raw data in layers can come from one of sources: - * 1. from an existing packet - this is the case when parsing packets received from files or the network. In - * this case the data was already allocated by someone else, and layer only holds the pointer to the relevant - * place inside this data - * 2. when creating packets, data is allocated when layer is created. In this case the layer is responsible for - * freeing it as well - * - * @return Returns true if the data was allocated by an external source (a packet) or false if it was allocated - * by the layer itself - */ + /// Raw data in layers can come from one of sources: + /// 1. from an existing packet - this is the case when parsing packets received from files or the network. In + /// this case the data was already allocated by someone else, and layer only holds the pointer to the relevant + /// place inside this data + /// 2. when creating packets, data is allocated when layer is created. In this case the layer is responsible for + /// freeing it as well + /// + /// @return Returns true if the data was allocated by an external source (a packet) or false if it was allocated + /// by the layer itself bool isAllocatedToPacket() const { return m_Packet != nullptr; } - /** - * Copy the raw data of this layer to another array - * @param[out] toArr The destination byte array - */ + /// Copy the raw data of this layer to another array + /// @param[out] toArr The destination byte array void copyData(uint8_t* toArr) const; // implement abstract methods @@ -170,30 +139,20 @@ namespace pcpp // abstract methods - /** - * Each layer is responsible for parsing the next layer - */ + /// Each layer is responsible for parsing the next layer virtual void parseNextLayer() = 0; - /** - * @return The header length in bytes - */ + /// @return The header length in bytes virtual size_t getHeaderLen() const = 0; - /** - * Each layer can compute field values automatically using this method. This is an abstract method - */ + /// Each layer can compute field values automatically using this method. This is an abstract method virtual void computeCalculateFields() = 0; - /** - * @return A string representation of the layer most important data (should look like the layer description in - * Wireshark) - */ + /// @return A string representation of the layer most important data (should look like the layer description in + /// Wireshark) virtual std::string toString() const = 0; - /** - * @return The OSI Model layer this protocol belongs to - */ + /// @return The OSI Model layer this protocol belongs to virtual OsiModelLayer getOsiModelLayer() const = 0; protected: diff --git a/Packet++/header/LdapLayer.h b/Packet++/header/LdapLayer.h index 9ab9b888dd..4485d17c28 100644 --- a/Packet++/header/LdapLayer.h +++ b/Packet++/header/LdapLayer.h @@ -8,22 +8,16 @@ /// @file -/** - * @namespace pcpp - * @brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @class LdapOperationType - * @brief An enum wrapper class for LDAP operation types - */ + /// @class LdapOperationType + /// @brief An enum wrapper class for LDAP operation types class LdapOperationType { public: - /** - * Define enum types and the corresponding int values - */ + /// Define enum types and the corresponding int values enum Value : uint8_t { /// Bind Request @@ -75,24 +69,18 @@ namespace pcpp LdapOperationType() = default; // cppcheck-suppress noExplicitConstructor - /** - * Construct LdapOperationType from Value enum - * @param[in] value the operation type enum value - */ + /// Construct LdapOperationType from Value enum + /// @param[in] value the operation type enum value constexpr LdapOperationType(Value value) : m_Value(value) {} - /** - * @return A string representation of the operation type - */ + /// @return A string representation of the operation type std::string toString() const; - /** - * A static method that creates LdapOperationType from an integer value - * @param[in] value The operation type integer value - * @return The operation type that corresponds to the integer value. If the integer value - * doesn't corresponds to any operation type, LdapOperationType::Unknown is returned - */ + /// A static method that creates LdapOperationType from an integer value + /// @param[in] value The operation type integer value + /// @return The operation type that corresponds to the integer value. If the integer value + /// doesn't corresponds to any operation type, LdapOperationType::Unknown is returned static LdapOperationType fromUintValue(uint8_t value); // Allow switch and comparisons. @@ -108,231 +96,141 @@ namespace pcpp Value m_Value = LdapOperationType::Unknown; }; - /** - * @class LdapResultCode - * @brief An enum wrapper class for LDAP result codes - */ + /// @class LdapResultCode + /// @brief An enum wrapper class for LDAP result codes class LdapResultCode { public: - /** - * Define enum types and the corresponding int values - */ + /// Define enum types and the corresponding int values enum Value : uint8_t { - /** - * Indicates that the associated operation completed successfully - */ + /// Indicates that the associated operation completed successfully Success = 0, - /** - * Indicates that there was a problem with the client’s use of the LDAP protocol - */ + /// Indicates that there was a problem with the client’s use of the LDAP protocol OperationsError = 1, - /** - * Indicates that there was a problem with the client’s use of the LDAP protocol - */ + /// Indicates that there was a problem with the client’s use of the LDAP protocol ProtocolError = 2, - /** - * Indicates that the associated operation failed because it hadn’t completed by the time - * a maximum processing time limit had been reached - */ + /// Indicates that the associated operation failed because it hadn’t completed by the time + /// a maximum processing time limit had been reached TimeLimitExceeded = 3, - /** - * Indicates that the associated search operation failed because the server has determined - * that the number of entries that would be returned in response to the search would exceed - * the upper bound for that operation - */ + /// Indicates that the associated search operation failed because the server has determined + /// that the number of entries that would be returned in response to the search would exceed + /// the upper bound for that operation SizeLimitExceeded = 4, - /** - * Indicates that the associated compare request targeted an entry that exists and that contains - * the targeted attribute, but does not have any value that matches the provided assertion value - */ + /// Indicates that the associated compare request targeted an entry that exists and that contains + /// the targeted attribute, but does not have any value that matches the provided assertion value CompareFalse = 5, - /** - * Indicates that the associated compare request targeted an entry that exists and that contains - * the targeted attribute with a value that matches the provided assertion value - */ + /// Indicates that the associated compare request targeted an entry that exists and that contains + /// the targeted attribute with a value that matches the provided assertion value CompareTrue = 6, - /** - * Indicates that the associated bind operation failed because the client attempted to authenticate - * with a mechanism that the server does not support or that it does not allow the client to use - */ + /// Indicates that the associated bind operation failed because the client attempted to authenticate + /// with a mechanism that the server does not support or that it does not allow the client to use AuthMethodNotSupported = 7, - /** - * Indicates that the server requires the client to authenticate with a stronger form of authentication - */ + /// Indicates that the server requires the client to authenticate with a stronger form of authentication StrongerAuthRequired = 8, - /** - * Indicates that the request cannot be processed exactly as issued, but that it might succeed - * if re-issued to a different server, or is updated to target a different location in the DIT - */ + /// Indicates that the request cannot be processed exactly as issued, but that it might succeed + /// if re-issued to a different server, or is updated to target a different location in the DIT Referral = 10, - /** - * Indicates that some administrative limit within the server was exceeded while processing the request - */ + /// Indicates that some administrative limit within the server was exceeded while processing the request AdminLimitExceeded = 11, - /** - * Indicates that the request includes a control with a criticality of true, - * but that control could not be honored for some reason - */ + /// Indicates that the request includes a control with a criticality of true, + /// but that control could not be honored for some reason UnavailableCriticalExtension = 12, - /** - * Indicates that the server is only willing to process the requested operation if it is received - * over a secure connection that does not allow an eavesdropper to decipher or alter the contents - * of the request or response - */ + /// Indicates that the server is only willing to process the requested operation if it is received + /// over a secure connection that does not allow an eavesdropper to decipher or alter the contents + /// of the request or response ConfidentialityRequired = 13, - /** - * Indicates that the server has completed a portion of the processing for the provided SASL - * bind request, but that it needs additional information from the client to complete the authentication - */ + /// Indicates that the server has completed a portion of the processing for the provided SASL + /// bind request, but that it needs additional information from the client to complete the authentication SaslBindInProgress = 14, - /** - * Indicates that the request targeted an attribute that does not exist in the specified entry - */ + /// Indicates that the request targeted an attribute that does not exist in the specified entry NoSuchAttribute = 16, - /** - * Indicates that the request attempted to provide one or more values for an attribute type - * that is not defined in the server schema - */ + /// Indicates that the request attempted to provide one or more values for an attribute type + /// that is not defined in the server schema UndefinedAttributeType = 17, - /** - * Indicates that the search request tried to perform some type of matching that is not - * supported for the target attribute type - */ + /// Indicates that the search request tried to perform some type of matching that is not + /// supported for the target attribute type InappropriateMatching = 18, - /** - * Indicates that the requested operation would have resulted in an entry that violates - * some constraint defined within the server - */ + /// Indicates that the requested operation would have resulted in an entry that violates + /// some constraint defined within the server ConstraintViolation = 19, - /** - * Indicates that the requested operation would have resulted in an attribute in which - * the same value appeared more than once - */ + /// Indicates that the requested operation would have resulted in an attribute in which + /// the same value appeared more than once AttributeOrValueExists = 20, - /** - * Indicates that the requested add or modify operation would have resulted in an entry - * that had at least one attribute value that does not conform to the constraints of the - * associated attribute syntax - */ + /// Indicates that the requested add or modify operation would have resulted in an entry + /// that had at least one attribute value that does not conform to the constraints of the + /// associated attribute syntax InvalidAttributeSyntax = 21, - /** - * Indicates that the requested operation targeted an entry that does not exist within the DIT - */ + /// Indicates that the requested operation targeted an entry that does not exist within the DIT NoSuchObject = 32, - /** - * Indicates that a problem occurred while attempting to dereference an alias during search processing - */ + /// Indicates that a problem occurred while attempting to dereference an alias during search processing AliasProblem = 33, - /** - * Indicates that the request included a malformed entry DN - */ + /// Indicates that the request included a malformed entry DN InvalidDNSyntax = 34, - /** - * Indicates that the server encountered an alias while processing the request and that there - * was some problem related to that alias - */ + /// Indicates that the server encountered an alias while processing the request and that there + /// was some problem related to that alias AliasDereferencingProblem = 36, - /** - * Indicates that the client attempted to bind in an inappropriate manner that is inappropriate - * for the target account - */ + /// Indicates that the client attempted to bind in an inappropriate manner that is inappropriate + /// for the target account InappropriateAuthentication = 48, - /** - * Indicates that the client attempted to bind with a set of credentials that cannot - * be used to authenticate - */ + /// Indicates that the client attempted to bind with a set of credentials that cannot + /// be used to authenticate InvalidCredentials = 49, - /** - * Indicates that the client requested an operation for which it does not have the necessary - * access control permissions - */ + /// Indicates that the client requested an operation for which it does not have the necessary + /// access control permissions InsufficientAccessRights = 50, - /** - * Indicates that the requested operation cannot be processed because the server is currently too busy - */ + /// Indicates that the requested operation cannot be processed because the server is currently too busy Busy = 51, - /** - * Indicates that the server is currently not available to process the requested operation - */ + /// Indicates that the server is currently not available to process the requested operation Unavailable = 52, - /** - * Indicates that the server is not willing to process the requested operation for some reason - */ + /// Indicates that the server is not willing to process the requested operation for some reason UnwillingToPerform = 53, - /** - * Indicates that the server detected some kind of circular reference in the course - * of processing an operation - */ + /// Indicates that the server detected some kind of circular reference in the course + /// of processing an operation LoopDetect = 54, - /** - * Indicates that the requested add or modify DN operation would have resulted in an entry - * that violates some naming constraint within the server - */ + /// Indicates that the requested add or modify DN operation would have resulted in an entry + /// that violates some naming constraint within the server NamingViolation = 64, - /** - * Indicates that the requested operation would have resulted in an entry that has - * an inappropriate set of object classes, or whose attributes violate the constraints - * associated with its set of object classes - */ + /// Indicates that the requested operation would have resulted in an entry that has + /// an inappropriate set of object classes, or whose attributes violate the constraints + /// associated with its set of object classes ObjectClassViolation = 65, - /** - * Indicates that the requested operation is only supported for leaf entries, - * but the targeted entry has one or more subordinates - */ + /// Indicates that the requested operation is only supported for leaf entries, + /// but the targeted entry has one or more subordinates NotAllowedOnNonLeaf = 66, - /** - * Indicates that the requested modify operation would have resulted in an entry that - * does not include all of the attributes used in its RDN - */ + /// Indicates that the requested modify operation would have resulted in an entry that + /// does not include all of the attributes used in its RDN NotAllowedOnRDN = 67, - /** - * Indicates that the requested operation would have resulted in an entry with the same - * DN as an entry that already exists in the server - */ + /// Indicates that the requested operation would have resulted in an entry with the same + /// DN as an entry that already exists in the server EntryAlreadyExists = 68, - /** - * Indicates that the requested modify operation would have altered the target entry’s - * set of object classes in a way that is not supported - */ + /// Indicates that the requested modify operation would have altered the target entry’s + /// set of object classes in a way that is not supported ObjectClassModsProhibited = 69, - /** - * Indicates that the requested operation would have required manipulating information - * in multiple servers in a way that is not supported - */ + /// Indicates that the requested operation would have required manipulating information + /// in multiple servers in a way that is not supported AffectsMultipleDSAs = 71, - /** - * Used when a problem occurs for which none of the other result codes is more appropriate - */ + /// Used when a problem occurs for which none of the other result codes is more appropriate Other = 80, - /** - * Unknown result code - */ + /// Unknown result code Unknown = 255 }; LdapResultCode() = default; // cppcheck-suppress noExplicitConstructor - /** - * Construct LdapResultCode from Value enum - * @param[in] value the result code enum value - */ + /// Construct LdapResultCode from Value enum + /// @param[in] value the result code enum value constexpr LdapResultCode(Value value) : m_Value(value) {} - /** - * @return A string representation of the result code - */ + /// @return A string representation of the result code std::string toString() const; - /** - * A static method that creates LdapResultCode from an integer value - * @param[in] value The result code integer value - * @return The result code that corresponds to the integer value. If the integer value - * doesn't corresponds to any operation type, LdapResultCode::Unknown is returned - */ + /// A static method that creates LdapResultCode from an integer value + /// @param[in] value The result code integer value + /// @return The result code that corresponds to the integer value. If the integer value + /// doesn't corresponds to any operation type, LdapResultCode::Unknown is returned static LdapResultCode fromUintValue(uint8_t value); // Allow switch and comparisons @@ -348,10 +246,8 @@ namespace pcpp Value m_Value = LdapResultCode::Unknown; }; - /** - * @struct LdapControl - * A struct that represents an LDAP Control - */ + /// @struct LdapControl + /// A struct that represents an LDAP Control struct LdapControl { /// LDAP control type @@ -359,21 +255,17 @@ namespace pcpp /// LDAP control value std::string controlValue; - /** - * Equality operator overload for this struct - * @param[in] other The value to compare with - * @return True if both values are equal, false otherwise - */ + /// Equality operator overload for this struct + /// @param[in] other The value to compare with + /// @return True if both values are equal, false otherwise bool operator==(const LdapControl& other) const { return controlType == other.controlType && controlValue == other.controlValue; } }; - /** - * @struct LdapAttribute - * A struct that represents an LDAP attribute - */ + /// @struct LdapAttribute + /// A struct that represents an LDAP attribute struct LdapAttribute { /// Attribute description @@ -381,121 +273,95 @@ namespace pcpp /// A list of attribute values (zero or more) std::vector values; - /** - * Equality operator overload for this struct - * @param[in] other The value to compare with - * @return True if both values are equal, false otherwise - */ + /// Equality operator overload for this struct + /// @param[in] other The value to compare with + /// @return True if both values are equal, false otherwise bool operator==(const LdapAttribute& other) const { return type == other.type && values == other.values; } }; - /** - * @class LdapLayer - * Represents an LDAP message - */ + /// @class LdapLayer + /// Represents an LDAP message class LdapLayer : public Layer { public: - /** - * A constructor to create a new LDAP message - * @param[in] messageId The LDAP message ID - * @param[in] operationType The LDAP operation type - * @param[in] messageRecords A vector of ASN.1 records that comprise the LDAP message - * @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message - * will be created without LDAP controls - */ + /// A constructor to create a new LDAP message + /// @param[in] messageId The LDAP message ID + /// @param[in] operationType The LDAP operation type + /// @param[in] messageRecords A vector of ASN.1 records that comprise the LDAP message + /// @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message + /// will be created without LDAP controls LdapLayer(uint16_t messageId, LdapOperationType operationType, const std::vector& messageRecords, const std::vector& controls = std::vector()); ~LdapLayer() override = default; - /** - * @return The root ASN.1 record of the LDAP message. All of the message data will be under this record. - * If the Root ASN.1 record is malformed, an exception is thrown - */ + /// @return The root ASN.1 record of the LDAP message. All of the message data will be under this record. + /// If the Root ASN.1 record is malformed, an exception is thrown Asn1SequenceRecord* getRootAsn1Record() const; - /** - * @return The ASN.1 record of the specific LDAP operation in this LDAP message. Each operation has a specific - * structure. If the Operation ASN.1 record is malformed, an exception is thrown - */ + /// @return The ASN.1 record of the specific LDAP operation in this LDAP message. Each operation has a specific + /// structure. If the Operation ASN.1 record is malformed, an exception is thrown Asn1ConstructedRecord* getLdapOperationAsn1Record() const; - /** - * @return The LDAP message ID. If the ASN.1 record is malformed, an exception is thrown - */ + /// @return The LDAP message ID. If the ASN.1 record is malformed, an exception is thrown uint16_t getMessageID() const; - /** - * @return A vector of LDAP controls in this message. If the message contains no controls then an empty - * vector is returned. If the Controls ASN.1 record is malformed, an exception is thrown - */ + /// @return A vector of LDAP controls in this message. If the message contains no controls then an empty + /// vector is returned. If the Controls ASN.1 record is malformed, an exception is thrown std::vector getControls() const; - /** - * @return The LDAP operation of this message. If the Operation ASN.1 record is malformed, an exception is - * thrown - */ + /// @return The LDAP operation of this message. If the Operation ASN.1 record is malformed, an exception is + /// thrown virtual LdapOperationType getLdapOperationType() const; - /** - * Most getter methods in this class throw an exception if the corresponding ASN.1 record is invalid. - * This is a wrapper method that allows calling these getters without adding a `try...catch` clause. - * It accepts the getter method and an out variable. It tries to call the getter and if no exception - * is thrown, the out variable will contain the result. - * - * Here is an example: - * @code - * uint16_t messageId; - * ldapLayer->tryGet(&pcpp::LdapLayer::getMessageID, messageId)); - * @endcode - * - * We call getMessageID(), if no exception is thrown the variable messageId will hold the result - * - * @tparam Method The class method type - * @tparam ResultType The expected result type (for example: uint8_t, std::string, etc.) - * @param[in] method The class method to call - * @param[out] result An outvariable to contain the result if no exception is thrown - * @return True if no exception was thrown or false otherwise - */ + /// Most getter methods in this class throw an exception if the corresponding ASN.1 record is invalid. + /// This is a wrapper method that allows calling these getters without adding a `try...catch` clause. + /// It accepts the getter method and an out variable. It tries to call the getter and if no exception + /// is thrown, the out variable will contain the result. + /// + /// Here is an example: + /// @code + /// uint16_t messageId; + /// ldapLayer->tryGet(&pcpp::LdapLayer::getMessageID, messageId)); + /// @endcode + /// + /// We call getMessageID(), if no exception is thrown the variable messageId will hold the result + /// + /// @tparam Method The class method type + /// @tparam ResultType The expected result type (for example: uint8_t, std::string, etc.) + /// @param[in] method The class method to call + /// @param[out] result An outvariable to contain the result if no exception is thrown + /// @return True if no exception was thrown or false otherwise template bool tryGet(Method method, ResultType& result) { return internalTryGet(this, method, result); } - /** - * A static method that checks whether a source or dest port match those associated with the LDAP protocol - * @param[in] port The port number to check - * @return True if this is an LDAP port, false otherwise - */ + /// A static method that checks whether a source or dest port match those associated with the LDAP protocol + /// @param[in] port The port number to check + /// @return True if this is an LDAP port, false otherwise static bool isLdapPort(uint16_t port) { return port == 389; } - /** - * A static message to parse an LDAP message from raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - * @return An instance of LdapLayer if this is indeed an LDAP message, nullptr otherwise - */ + /// A static message to parse an LDAP message from raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in + /// @return An instance of LdapLayer if this is indeed an LDAP message, nullptr otherwise static LdapLayer* parseLdapMessage(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); // implement abstract methods - /** - * Tries to identify more LDAP messages in this packet if exist - */ + /// Tries to identify more LDAP messages in this packet if exist void parseNextLayer() override; - /** - * @return The size of the LDAP message - */ + /// @return The size of the LDAP message size_t getHeaderLen() const override { return m_Asn1Record->getTotalLength(); @@ -546,35 +412,25 @@ namespace pcpp } }; - /** - * @class LdapResponseLayer - * An abstract class for representing an LDAP response message. It's the parent class - * for all response message layers - */ + /// @class LdapResponseLayer + /// An abstract class for representing an LDAP response message. It's the parent class + /// for all response message layers class LdapResponseLayer : public LdapLayer { public: - /** - * @return LDAP result code - */ + /// @return LDAP result code LdapResultCode getResultCode() const; - /** - * @return An optional distinguished name (DN) that may be included in the response to a request - * targeting an entry that does not exist - */ + /// @return An optional distinguished name (DN) that may be included in the response to a request + /// targeting an entry that does not exist std::string getMatchedDN() const; - /** - * @return An optional string that can provide additional information about the processing that - * was performed - */ + /// @return An optional string that can provide additional information about the processing that + /// was performed std::string getDiagnosticMessage() const; - /** - * @return An optional list of one or more URIs that the client may use to re-try the operation - * somewhere else. If referral doesn't exist on the message, and empty vector is returned - */ + /// @return An optional list of one or more URIs that the client may use to re-try the operation + /// somewhere else. If referral doesn't exist on the message, and empty vector is returned std::vector getReferral() const; protected: @@ -605,16 +461,12 @@ namespace pcpp std::string getExtendedInfoString() const override; }; - /** - * @class LdapBindRequestLayer - * Represents LDAP bind request operation - */ + /// @class LdapBindRequestLayer + /// Represents LDAP bind request operation class LdapBindRequestLayer : public LdapLayer { public: - /** - * An enum to represent the bind request authentication type - */ + /// An enum to represent the bind request authentication type enum class AuthenticationType : uint8_t { /// Simple authentication @@ -625,10 +477,8 @@ namespace pcpp NotApplicable = 255 }; - /** - * @struct SaslAuthentication - * A struct to represent SASL authentication - */ + /// @struct SaslAuthentication + /// A struct to represent SASL authentication struct SaslAuthentication { /// The SASL mechanism @@ -636,78 +486,60 @@ namespace pcpp /// Encoded SASL credentials std::vector credentials; - /** - * Equality operator overload for this struct - * @param[in] other The value to compare with - * @return True if both values are equal, false otherwise - */ + /// Equality operator overload for this struct + /// @param[in] other The value to compare with + /// @return True if both values are equal, false otherwise bool operator==(const SaslAuthentication& other) const { return mechanism == other.mechanism && credentials == other.credentials; } - /** - * Inequality operator overload for this struct - * @param[in] other The value to compare with - * @return False if both values are equal, true otherwise - */ + /// Inequality operator overload for this struct + /// @param[in] other The value to compare with + /// @return False if both values are equal, true otherwise bool operator!=(const SaslAuthentication& other) const { return !operator==(other); } }; - /** - * A constructor to create a new LDAP bind request message with simple authentication - * @param[in] messageId The LDAP message ID - * @param[in] version The LDAP protocol version that the client wants to use - * @param[in] name The DN of the user to authenticate - * @param[in] simpleAuthentication Simple authentication to use in this message - * @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message - * will be created without LDAP controls - */ + /// A constructor to create a new LDAP bind request message with simple authentication + /// @param[in] messageId The LDAP message ID + /// @param[in] version The LDAP protocol version that the client wants to use + /// @param[in] name The DN of the user to authenticate + /// @param[in] simpleAuthentication Simple authentication to use in this message + /// @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message + /// will be created without LDAP controls LdapBindRequestLayer(uint16_t messageId, uint8_t version, const std::string& name, const std::string& simpleAuthentication, const std::vector& controls = std::vector()); - /** - * A constructor to create a new LDAP bind request message with SASL authentication - * @param[in] messageId The LDAP message ID - * @param[in] version The LDAP protocol version that the client wants to use - * @param[in] name The DN of the user to authenticate - * @param[in] saslAuthentication SASL authentication to use in this message - * @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message - * will be created without LDAP controls - */ + /// A constructor to create a new LDAP bind request message with SASL authentication + /// @param[in] messageId The LDAP message ID + /// @param[in] version The LDAP protocol version that the client wants to use + /// @param[in] name The DN of the user to authenticate + /// @param[in] saslAuthentication SASL authentication to use in this message + /// @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message + /// will be created without LDAP controls LdapBindRequestLayer(uint16_t messageId, uint8_t version, const std::string& name, const SaslAuthentication& saslAuthentication, const std::vector& controls = std::vector()); - /** - * @return The LDAP protocol version that the client wants to use - */ + /// @return The LDAP protocol version that the client wants to use uint32_t getVersion() const; - /** - * @return The DN of the user to authenticate - */ + /// @return The DN of the user to authenticate std::string getName() const; - /** - * @return The authentication type included in this message - */ + /// @return The authentication type included in this message AuthenticationType getAuthenticationType() const; - /** - * @return The simple authentication included in this message - * @throws std::invalid_argument if the message doesn't include simple authentication - */ + /// @return The simple authentication included in this message + /// @throws std::invalid_argument if the message doesn't include simple authentication std::string getSimpleAuthentication() const; - /** - * @return The SASL authentication included in this message - * @throws std::invalid_argument if the message doesn't include SASL authentication - */ + /// @return The SASL authentication included in this message + /// @throws std::invalid_argument if the message doesn't include SASL authentication SaslAuthentication getSaslAuthentication() const; template bool tryGet(Method method, ResultType& result) @@ -734,36 +566,30 @@ namespace pcpp static constexpr int saslCredentialsIndex = 1; }; - /** - * @class LdapBindResponseLayer - * Represents LDAP bind response operation - */ + /// @class LdapBindResponseLayer + /// Represents LDAP bind response operation class LdapBindResponseLayer : public LdapResponseLayer { public: - /** - * A constructor to create a new LDAP bind response message - * @param[in] messageId The LDAP message ID - * @param[in] resultCode The LDAP result code - * @param[in] matchedDN The distinguished name (DN) to set on the message. If not applicable - * pass an empty string - * @param[in] diagnosticMessage The additional information to set on the message. If not applicable - * pass an empty string - * @param[in] referral A list of URIs to re-try the operation somewhere else. This is an optional - * parameter. If not provided then referral won't be added to the message - * @param[in] serverSaslCredentials Encoded server SASL credentials for use in subsequent processing - * @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message - * will be created without LDAP controls - */ + /// A constructor to create a new LDAP bind response message + /// @param[in] messageId The LDAP message ID + /// @param[in] resultCode The LDAP result code + /// @param[in] matchedDN The distinguished name (DN) to set on the message. If not applicable + /// pass an empty string + /// @param[in] diagnosticMessage The additional information to set on the message. If not applicable + /// pass an empty string + /// @param[in] referral A list of URIs to re-try the operation somewhere else. This is an optional + /// parameter. If not provided then referral won't be added to the message + /// @param[in] serverSaslCredentials Encoded server SASL credentials for use in subsequent processing + /// @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message + /// will be created without LDAP controls LdapBindResponseLayer(uint16_t messageId, LdapResultCode resultCode, const std::string& matchedDN, const std::string& diagnosticMessage, const std::vector& referral = std::vector(), const std::vector& serverSaslCredentials = std::vector(), const std::vector& controls = std::vector()); - /** - * @return Encoded server SASL credentials for use in subsequent processing - */ + /// @return Encoded server SASL credentials for use in subsequent processing std::vector getServerSaslCredentials() const; protected: @@ -777,19 +603,15 @@ namespace pcpp {} }; - /** - * @class LdapUnbindRequestLayer - * Represents LDAP unbind operation - */ + /// @class LdapUnbindRequestLayer + /// Represents LDAP unbind operation class LdapUnbindRequestLayer : public LdapLayer { public: - /** - * A constructor to create a new LDAP unbind message - * @param[in] messageId The LDAP message ID - * @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message - * will be created without LDAP controls - */ + /// A constructor to create a new LDAP unbind message + /// @param[in] messageId The LDAP message ID + /// @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message + /// will be created without LDAP controls explicit LdapUnbindRequestLayer(uint16_t messageId, const std::vector& controls = std::vector()); @@ -815,72 +637,50 @@ namespace pcpp {} }; - /** - * @class LdapSearchRequestLayer - * Represents LDAP search request operation - */ + /// @class LdapSearchRequestLayer + /// Represents LDAP search request operation class LdapSearchRequestLayer : public LdapLayer { public: - /** - * @class SearchRequestScope - * An enum wrapper class for LDAP search request scope - */ + /// @class SearchRequestScope + /// An enum wrapper class for LDAP search request scope class SearchRequestScope { public: - /** - * Define enum types and the corresponding int values - */ + /// Define enum types and the corresponding int values enum Value : uint8_t { - /** - * The search operation should only be performed against the entry specified as the search base DN - */ + /// The search operation should only be performed against the entry specified as the search base DN BaseObject = 0, - /** - * The search operation should only be performed against entries that are immediate subordinates - * of the entry specified as the search base DN - */ + /// The search operation should only be performed against entries that are immediate subordinates + /// of the entry specified as the search base DN SingleLevel = 1, - /** - * The search operation should be performed against the entry specified as the search base - * and all of its subordinates to any depth - */ + /// The search operation should be performed against the entry specified as the search base + /// and all of its subordinates to any depth WholeSubtree = 2, - /** - * The search operation should be performed against any subordinate entries (to any depth) below the - * entry specified by the base DN should be considered, but the base entry itself - * should not be considered - */ + /// The search operation should be performed against any subordinate entries (to any depth) below the + /// entry specified by the base DN should be considered, but the base entry itself + /// should not be considered subordinateSubtree = 3, - /** - * Unknown or unsupported scope - */ + /// Unknown or unsupported scope Unknown = 255 }; SearchRequestScope() = default; // cppcheck-suppress noExplicitConstructor - /** - * Construct SearchRequestScope from Value enum - * @param[in] value the scope enum value - */ + /// Construct SearchRequestScope from Value enum + /// @param[in] value the scope enum value constexpr SearchRequestScope(Value value) : m_Value(value) {} - /** - * @return A string representation of the scope value - */ + /// @return A string representation of the scope value std::string toString() const; - /** - * A static method that creates SearchRequestScope from an integer value - * @param[in] value The scope integer value - * @return The scope that corresponds to the integer value. If the integer value - * doesn't corresponds to any enum value, SearchRequestScope::Unknown is returned - */ + /// A static method that creates SearchRequestScope from an integer value + /// @param[in] value The scope integer value + /// @return The scope that corresponds to the integer value. If the integer value + /// doesn't corresponds to any enum value, SearchRequestScope::Unknown is returned static SearchRequestScope fromUintValue(uint8_t value); // Allow switch and comparisons. @@ -896,16 +696,12 @@ namespace pcpp Value m_Value = SearchRequestScope::Unknown; }; - /** - * @class DerefAliases - * An enum wrapper class for LDAP search request dereferencing aliases - */ + /// @class DerefAliases + /// An enum wrapper class for LDAP search request dereferencing aliases class DerefAliases { public: - /** - * Define enum types and the corresponding int values - */ + /// Define enum types and the corresponding int values enum Value : uint8_t { /// Never dereferences aliases @@ -923,24 +719,18 @@ namespace pcpp DerefAliases() = default; // cppcheck-suppress noExplicitConstructor - /** - * Construct DerefAliases from Value enum - * @param[in] value the dereference alias enum value - */ + /// Construct DerefAliases from Value enum + /// @param[in] value the dereference alias enum value constexpr DerefAliases(Value value) : m_Value(value) {} - /** - * @return A string representation of the dereference alias value - */ + /// @return A string representation of the dereference alias value std::string toString() const; - /** - * A static method that creates DerefAliases from an integer value - * @param[in] value The dereference alias integer value - * @return The dereference alias that corresponds to the integer value. If the integer value - * doesn't corresponds to any enum value, DerefAliases::Unknown is returned - */ + /// A static method that creates DerefAliases from an integer value + /// @param[in] value The dereference alias integer value + /// @return The dereference alias that corresponds to the integer value. If the integer value + /// doesn't corresponds to any enum value, DerefAliases::Unknown is returned static DerefAliases fromUintValue(uint8_t value); // Allow switch and comparisons. @@ -956,74 +746,56 @@ namespace pcpp Value m_Value = DerefAliases::Unknown; }; - /** - * A constructor to create a new LDAP search request message - * @param[in] messageId The LDAP message ID - * @param[in] baseObject The base object for the LDAP search request entry - * @param[in] scope The portion of the target subtree that should be considered - * @param[in] derefAliases The alias dereferencing behavior, which indicates how the server should treat - * any aliases encountered while processing the search - * @param[in] sizeLimit The maximum number of entries that should be returned from the search - * @param[in] timeLimit The time limit for the search in seconds - * @param[in] typesOnly If this is given a value of true, then it indicates that entries that match the - * search criteria should be returned containing only the attribute descriptions for the attributes - * contained in that entry but should not include the values for those attributes. - * If this is given a value of false, then it indicates that the attribute values should be included - * in the entries that are returned - * @param[in] filterRecord The filter for the search. Please note that parsing for the search filter - * doesn't exist yet. Therefore, the expected input value should be a plain ASN.1 record - * @param[in] attributes A set of attributes to request for inclusion in entries that match the search - * criteria and are returned to the client - * @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message - * will be created without LDAP controls - */ + /// A constructor to create a new LDAP search request message + /// @param[in] messageId The LDAP message ID + /// @param[in] baseObject The base object for the LDAP search request entry + /// @param[in] scope The portion of the target subtree that should be considered + /// @param[in] derefAliases The alias dereferencing behavior, which indicates how the server should treat + /// any aliases encountered while processing the search + /// @param[in] sizeLimit The maximum number of entries that should be returned from the search + /// @param[in] timeLimit The time limit for the search in seconds + /// @param[in] typesOnly If this is given a value of true, then it indicates that entries that match the + /// search criteria should be returned containing only the attribute descriptions for the attributes + /// contained in that entry but should not include the values for those attributes. + /// If this is given a value of false, then it indicates that the attribute values should be included + /// in the entries that are returned + /// @param[in] filterRecord The filter for the search. Please note that parsing for the search filter + /// doesn't exist yet. Therefore, the expected input value should be a plain ASN.1 record + /// @param[in] attributes A set of attributes to request for inclusion in entries that match the search + /// criteria and are returned to the client + /// @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message + /// will be created without LDAP controls LdapSearchRequestLayer(uint16_t messageId, const std::string& baseObject, SearchRequestScope scope, DerefAliases derefAliases, uint8_t sizeLimit, uint8_t timeLimit, bool typesOnly, Asn1Record* filterRecord, const std::vector& attributes, const std::vector& controls = std::vector()); - /** - * @return The base object for the LDAP search request entry - */ + /// @return The base object for the LDAP search request entry std::string getBaseObject() const; - /** - * @return The portion of the target subtree that should be considered - */ + /// @return The portion of the target subtree that should be considered SearchRequestScope getScope() const; - /** - * @return The alias dereferencing behavior - */ + /// @return The alias dereferencing behavior DerefAliases getDerefAlias() const; - /** - * @return The maximum number of entries that should be returned from the search - */ + /// @return The maximum number of entries that should be returned from the search uint8_t getSizeLimit() const; - /** - * @return The time limit for the search in seconds - */ + /// @return The time limit for the search in seconds uint8_t getTimeLimit() const; - /** - * @return If this flag is true, then it indicates that entries that match the search criteria should be - * returned containing only the attribute descriptions for the attributes contained in that entry but - * should not include the values for those attributes. If this flag is false, then it indicates that the - * attribute values should be included in the entries that are returned - */ + /// @return If this flag is true, then it indicates that entries that match the search criteria should be + /// returned containing only the attribute descriptions for the attributes contained in that entry but + /// should not include the values for those attributes. If this flag is false, then it indicates that the + /// attribute values should be included in the entries that are returned bool getTypesOnly() const; - /** - * @return The filter for the search. Please note that parsing for the search filter doesn't exist yet. - * Therefore, the return value is a plain ASN.1 record - */ + /// @return The filter for the search. Please note that parsing for the search filter doesn't exist yet. + /// Therefore, the return value is a plain ASN.1 record Asn1Record* getFilter() const; - /** - * @return A list of search request attributes - */ + /// @return A list of search request attributes std::vector getAttributes() const; template bool tryGet(Method method, ResultType& result) @@ -1051,33 +823,25 @@ namespace pcpp std::string getExtendedInfoString() const override; }; - /** - * @class LdapSearchResultEntryLayer - * Represents LDAP search result entry message - */ + /// @class LdapSearchResultEntryLayer + /// Represents LDAP search result entry message class LdapSearchResultEntryLayer : public LdapLayer { public: - /** - * A constructor to create a new LDAP search result entry message - * @param[in] messageId The LDAP message ID - * @param[in] objectName The entry's DN - * @param[in] attributes The entry's attributes - * @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message - * will be created without LDAP controls - */ + /// A constructor to create a new LDAP search result entry message + /// @param[in] messageId The LDAP message ID + /// @param[in] objectName The entry's DN + /// @param[in] attributes The entry's attributes + /// @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message + /// will be created without LDAP controls LdapSearchResultEntryLayer(uint16_t messageId, const std::string& objectName, const std::vector& attributes, const std::vector& controls = std::vector()); - /** - * @return The entry's DN - */ + /// @return The entry's DN std::string getObjectName() const; - /** - * @return The entry's attributes - */ + /// @return The entry's attributes std::vector getAttributes() const; template bool tryGet(Method method, ResultType& result) @@ -1099,26 +863,22 @@ namespace pcpp {} }; - /** - * @class LdapSearchResultDoneLayer - * Represents LDAP search result done message - */ + /// @class LdapSearchResultDoneLayer + /// Represents LDAP search result done message class LdapSearchResultDoneLayer : public LdapResponseLayer { public: - /** - * A constructor to create a new LDAP search result done message - * @param[in] messageId The LDAP message ID - * @param[in] resultCode The LDAP result code - * @param[in] matchedDN The distinguished name (DN) to set on the message. If not applicable - * pass an empty string - * @param[in] diagnosticMessage The additional information to set on the message. If not applicable - * pass an empty string - * @param[in] referral A list of URIs to re-try the operation somewhere else. This is an optional - * parameter. If not provided then referral won't be added to the message - * @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message - * will be created without LDAP controls - */ + /// A constructor to create a new LDAP search result done message + /// @param[in] messageId The LDAP message ID + /// @param[in] resultCode The LDAP result code + /// @param[in] matchedDN The distinguished name (DN) to set on the message. If not applicable + /// pass an empty string + /// @param[in] diagnosticMessage The additional information to set on the message. If not applicable + /// pass an empty string + /// @param[in] referral A list of URIs to re-try the operation somewhere else. This is an optional + /// parameter. If not provided then referral won't be added to the message + /// @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message + /// will be created without LDAP controls LdapSearchResultDoneLayer(uint16_t messageId, LdapResultCode resultCode, const std::string& matchedDN, const std::string& diagnosticMessage, const std::vector& referral = std::vector(), @@ -1136,26 +896,22 @@ namespace pcpp {} }; - /** - * @class LdapModifyResponseLayer - * Represents LDAP modify response message - */ + /// @class LdapModifyResponseLayer + /// Represents LDAP modify response message class LdapModifyResponseLayer : public LdapResponseLayer { public: - /** - * A constructor to create a new LDAP modify response message - * @param[in] messageId The LDAP message ID - * @param[in] resultCode The LDAP result code - * @param[in] matchedDN The distinguished name (DN) to set on the message. If not applicable - * pass an empty string - * @param[in] diagnosticMessage The additional information to set on the message. If not applicable - * pass an empty string - * @param[in] referral A list of URIs to re-try the operation somewhere else. This is an optional - * parameter. If not provided then referral won't be added to the message - * @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message - * will be created without LDAP controls - */ + /// A constructor to create a new LDAP modify response message + /// @param[in] messageId The LDAP message ID + /// @param[in] resultCode The LDAP result code + /// @param[in] matchedDN The distinguished name (DN) to set on the message. If not applicable + /// pass an empty string + /// @param[in] diagnosticMessage The additional information to set on the message. If not applicable + /// pass an empty string + /// @param[in] referral A list of URIs to re-try the operation somewhere else. This is an optional + /// parameter. If not provided then referral won't be added to the message + /// @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message + /// will be created without LDAP controls LdapModifyResponseLayer(uint16_t messageId, LdapResultCode resultCode, const std::string& matchedDN, const std::string& diagnosticMessage, const std::vector& referral = std::vector(), @@ -1173,26 +929,22 @@ namespace pcpp {} }; - /** - * @class LdapAddResponseLayer - * Represents LDAP add response message - */ + /// @class LdapAddResponseLayer + /// Represents LDAP add response message class LdapAddResponseLayer : public LdapResponseLayer { public: - /** - * A constructor to create a new LDAP add response message - * @param[in] messageId The LDAP message ID - * @param[in] resultCode The LDAP result code - * @param[in] matchedDN The distinguished name (DN) to set on the message. If not applicable - * pass an empty string - * @param[in] diagnosticMessage The additional information to set on the message. If not applicable - * pass an empty string - * @param[in] referral A list of URIs to re-try the operation somewhere else. This is an optional - * parameter. If not provided then referral won't be added to the message - * @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message - * will be created without LDAP controls - */ + /// A constructor to create a new LDAP add response message + /// @param[in] messageId The LDAP message ID + /// @param[in] resultCode The LDAP result code + /// @param[in] matchedDN The distinguished name (DN) to set on the message. If not applicable + /// pass an empty string + /// @param[in] diagnosticMessage The additional information to set on the message. If not applicable + /// pass an empty string + /// @param[in] referral A list of URIs to re-try the operation somewhere else. This is an optional + /// parameter. If not provided then referral won't be added to the message + /// @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message + /// will be created without LDAP controls LdapAddResponseLayer(uint16_t messageId, LdapResultCode resultCode, const std::string& matchedDN, const std::string& diagnosticMessage, const std::vector& referral = std::vector(), @@ -1210,26 +962,22 @@ namespace pcpp {} }; - /** - * @class LdapDeleteResponseLayer - * Represents LDAP delete response message - */ + /// @class LdapDeleteResponseLayer + /// Represents LDAP delete response message class LdapDeleteResponseLayer : public LdapResponseLayer { public: - /** - * A constructor to create a new LDAP delete response message - * @param[in] messageId The LDAP message ID - * @param[in] resultCode The LDAP result code - * @param[in] matchedDN The distinguished name (DN) to set on the message. If not applicable - * pass an empty string - * @param[in] diagnosticMessage The additional information to set on the message. If not applicable - * pass an empty string - * @param[in] referral A list of URIs to re-try the operation somewhere else. This is an optional - * parameter. If not provided then referral won't be added to the message - * @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message - * will be created without LDAP controls - */ + /// A constructor to create a new LDAP delete response message + /// @param[in] messageId The LDAP message ID + /// @param[in] resultCode The LDAP result code + /// @param[in] matchedDN The distinguished name (DN) to set on the message. If not applicable + /// pass an empty string + /// @param[in] diagnosticMessage The additional information to set on the message. If not applicable + /// pass an empty string + /// @param[in] referral A list of URIs to re-try the operation somewhere else. This is an optional + /// parameter. If not provided then referral won't be added to the message + /// @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message + /// will be created without LDAP controls LdapDeleteResponseLayer(uint16_t messageId, LdapResultCode resultCode, const std::string& matchedDN, const std::string& diagnosticMessage, const std::vector& referral = std::vector(), @@ -1247,26 +995,22 @@ namespace pcpp {} }; - /** - * @class LdapModifyDNResponseLayer - * Represents LDAP modify DN response message - */ + /// @class LdapModifyDNResponseLayer + /// Represents LDAP modify DN response message class LdapModifyDNResponseLayer : public LdapResponseLayer { public: - /** - * A constructor to create a new LDAP modify DN response message - * @param[in] messageId The LDAP message ID - * @param[in] resultCode The LDAP result code - * @param[in] matchedDN The distinguished name (DN) to set on the message. If not applicable - * pass an empty string - * @param[in] diagnosticMessage The additional information to set on the message. If not applicable - * pass an empty string - * @param[in] referral A list of URIs to re-try the operation somewhere else. This is an optional - * parameter. If not provided then referral won't be added to the message - * @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message - * will be created without LDAP controls - */ + /// A constructor to create a new LDAP modify DN response message + /// @param[in] messageId The LDAP message ID + /// @param[in] resultCode The LDAP result code + /// @param[in] matchedDN The distinguished name (DN) to set on the message. If not applicable + /// pass an empty string + /// @param[in] diagnosticMessage The additional information to set on the message. If not applicable + /// pass an empty string + /// @param[in] referral A list of URIs to re-try the operation somewhere else. This is an optional + /// parameter. If not provided then referral won't be added to the message + /// @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message + /// will be created without LDAP controls LdapModifyDNResponseLayer(uint16_t messageId, LdapResultCode resultCode, const std::string& matchedDN, const std::string& diagnosticMessage, const std::vector& referral = std::vector(), @@ -1284,26 +1028,22 @@ namespace pcpp {} }; - /** - * @class LdapCompareResponseLayer - * Represents LDAP compare response message - */ + /// @class LdapCompareResponseLayer + /// Represents LDAP compare response message class LdapCompareResponseLayer : public LdapResponseLayer { public: - /** - * A constructor to create a new LDAP compare response message - * @param[in] messageId The LDAP message ID - * @param[in] resultCode The LDAP result code - * @param[in] matchedDN The distinguished name (DN) to set on the message. If not applicable - * pass an empty string - * @param[in] diagnosticMessage The additional information to set on the message. If not applicable - * pass an empty string - * @param[in] referral A list of URIs to re-try the operation somewhere else. This is an optional - * parameter. If not provided then referral won't be added to the message - * @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message - * will be created without LDAP controls - */ + /// A constructor to create a new LDAP compare response message + /// @param[in] messageId The LDAP message ID + /// @param[in] resultCode The LDAP result code + /// @param[in] matchedDN The distinguished name (DN) to set on the message. If not applicable + /// pass an empty string + /// @param[in] diagnosticMessage The additional information to set on the message. If not applicable + /// pass an empty string + /// @param[in] referral A list of URIs to re-try the operation somewhere else. This is an optional + /// parameter. If not provided then referral won't be added to the message + /// @param[in] controls A vector of LDAP controls. This is an optional parameter, if not provided the message + /// will be created without LDAP controls LdapCompareResponseLayer(uint16_t messageId, LdapResultCode resultCode, const std::string& matchedDN, const std::string& diagnosticMessage, const std::vector& referral = std::vector(), diff --git a/Packet++/header/MplsLayer.h b/Packet++/header/MplsLayer.h index eb341fd87d..2cebbcbbc0 100644 --- a/Packet++/header/MplsLayer.h +++ b/Packet++/header/MplsLayer.h @@ -4,17 +4,12 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @class MplsLayer - * Represents a MPLS (Multi-Protocol Label Switching) layer - */ + /// @class MplsLayer + /// Represents a MPLS (Multi-Protocol Label Switching) layer class MplsLayer : public Layer { private: @@ -34,100 +29,75 @@ namespace pcpp } public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in MplsLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, MPLS) {} - /** - * A constructor that allocates a new MPLS header - * @param[in] mplsLabel MPLS label - * @param[in] ttl Time-to-leave value - * @param[in] experimentalUseValue Experimental use value - * @param[in] bottomOfStack Bottom-of-stack value which indicate whether the next layer will also be a MPLS - * label or not - */ + /// A constructor that allocates a new MPLS header + /// @param[in] mplsLabel MPLS label + /// @param[in] ttl Time-to-leave value + /// @param[in] experimentalUseValue Experimental use value + /// @param[in] bottomOfStack Bottom-of-stack value which indicate whether the next layer will also be a MPLS + /// label or not MplsLayer(uint32_t mplsLabel, uint8_t ttl, uint8_t experimentalUseValue, bool bottomOfStack); ~MplsLayer() override = default; - /** - * @return TTL value of the MPLS header - */ + /// @return TTL value of the MPLS header uint8_t getTTL() const { return getMplsHeader()->ttl; } - /** - * Set the TTL value - * @param[in] ttl The TTL value to set - */ + /// Set the TTL value + /// @param[in] ttl The TTL value to set void setTTL(uint8_t ttl) { getMplsHeader()->ttl = ttl; } - /** - * Get an indication whether the next layer is also be a MPLS label or not - * @return True if it's the last MPLS layer, false otherwise - */ + /// Get an indication whether the next layer is also be a MPLS label or not + /// @return True if it's the last MPLS layer, false otherwise bool isBottomOfStack() const; - /** - * Set the bottom-of-stack bit in the MPLS label - * @param[in] val Set or unset the bit - */ + /// Set the bottom-of-stack bit in the MPLS label + /// @param[in] val Set or unset the bit void setBottomOfStack(bool val); - /** - * @return The exp value (3 bits) of the MPLS label - */ + /// @return The exp value (3 bits) of the MPLS label uint8_t getExperimentalUseValue() const; - /** - * Set the exp value (3 bits) of the MPLS label - * @param[in] val The exp value to set. val must be a valid number meaning between 0 and 7 (inclusive) - * @return True if exp value was set successfully or false if val has invalid value - */ + /// Set the exp value (3 bits) of the MPLS label + /// @param[in] val The exp value to set. val must be a valid number meaning between 0 and 7 (inclusive) + /// @return True if exp value was set successfully or false if val has invalid value bool setExperimentalUseValue(uint8_t val); - /** - * @return The MPLS label value (20 bits) - */ + /// @return The MPLS label value (20 bits) uint32_t getMplsLabel() const; - /** - * Set the MPLS label (20 bits) - * @param[in] label The label to set. label must be a valid number meaning between 0 and 0xFFFFF (inclusive) - * @return True if label was set successfully or false if label has invalid value - */ + /// Set the MPLS label (20 bits) + /// @param[in] label The label to set. label must be a valid number meaning between 0 and 0xFFFFF (inclusive) + /// @return True if label was set successfully or false if label has invalid value bool setMplsLabel(uint32_t label); // implement abstract methods - /** - * Currently identifies the following next layers: IPv4Layer, IPv6Layer, MplsLayer. Otherwise sets PayloadLayer - */ + /// Currently identifies the following next layers: IPv4Layer, IPv6Layer, MplsLayer. Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * @return Size of MPLS header (4 bytes) - */ + /// @return Size of MPLS header (4 bytes) size_t getHeaderLen() const override { return sizeof(mpls_header); } - /** - * Set/unset the bottom-of-stack bit according to next layer: if it's a MPLS layer then bottom-of-stack will be - * unset. If it's not a MPLS layer this bit will be set - */ + /// Set/unset the bottom-of-stack bit according to next layer: if it's a MPLS layer then bottom-of-stack will be + /// unset. If it's not a MPLS layer this bit will be set void computeCalculateFields() override; std::string toString() const override; diff --git a/Packet++/header/NdpLayer.h b/Packet++/header/NdpLayer.h index 6c88df2403..e769f5a60f 100644 --- a/Packet++/header/NdpLayer.h +++ b/Packet++/header/NdpLayer.h @@ -10,16 +10,12 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * An enum representing the available option types for Neighbor Discovery in IPv6 (see RFC 4861) - */ + /// An enum representing the available option types for Neighbor Discovery in IPv6 (see RFC 4861) enum class NDPNeighborOptionTypes : int { NDP_OPTION_SOURCE_LINK_LAYER = 1, @@ -30,30 +26,22 @@ namespace pcpp NDP_OPTION_UNKNOWN = 255 }; - /** - * @class NdpOption - * A wrapper class for NDP options. This class does not create or modify NDP option records, but rather - * serves as a wrapper and provides useful methods for retrieving data from them - */ + /// @class NdpOption + /// A wrapper class for NDP options. This class does not create or modify NDP option records, but rather + /// serves as a wrapper and provides useful methods for retrieving data from them class NdpOption : public TLVRecord { public: - /** - * A c'tor for this class that gets a pointer to the option raw data (byte array) - * @param[in] optionRawData A pointer to the NDP option raw data - */ + /// A c'tor for this class that gets a pointer to the option raw data (byte array) + /// @param[in] optionRawData A pointer to the NDP option raw data explicit NdpOption(uint8_t* optionRawData) : TLVRecord(optionRawData) {} - /** - * A d'tor for this class, currently does nothing - */ + /// A d'tor for this class, currently does nothing ~NdpOption() override = default; - /** - * @return NDP option type casted as pcpp::NDPNeighborOptionTypes enum. If the data is null a value - * of NDP_OPTION_UNKNOWN is returned - */ + /// @return NDP option type casted as pcpp::NDPNeighborOptionTypes enum. If the data is null a value + /// of NDP_OPTION_UNKNOWN is returned NDPNeighborOptionTypes getNdpOptionType() const { if (m_Data == nullptr) @@ -84,85 +72,65 @@ namespace pcpp } }; - /** - * @class NdpOptionBuilder - * A class for building NDP option records. This builder receives the NDP option parameters in its c'tor, - * builds the NDP option raw buffer and provides a build() method to get a NdpOption object out of it - */ + /// @class NdpOptionBuilder + /// A class for building NDP option records. This builder receives the NDP option parameters in its c'tor, + /// builds the NDP option raw buffer and provides a build() method to get a NdpOption object out of it class NdpOptionBuilder : public TLVRecordBuilder { public: - /** - * A c'tor for building NDP options which their value is a byte array. The NdpOption object can be later - * retrieved by calling build(). Each option is padded to have a 64-bit boundary. - * @param[in] optionType NDP option type - * @param[in] optionValue A buffer containing the option value. This buffer is read-only and isn't modified in - * any way. - * @param[in] optionValueLen Option value length in bytes - */ + /// A c'tor for building NDP options which their value is a byte array. The NdpOption object can be later + /// retrieved by calling build(). Each option is padded to have a 64-bit boundary. + /// @param[in] optionType NDP option type + /// @param[in] optionValue A buffer containing the option value. This buffer is read-only and isn't modified in + /// any way. + /// @param[in] optionValueLen Option value length in bytes NdpOptionBuilder(NDPNeighborOptionTypes optionType, const uint8_t* optionValue, uint8_t optionValueLen) : TLVRecordBuilder((uint8_t)optionType, optionValue, optionValueLen) {} - /** - * Build the NdpOption object out of the parameters defined in the c'tor. Padding bytes are added to the - * option for option length with 64-bit boundaries. - * @return The NdpOption object - */ + /// Build the NdpOption object out of the parameters defined in the c'tor. Padding bytes are added to the + /// option for option length with 64-bit boundaries. + /// @return The NdpOption object NdpOption build() const; }; - /** - * @class NDPLayerBase - * Represents a base for NDP packet types - */ + /// @class NDPLayerBase + /// Represents a base for NDP packet types class NDPLayerBase : public IcmpV6Layer { public: ~NDPLayerBase() override = default; - /** - * @return The number of NDP options in this layer - */ + /// @return The number of NDP options in this layer size_t getNdpOptionCount() const; - /** - * Get a NDP option by type. - * @param[in] option NDP option type - * @return An NdpOption object that contains the first option that matches this type, or logical null - * (NdpOption#isNull() == true) if no such option found - */ + /// Get a NDP option by type. + /// @param[in] option NDP option type + /// @return An NdpOption object that contains the first option that matches this type, or logical null + /// (NdpOption#isNull() == true) if no such option found NdpOption getNdpOption(NDPNeighborOptionTypes option) const; - /** - * @return The first NDP option in the packet. If the current layer contains no options the returned value will - * contain a logical null (NdpOption#isNull() == true) - */ + /// @return The first NDP option in the packet. If the current layer contains no options the returned value will + /// contain a logical null (NdpOption#isNull() == true) NdpOption getFirstNdpOption() const; - /** - * Get the NDP option that comes after a given option. If the given option was the last one, the - * returned value will contain a logical null (IdpOption#isNull() == true) - * @param[in] option An NDP option object that exists in the current layer - * @return A NdpOption object that contains the NDP option data that comes next, or logical null if the given - * NDP option: (1) was the last one; or (2) contains a logical null; or (3) doesn't belong to this packet - */ + /// Get the NDP option that comes after a given option. If the given option was the last one, the + /// returned value will contain a logical null (IdpOption#isNull() == true) + /// @param[in] option An NDP option object that exists in the current layer + /// @return A NdpOption object that contains the NDP option data that comes next, or logical null if the given + /// NDP option: (1) was the last one; or (2) contains a logical null; or (3) doesn't belong to this packet NdpOption getNextNdpOption(NdpOption& option) const; - /** - * Add a new NDP option at the end of the layer (after the last NDP option) - * @param[in] optionBuilder An NdpOptionBuilder object that contains the NDP option data to be added - * @return A NdpOption object that contains the newly added NDP option data or logical null - * (NdpOption#isNull() == true) if addition failed. In case of a failure a corresponding error message will be - * printed to log - */ + /// Add a new NDP option at the end of the layer (after the last NDP option) + /// @param[in] optionBuilder An NdpOptionBuilder object that contains the NDP option data to be added + /// @return A NdpOption object that contains the newly added NDP option data or logical null + /// (NdpOption#isNull() == true) if addition failed. In case of a failure a corresponding error message will be + /// printed to log NdpOption addNdpOption(const NdpOptionBuilder& optionBuilder); - /** - * Remove all NDP options from the layer - * @return True if options removed successfully or false if some error occurred (an appropriate error message - * will be printed to log) - */ + /// Remove all NDP options from the layer + /// @return True if options removed successfully or false if some error occurred (an appropriate error message + /// will be printed to log) bool removeAllNdpOptions(); protected: @@ -183,73 +151,57 @@ namespace pcpp NdpOption addNdpOptionAt(const NdpOptionBuilder& optionBuilder, int offset); }; - /** - * @class NDPNeighborSolicitationLayer - * Represents a NDP Neighbor Solicitation protocol layer - */ + /// @class NDPNeighborSolicitationLayer + /// Represents a NDP Neighbor Solicitation protocol layer class NDPNeighborSolicitationLayer : public NDPLayerBase { public: - /** - * @struct ndpneighborsolicitationhdr - * Represents neighbor solicitation message format - */ + /// @struct ndpneighborsolicitationhdr + /// Represents neighbor solicitation message format #pragma pack(push, 1) struct ndpneighborsolicitationhdr : icmpv6hdr { - /** Reserved */ + /// Reserved uint32_t reserved; - /** Target address - Target address of solicitation message */ + /// Target address - Target address of solicitation message uint8_t targetIP[16]; }; #pragma pack(pop) - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in NDPNeighborSolicitationLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : NDPLayerBase(data, dataLen, prevLayer, packet) {} - /** - * A constructor for a new NDPNeighborSolicitationLayer object - * @param[in] code Code field - * @param[in] targetIP Target IP address for which the solicitation shall be created - */ + /// A constructor for a new NDPNeighborSolicitationLayer object + /// @param[in] code Code field + /// @param[in] targetIP Target IP address for which the solicitation shall be created NDPNeighborSolicitationLayer(uint8_t code, const IPv6Address& targetIP); - /** - * A constructor for a new NDPNeighborSolicitationLayer object - * @param[in] code Code field - * @param[in] targetIP Target IP address for which the solicitation shall be created - * @param[in] srcMac Mac address which shall be put in the linklayer option - */ + /// A constructor for a new NDPNeighborSolicitationLayer object + /// @param[in] code Code field + /// @param[in] targetIP Target IP address for which the solicitation shall be created + /// @param[in] srcMac Mac address which shall be put in the linklayer option NDPNeighborSolicitationLayer(uint8_t code, const IPv6Address& targetIP, const MacAddress& srcMac); ~NDPNeighborSolicitationLayer() override = default; - /** - * @return Get the IP address specified as the target IP address in the solicitation message - */ + /// @return Get the IP address specified as the target IP address in the solicitation message IPv6Address getTargetIP() const { return IPv6Address(getNdpHeader()->targetIP); }; - /** - * Checks if the layer has a link layer address option set - * @return true if link layer address option is available, false otherwise - */ + /// Checks if the layer has a link layer address option set + /// @return true if link layer address option is available, false otherwise bool hasLinkLayerAddress() const; - /** - * Get the Link Layer Address - * @return Mac address which is specified in the link layer address option - */ + /// Get the Link Layer Address + /// @return Mac address which is specified in the link layer address option MacAddress getLinkLayerAddress() const; std::string toString() const override; @@ -266,125 +218,103 @@ namespace pcpp }; }; - /** - * @class NDPNeighborAdvertisementLayer - * Represents a NDP Neighbor Advertisement protocol layer - */ + /// @class NDPNeighborAdvertisementLayer + /// Represents a NDP Neighbor Advertisement protocol layer class NDPNeighborAdvertisementLayer : public NDPLayerBase { public: - /** - * @struct ndpneighboradvertisementhdr - * Represents neighbor advertisement message format - */ + /// @struct ndpneighboradvertisementhdr + /// Represents neighbor advertisement message format #pragma pack(push, 1) struct ndpneighboradvertisementhdr : icmpv6hdr { #if (BYTE_ORDER == LITTLE_ENDIAN) uint32_t - /** Unused field */ + /// Unused field reserved : 5, - /** Flag indicating that this entry should override the old one */ + /// Flag indicating that this entry should override the old one override : 1, - /** Flag indicating that the advertisement was sent in response to a Neighbor Solicitation from the - Destination address */ + /// Flag indicating that the advertisement was sent in response to a Neighbor Solicitation from the + /// Destination address solicited : 1, - /** Flag indicating that the advertisement is sent by a router */ + /// Flag indicating that the advertisement is sent by a router router : 1, - /** Unused field */ + /// Unused field reserved2 : 24; #else uint32_t - /** Flag indicating that the advertisement is sent by a router */ + /// Flag indicating that the advertisement is sent by a router router : 1, - /** Flag indicating that the advertisement was sent in response to a Neighbor Solicitation from the - Destination address */ + /// Flag indicating that the advertisement was sent in response to a Neighbor Solicitation from the + /// Destination address solicited : 1, - /** Flag indicating that this entry should override the old one */ + /// Flag indicating that this entry should override the old one override : 1, - /** Unused field */ + /// Unused field reserved : 29; #endif - /** Target address - Either source address of advertisement or address for requested MAC */ + /// Target address - Either source address of advertisement or address for requested MAC uint8_t targetIP[16]; }; #pragma pack(pop) - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in NDPNeighborAdvertisementLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : NDPLayerBase(data, dataLen, prevLayer, packet) {} - /** - * A constructor that allocates a new NDP Advertisement Layer with target link-layer address option - * @param[in] code Code field - * @param[in] targetIP The target IP address from the Neighbor Solicitation message (solicited advertisements) - * or the address whose link-layer address has changed (unsolicited advertisement) - * @param[in] targetMac Adds the target link-layer address into the option field of the layer - * @param[in] routerFlag The router flag - * @param[in] unicastFlag The solicited flag - * @param[in] overrideFlag The override flag - */ + /// A constructor that allocates a new NDP Advertisement Layer with target link-layer address option + /// @param[in] code Code field + /// @param[in] targetIP The target IP address from the Neighbor Solicitation message (solicited advertisements) + /// or the address whose link-layer address has changed (unsolicited advertisement) + /// @param[in] targetMac Adds the target link-layer address into the option field of the layer + /// @param[in] routerFlag The router flag + /// @param[in] unicastFlag The solicited flag + /// @param[in] overrideFlag The override flag NDPNeighborAdvertisementLayer(uint8_t code, const IPv6Address& targetIP, const MacAddress& targetMac, bool routerFlag, bool unicastFlag, bool overrideFlag); - /** - * A constructor that allocates a new NDP Advertisement Layer - * @param code Code field - * @param targetIP The target IP address from the Neighbor Solicitation message (solicited advertisements) or - * the address whose link-layer address has changed (unsolicited advertisement) - * @param routerFlag The router flag - * @param unicastFlag The solicited flag - * @param overrideFlag The override flag - */ + /// A constructor that allocates a new NDP Advertisement Layer + /// @param code Code field + /// @param targetIP The target IP address from the Neighbor Solicitation message (solicited advertisements) or + /// the address whose link-layer address has changed (unsolicited advertisement) + /// @param routerFlag The router flag + /// @param unicastFlag The solicited flag + /// @param overrideFlag The override flag NDPNeighborAdvertisementLayer(uint8_t code, const IPv6Address& targetIP, bool routerFlag, bool unicastFlag, bool overrideFlag); ~NDPNeighborAdvertisementLayer() override = default; - /** - * @return Get the target MAC address - */ + /// @return Get the target MAC address MacAddress getTargetMac() const; - /** - * @return Get the target IP address - */ + /// @return Get the target IP address IPv6Address getTargetIP() const { return IPv6Address(getNdpHeader()->targetIP); } - /** - * @return Get information if the target link-layer address was added in the option field of the header - */ + /// @return Get information if the target link-layer address was added in the option field of the header bool hasTargetMacInfo() const; - /** - * @return Get the router flag - */ + /// @return Get the router flag bool getRouterFlag() const { return getNdpHeader()->router; } - /** - * @return Get the unicast flag - */ + /// @return Get the unicast flag bool getUnicastFlag() const { return getNdpHeader()->solicited; } - /** - * @return Get the override flag - */ + /// @return Get the override flag bool getOverrideFlag() const { return getNdpHeader()->override; diff --git a/Packet++/header/NflogLayer.h b/Packet++/header/NflogLayer.h index a5301799b7..ed997e50b5 100644 --- a/Packet++/header/NflogLayer.h +++ b/Packet++/header/NflogLayer.h @@ -6,103 +6,91 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @struct nflog_header - * Represents Nflog header - */ + /// @struct nflog_header + /// Represents Nflog header #pragma pack(push, 1) struct nflog_header { - /** A Linux AF_ value, so it's 2 for IPv4 and 10 for IPv6 */ + /// A Linux AF_ value, so it's 2 for IPv4 and 10 for IPv6 uint8_t addressFamily; - /** The version field is 0 for the current version of the pseudo-header */ + /// The version field is 0 for the current version of the pseudo-header uint8_t version; - /** The network byte order (big-endian) */ + /// The network byte order (big-endian) uint16_t resourceId; }; #pragma pack(pop) static_assert(sizeof(nflog_header) == 4, "nflog_header size is not 4 bytes"); - /** - * @enum NflogTlvType - * Represents TLV types of NFLOG packets - */ + /// @enum NflogTlvType + /// Represents TLV types of NFLOG packets enum class NflogTlvType { - /** the packet header structure */ + /// the packet header structure NFULA_PACKET_HDR = 1, - /** packet mark from skbuff */ + /// packet mark from skbuff NFULA_MARK = 2, - /** nflog_timestamp_t for skbuff's time stamp */ + /// nflog_timestamp_t for skbuff's time stamp NFULA_TIMESTAMP = 3, - /** ifindex of device on which packet received (possibly bridge group) */ + /// ifindex of device on which packet received (possibly bridge group) NFULA_IFINDEX_INDEV = 4, - /** ifindex of device on which packet transmitted (possibly bridge group) */ + /// ifindex of device on which packet transmitted (possibly bridge group) NFULA_IFINDEX_OUTDEV = 5, - /** ifindex of physical device on which packet received (not bridge group) */ + /// ifindex of physical device on which packet received (not bridge group) NFULA_IFINDEX_PHYSINDEV = 6, - /** ifindex of physical device on which packet transmitted (not bridge group) */ + /// ifindex of physical device on which packet transmitted (not bridge group) NFULA_IFINDEX_PHYSOUTDEV = 7, - /** nflog_hwaddr_t for hardware address */ + /// nflog_hwaddr_t for hardware address NFULA_HWADDR = 8, - /** packet payload */ + /// packet payload NFULA_PAYLOAD = 9, - /** text string - null-terminated, count includes NUL */ + /// text string - null-terminated, count includes NUL NFULA_PREFIX = 10, - /** UID owning socket on which packet was sent/received */ + /// UID owning socket on which packet was sent/received NFULA_UID = 11, - /** sequence number of packets on this NFLOG socket */ + /// sequence number of packets on this NFLOG socket NFULA_SEQ = 12, - /** sequence number of packets on all NFLOG sockets */ + /// sequence number of packets on all NFLOG sockets NFULA_SEQ_GLOBAL = 13, - /** GID owning socket on which packet was sent/received */ + /// GID owning socket on which packet was sent/received NFULA_GID = 14, - /** ARPHRD_ type of skbuff's device */ + /// ARPHRD_ type of skbuff's device NFULA_HWTYPE = 15, - /** skbuff's MAC-layer header */ + /// skbuff's MAC-layer header NFULA_HWHEADER = 16, - /** length of skbuff's MAC-layer header */ + /// length of skbuff's MAC-layer header NFULA_HWLEN = 17, }; - /** - * @class NflogTlv - * A wrapper class for NFLOG TLV fields. This class does not create or modify TLVs related to NFLOG, but rather - * serves as a wrapper and provides useful methods for setting and retrieving data to/from them - */ + /// @class NflogTlv + /// A wrapper class for NFLOG TLV fields. This class does not create or modify TLVs related to NFLOG, but rather + /// serves as a wrapper and provides useful methods for setting and retrieving data to/from them class NflogTlv { private: struct NflogTLVRawData { - /** Record length in bytes */ + /// Record length in bytes uint16_t recordLen; - /** Record type */ + /// Record type uint16_t recordType; - /** Record value (variable size) */ + /// Record value (variable size) uint8_t recordValue[]; }; NflogTLVRawData* m_Data; public: - /** - * A c'tor for this class that gets a pointer to the option raw data (byte array) - * @param[in] recordRawData A pointer to the option raw data - */ + /// A c'tor for this class that gets a pointer to the option raw data (byte array) + /// @param[in] recordRawData A pointer to the option raw data explicit NflogTlv(uint8_t* recordRawData) { assign(recordRawData); } - /** - * @return recordLen attribute in NflogTLVRawData - */ + /// @return recordLen attribute in NflogTLVRawData size_t getTotalSize() const { // as in @@ -110,130 +98,98 @@ namespace pcpp return align<4>(m_Data->recordLen); } - /** - * Assign a pointer to the TLV record raw data (byte array) - * @param[in] recordRawData A pointer to the TLV record raw data - */ + /// Assign a pointer to the TLV record raw data (byte array) + /// @param[in] recordRawData A pointer to the TLV record raw data void assign(uint8_t* recordRawData) { m_Data = reinterpret_cast(recordRawData); } - /** - * Check if a pointer can be assigned to the TLV record data - * @param[in] recordRawData A pointer to the TLV record raw data - * @param[in] tlvDataLen The size of the TLV record raw data - * * @return True if data is valid and can be assigned - */ + /// Check if a pointer can be assigned to the TLV record data + /// @param[in] recordRawData A pointer to the TLV record raw data + /// @param[in] tlvDataLen The size of the TLV record raw data + /// * @return True if data is valid and can be assigned static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen) { return recordRawData != nullptr && tlvDataLen >= sizeof(NflogTLVRawData::recordLen); } - /** - * @return True if the TLV record raw data is nullptr, false otherwise - */ + /// @return True if the TLV record raw data is nullptr, false otherwise bool isNull() const { return (m_Data == nullptr); } - /** - * @return The type field of the record (the 'T' in __Type__-Length-Value) - */ + /// @return The type field of the record (the 'T' in __Type__-Length-Value) uint16_t getType() const { return m_Data->recordType; } - /** - * @return A pointer to the TLV record raw data byte stream - */ + /// @return A pointer to the TLV record raw data byte stream uint8_t* getRecordBasePtr() const { return reinterpret_cast(m_Data); } - /** - * @return A pointer to the value of the record as byte array (the 'V' in Type-Length- __Value__) - */ + /// @return A pointer to the value of the record as byte array (the 'V' in Type-Length- __Value__) uint8_t* getValue() const { return m_Data->recordValue; } }; - /** - * @class NflogLayer - * Represents an NFLOG protocol layer - */ + /// @class NflogLayer + /// Represents an NFLOG protocol layer class NflogLayer : public Layer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to ether_header) - * @param[in] dataLen Size of the data in bytes - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to ether_header) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] packet A pointer to the Packet instance where layer will be stored in NflogLayer(uint8_t* data, size_t dataLen, Packet* packet) : Layer(data, dataLen, nullptr, packet, NFLOG) {} ~NflogLayer() override = default; - /** - * Get a pointer to the Nflog header. - * @return A pointer to the nflog_header - */ + /// Get a pointer to the Nflog header. + /// @return A pointer to the nflog_header nflog_header* getNflogHeader() const { return reinterpret_cast(m_Data); } - /** - * Get address family of the packet. e.g. 2 for ipv4 and 10 for ipv6 - * @return an unsigned char of address family - */ + /// Get address family of the packet. e.g. 2 for ipv4 and 10 for ipv6 + /// @return an unsigned char of address family uint8_t getFamily(); - /** - * Get Version number inside packet header - * The version field is 0 for the current version of the pseudo-header - * @return an unsigned char for version - */ + /// Get Version number inside packet header + /// The version field is 0 for the current version of the pseudo-header + /// @return an unsigned char for version uint8_t getVersion(); - /** - * Get Resource Id in packet header - * On one netlink socket it's possible to listen to several nflog groups; the resource ID is the nflog group for - * the packet - */ + /// Get Resource Id in packet header + /// On one netlink socket it's possible to listen to several nflog groups; the resource ID is the nflog group + /// for the packet uint16_t getResourceId(); - /** - * Get a TLV object found with the input type. if no tlv is found, the internal value of the object will set to - * nullptr - * @param[in] type type of tlv by using enum class defined as NflogTlvType - * @return NflogTlv obtained by type - */ + /// Get a TLV object found with the input type. if no tlv is found, the internal value of the object will set to + /// nullptr + /// @param[in] type type of tlv by using enum class defined as NflogTlvType + /// @return NflogTlv obtained by type NflogTlv getTlvByType(NflogTlvType type) const; // implement abstract methods - /** - * Currently identifies the following next layers: IPv4Layer, IPv6Layer using address family - * Otherwise sets PayloadLayer - */ + /// Currently identifies the following next layers: IPv4Layer, IPv6Layer using address family + /// Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * @return Size of nflog_header - */ + /// @return Size of nflog_header size_t getHeaderLen() const override; - /** - * Does nothing for this layer - */ + /// Does nothing for this layer void computeCalculateFields() override {}; std::string toString() const override; @@ -243,12 +199,10 @@ namespace pcpp return OsiModelDataLinkLayer; } - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of an NFLOG packet - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent an NFLOG packet - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of an NFLOG packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent an NFLOG packet static bool isDataValid(const uint8_t* data, size_t dataLen); private: diff --git a/Packet++/header/NtpLayer.h b/Packet++/header/NtpLayer.h index 9099ede363..7dec0ae463 100644 --- a/Packet++/header/NtpLayer.h +++ b/Packet++/header/NtpLayer.h @@ -6,70 +6,65 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @class NtpLayer - * Represents a NTP (Network Time Protocol) layer - * - * @brief The NTP packet consists of an integral number of 32-bit (4 octet) words in network byte order. - * The packet format consists of three components: the header itself, one or more optional extension fields (for - * v4), and an optional message authentication code (MAC). Currently the extension fields are not supported. The NTP - * header is: - * - * @verbatim - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |LI | VN |Mode | Stratum | Poll | Precision | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Root Delay | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Root Dispersion | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Reference ID | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - + Reference Timestamp (64) + - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - + Origin Timestamp (64) + - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - + Receive Timestamp (64) + - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - + Transmit Timestamp (64) + - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - . . - . Extension Field 1 (variable, only v4) . - . . - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - . . - . Extension Field 1 (variable, only v4) . - . . - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Key Identifier | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - | dgst (128 for v4, 64 for v3) | - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - @endverbatim - * - */ + /// @class NtpLayer + /// Represents a NTP (Network Time Protocol) layer + /// + /// @brief The NTP packet consists of an integral number of 32-bit (4 octet) words in network byte order. + /// The packet format consists of three components: the header itself, one or more optional extension fields (for + /// v4), and an optional message authentication code (MAC). Currently the extension fields are not supported. The + /// NTP header is: + /// + /// @code{.unparsed} + /// 0 1 2 3 + /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// |LI | VN |Mode | Stratum | Poll | Precision | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | Root Delay | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | Root Dispersion | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | Reference ID | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | | + /// + Reference Timestamp (64) + + /// | | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | | + /// + Origin Timestamp (64) + + /// | | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | | + /// + Receive Timestamp (64) + + /// | | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | | + /// + Transmit Timestamp (64) + + /// | | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | | + /// . . + /// . Extension Field 1 (variable, only v4) . + /// . . + /// | | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | | + /// . . + /// . Extension Field 1 (variable, only v4) . + /// . . + /// | | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | Key Identifier | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | | + /// | dgst (128 for v4, 64 for v3) | + /// | | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// @endcode class NtpLayer : public Layer { private: @@ -157,9 +152,7 @@ namespace pcpp } public: - /** - * Warning of an impending leap second to be inserted or deleted in the last minute of the current month - */ + /// Warning of an impending leap second to be inserted or deleted in the last minute of the current month enum LeapIndicator { /// Normal, no leap second @@ -172,9 +165,7 @@ namespace pcpp Unknown }; - /** - * Representing the NTP association modes - */ + /// Representing the NTP association modes enum Mode { /// Reserved variable @@ -195,10 +186,8 @@ namespace pcpp PrivateUse }; - /** - * 32-bit code identifying the particular server or reference clock. - * The interpretation depends on the value in the stratum field. - */ + /// 32-bit code identifying the particular server or reference clock. + /// The interpretation depends on the value in the stratum field. enum class ClockSource : uint32_t { // NTPv4 @@ -286,9 +275,7 @@ namespace pcpp VLF = ('V') | ('L' << 8) | ('F' << 16) }; - /** - * 32-bit Kiss of Death (KoD) codes - */ + /// 32-bit Kiss of Death (KoD) codes enum class KissODeath : uint32_t { /// The association belongs to a anycast server @@ -322,349 +309,225 @@ namespace pcpp STEP = ('S') | ('T' << 8) | ('E' << 16) | ('P' << 24), }; - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in NtpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, NTP) {} - /** - * Empty c'tor - */ + /// Empty c'tor NtpLayer(); - /** - * @return The leap indicator - */ + /// @return The leap indicator LeapIndicator getLeapIndicator() const; - /** - * Set the leap indicator - */ + /// Set the leap indicator void setLeapIndicator(LeapIndicator val); - /** - * @return The version of NTP - */ + /// @return The version of NTP uint8_t getVersion() const; - /** - * Set the version of NTP - */ + /// Set the version of NTP void setVersion(uint8_t val); - /** - * @return The mode value - */ + /// @return The mode value Mode getMode() const; - /** - * @return The mode as string - */ + /// @return The mode as string std::string getModeString() const; - /** - * Set the mode - */ + /// Set the mode void setMode(Mode val); - /** - * @return The value of stratum - */ + /// @return The value of stratum uint8_t getStratum() const; - /** - * Set the value of stratum - */ + /// Set the value of stratum void setStratum(uint8_t val); - /** - * @return The value of poll interval in log2 seconds - */ + /// @return The value of poll interval in log2 seconds int8_t getPollInterval() const; - /** - * Set the value of poll interval - * @param[in] val Poll interval in log2 seconds - */ + /// Set the value of poll interval + /// @param[in] val Poll interval in log2 seconds void setPollInterval(int8_t val); - /** - * @return The value of poll interval in seconds - */ + /// @return The value of poll interval in seconds double getPollIntervalInSecs() const; - /** - * @return The value of precision in log2 seconds - */ + /// @return The value of precision in log2 seconds int8_t getPrecision() const; - /** - * Set the value of precision - * @param[in] val Precision in log2 seconds - */ + /// Set the value of precision + /// @param[in] val Precision in log2 seconds void setPrecision(int8_t val); - /** - * @return The value of precision in seconds - */ + /// @return The value of precision in seconds double getPrecisionInSecs() const; - /** - * @return The value of root delay in NTP short format - */ + /// @return The value of root delay in NTP short format uint32_t getRootDelay() const; - /** - * Set the value of root delay - * @param[in] val Root delay in NTP short format - */ + /// Set the value of root delay + /// @param[in] val Root delay in NTP short format void setRootDelay(uint32_t val); - /** - * @return The value of root delay in seconds - */ + /// @return The value of root delay in seconds double getRootDelayInSecs() const; - /** - * Set the value of root delay - * @param[in] val Root delay in seconds - */ + /// Set the value of root delay + /// @param[in] val Root delay in seconds void setRootDelayInSecs(double val); - /** - * @return The value of root dispersion in NTP short format - */ + /// @return The value of root dispersion in NTP short format uint32_t getRootDispersion() const; - /** - * Set the value of root delay - * @param[in] val Root dispersion in NTP short format - */ + /// Set the value of root delay + /// @param[in] val Root dispersion in NTP short format void setRootDispersion(uint32_t val); - /** - * @return The value of root dispersion in seconds - */ + /// @return The value of root dispersion in seconds double getRootDispersionInSecs() const; - /** - * Set the value of root dispersion - * @param[in] val Root dispersion in seconds - */ + /// Set the value of root dispersion + /// @param[in] val Root dispersion in seconds void setRootDispersionInSecs(double val); - /** - * @return The value of reference identifier - */ + /// @return The value of reference identifier uint32_t getReferenceIdentifier() const; - /** - * Set the value of reference identifier - * @param[in] val Value of the reference identifier as IPv4 address - */ + /// Set the value of reference identifier + /// @param[in] val Value of the reference identifier as IPv4 address void setReferenceIdentifier(IPv4Address val); - /** - * Set the value of reference identifier - * @param[in] val Value of the reference identifier as ClockSource - */ + /// Set the value of reference identifier + /// @param[in] val Value of the reference identifier as ClockSource void setReferenceIdentifier(ClockSource val); - /** - * Set the value of reference identifier - * @param[in] val Value of the reference identifier as Kiss-O-Death code - */ + /// Set the value of reference identifier + /// @param[in] val Value of the reference identifier as Kiss-O-Death code void setReferenceIdentifier(KissODeath val); - /** - * @return The value of reference identifier as a string. String representation of NTP clock source if stratum - * is 1, IPv4 address or MD5 hash of first four octets of IPv6 - */ + /// @return The value of reference identifier as a string. String representation of NTP clock source if + /// stratum is 1, IPv4 address or MD5 hash of first four octets of IPv6 std::string getReferenceIdentifierString() const; - /** - * @return The value of reference timestamp in NTP timestamp format - */ + /// @return The value of reference timestamp in NTP timestamp format uint64_t getReferenceTimestamp() const; - /** - * Set the value of reference timestamp - * @param[in] val Timestamp in NTP timestamp format - */ + /// Set the value of reference timestamp + /// @param[in] val Timestamp in NTP timestamp format void setReferenceTimestamp(uint64_t val); - /** - * @return The value of reference timestamp in seconds from Unix Epoch (1 Jan 1970) - */ + /// @return The value of reference timestamp in seconds from Unix Epoch (1 Jan 1970) double getReferenceTimestampInSecs() const; - /** - * Set the value of reference timestamp - * @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) - */ + /// Set the value of reference timestamp + /// @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) void setReferenceTimestampInSecs(double val); - /** - * @return The reference timestamp value as readable string in ISO8601 format - */ + /// @return The reference timestamp value as readable string in ISO8601 format std::string getReferenceTimestampAsString(); - /** - * @return The value of origin timestamp in NTP timestamp format - */ + /// @return The value of origin timestamp in NTP timestamp format uint64_t getOriginTimestamp() const; - /** - * Set the value of origin timestamp - * @param[in] val Value in NTP timestamp format - */ + /// Set the value of origin timestamp + /// @param[in] val Value in NTP timestamp format void setOriginTimestamp(uint64_t val); - /** - * @return The value of origin timestamp in seconds from Unix Epoch (1 Jan 1970) - */ + /// @return The value of origin timestamp in seconds from Unix Epoch (1 Jan 1970) double getOriginTimestampInSecs() const; - /** - * Set the value of origin timestamp - * @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) - */ + /// Set the value of origin timestamp + /// @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) void setOriginTimestampInSecs(double val); - /** - * @return the origin timestamp value as readable string in ISO8601 format - */ + /// @return the origin timestamp value as readable string in ISO8601 format std::string getOriginTimestampAsString(); - /** - * @return The value of receive timestamp in NTP timestamp format - */ + /// @return The value of receive timestamp in NTP timestamp format uint64_t getReceiveTimestamp() const; - /** - * Set the value of receive timestamp - * @param[in] val Value in NTP timestamp format - */ + /// Set the value of receive timestamp + /// @param[in] val Value in NTP timestamp format void setReceiveTimestamp(uint64_t val); - /** - * @return The value of receive timestampin seconds from Unix Epoch (1 Jan 1970) - */ + /// @return The value of receive timestampin seconds from Unix Epoch (1 Jan 1970) double getReceiveTimestampInSecs() const; - /** - * Set the value of receive timestamp - * @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) - */ + /// Set the value of receive timestamp + /// @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) void setReceiveTimestampInSecs(double val); - /** - * @return The receive timestamp value as readable string in ISO8601 format - */ + /// @return The receive timestamp value as readable string in ISO8601 format std::string getReceiveTimestampAsString(); - /** - * @return The value of transmit timestamp in NTP timestamp format - */ + /// @return The value of transmit timestamp in NTP timestamp format uint64_t getTransmitTimestamp() const; - /** - * Set the value of transmit timestamp - * @param[in] val Value in NTP timestamp format - */ + /// Set the value of transmit timestamp + /// @param[in] val Value in NTP timestamp format void setTransmitTimestamp(uint64_t val); - /** - * @return The value of transmit timestamp in seconds from Unix Epoch (1 Jan 1970) - */ + /// @return The value of transmit timestamp in seconds from Unix Epoch (1 Jan 1970) double getTransmitTimestampInSecs() const; - /** - * Set the value of transmit timestamp - * @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) - */ + /// Set the value of transmit timestamp + /// @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) void setTransmitTimestampInSecs(double val); - /** - * @return The transmit timestamp value as readable string in ISO8601 format - */ + /// @return The transmit timestamp value as readable string in ISO8601 format std::string getTransmitTimestampAsString(); - /** - * @return Returns the key identifier if exists, returns 0 on unsupported NTP version or key identifier not - * found - */ + /// @return Returns the key identifier if exists, returns 0 on unsupported NTP version or key identifier not + /// found uint32_t getKeyID() const; - /** - * @return Get the digest value as hexadecimal string, empty string on unsupported version - */ + /// @return Get the digest value as hexadecimal string, empty string on unsupported version std::string getDigest() const; - /** - * Convert NTP short format to seconds from the Unix Epoch - * - * @param[in] val Value in NTP short format - * @return Value in seconds from Unix Epoch (1 Jan 1970) - */ + /// Convert NTP short format to seconds from the Unix Epoch + /// @param[in] val Value in NTP short format + /// @return Value in seconds from Unix Epoch (1 Jan 1970) static double convertFromShortFormat(const uint32_t val); - /** - * Convert NTP timestamp format to seconds from the Unix Epoch - * - * @param[in] val Value in NTP timestamp format - * @return Value in seconds from Unix Epoch (1 Jan 1970) - */ + /// Convert NTP timestamp format to seconds from the Unix Epoch + /// @param[in] val Value in NTP timestamp format + /// @return Value in seconds from Unix Epoch (1 Jan 1970) static double convertFromTimestampFormat(const uint64_t val); - /** - * Convert seconds from the Unix Epoch to NTP short format - * - * @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) - * @return Value in NTP short format - */ + /// Convert seconds from the Unix Epoch to NTP short format + /// @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) + /// @return Value in NTP short format static uint32_t convertToShortFormat(const double val); - /** - * Convert seconds from the Unix Epoch to NTP timestamp format - * - * @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) - * @return Value in NTP timestamp format - */ + /// Convert seconds from the Unix Epoch to NTP timestamp format + /// @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) + /// @return Value in NTP timestamp format static uint64_t convertToTimestampFormat(const double val); - /** - * A static method to convert timestamp value to ISO8601 date time format - * @param[in] timestamp Value in seconds from the Unix Epoch - * @return std::string ISO8601 formatted string - */ + /// A static method to convert timestamp value to ISO8601 date time format + /// @param[in] timestamp Value in seconds from the Unix Epoch + /// @return std::string ISO8601 formatted string static std::string convertToIsoFormat(const double timestamp); - /** - * A static method to convert timestamp value to ISO8601 date time format - * @param[in] timestampInNTPformat Value in NTP timestamp format - * @return std::string ISO8601 formatted string - */ + /// A static method to convert timestamp value to ISO8601 date time format + /// @param[in] timestampInNTPformat Value in NTP timestamp format + /// @return std::string ISO8601 formatted string static std::string convertToIsoFormat(const uint64_t timestampInNTPformat); - /** - * A static method that takes a byte array and detects whether it is a NTP message - * @param[in] data A byte array - * @param[in] dataSize The byte array size (in bytes) - * @return True if the data is identified as NTP message - */ + /// A static method that takes a byte array and detects whether it is a NTP message + /// @param[in] data A byte array + /// @param[in] dataSize The byte array size (in bytes) + /// @return True if the data is identified as NTP message static bool isDataValid(const uint8_t* data, size_t dataSize); - /** - * A static method that checks whether the port is considered as NTP - * @param[in] port The port number to be checked - */ + /// A static method that checks whether the port is considered as NTP + /// @param[in] port The port number to be checked static bool isNTPPort(uint16_t port) { return port == 123; @@ -676,9 +539,7 @@ namespace pcpp void parseNextLayer() override {} - /** - * @return Get the size of the layer (Including the extension and authentication fields if exists) - */ + /// @return Get the size of the layer (Including the extension and authentication fields if exists) size_t getHeaderLen() const override { return m_DataLen; @@ -688,18 +549,13 @@ namespace pcpp void computeCalculateFields() override {} - /** - * @return The OSI layer level of NTP (Application Layer). - */ + /// @return The OSI layer level of NTP (Application Layer). OsiModelLayer getOsiModelLayer() const override { return OsiModelApplicationLayer; } - /** - * @return Returns the protocol info as readable string - */ + /// @return Returns the protocol info as readable string std::string toString() const override; }; - } // namespace pcpp diff --git a/Packet++/header/NullLoopbackLayer.h b/Packet++/header/NullLoopbackLayer.h index 726133c3f9..0903781771 100644 --- a/Packet++/header/NullLoopbackLayer.h +++ b/Packet++/header/NullLoopbackLayer.h @@ -1,89 +1,74 @@ #pragma once -/// @file - #include "Layer.h" +/// @file + +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { -/** IPv4 protocol **/ +/// IPv4 protocol * #define PCPP_BSD_AF_INET 2 -/** XEROX NS protocols */ +/// XEROX NS protocols #define PCPP_BSD_AF_NS 6 -/** ISO */ +/// ISO #define PCPP_BSD_AF_ISO 7 -/** AppleTalk */ +/// AppleTalk #define PCPP_BSD_AF_APPLETALK 16 -/** IPX */ +/// IPX #define PCPP_BSD_AF_IPX 23 -/** OpenBSD (and probably NetBSD), BSD/OS IPv6 */ +/// OpenBSD (and probably NetBSD), BSD/OS IPv6 #define PCPP_BSD_AF_INET6_BSD 24 -/** FreeBSD IPv6 */ +/// FreeBSD IPv6 #define PCPP_BSD_AF_INET6_FREEBSD 28 -/** Darwin IPv6 */ +/// Darwin IPv6 #define PCPP_BSD_AF_INET6_DARWIN 30 - /** - * @class NullLoopbackLayer - * Represents a Null/Loopback layer - */ + /// @class NullLoopbackLayer + /// Represents a Null/Loopback layer class NullLoopbackLayer : public Layer { public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] packet A pointer to the Packet instance where layer will be stored in NullLoopbackLayer(uint8_t* data, size_t dataLen, Packet* packet) : Layer(data, dataLen, nullptr, packet, NULL_LOOPBACK) {} - /** - * A constructor that allocates a new Null/Loopback header - * @param[in] family The family protocol to set - */ + /// A constructor that allocates a new Null/Loopback header + /// @param[in] family The family protocol to set explicit NullLoopbackLayer(uint32_t family); - /** - * A destructor for this layer (does nothing) - */ + /// A destructor for this layer (does nothing) ~NullLoopbackLayer() override = default; - /** - * @return The protocol family in this layer - */ + /// @return The protocol family in this layer uint32_t getFamily() const; - /** - * Set a protocol family - * @param[in] family The family protocol to set - */ + /// Set a protocol family + /// @param[in] family The family protocol to set void setFamily(uint32_t family); // implement abstract methods - /** - * Identifies the next layers by family: - * - for ::PCPP_BSD_AF_INET the next layer is IPv4Layer - * - for ::PCPP_BSD_AF_INET6_BSD, ::PCPP_BSD_AF_INET6_FREEBSD, ::PCPP_BSD_AF_INET6_DARWIN the next layer is - * IPv6Layer - * - for other values the next layer in PayloadLayer (unknown protocol) - */ + /// Identifies the next layers by family: + /// - for ::PCPP_BSD_AF_INET the next layer is IPv4Layer + /// - for ::PCPP_BSD_AF_INET6_BSD, ::PCPP_BSD_AF_INET6_FREEBSD, ::PCPP_BSD_AF_INET6_DARWIN the next layer is + /// IPv6Layer + /// - for other values the next layer in PayloadLayer (unknown protocol) void parseNextLayer() override; - /** - * @return Size of Null/Loopback header = 4B - */ + /// @return Size of Null/Loopback header = 4B size_t getHeaderLen() const override { return sizeof(uint32_t); } - /** - * Does nothing for this layer - */ + /// Does nothing for this layer void computeCalculateFields() override {} @@ -94,5 +79,4 @@ namespace pcpp return OsiModelDataLinkLayer; } }; - } // namespace pcpp diff --git a/Packet++/header/PPPoELayer.h b/Packet++/header/PPPoELayer.h index 2a3622f56d..aba14b0c8a 100644 --- a/Packet++/header/PPPoELayer.h +++ b/Packet++/header/PPPoELayer.h @@ -7,87 +7,76 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct pppoe_header - * Represents an PPPoE protocol header - */ + /// @struct pppoe_header + /// Represents an PPPoE protocol header #pragma pack(push, 1) struct pppoe_header { #if (BYTE_ORDER == LITTLE_ENDIAN) - /** PPPoE version */ + /// PPPoE version uint8_t version : 4; - /** PPPoE type */ + /// PPPoE type uint8_t type : 4; - /** PPPoE code */ + /// PPPoE code uint8_t code; #else - /** PPPoE version */ + /// PPPoE version uint16_t version : 4; - /** PPPoE type */ + /// PPPoE type uint16_t type : 4; - /** PPPoE code */ + /// PPPoE code uint16_t code : 8; #endif - /** PPPoE session ID (relevant for PPPoE session packets only) */ + /// PPPoE session ID (relevant for PPPoE session packets only) uint16_t sessionId; - /** Length (in bytes) of payload, not including the PPPoE header */ + /// Length (in bytes) of payload, not including the PPPoE header uint16_t payloadLength; }; #pragma pack(pop) static_assert(sizeof(pppoe_header) == 6, "pppoe_header size is not 6 bytes"); - /** - * @class PPPoELayer - * An abstract class that describes the PPPoE protocol. Contains common data and logic of the two types of PPPoE - * packets: PPPoE session and PPPoE discovery - */ + /// @class PPPoELayer + /// An abstract class that describes the PPPoE protocol. Contains common data and logic of the two types of PPPoE + /// packets: PPPoE session and PPPoE discovery class PPPoELayer : public Layer { public: - /** - * PPPoE possible codes - */ + /// PPPoE possible codes enum PPPoECode { - /** PPPoE session code */ + /// PPPoE session code PPPOE_CODE_SESSION = 0x00, - /** PPPoE discovery PADO */ + /// PPPoE discovery PADO PPPOE_CODE_PADO = 0x07, - /** PPPoE discovery PADI */ + /// PPPoE discovery PADI PPPOE_CODE_PADI = 0x09, - /** PPPoE discovery PADG */ + /// PPPoE discovery PADG PPPOE_CODE_PADG = 0x0a, - /** PPPoE discovery PADC */ + /// PPPoE discovery PADC PPPOE_CODE_PADC = 0x0b, - /** PPPoE discovery PADQ */ + /// PPPoE discovery PADQ PPPOE_CODE_PADQ = 0x0c, - /** PPPoE discovery PADR */ + /// PPPoE discovery PADR PPPOE_CODE_PADR = 0x19, - /** PPPoE discovery PADS */ + /// PPPoE discovery PADS PPPOE_CODE_PADS = 0x65, - /** PPPoE discovery PADT */ + /// PPPoE discovery PADT PPPOE_CODE_PADT = 0xa7, - /** PPPoE discovery PADM */ + /// PPPoE discovery PADM PPPOE_CODE_PADM = 0xd3, - /** PPPoE discovery PADN */ + /// PPPoE discovery PADN PPPOE_CODE_PADN = 0xd4 }; ~PPPoELayer() override = default; - /** - * Get a pointer to the PPPoE header. Notice this points directly to the data, so every change will change the - * actual packet data - * @return A pointer to the pppoe_header - */ + /// Get a pointer to the PPPoE header. Notice this points directly to the data, so every change will change the + /// actual packet data + /// @return A pointer to the pppoe_header pppoe_header* getPPPoEHeader() const { return reinterpret_cast(m_Data); @@ -95,9 +84,7 @@ namespace pcpp // abstract methods implementation - /** - * Calculate @ref pppoe_header#payloadLength field - */ + /// Calculate @ref pppoe_header#payloadLength field void computeCalculateFields() override; OsiModelLayer getOsiModelLayer() const override @@ -116,32 +103,26 @@ namespace pcpp size_t additionalBytesToAllocate = 0); }; - /** - * @class PPPoESessionLayer - * Describes the PPPoE session protocol - */ + /// @class PPPoESessionLayer + /// Describes the PPPoE session protocol class PPPoESessionLayer : public PPPoELayer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to @ref pppoe_header) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to @ref pppoe_header) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in PPPoESessionLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : PPPoELayer(data, dataLen, prevLayer, packet, PPPoESession) {} - /** - * A constructor that allocates a new PPPoE Session header with version, type and session ID - * @param[in] version PPPoE version - * @param[in] type PPPoE type - * @param[in] sessionId PPPoE session ID - * @param[in] pppNextProtocol The next protocol to come after the PPPoE session header. Should be one of the - * PPP_* macros listed below - */ + /// A constructor that allocates a new PPPoE Session header with version, type and session ID + /// @param[in] version PPPoE version + /// @param[in] type PPPoE type + /// @param[in] sessionId PPPoE session ID + /// @param[in] pppNextProtocol The next protocol to come after the PPPoE session header. Should be one of the + /// PPP_* macros listed below PPPoESessionLayer(uint8_t version, uint8_t type, uint16_t sessionId, uint16_t pppNextProtocol) : PPPoELayer(version, type, PPPoELayer::PPPOE_CODE_SESSION, sessionId, sizeof(uint16_t)) { @@ -150,37 +131,27 @@ namespace pcpp ~PPPoESessionLayer() override = default; - /** - * @return The protocol after the PPPoE session header. The return value is one of the PPP_* macros listed - * below. This method is also used when parsing a packet (this way we know which layer comes after the PPPoE - * session) - */ + /// @return The protocol after the PPPoE session header. The return value is one of the PPP_* macros listed + /// below. This method is also used when parsing a packet (this way we know which layer comes after the PPPoE + /// session) uint16_t getPPPNextProtocol() const; - /** - * Set the field that describes which header comes after the PPPoE session header - * @param[in] nextProtocol The protocol value. Should be one of the PPP_* macros listed below - */ + /// Set the field that describes which header comes after the PPPoE session header + /// @param[in] nextProtocol The protocol value. Should be one of the PPP_* macros listed below void setPPPNextProtocol(uint16_t nextProtocol); - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of byte stream of a packet - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent a PPPoES packet - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of byte stream of a packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent a PPPoES packet static inline bool isDataValid(const uint8_t* data, size_t dataLen); // abstract methods implementation - /** - * Currently identifies the following next layers: IPv4Layer, IPv6Layer. Otherwise sets PayloadLayer - */ + /// Currently identifies the following next layers: IPv4Layer, IPv6Layer. Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * @return Size of @ref pppoe_header - */ + /// @return Size of @ref pppoe_header size_t getHeaderLen() const override { return sizeof(pppoe_header) + sizeof(uint16_t); @@ -189,84 +160,70 @@ namespace pcpp std::string toString() const override; }; - /** - * @class PPPoEDiscoveryLayer - * Describes the PPPoE discovery protocol - */ + /// @class PPPoEDiscoveryLayer + /// Describes the PPPoE discovery protocol class PPPoEDiscoveryLayer : public PPPoELayer { public: - /** - * PPPoE tag types - */ + /// PPPoE tag types enum PPPoETagTypes { - /** End-Of-List tag type*/ + /// End-Of-List tag type PPPOE_TAG_EOL = 0x0000, - /** Service-Name tag type*/ + /// Service-Name tag type PPPOE_TAG_SVC_NAME = 0x0101, - /** AC-Name tag type*/ + /// AC-Name tag type PPPOE_TAG_AC_NAME = 0x0102, - /** Host-Uniq tag type*/ + /// Host-Uniq tag type PPPOE_TAG_HOST_UNIQ = 0x0103, - /** AC-Cookie tag type*/ + /// AC-Cookie tag type PPPOE_TAG_AC_COOKIE = 0x0104, - /** Vendor-Specific tag type*/ + /// Vendor-Specific tag type PPPOE_TAG_VENDOR = 0x0105, - /** Credits tag type*/ + /// Credits tag type PPPOE_TAG_CREDITS = 0x0106, - /** Metrics tag type*/ + /// Metrics tag type PPPOE_TAG_METRICS = 0x0107, - /** Sequence Number tag type */ + /// Sequence Number tag type PPPOE_TAG_SEQ_NUM = 0x0108, - /** Credit Scale Factor tag type */ + /// Credit Scale Factor tag type PPPOE_TAG_CRED_SCALE = 0x0109, - /** Relay-Session-Id tag type */ + /// Relay-Session-Id tag type PPPOE_TAG_RELAY_ID = 0x0110, - /** HURL tag type */ + /// HURL tag type PPPOE_TAG_HURL = 0x0111, - /** MOTM tag type */ + /// MOTM tag type PPPOE_TAG_MOTM = 0x0112, - /** PPP-Max-Payload tag type */ + /// PPP-Max-Payload tag type PPPOE_TAG_MAX_PAYLD = 0x0120, - /** IP_Route_Add tag type */ + /// IP_Route_Add tag type PPPOE_TAG_IP_RT_ADD = 0x0121, - /** Service-Name-Error tag type */ + /// Service-Name-Error tag type PPPOE_TAG_SVC_ERR = 0x0201, - /** AC-System-Error tag type */ + /// AC-System-Error tag type PPPOE_TAG_AC_ERR = 0x0202, - /** Generic-Error tag type */ + /// Generic-Error tag type PPPOE_TAG_GENERIC_ERR = 0x0203 }; - /** - * @class PPPoETag - * Represents a PPPoE tag and its data - */ + /// @class PPPoETag + /// Represents a PPPoE tag and its data class PPPoETag : public TLVRecord { public: - /** - * A c'tor that gets a pointer to the tag raw data (byte array) - * @param[in] tagRawData A pointer to the tag raw data - */ + /// A c'tor that gets a pointer to the tag raw data (byte array) + /// @param[in] tagRawData A pointer to the tag raw data explicit PPPoETag(uint8_t* tagRawData) : TLVRecord(tagRawData) {} - /** - * A d'tor for this class, currently does nothing - */ + /// A d'tor for this class, currently does nothing ~PPPoETag() override = default; - /** - * @return The tag type converted to PPPoEDiscoveryLayer#PPPoETagTypes enum - */ + /// @return The tag type converted to PPPoEDiscoveryLayer#PPPoETagTypes enum PPPoEDiscoveryLayer::PPPoETagTypes getType() const; - /** - * Retrieve the tag data as string. Relevant only if the tag value is indeed a string - * @return The tag data as string - */ + /// Retrieve the tag data as string. Relevant only if the tag value is indeed a string + /// @return The tag data as string std::string getValueAsString() const { size_t dataSize = getDataSize(); @@ -283,156 +240,120 @@ namespace pcpp size_t getDataSize() const override; }; - /** - * @class PPPoETagBuilder - * A class for building PPPoE Tags. This builder receives the tag parameters in its c'tor, - * builds the PPPoE Tag raw buffer and provides a build() method to get a PPPoETag object out of it - */ + /// @class PPPoETagBuilder + /// A class for building PPPoE Tags. This builder receives the tag parameters in its c'tor, + /// builds the PPPoE Tag raw buffer and provides a build() method to get a PPPoETag object out of it class PPPoETagBuilder : public TLVRecordBuilder { public: - /** - * A c'tor for building a PPPoE Tag which has no value (tag len is zero). The PPPoETag object can later - * be retrieved by calling build() - * @param[in] tagType Tag type - */ + /// A c'tor for building a PPPoE Tag which has no value (tag len is zero). The PPPoETag object can later + /// be retrieved by calling build() + /// @param[in] tagType Tag type explicit PPPoETagBuilder(PPPoETagTypes tagType) : TLVRecordBuilder(static_cast(tagType), nullptr, 0) {} - /** - * A c'tor for building a PPPoE Tag which has a 4-byte value. The PPPoETag object can later - * be retrieved by calling build() - * @param[in] tagType Tag type - * @param[in] tagValue The tag's 4-byte value - */ + /// A c'tor for building a PPPoE Tag which has a 4-byte value. The PPPoETag object can later + /// be retrieved by calling build() + /// @param[in] tagType Tag type + /// @param[in] tagValue The tag's 4-byte value PPPoETagBuilder(PPPoETagTypes tagType, uint32_t tagValue) : TLVRecordBuilder(static_cast(tagType), tagValue) {} - /** - * A c'tor for building a PPPoE Tag which has some arbitrary value. The PPPoETag object can later - * be retrieved by calling build() - * @param[in] tagType Tag type - * @param[in] tagValue A byte array that contains the tag data - * @param[in] tagValueLen The length of the value byte array - */ + /// A c'tor for building a PPPoE Tag which has some arbitrary value. The PPPoETag object can later + /// be retrieved by calling build() + /// @param[in] tagType Tag type + /// @param[in] tagValue A byte array that contains the tag data + /// @param[in] tagValueLen The length of the value byte array PPPoETagBuilder(PPPoETagTypes tagType, uint8_t* tagValue, uint8_t tagValueLen) : TLVRecordBuilder(static_cast(tagType), tagValue, tagValueLen) {} - /** - * Build the PPPoETag object out of the parameters defined in the c'tor - * @return The PPPoETag object - */ + /// Build the PPPoETag object out of the parameters defined in the c'tor + /// @return The PPPoETag object PPPoETag build() const; }; - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to @ref pppoe_header) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to @ref pppoe_header) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in PPPoEDiscoveryLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : PPPoELayer(data, dataLen, prevLayer, packet, PPPoEDiscovery) { m_DataLen = getHeaderLen(); } - /** - * A constructor that allocates a new PPPoE Discovery header with version, type, PPPoE code and session ID - * @param[in] version PPPoE version - * @param[in] type PPPoE type - * @param[in] code PPPoE code enum - * @param[in] sessionId PPPoE session ID - */ + /// A constructor that allocates a new PPPoE Discovery header with version, type, PPPoE code and session ID + /// @param[in] version PPPoE version + /// @param[in] type PPPoE type + /// @param[in] code PPPoE code enum + /// @param[in] sessionId PPPoE session ID PPPoEDiscoveryLayer(uint8_t version, uint8_t type, PPPoELayer::PPPoECode code, uint16_t sessionId) : PPPoELayer(version, type, code, sessionId) { m_Protocol = PPPoEDiscovery; } - /** - * Get a PPPoE Tag by tag type. - * @param[in] tagType The type of the tag to search - * @return A PPPoETag object that contains the first tag that matches this type, or logical null - * (PPPoETag#isNull() == true) if no such tag found - */ + /// Get a PPPoE Tag by tag type. + /// @param[in] tagType The type of the tag to search + /// @return A PPPoETag object that contains the first tag that matches this type, or logical null + /// (PPPoETag#isNull() == true) if no such tag found PPPoETag getTag(PPPoEDiscoveryLayer::PPPoETagTypes tagType) const; - /** - * @return The first tag in the PPPoE discovery layer. If the current layer contains no tags the returned value - * will contain a logical null (PPPoETag#isNull() == true) - */ + /// @return The first tag in the PPPoE discovery layer. If the current layer contains no tags the returned value + /// will contain a logical null (PPPoETag#isNull() == true) PPPoETag getFirstTag() const; - /** - * Get the tag that comes right after the "tag" parameter. If the given tag is the last one, the returned value - * will contain a logical null (PPPoETag#isNull() == true) - * @param[in] tag A given tag - * @return A PPPoETag object containing the tag that comes next, or logical null if the given - * tag: (1) was the last one; (2) contains a logical null or (3) doesn't belong to this packet - */ + /// Get the tag that comes right after the "tag" parameter. If the given tag is the last one, the returned value + /// will contain a logical null (PPPoETag#isNull() == true) + /// @param[in] tag A given tag + /// @return A PPPoETag object containing the tag that comes next, or logical null if the given + /// tag: (1) was the last one; (2) contains a logical null or (3) doesn't belong to this packet PPPoETag getNextTag(const PPPoETag& tag) const; - /** - * @return The number of tags in this layer - */ + /// @return The number of tags in this layer int getTagCount() const; - /** - * Add a new PPPoE Tag at the end of the layer - * @param[in] tagBuilder A PPPoETagBuilder object that contains the requested tag data to add - * @return A PPPoETag object containing the newly added PPPoE Tag data or logical null - * (PPPoETag#isNull() == true) if addition failed - */ + /// Add a new PPPoE Tag at the end of the layer + /// @param[in] tagBuilder A PPPoETagBuilder object that contains the requested tag data to add + /// @return A PPPoETag object containing the newly added PPPoE Tag data or logical null + /// (PPPoETag#isNull() == true) if addition failed PPPoETag addTag(const PPPoETagBuilder& tagBuilder); - /** - * Add a new PPPoE Tag after an existing one - * @param[in] tagBuilder A PPPoETagBuilder object that contains the requested tag data to add - * @param[in] prevTagType The PPPoE Tag which the newly added tag will come after - * @return A PPPoETag object containing the newly added PPPoE Tag data or logical null - * (PPPoETag#isNull() == true) if addition failed - */ + /// Add a new PPPoE Tag after an existing one + /// @param[in] tagBuilder A PPPoETagBuilder object that contains the requested tag data to add + /// @param[in] prevTagType The PPPoE Tag which the newly added tag will come after + /// @return A PPPoETag object containing the newly added PPPoE Tag data or logical null + /// (PPPoETag#isNull() == true) if addition failed PPPoETag addTagAfter(const PPPoETagBuilder& tagBuilder, PPPoETagTypes prevTagType); - /** - * Remove an existing tag. Tag will be found by the tag type - * @param[in] tagType The tag type to remove - * @return True if tag was removed or false if tag wasn't found or if tag removal failed (in each case a proper - * error will be written to log) - */ + /// Remove an existing tag. Tag will be found by the tag type + /// @param[in] tagType The tag type to remove + /// @return True if tag was removed or false if tag wasn't found or if tag removal failed (in each case a proper + /// error will be written to log) bool removeTag(PPPoEDiscoveryLayer::PPPoETagTypes tagType); - /** - * Remove all tags in this layer - * @return True if all tags were successfully or false if removal failed for some reason (a proper error will be - * written to log) - */ + /// Remove all tags in this layer + /// @return True if all tags were successfully or false if removal failed for some reason (a proper error will + /// be written to log) bool removeAllTags(); - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of byte stream of a packet - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent a PPPoED packet - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of byte stream of a packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent a PPPoED packet static inline bool isDataValid(const uint8_t* data, size_t dataLen); // abstract methods implementation - /** - * Does nothing for this layer (PPPoE discovery is always the last layer) - */ + /// Does nothing for this layer (PPPoE discovery is always the last layer) void parseNextLayer() override {} - /** - * @return The header length which is size of strcut pppoe_header plus the total size of tags - */ + /// @return The header length which is size of strcut pppoe_header plus the total size of tags size_t getHeaderLen() const override; std::string toString() const override @@ -467,271 +388,271 @@ namespace pcpp // Copied from Wireshark: ppptypes.h - /** Padding Protocol */ + /// Padding Protocol #define PCPP_PPP_PADDING 0x1 - /** ROHC small-CID */ + /// ROHC small-CID #define PCPP_PPP_ROHC_SCID 0x3 - /** ROHC large-CID */ + /// ROHC large-CID #define PCPP_PPP_ROHC_LCID 0x5 - /** Internet Protocol version 4 */ + /// Internet Protocol version 4 #define PCPP_PPP_IP 0x21 - /** OSI Network Layer */ + /// OSI Network Layer #define PCPP_PPP_OSI 0x23 - /** Xerox NS IDP */ + /// Xerox NS IDP #define PCPP_PPP_XNSIDP 0x25 - /** DECnet Phase IV */ + /// DECnet Phase IV #define PCPP_PPP_DEC4 0x27 - /** AppleTalk */ + /// AppleTalk #define PCPP_PPP_AT 0x29 - /** Novell IPX */ + /// Novell IPX #define PCPP_PPP_IPX 0x2b - /** Van Jacobson Compressed TCP/IP */ + /// Van Jacobson Compressed TCP/IP #define PCPP_PPP_VJC_COMP 0x2d - /** Van Jacobson Uncompressed TCP/IP */ + /// Van Jacobson Uncompressed TCP/IP #define PCPP_PPP_VJC_UNCOMP 0x2f - /** Bridging PDU */ + /// Bridging PDU #define PCPP_PPP_BCP 0x31 - /** Stream Protocol (ST-II) */ + /// Stream Protocol (ST-II) #define PCPP_PPP_ST 0x33 - /** Banyan Vines */ + /// Banyan Vines #define PCPP_PPP_VINES 0x35 - /** AppleTalk EDDP */ + /// AppleTalk EDDP #define PCPP_PPP_AT_EDDP 0x39 - /** AppleTalk SmartBuffered */ + /// AppleTalk SmartBuffered #define PCPP_PPP_AT_SB 0x3b - /** Multi-Link */ + /// Multi-Link #define PCPP_PPP_MP 0x3d - /** NETBIOS Framing */ + /// NETBIOS Framing #define PCPP_PPP_NB 0x3f - /** Cisco Systems */ + /// Cisco Systems #define PCPP_PPP_CISCO 0x41 - /** Ascom Timeplex */ + /// Ascom Timeplex #define PCPP_PPP_ASCOM 0x43 - /** Fujitsu Link Backup and Load Balancing */ + /// Fujitsu Link Backup and Load Balancing #define PCPP_PPP_LBLB 0x45 - /** DCA Remote Lan */ + /// DCA Remote Lan #define PCPP_PPP_RL 0x47 - /** Serial Data Transport Protocol */ + /// Serial Data Transport Protocol #define PCPP_PPP_SDTP 0x49 - /** SNA over 802.2 */ + /// SNA over 802.2 #define PCPP_PPP_LLC 0x4b - /** SNA */ + /// SNA #define PCPP_PPP_SNA 0x4d - /** IPv6 Header Compression */ + /// IPv6 Header Compression #define PCPP_PPP_IPV6HC 0x4f - /** KNX Bridging Data */ + /// KNX Bridging Data #define PCPP_PPP_KNX 0x51 - /** Encryption */ + /// Encryption #define PCPP_PPP_ENCRYPT 0x53 - /** Individual Link Encryption */ + /// Individual Link Encryption #define PCPP_PPP_ILE 0x55 - /** Internet Protocol version 6 */ + /// Internet Protocol version 6 #define PCPP_PPP_IPV6 0x57 - /** PPP Muxing */ + /// PPP Muxing #define PCPP_PPP_MUX 0x59 - /** Vendor-Specific Network Protocol (VSNP) */ + /// Vendor-Specific Network Protocol (VSNP) #define PCPP_PPP_VSNP 0x5b - /** TRILL Network Protocol (TNP) */ + /// TRILL Network Protocol (TNP) #define PCPP_PPP_TNP 0x5d - /** RTP IPHC Full Header */ + /// RTP IPHC Full Header #define PCPP_PPP_RTP_FH 0x61 - /** RTP IPHC Compressed TCP */ + /// RTP IPHC Compressed TCP #define PCPP_PPP_RTP_CTCP 0x63 - /** RTP IPHC Compressed Non TCP */ + /// RTP IPHC Compressed Non TCP #define PCPP_PPP_RTP_CNTCP 0x65 - /** RTP IPHC Compressed UDP 8 */ + /// RTP IPHC Compressed UDP 8 #define PCPP_PPP_RTP_CUDP8 0x67 - /** RTP IPHC Compressed RTP 8 */ + /// RTP IPHC Compressed RTP 8 #define PCPP_PPP_RTP_CRTP8 0x69 - /** Stampede Bridging */ + /// Stampede Bridging #define PCPP_PPP_STAMPEDE 0x6f - /** MP+ Protocol */ + /// MP+ Protocol #define PCPP_PPP_MPPLUS 0x73 - /** NTCITS IPI */ + /// NTCITS IPI #define PCPP_PPP_NTCITS_IPI 0xc1 - /** Single link compression in multilink */ + /// Single link compression in multilink #define PCPP_PPP_ML_SLCOMP 0xfb - /** Compressed datagram */ + /// Compressed datagram #define PCPP_PPP_COMP 0xfd - /** 802.1d Hello Packets */ + /// 802.1d Hello Packets #define PCPP_PPP_STP_HELLO 0x0201 - /** IBM Source Routing BPDU */ + /// IBM Source Routing BPDU #define PCPP_PPP_IBM_SR 0x0203 - /** DEC LANBridge100 Spanning Tree */ + /// DEC LANBridge100 Spanning Tree #define PCPP_PPP_DEC_LB 0x0205 - /** Cisco Discovery Protocol */ + /// Cisco Discovery Protocol #define PCPP_PPP_CDP 0x0207 - /** Netcs Twin Routing */ + /// Netcs Twin Routing #define PCPP_PPP_NETCS 0x0209 - /** STP - Scheduled Transfer Protocol */ + /// STP - Scheduled Transfer Protocol #define PCPP_PPP_STP 0x020b - /** EDP - Extreme Discovery Protocol */ + /// EDP - Extreme Discovery Protocol #define PCPP_PPP_EDP 0x020d - /** Optical Supervisory Channel Protocol */ + /// Optical Supervisory Channel Protocol #define PCPP_PPP_OSCP 0x0211 - /** Optical Supervisory Channel Protocol */ + /// Optical Supervisory Channel Protocol #define PCPP_PPP_OSCP2 0x0213 - /** Luxcom */ + /// Luxcom #define PCPP_PPP_LUXCOM 0x0231 - /** Sigma Network Systems */ + /// Sigma Network Systems #define PCPP_PPP_SIGMA 0x0233 - /** Apple Client Server Protocol */ + /// Apple Client Server Protocol #define PCPP_PPP_ACSP 0x0235 - /** MPLS Unicast */ + /// MPLS Unicast #define PCPP_PPP_MPLS_UNI 0x0281 - /** MPLS Multicast */ + /// MPLS Multicast #define PCPP_PPP_MPLS_MULTI 0x0283 - /** IEEE p1284.4 standard - data packets */ + /// IEEE p1284.4 standard - data packets #define PCPP_PPP_P12844 0x0285 - /** ETSI TETRA Network Protocol Type 1 */ + /// ETSI TETRA Network Protocol Type 1 #define PCPP_PPP_TETRA 0x0287 - /** Multichannel Flow Treatment Protocol */ + /// Multichannel Flow Treatment Protocol #define PCPP_PPP_MFTP 0x0289 - /** RTP IPHC Compressed TCP No Delta */ + /// RTP IPHC Compressed TCP No Delta #define PCPP_PPP_RTP_CTCPND 0x2063 - /** RTP IPHC Context State */ + /// RTP IPHC Context State #define PCPP_PPP_RTP_CS 0x2065 - /** RTP IPHC Compressed UDP 16 */ + /// RTP IPHC Compressed UDP 16 #define PCPP_PPP_RTP_CUDP16 0x2067 - /** RTP IPHC Compressed RTP 16 */ + /// RTP IPHC Compressed RTP 16 #define PCPP_PPP_RTP_CRDP16 0x2069 - /** Cray Communications Control Protocol */ + /// Cray Communications Control Protocol #define PCPP_PPP_CCCP 0x4001 - /** CDPD Mobile Network Registration Protocol */ + /// CDPD Mobile Network Registration Protocol #define PCPP_PPP_CDPD_MNRP 0x4003 - /** Expand accelerator protocol */ + /// Expand accelerator protocol #define PCPP_PPP_EXPANDAP 0x4005 - /** ODSICP NCP */ + /// ODSICP NCP #define PCPP_PPP_ODSICP 0x4007 - /** DOCSIS DLL */ + /// DOCSIS DLL #define PCPP_PPP_DOCSIS 0x4009 - /** Cetacean Network Detection Protocol */ + /// Cetacean Network Detection Protocol #define PCPP_PPP_CETACEANNDP 0x400b - /** Stacker LZS */ + /// Stacker LZS #define PCPP_PPP_LZS 0x4021 - /** RefTek Protocol */ + /// RefTek Protocol #define PCPP_PPP_REFTEK 0x4023 - /** Fibre Channel */ + /// Fibre Channel #define PCPP_PPP_FC 0x4025 - /** EMIT Protocols */ + /// EMIT Protocols #define PCPP_PPP_EMIT 0x4027 - /** Vendor-Specific Protocol (VSP) */ + /// Vendor-Specific Protocol (VSP) #define PCPP_PPP_VSP 0x405b - /** TRILL Link State Protocol (TLSP) */ + /// TRILL Link State Protocol (TLSP) #define PCPP_PPP_TLSP 0x405d - /** Internet Protocol Control Protocol */ + /// Internet Protocol Control Protocol #define PCPP_PPP_IPCP 0x8021 - /** OSI Network Layer Control Protocol */ + /// OSI Network Layer Control Protocol #define PCPP_PPP_OSINLCP 0x8023 - /** Xerox NS IDP Control Protocol */ + /// Xerox NS IDP Control Protocol #define PCPP_PPP_XNSIDPCP 0x8025 - /** DECnet Phase IV Control Protocol */ + /// DECnet Phase IV Control Protocol #define PCPP_PPP_DECNETCP 0x8027 - /** AppleTalk Control Protocol */ + /// AppleTalk Control Protocol #define PCPP_PPP_ATCP 0x8029 - /** Novell IPX Control Protocol */ + /// Novell IPX Control Protocol #define PCPP_PPP_IPXCP 0x802b - /** Bridging NCP */ + /// Bridging NCP #define PCPP_PPP_BRIDGENCP 0x8031 - /** Stream Protocol Control Protocol */ + /// Stream Protocol Control Protocol #define PCPP_PPP_SPCP 0x8033 - /** Banyan Vines Control Protocol */ + /// Banyan Vines Control Protocol #define PCPP_PPP_BVCP 0x8035 - /** Multi-Link Control Protocol */ + /// Multi-Link Control Protocol #define PCPP_PPP_MLCP 0x803d - /** NETBIOS Framing Control Protocol */ + /// NETBIOS Framing Control Protocol #define PCPP_PPP_NBCP 0x803f - /** Cisco Systems Control Protocol */ + /// Cisco Systems Control Protocol #define PCPP_PPP_CISCOCP 0x8041 - /** Ascom Timeplex Control Protocol (?) */ + /// Ascom Timeplex Control Protocol (?) #define PCPP_PPP_ASCOMCP 0x8043 - /** Fujitsu LBLB Control Protocol */ + /// Fujitsu LBLB Control Protocol #define PCPP_PPP_LBLBCP 0x8045 - /** DCA Remote Lan Network Control Protocol */ + /// DCA Remote Lan Network Control Protocol #define PCPP_PPP_RLNCP 0x8047 - /** Serial Data Control Protocol */ + /// Serial Data Control Protocol #define PCPP_PPP_SDCP 0x8049 - /** SNA over 802.2 Control Protocol */ + /// SNA over 802.2 Control Protocol #define PCPP_PPP_LLCCP 0x804b - /** SNA Control Protocol */ + /// SNA Control Protocol #define PCPP_PPP_SNACP 0x804d - /** IP6 Header Compression Control Protocol */ + /// IP6 Header Compression Control Protocol #define PCPP_PPP_IP6HCCP 0x804f - /** KNX Bridging Control Protocol */ + /// KNX Bridging Control Protocol #define PCPP_PPP_KNXCP 0x8051 - /** Encryption Control Protocol */ + /// Encryption Control Protocol #define PCPP_PPP_ECP 0x8053 - /** Individual Link Encryption Control Protocol */ + /// Individual Link Encryption Control Protocol #define PCPP_PPP_ILECP 0x8055 - /** IPv6 Control Protocol */ + /// IPv6 Control Protocol #define PCPP_PPP_IPV6CP 0x8057 - /** PPP Muxing Control Protocol */ + /// PPP Muxing Control Protocol #define PCPP_PPP_MUXCP 0x8059 - /** Vendor-Specific Network Control Protocol (VSNCP) [RFC3772] */ + /// Vendor-Specific Network Control Protocol (VSNCP) [RFC3772] #define PCPP_PPP_VSNCP 0x805b - /** TRILL Network Control Protocol (TNCP) */ + /// TRILL Network Control Protocol (TNCP) #define PCPP_PPP_TNCP 0x805d - /** Stampede Bridging Control Protocol */ + /// Stampede Bridging Control Protocol #define PCPP_PPP_STAMPEDECP 0x806f - /** MP+ Contorol Protocol */ + /// MP+ Contorol Protocol #define PCPP_PPP_MPPCP 0x8073 - /** NTCITS IPI Control Protocol */ + /// NTCITS IPI Control Protocol #define PCPP_PPP_IPICP 0x80c1 - /** Single link compression in multilink control */ + /// Single link compression in multilink control #define PCPP_PPP_SLCC 0x80fb - /** Compression Control Protocol */ + /// Compression Control Protocol #define PCPP_PPP_CCP 0x80fd - /** Cisco Discovery Protocol Control Protocol */ + /// Cisco Discovery Protocol Control Protocol #define PCPP_PPP_CDPCP 0x8207 - /** Netcs Twin Routing */ + /// Netcs Twin Routing #define PCPP_PPP_NETCSCP 0x8209 - /** STP - Control Protocol */ + /// STP - Control Protocol #define PCPP_PPP_STPCP 0x820b - /** EDPCP - Extreme Discovery Protocol Control Protocol */ + /// EDPCP - Extreme Discovery Protocol Control Protocol #define PCPP_PPP_EDPCP 0x820d - /** Apple Client Server Protocol Control */ + /// Apple Client Server Protocol Control #define PCPP_PPP_ACSPC 0x8235 - /** MPLS Control Protocol */ + /// MPLS Control Protocol #define PCPP_PPP_MPLSCP 0x8281 - /** IEEE p1284.4 standard - Protocol Control */ + /// IEEE p1284.4 standard - Protocol Control #define PCPP_PPP_P12844CP 0x8285 - /** ETSI TETRA TNP1 Control Protocol */ + /// ETSI TETRA TNP1 Control Protocol #define PCPP_PPP_TETRACP 0x8287 - /** Multichannel Flow Treatment Protocol */ + /// Multichannel Flow Treatment Protocol #define PCPP_PPP_MFTPCP 0x8289 - /** Link Control Protocol */ + /// Link Control Protocol #define PCPP_PPP_LCP 0xc021 - /** Password Authentication Protocol */ + /// Password Authentication Protocol #define PCPP_PPP_PAP 0xc023 - /** Link Quality Report */ + /// Link Quality Report #define PCPP_PPP_LQR 0xc025 - /** Shiva Password Authentication Protocol */ + /// Shiva Password Authentication Protocol #define PCPP_PPP_SPAP 0xc027 - /** CallBack Control Protocol (CBCP) */ + /// CallBack Control Protocol (CBCP) #define PCPP_PPP_CBCP 0xc029 - /** BACP Bandwidth Allocation Control Protocol */ + /// BACP Bandwidth Allocation Control Protocol #define PCPP_PPP_BACP 0xc02b - /** BAP Bandwidth Allocation Protocol */ + /// BAP Bandwidth Allocation Protocol #define PCPP_PPP_BAP 0xc02d - /** Vendor-Specific Authentication Protocol (VSAP) */ + /// Vendor-Specific Authentication Protocol (VSAP) #define PCPP_PPP_VSAP 0xc05b - /** Container Control Protocol */ + /// Container Control Protocol #define PCPP_PPP_CONTCP 0xc081 - /** Challenge Handshake Authentication Protocol */ + /// Challenge Handshake Authentication Protocol #define PCPP_PPP_CHAP 0xc223 - /** RSA Authentication Protocol */ + /// RSA Authentication Protocol #define PCPP_PPP_RSAAP 0xc225 - /** Extensible Authentication Protocol */ + /// Extensible Authentication Protocol #define PCPP_PPP_EAP 0xc227 - /** Mitsubishi Security Information Exchange Protocol (SIEP) */ + /// Mitsubishi Security Information Exchange Protocol (SIEP) #define PCPP_PPP_SIEP 0xc229 - /** Stampede Bridging Authorization Protocol */ + /// Stampede Bridging Authorization Protocol #define PCPP_PPP_SBAP 0xc26f - /** Proprietary Authentication Protocol */ + /// Proprietary Authentication Protocol #define PCPP_PPP_PRPAP 0xc281 - /** Proprietary Authentication Protocol */ + /// Proprietary Authentication Protocol #define PCPP_PPP_PRPAP2 0xc283 - /** Proprietary Node ID Authentication Protocol */ + /// Proprietary Node ID Authentication Protocol #define PCPP_PPP_PRPNIAP 0xc481 } // namespace pcpp diff --git a/Packet++/header/Packet.h b/Packet++/header/Packet.h index 65324f6f26..b430ba6c8e 100644 --- a/Packet++/header/Packet.h +++ b/Packet++/header/Packet.h @@ -6,23 +6,18 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @class Packet - * This class represents a parsed packet. It contains the raw data (RawPacket instance), and a linked list of - * layers, each layer is a parsed protocol that this packet contains. The layers linked list is ordered where the - * first layer is the lowest in the packet (currently it's always Ethernet protocol as PcapPlusPlus supports only - * Ethernet packets), the next layer will be L2.5 or L3 (e.g VLAN, IPv4, IPv6, etc.), and so on. etc.), etc. The - * last layer in the linked list will be the highest in the packet. For example: for a standard HTTP request packet - * the layer will look like this: EthLayer -> IPv4Layer -> TcpLayer -> HttpRequestLayer
Packet instance isn't - * read only. The user can add or remove layers, update current layer, etc. - */ + /// @class Packet + /// This class represents a parsed packet. It contains the raw data (RawPacket instance), and a linked list of + /// layers, each layer is a parsed protocol that this packet contains. The layers linked list is ordered where the + /// first layer is the lowest in the packet (currently it's always Ethernet protocol as PcapPlusPlus supports only + /// Ethernet packets), the next layer will be L2.5 or L3 (e.g VLAN, IPv4, IPv6, etc.), and so on. etc.), etc. The + /// last layer in the linked list will be the highest in the packet. For example: for a standard HTTP request packet + /// the layer will look like this: EthLayer -> IPv4Layer -> TcpLayer -> HttpRequestLayer
Packet instance isn't + /// read only. The user can add or remove layers, update current layer, etc. class Packet { friend class Layer; @@ -36,349 +31,288 @@ namespace pcpp bool m_CanReallocateData; public: - /** - * A constructor for creating a new packet (with no layers). - * When using this constructor an empty raw buffer is allocated (with the size of maxPacketLen) and a new - * RawPacket is created - * @param[in] maxPacketLen The expected packet length in bytes - */ + /// A constructor for creating a new packet (with no layers). + /// When using this constructor an empty raw buffer is allocated (with the size of maxPacketLen) and a new + /// RawPacket is created + /// @param[in] maxPacketLen The expected packet length in bytes explicit Packet(size_t maxPacketLen = 1); - /** - * A constructor for creating a new packet with a buffer that is pre-allocated by the user. - * The packet is created empty (with no layers), which means the constructor doesn't parse the data in the - * buffer. Instead, all of the raw data of this packet it written to this buffer: whenever a layer is added, - * it's data is written to this buffer. The buffer isn't freed and it's content isn't erased when the packet - * object is deleted. This constructor is useful when you already have a memory buffer and you want to create - * packet data in it. - * @param[in] buffer A pointer to a pre-allocated memory buffer - * @param[in] bufferSize The size of the buffer - */ + /// A constructor for creating a new packet with a buffer that is pre-allocated by the user. + /// The packet is created empty (with no layers), which means the constructor doesn't parse the data in the + /// buffer. Instead, all of the raw data of this packet it written to this buffer: whenever a layer is added, + /// it's data is written to this buffer. The buffer isn't freed and it's content isn't erased when the packet + /// object is deleted. This constructor is useful when you already have a memory buffer and you want to create + /// packet data in it. + /// @param[in] buffer A pointer to a pre-allocated memory buffer + /// @param[in] bufferSize The size of the buffer Packet(uint8_t* buffer, size_t bufferSize); - /** - * A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets that - * came from the network. When using this constructor a pointer to the RawPacket is saved (data isn't copied) - * and the RawPacket is parsed, meaning all layers are created and linked to each other in the right order. In - * this overload of the constructor the user can specify whether to free the instance of raw packet when the - * Packet is free or not - * @param[in] rawPacket A pointer to the raw packet - * @param[in] freeRawPacket Optional parameter. A flag indicating if the destructor should also call the raw - * packet destructor or not. Default value is false - * @param[in] parseUntil Optional parameter. Parse the packet until you reach a certain protocol (inclusive). - * Can be useful for cases when you need to parse only up to a certain layer and want to avoid the performance - * impact and memory consumption of parsing the whole packet. Default value is ::UnknownProtocol which means - * don't take this parameter into account - * @param[in] parseUntilLayer Optional parameter. Parse the packet until you reach a certain layer in the OSI - * model (inclusive). Can be useful for cases when you need to parse only up to a certain OSI layer (for example - * transport layer) and want to avoid the performance impact and memory consumption of parsing the whole packet. - * Default value is ::OsiModelLayerUnknown which means don't take this parameter into account - */ + /// A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets + /// that came from the network. When using this constructor a pointer to the RawPacket is saved (data isn't + /// copied) and the RawPacket is parsed, meaning all layers are created and linked to each other in the right + /// order. In this overload of the constructor the user can specify whether to free the instance of raw packet + /// when the Packet is free or not + /// @param[in] rawPacket A pointer to the raw packet + /// @param[in] freeRawPacket Optional parameter. A flag indicating if the destructor should also call the raw + /// packet destructor or not. Default value is false + /// @param[in] parseUntil Optional parameter. Parse the packet until you reach a certain protocol (inclusive). + /// Can be useful for cases when you need to parse only up to a certain layer and want to avoid the performance + /// impact and memory consumption of parsing the whole packet. Default value is ::UnknownProtocol which means + /// don't take this parameter into account + /// @param[in] parseUntilLayer Optional parameter. Parse the packet until you reach a certain layer in the OSI + /// model (inclusive). Can be useful for cases when you need to parse only up to a certain OSI layer (for + /// example transport layer) and want to avoid the performance impact and memory consumption of parsing the + /// whole packet. Default value is ::OsiModelLayerUnknown which means don't take this parameter into account explicit Packet(RawPacket* rawPacket, bool freeRawPacket = false, ProtocolType parseUntil = UnknownProtocol, OsiModelLayer parseUntilLayer = OsiModelLayerUnknown); - /** - * A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets that - * came from the network. When using this constructor a pointer to the RawPacket is saved (data isn't copied) - * and the RawPacket is parsed, meaning all layers are created and linked to each other in the right order. In - * this overload of the constructor the user can specify whether to free the instance of raw packet when the - * Packet is free or not. This constructor should be used to parse the packet up to a certain layer - * @param[in] rawPacket A pointer to the raw packet - * @param[in] parseUntil Parse the packet until you reach a certain protocol (inclusive). Can be useful for - * cases when you need to parse only up to a certain layer and want to avoid the performance impact and memory - * consumption of parsing the whole packet - */ + /// A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets + /// that came from the network. When using this constructor a pointer to the RawPacket is saved (data isn't + /// copied) and the RawPacket is parsed, meaning all layers are created and linked to each other in the right + /// order. In this overload of the constructor the user can specify whether to free the instance of raw packet + /// when the Packet is free or not. This constructor should be used to parse the packet up to a certain layer + /// @param[in] rawPacket A pointer to the raw packet + /// @param[in] parseUntil Parse the packet until you reach a certain protocol (inclusive). Can be useful for + /// cases when you need to parse only up to a certain layer and want to avoid the performance impact and memory + /// consumption of parsing the whole packet explicit Packet(RawPacket* rawPacket, ProtocolType parseUntil); - /** - * A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets that - * came from the network. When using this constructor a pointer to the RawPacket is saved (data isn't copied) - * and the RawPacket is parsed, meaning all layers are created and linked to each other in the right order. In - * this overload of the constructor the user can specify whether to free the instance of raw packet when the - * Packet is free or not. This constructor should be used to parse the packet up to a certain layer - * @param[in] rawPacket A pointer to the raw packet - * @param[in] parseUntilFamily Parse the packet until you reach a certain protocol family (inclusive). Can be - * useful for cases when you need to parse only up to a certain layer and want to avoid the performance impact - * and memory consumption of parsing the whole packet - */ + /// A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets + /// that came from the network. When using this constructor a pointer to the RawPacket is saved (data isn't + /// copied) and the RawPacket is parsed, meaning all layers are created and linked to each other in the right + /// order. In this overload of the constructor the user can specify whether to free the instance of raw packet + /// when the Packet is free or not. This constructor should be used to parse the packet up to a certain layer + /// @param[in] rawPacket A pointer to the raw packet + /// @param[in] parseUntilFamily Parse the packet until you reach a certain protocol family (inclusive). Can be + /// useful for cases when you need to parse only up to a certain layer and want to avoid the performance impact + /// and memory consumption of parsing the whole packet explicit Packet(RawPacket* rawPacket, ProtocolTypeFamily parseUntilFamily); - /** - * A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets that - * came from the network. When using this constructor a pointer to the RawPacket is saved (data isn't copied) - * and the RawPacket is parsed, meaning all layers are created and linked to each other in the right order. In - * this overload of the constructor the user can specify whether to free the instance of raw packet when the - * Packet is free or not. This constructor should be used to parse the packet up to a certain layer in the OSI - * model - * @param[in] rawPacket A pointer to the raw packet - * @param[in] parseUntilLayer Optional parameter. Parse the packet until you reach a certain layer in the OSI - * model (inclusive). Can be useful for cases when you need to parse only up to a certain OSI layer (for example - * transport layer) and want to avoid the performance impact and memory consumption of parsing the whole packet - */ + /// A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets + /// that came from the network. When using this constructor a pointer to the RawPacket is saved (data isn't + /// copied) and the RawPacket is parsed, meaning all layers are created and linked to each other in the right + /// order. In this overload of the constructor the user can specify whether to free the instance of raw packet + /// when the Packet is free or not. This constructor should be used to parse the packet up to a certain layer in + /// the OSI model + /// @param[in] rawPacket A pointer to the raw packet + /// @param[in] parseUntilLayer Optional parameter. Parse the packet until you reach a certain layer in the OSI + /// model (inclusive). Can be useful for cases when you need to parse only up to a certain OSI layer (for + /// example transport layer) and want to avoid the performance impact and memory consumption of parsing the + /// whole packet explicit Packet(RawPacket* rawPacket, OsiModelLayer parseUntilLayer); - /** - * A destructor for this class. Frees all layers allocated by this instance (Notice: it doesn't free layers that - * weren't allocated by this class, for example layers that were added by addLayer() or insertLayer() ). In - * addition it frees the raw packet if it was allocated by this instance (meaning if it was allocated by this - * instance constructor) - */ + /// A destructor for this class. Frees all layers allocated by this instance (Notice: it doesn't free layers + /// that weren't allocated by this class, for example layers that were added by addLayer() or insertLayer() ). + /// In addition it frees the raw packet if it was allocated by this instance (meaning if it was allocated by + /// this instance constructor) virtual ~Packet() { destructPacketData(); } - /** - * A copy constructor for this class. This copy constructor copies all the raw data and re-create all layers. So - * when the original Packet is being freed, no data will be lost in the copied instance - * @param[in] other The instance to copy from - */ + /// A copy constructor for this class. This copy constructor copies all the raw data and re-create all layers. + /// So when the original Packet is being freed, no data will be lost in the copied instance + /// @param[in] other The instance to copy from Packet(const Packet& other) { copyDataFrom(other); } - /** - * Assignment operator overloading. It first frees all layers allocated by this instance (Notice: it doesn't - * free layers that weren't allocated by this class, for example layers that were added by addLayer() or - * insertLayer() ). In addition it frees the raw packet if it was allocated by this instance (meaning if it was - * allocated by this instance constructor). Afterwards it copies the data from the other packet in the same way - * used in the copy constructor. - * @param[in] other The instance to copy from - */ + /// Assignment operator overloading. It first frees all layers allocated by this instance (Notice: it doesn't + /// free layers that weren't allocated by this class, for example layers that were added by addLayer() or + /// insertLayer() ). In addition it frees the raw packet if it was allocated by this instance (meaning if it was + /// allocated by this instance constructor). Afterwards it copies the data from the other packet in the same way + /// used in the copy constructor. + /// @param[in] other The instance to copy from Packet& operator=(const Packet& other); - /** - * Get a pointer to the Packet's RawPacket - * @return A pointer to the Packet's RawPacket - */ + /// Get a pointer to the Packet's RawPacket + /// @return A pointer to the Packet's RawPacket RawPacket* getRawPacket() const { return m_RawPacket; } - /** - * Set a RawPacket and re-construct all packet layers - * @param[in] rawPacket Raw packet to set - * @param[in] freeRawPacket A flag indicating if the destructor should also call the raw packet destructor or - * not - * @param[in] parseUntil Parse the packet until it reaches this protocol. Can be useful for cases when you need - * to parse only up to a certain layer and want to avoid the performance impact and memory consumption of - * parsing the whole packet. Default value is ::UnknownProtocol which means don't take this parameter into - * account - * @param[in] parseUntilLayer Parse the packet until certain layer in OSI model. Can be useful for cases when - * you need to parse only up to a certain layer and want to avoid the performance impact and memory consumption - * of parsing the whole packet. Default value is ::OsiModelLayerUnknown which means don't take this parameter - * into account - */ + /// Set a RawPacket and re-construct all packet layers + /// @param[in] rawPacket Raw packet to set + /// @param[in] freeRawPacket A flag indicating if the destructor should also call the raw packet destructor or + /// not + /// @param[in] parseUntil Parse the packet until it reaches this protocol. Can be useful for cases when you need + /// to parse only up to a certain layer and want to avoid the performance impact and memory consumption of + /// parsing the whole packet. Default value is ::UnknownProtocol which means don't take this parameter into + /// account + /// @param[in] parseUntilLayer Parse the packet until certain layer in OSI model. Can be useful for cases when + /// you need to parse only up to a certain layer and want to avoid the performance impact and memory consumption + /// of parsing the whole packet. Default value is ::OsiModelLayerUnknown which means don't take this parameter + /// into account void setRawPacket(RawPacket* rawPacket, bool freeRawPacket, ProtocolTypeFamily parseUntil = UnknownProtocol, OsiModelLayer parseUntilLayer = OsiModelLayerUnknown); - /** - * Get a pointer to the Packet's RawPacket in a read-only manner - * @return A pointer to the Packet's RawPacket - */ + /// Get a pointer to the Packet's RawPacket in a read-only manner + /// @return A pointer to the Packet's RawPacket const RawPacket* getRawPacketReadOnly() const { return m_RawPacket; } - /** - * Get a pointer to the first (lowest) layer in the packet - * @return A pointer to the first (lowest) layer in the packet - */ + /// Get a pointer to the first (lowest) layer in the packet + /// @return A pointer to the first (lowest) layer in the packet Layer* getFirstLayer() const { return m_FirstLayer; } - /** - * Get a pointer to the last (highest) layer in the packet - * @return A pointer to the last (highest) layer in the packet - */ + /// Get a pointer to the last (highest) layer in the packet + /// @return A pointer to the last (highest) layer in the packet Layer* getLastLayer() const { return m_LastLayer; } - /** - * Add a new layer as the last layer in the packet. This method gets a pointer to the new layer as a parameter - * and attaches it to the packet. Notice after calling this method the input layer is attached to the packet so - * every change you make in it affect the packet; Also it cannot be attached to other packets - * @param[in] newLayer A pointer to the new layer to be added to the packet - * @param[in] ownInPacket If true, Packet fully owns newLayer, including memory deletion upon destruct. Default - * is false. - * @return True if everything went well or false otherwise (an appropriate error log message will be printed in - * such cases) - */ + /// Add a new layer as the last layer in the packet. This method gets a pointer to the new layer as a parameter + /// and attaches it to the packet. Notice after calling this method the input layer is attached to the packet so + /// every change you make in it affect the packet; Also it cannot be attached to other packets + /// @param[in] newLayer A pointer to the new layer to be added to the packet + /// @param[in] ownInPacket If true, Packet fully owns newLayer, including memory deletion upon destruct. Default + /// is false. + /// @return True if everything went well or false otherwise (an appropriate error log message will be printed in + /// such cases) bool addLayer(Layer* newLayer, bool ownInPacket = false) { return insertLayer(m_LastLayer, newLayer, ownInPacket); } - /** - * Insert a new layer after an existing layer in the packet. This method gets a pointer to the new layer as a - * parameter and attaches it to the packet. Notice after calling this method the input layer is attached to the - * packet so every change you make in it affect the packet; Also it cannot be attached to other packets - * @param[in] prevLayer A pointer to an existing layer in the packet which the new layer should followed by. If - * this layer isn't attached to a packet and error will be printed to log and false will be returned - * @param[in] newLayer A pointer to the new layer to be added to the packet - * @param[in] ownInPacket If true, Packet fully owns newLayer, including memory deletion upon destruct. Default - * is false. - * @return True if everything went well or false otherwise (an appropriate error log message will be printed in - * such cases) - */ + /// Insert a new layer after an existing layer in the packet. This method gets a pointer to the new layer as a + /// parameter and attaches it to the packet. Notice after calling this method the input layer is attached to the + /// packet so every change you make in it affect the packet; Also it cannot be attached to other packets + /// @param[in] prevLayer A pointer to an existing layer in the packet which the new layer should followed by. If + /// this layer isn't attached to a packet and error will be printed to log and false will be returned + /// @param[in] newLayer A pointer to the new layer to be added to the packet + /// @param[in] ownInPacket If true, Packet fully owns newLayer, including memory deletion upon destruct. Default + /// is false. + /// @return True if everything went well or false otherwise (an appropriate error log message will be printed in + /// such cases) bool insertLayer(Layer* prevLayer, Layer* newLayer, bool ownInPacket = false); - /** - * Remove an existing layer from the packet. The layer to removed is identified by its type (protocol). If the - * packet has multiple layers of the same type in the packet the user may specify the index of the layer to - * remove (the default index is 0 - remove the first layer of this type). If the layer was allocated during - * packet creation it will be deleted and any pointer to it will get invalid. However if the layer was allocated - * by the user and manually added to the packet it will simply get detached from the packet, meaning the pointer - * to it will stay valid and its data (that was removed from the packet) will be copied back to the layer. In - * that case it's the user's responsibility to delete the layer instance - * @param[in] layerType The layer type (protocol) to remove - * @param[in] index If there are multiple layers of the same type, indicate which instance to remove. The - * default value is 0, meaning remove the first layer of this type - * @return True if everything went well or false otherwise (an appropriate error log message will be printed in - * such cases) - */ + /// Remove an existing layer from the packet. The layer to removed is identified by its type (protocol). If the + /// packet has multiple layers of the same type in the packet the user may specify the index of the layer to + /// remove (the default index is 0 - remove the first layer of this type). If the layer was allocated during + /// packet creation it will be deleted and any pointer to it will get invalid. However if the layer was + /// allocated by the user and manually added to the packet it will simply get detached from the packet, meaning + /// the pointer to it will stay valid and its data (that was removed from the packet) will be copied back to the + /// layer. In that case it's the user's responsibility to delete the layer instance + /// @param[in] layerType The layer type (protocol) to remove + /// @param[in] index If there are multiple layers of the same type, indicate which instance to remove. The + /// default value is 0, meaning remove the first layer of this type + /// @return True if everything went well or false otherwise (an appropriate error log message will be printed in + /// such cases) bool removeLayer(ProtocolType layerType, int index = 0); - /** - * Remove the first layer in the packet. The layer will be deleted if it was allocated during packet creation, - * or detached if was allocated outside of the packet. Please refer to removeLayer() to get more info - * @return True if layer removed successfully, or false if removing the layer failed or if there are no layers - * in the packet. In any case of failure an appropriate error log message will be printed - */ + /// Remove the first layer in the packet. The layer will be deleted if it was allocated during packet creation, + /// or detached if was allocated outside of the packet. Please refer to removeLayer() to get more info + /// @return True if layer removed successfully, or false if removing the layer failed or if there are no layers + /// in the packet. In any case of failure an appropriate error log message will be printed bool removeFirstLayer(); - /** - * Remove the last layer in the packet. The layer will be deleted if it was allocated during packet creation, or - * detached if was allocated outside of the packet. Please refer to removeLayer() to get more info - * @return True if layer removed successfully, or false if removing the layer failed or if there are no layers - * in the packet. In any case of failure an appropriate error log message will be printed - */ + /// Remove the last layer in the packet. The layer will be deleted if it was allocated during packet creation, + /// or detached if was allocated outside of the packet. Please refer to removeLayer() to get more info + /// @return True if layer removed successfully, or false if removing the layer failed or if there are no layers + /// in the packet. In any case of failure an appropriate error log message will be printed bool removeLastLayer(); - /** - * Remove all layers that come after a certain layer. All layers removed will be deleted if they were allocated - * during packet creation or detached if were allocated outside of the packet, please refer to removeLayer() to - * get more info - * @param[in] layer A pointer to the layer to begin removing from. Please note this layer will not be removed, - * only the layers that come after it will be removed. Also, if removal of one layer failed, the method will - * return immediately and the following layers won't be deleted - * @return True if all layers were removed successfully, or false if failed to remove at least one layer. In any - * case of failure an appropriate error log message will be printed - */ + /// Remove all layers that come after a certain layer. All layers removed will be deleted if they were allocated + /// during packet creation or detached if were allocated outside of the packet, please refer to removeLayer() to + /// get more info + /// @param[in] layer A pointer to the layer to begin removing from. Please note this layer will not be removed, + /// only the layers that come after it will be removed. Also, if removal of one layer failed, the method will + /// return immediately and the following layers won't be deleted + /// @return True if all layers were removed successfully, or false if failed to remove at least one layer. In + /// any case of failure an appropriate error log message will be printed bool removeAllLayersAfter(Layer* layer); - /** - * Detach a layer from the packet. Detaching means the layer instance will not be deleted, but rather separated - * from the packet - e.g it will be removed from the layer chain of the packet and its data will be copied from - * the packet buffer into an internal layer buffer. After a layer is detached, it can be added into another - * packet (but it's impossible to attach a layer to multiple packets in the same time). After layer is detached, - * it's the user's responsibility to delete it when it's not needed anymore - * @param[in] layerType The layer type (protocol) to detach from the packet - * @param[in] index If there are multiple layers of the same type, indicate which instance to detach. The - * default value is 0, meaning detach the first layer of this type - * @return A pointer to the detached layer or nullptr if detaching process failed. In any case of failure an - * appropriate error log message will be printed - */ + /// Detach a layer from the packet. Detaching means the layer instance will not be deleted, but rather separated + /// from the packet - e.g it will be removed from the layer chain of the packet and its data will be copied from + /// the packet buffer into an internal layer buffer. After a layer is detached, it can be added into another + /// packet (but it's impossible to attach a layer to multiple packets in the same time). After layer is + /// detached, it's the user's responsibility to delete it when it's not needed anymore + /// @param[in] layerType The layer type (protocol) to detach from the packet + /// @param[in] index If there are multiple layers of the same type, indicate which instance to detach. The + /// default value is 0, meaning detach the first layer of this type + /// @return A pointer to the detached layer or nullptr if detaching process failed. In any case of failure an + /// appropriate error log message will be printed Layer* detachLayer(ProtocolType layerType, int index = 0); - /** - * Detach a layer from the packet. Detaching means the layer instance will not be deleted, but rather separated - * from the packet - e.g it will be removed from the layer chain of the packet and its data will be copied from - * the packet buffer into an internal layer buffer. After a layer is detached, it can be added into another - * packet (but it's impossible to attach a layer to multiple packets at the same time). After layer is detached, - * it's the user's responsibility to delete it when it's not needed anymore - * @param[in] layer A pointer to the layer to detach - * @return True if the layer was detached successfully, or false if something went wrong. In any case of failure - * an appropriate error log message will be printed - */ + /// Detach a layer from the packet. Detaching means the layer instance will not be deleted, but rather separated + /// from the packet - e.g it will be removed from the layer chain of the packet and its data will be copied from + /// the packet buffer into an internal layer buffer. After a layer is detached, it can be added into another + /// packet (but it's impossible to attach a layer to multiple packets at the same time). After layer is + /// detached, it's the user's responsibility to delete it when it's not needed anymore + /// @param[in] layer A pointer to the layer to detach + /// @return True if the layer was detached successfully, or false if something went wrong. In any case of + /// failure an appropriate error log message will be printed bool detachLayer(Layer* layer) { return removeLayer(layer, false); } - /** - * Get a pointer to the layer of a certain type (protocol). This method goes through the layers and returns a - * layer that matches the give protocol type - * @param[in] layerType The layer type (protocol) to fetch - * @param[in] index If there are multiple layers of the same type, indicate which instance to fetch. The default - * value is 0, meaning fetch the first layer of this type - * @return A pointer to the layer or nullptr if no such layer was found - */ + /// Get a pointer to the layer of a certain type (protocol). This method goes through the layers and returns a + /// layer that matches the give protocol type + /// @param[in] layerType The layer type (protocol) to fetch + /// @param[in] index If there are multiple layers of the same type, indicate which instance to fetch. The + /// default value is 0, meaning fetch the first layer of this type + /// @return A pointer to the layer or nullptr if no such layer was found Layer* getLayerOfType(ProtocolType layerType, int index = 0) const; - /** - * A templated method to get a layer of a certain type (protocol). If no layer of such type is found, nullptr is - * returned - * @param[in] reverseOrder The optional parameter that indicates that the lookup should run in reverse order, - * the default value is false - * @return A pointer to the layer of the requested type, nullptr if not found - */ + /// A templated method to get a layer of a certain type (protocol). If no layer of such type is found, nullptr + /// is returned + /// @param[in] reverseOrder The optional parameter that indicates that the lookup should run in reverse order, + /// the default value is false + /// @return A pointer to the layer of the requested type, nullptr if not found template TLayer* getLayerOfType(bool reverseOrder = false) const; - /** - * A templated method to get the first layer of a certain type (protocol), start searching from a certain layer. - * For example: if a packet looks like: EthLayer -> VlanLayer(1) -> VlanLayer(2) -> VlanLayer(3) -> IPv4Layer - * and the user put VlanLayer(2) as a parameter and wishes to search for a VlanLayer, VlanLayer(3) will be - * returned If no layer of such type is found, nullptr is returned - * @param[in] startLayer A pointer to the layer to start search from - * @return A pointer to the layer of the requested type, nullptr if not found - */ + /// A templated method to get the first layer of a certain type (protocol), start searching from a certain + /// layer. For example: if a packet looks like: EthLayer -> VlanLayer(1) -> VlanLayer(2) -> VlanLayer(3) -> + /// IPv4Layer and the user put VlanLayer(2) as a parameter and wishes to search for a VlanLayer, VlanLayer(3) + /// will be returned If no layer of such type is found, nullptr is returned + /// @param[in] startLayer A pointer to the layer to start search from + /// @return A pointer to the layer of the requested type, nullptr if not found template TLayer* getNextLayerOfType(Layer* startLayer) const; - /** - * A templated method to get the first layer of a certain type (protocol), start searching from a certain layer. - * For example: if a packet looks like: EthLayer -> VlanLayer(1) -> VlanLayer(2) -> VlanLayer(3) -> IPv4Layer - * and the user put VlanLayer(2) as a parameter and wishes to search for a VlanLayer, VlanLayer(1) will be - * returned If no layer of such type is found, nullptr is returned - * @param[in] startLayer A pointer to the layer to start search from - * @return A pointer to the layer of the requested type, nullptr if not found - */ + /// A templated method to get the first layer of a certain type (protocol), start searching from a certain + /// layer. For example: if a packet looks like: EthLayer -> VlanLayer(1) -> VlanLayer(2) -> VlanLayer(3) -> + /// IPv4Layer and the user put VlanLayer(2) as a parameter and wishes to search for a VlanLayer, VlanLayer(1) + /// will be returned If no layer of such type is found, nullptr is returned + /// @param[in] startLayer A pointer to the layer to start search from + /// @return A pointer to the layer of the requested type, nullptr if not found template TLayer* getPrevLayerOfType(Layer* startLayer) const; - /** - * Check whether the packet contains a layer of a certain protocol - * @param[in] protocolType The protocol type to search - * @return True if the packet contains a layer of a certain protocol, false otherwise - */ + /// Check whether the packet contains a layer of a certain protocol + /// @param[in] protocolType The protocol type to search + /// @return True if the packet contains a layer of a certain protocol, false otherwise bool isPacketOfType(ProtocolType protocolType) const; - /** - * Check whether the packet contains a layer of a certain protocol family - * @param[in] protocolTypeFamily The protocol type family to search - * @return True if the packet contains a layer of a certain protocol family, false otherwise - */ + /// Check whether the packet contains a layer of a certain protocol family + /// @param[in] protocolTypeFamily The protocol type family to search + /// @return True if the packet contains a layer of a certain protocol family, false otherwise bool isPacketOfType(ProtocolTypeFamily protocolTypeFamily) const; - /** - * Each layer can have fields that can be calculate automatically from other fields using - * Layer#computeCalculateFields(). This method forces all layers to calculate these fields values - */ + /// Each layer can have fields that can be calculate automatically from other fields using + /// Layer#computeCalculateFields(). This method forces all layers to calculate these fields values void computeCalculateFields(); - /** - * Each layer can print a string representation of the layer most important data using Layer#toString(). This - * method aggregates this string from all layers and print it to a complete string containing all packet's - * relevant data - * @param[in] timeAsLocalTime Print time as local time or GMT. Default (true value) is local time, for GMT set - * to false - * @return A string containing most relevant data from all layers (looks like the packet description in - * Wireshark) - */ + /// Each layer can print a string representation of the layer most important data using Layer#toString(). This + /// method aggregates this string from all layers and print it to a complete string containing all packet's + /// relevant data + /// @param[in] timeAsLocalTime Print time as local time or GMT. Default (true value) is local time, for GMT set + /// to false + /// @return A string containing most relevant data from all layers (looks like the packet description in + /// Wireshark) std::string toString(bool timeAsLocalTime = true) const; - /** - * Similar to toString(), but instead of one string it outputs a list of strings, one string for every layer - * @param[out] result A string vector that will contain all strings - * @param[in] timeAsLocalTime Print time as local time or GMT. Default (true value) is local time, for GMT set - * to false - */ + /// Similar to toString(), but instead of one string it outputs a list of strings, one string for every layer + /// @param[out] result A string vector that will contain all strings + /// @param[in] timeAsLocalTime Print time as local time or GMT. Default (true value) is local time, for GMT set + /// to false void toStringList(std::vector& result, bool timeAsLocalTime = true) const; private: diff --git a/Packet++/header/PacketTrailerLayer.h b/Packet++/header/PacketTrailerLayer.h index bf8d056074..fdcb8e6487 100644 --- a/Packet++/header/PacketTrailerLayer.h +++ b/Packet++/header/PacketTrailerLayer.h @@ -1,66 +1,59 @@ #pragma once -/// @file - #include "Layer.h" +/// @file + +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @class PacketTrailerLayer - * A class for representing packet trailer (a.k.a footer or padding) which refers to supplemental data placed at the - * end of a block of data being stored or transmitted, which may contain information for the handling of the data - * block, or just mark its end (taken from Wikipedia: https://en.wikipedia.org/wiki/Trailer_(computing) ) - * - * There are various reasons for adding a packet trailer, one of the most famous is FCS (Frame check sequence) which - * refers to the extra error-detecting code added to a frame. Another usage is padding which means adding data to - * reach a minimum required packet length. - * - * Although this layer inherits from the Layer class, it is not a standard layer in the sense that it can't be - * constructed by the user. This layer may be only be constructed in the Packet class, in the process of parsing the - * packet and creating the layers; if at the end of the parsing process there is data left that is not allocated to - * any layer, it's assumed to be the packet trailer and an instance of this class is created. This means this layer - * can only exist as the last layer in a packet, if a packet trailer indeed exists. - * - * No layer can be added by the user after this layer (trying to do that will result with an error). - * - * This layer can be removed by the user or extended/shortened, as any layer. - * - * It also contains method to extract the trailer data - */ + /// @class PacketTrailerLayer + /// A class for representing packet trailer (a.k.a footer or padding) which refers to supplemental data placed at + /// the end of a block of data being stored or transmitted, which may contain information for the handling of the + /// data block, or just mark its end (taken from Wikipedia: https://en.wikipedia.org/wiki/Trailer_(computing) ) + /// + /// There are various reasons for adding a packet trailer, one of the most famous is FCS (Frame check sequence) + /// which refers to the extra error-detecting code added to a frame. Another usage is padding which means adding + /// data to reach a minimum required packet length. + /// + /// Although this layer inherits from the Layer class, it is not a standard layer in the sense that it can't be + /// constructed by the user. This layer may be only be constructed in the Packet class, in the process of parsing + /// the packet and creating the layers; if at the end of the parsing process there is data left that is not + /// allocated to any layer, it's assumed to be the packet trailer and an instance of this class is created. This + /// means this layer can only exist as the last layer in a packet, if a packet trailer indeed exists. + /// + /// No layer can be added by the user after this layer (trying to do that will result with an error). + /// + /// This layer can be removed by the user or extended/shortened, as any layer. + /// + /// It also contains method to extract the trailer data class PacketTrailerLayer : public Layer { public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in PacketTrailerLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, PacketTrailer) {} ~PacketTrailerLayer() override = default; - /** - * Get a pointer to the trailer data - * @return A pointer to the trailer data - */ + /// Get a pointer to the trailer data + /// @return A pointer to the trailer data uint8_t* getTrailerData() const { return m_Data; } - /** - * @return Trailer data as hex string - */ + /// @return Trailer data as hex string std::string getTrailerDataAsHexString() const; - /** - * Get the trailer data length - * @return The trailer data length in bytes - */ + /// Get the trailer data length + /// @return The trailer data length in bytes size_t getTrailerLen() const { return m_DataLen; @@ -68,23 +61,17 @@ namespace pcpp // implement abstract methods - /** - * Does nothing for this layer (PacketTrailerLayer is always last) - */ + /// Does nothing for this layer (PacketTrailerLayer is always last) void parseNextLayer() override {} - /** - * @return trailer data length in bytes - */ + /// @return trailer data length in bytes size_t getHeaderLen() const override { return m_DataLen; } - /** - * Does nothing for this layer - */ + /// Does nothing for this layer void computeCalculateFields() override {} diff --git a/Packet++/header/PacketUtils.h b/Packet++/header/PacketUtils.h index 1bf04c091a..7be431337e 100644 --- a/Packet++/header/PacketUtils.h +++ b/Packet++/header/PacketUtils.h @@ -5,82 +5,61 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * A struct that represent a single buffer - */ + /// A struct that represent a single buffer template struct ScalarBuffer { - /** - * The pointer to the buffer - */ + /// The pointer to the buffer T* buffer; - /** - * Buffer length - */ + /// Buffer length size_t len; }; - /** - * Computes the checksum for a vector of buffers - * @param[in] vec The vector of buffers - * @param[in] vecSize Number of ScalarBuffers in vector - * @return The checksum result - */ + /// Computes the checksum for a vector of buffers + /// @param[in] vec The vector of buffers + /// @param[in] vecSize Number of ScalarBuffers in vector + /// @return The checksum result uint16_t computeChecksum(ScalarBuffer vec[], size_t vecSize); - /** - * Computes the checksum for Pseudo header - * @param[in] dataPtr Data pointer - * @param[in] dataLen Data length - * @param[in] ipAddrType IP address type(IPv4/IPv6) type @ref IPAddress::AddressType - * @param[in] protocolType Current protocol type @ref IPProtocolTypes - * @param[in] srcIPAddress Source IP Address - * @param[in] dstIPAddress Destination IP Address - * @return The checksum result - */ + /// Computes the checksum for Pseudo header + /// @param[in] dataPtr Data pointer + /// @param[in] dataLen Data length + /// @param[in] ipAddrType IP address type(IPv4/IPv6) type @ref IPAddress::AddressType + /// @param[in] protocolType Current protocol type @ref IPProtocolTypes + /// @param[in] srcIPAddress Source IP Address + /// @param[in] dstIPAddress Destination IP Address + /// @return The checksum result uint16_t computePseudoHdrChecksum(uint8_t* dataPtr, size_t dataLen, IPAddress::AddressType ipAddrType, uint8_t protocolType, IPAddress srcIPAddress, IPAddress dstIPAddress); - /** - * Computes Fowler-Noll-Vo (FNV-1) 32bit hash function on an array of byte buffers. The hash is calculated on each - * byte in each byte buffer, as if all byte buffers were one long byte buffer - * @param[in] vec An array of byte buffers (ScalarBuffer of type uint8_t) - * @param[in] vecSize The length of vec - * @return The 32bit hash value - */ + /// Computes Fowler-Noll-Vo (FNV-1) 32bit hash function on an array of byte buffers. The hash is calculated on each + /// byte in each byte buffer, as if all byte buffers were one long byte buffer + /// @param[in] vec An array of byte buffers (ScalarBuffer of type uint8_t) + /// @param[in] vecSize The length of vec + /// @return The 32bit hash value uint32_t fnvHash(ScalarBuffer vec[], size_t vecSize); - /** - * Computes Fowler-Noll-Vo (FNV-1) 32bit hash function on a byte buffer - * @param[in] buffer The byte buffer - * @param[in] bufSize The size of the byte buffer - * @return The 32bit hash value - */ + /// Computes Fowler-Noll-Vo (FNV-1) 32bit hash function on a byte buffer + /// @param[in] buffer The byte buffer + /// @param[in] bufSize The size of the byte buffer + /// @return The 32bit hash value uint32_t fnvHash(uint8_t* buffer, size_t bufSize); - /** - * A method that is given a packet and calculates a hash value by the packet's 5-tuple. Supports IPv4, IPv6, - * TCP and UDP. For packets which doesn't have 5-tuple (for example: packets which aren't IPv4/6 or aren't - * TCP/UDP) the value of 0 will be returned - * @param[in] packet The packet to calculate hash for - * @param[in] directionUnique Make hash value unique for each direction - * @return The hash value calculated for this packet or 0 if the packet doesn't contain 5-tuple - */ + /// A method that is given a packet and calculates a hash value by the packet's 5-tuple. Supports IPv4, IPv6, + /// TCP and UDP. For packets which doesn't have 5-tuple (for example: packets which aren't IPv4/6 or aren't + /// TCP/UDP) the value of 0 will be returned + /// @param[in] packet The packet to calculate hash for + /// @param[in] directionUnique Make hash value unique for each direction + /// @return The hash value calculated for this packet or 0 if the packet doesn't contain 5-tuple uint32_t hash5Tuple(Packet* packet, bool const& directionUnique = false); - /** - * A method that is given a packet and calculates a hash value by the packet's 2-tuple (IP src + IP dst). Supports - * IPv4 and IPv6. For packets which aren't IPv4/6 the value of 0 will be returned - * @param[in] packet The packet to calculate hash for - * @return The hash value calculated for this packet or 0 if the packet isn't IPv4/6 - */ + /// A method that is given a packet and calculates a hash value by the packet's 2-tuple (IP src + IP dst). Supports + /// IPv4 and IPv6. For packets which aren't IPv4/6 the value of 0 will be returned + /// @param[in] packet The packet to calculate hash for + /// @return The hash value calculated for this packet or 0 if the packet isn't IPv4/6 uint32_t hash2Tuple(Packet* packet); - } // namespace pcpp diff --git a/Packet++/header/PayloadLayer.h b/Packet++/header/PayloadLayer.h index dd66880e27..fb368c342f 100644 --- a/Packet++/header/PayloadLayer.h +++ b/Packet++/header/PayloadLayer.h @@ -4,62 +4,48 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @class PayloadLayer - * Represents a generic or unknown layer or a packet payload - */ + /// @class PayloadLayer + /// Represents a generic or unknown layer or a packet payload class PayloadLayer : public Layer { public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in PayloadLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, GenericPayload) {} - /** - * A constructor that allocates a new payload - * @param[in] data A raw buffer that will be used as a payload. This data will be copied to the layer - * @param[in] dataLen The raw buffer length - */ + /// A constructor that allocates a new payload + /// @param[in] data A raw buffer that will be used as a payload. This data will be copied to the layer + /// @param[in] dataLen The raw buffer length PayloadLayer(const uint8_t* data, size_t dataLen); - /** - * A constructor that allocates a new payload from an hex stream - * @param[in] payloadAsHexStream A string that represents an hex stream of the payload. For example: - * 0001080006040002842b2b774c56c0a80078000000000000c0a8. In order for the hex stream to be valid it has to - * contain valid hex chars only (which means, for example, that it can't begin with "0x") and it also has to - * have an even number of chars (each char represents one nibble). If the string is not a valid hex stream an - * error will be printed to log and the payload layer will be empty (no data) - */ + /// A constructor that allocates a new payload from an hex stream + /// @param[in] payloadAsHexStream A string that represents an hex stream of the payload. For example: + /// 0001080006040002842b2b774c56c0a80078000000000000c0a8. In order for the hex stream to be valid it has to + /// contain valid hex chars only (which means, for example, that it can't begin with "0x") and it also has to + /// have an even number of chars (each char represents one nibble). If the string is not a valid hex stream an + /// error will be printed to log and the payload layer will be empty (no data) explicit PayloadLayer(const std::string& payloadAsHexStream); ~PayloadLayer() override = default; - /** - * Get a pointer to the payload data - * @return A pointer to the payload data - */ + /// Get a pointer to the payload data + /// @return A pointer to the payload data uint8_t* getPayload() const { return m_Data; } - /** - * Get the payload data length - * @return The payload data length in bytes - */ + /// Get the payload data length + /// @return The payload data length in bytes size_t getPayloadLen() const { return m_DataLen; @@ -67,32 +53,24 @@ namespace pcpp // implement abstract methods - /** - * Does nothing for this layer (PayloadLayer is always last) - */ + /// Does nothing for this layer (PayloadLayer is always last) void parseNextLayer() override {} - /** - * @return Payload data length in bytes - */ + /// @return Payload data length in bytes size_t getHeaderLen() const override { return m_DataLen; } - /** - * Does nothing for this layer - */ + /// Does nothing for this layer void computeCalculateFields() override {} - /** - * Sets the payload of the PayloadLayer to the given pointer. This will resize (extend/shorten) the underlying - * packet respectively if there is one. - * @param[in] newPayload New payload that shall be set - * @param[in] newPayloadLength New length of payload - */ + /// Sets the payload of the PayloadLayer to the given pointer. This will resize (extend/shorten) the underlying + /// packet respectively if there is one. + /// @param[in] newPayload New payload that shall be set + /// @param[in] newPayloadLength New length of payload void setPayload(const uint8_t* newPayload, size_t newPayloadLength); std::string toString() const override; @@ -102,5 +80,4 @@ namespace pcpp return OsiModelApplicationLayer; } }; - } // namespace pcpp diff --git a/Packet++/header/ProtocolType.h b/Packet++/header/ProtocolType.h index f853b63f88..a56a5b5a9a 100644 --- a/Packet++/header/ProtocolType.h +++ b/Packet++/header/ProtocolType.h @@ -4,380 +4,237 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @typedef ProtocolType - * Representing all protocols supported by PcapPlusPlus - */ + /// @typedef ProtocolType + /// Representing all protocols supported by PcapPlusPlus typedef uint8_t ProtocolType; - /** - * @typedef ProtocolTypeFamily - * Representing a family of protocols - */ + /// @typedef ProtocolTypeFamily + /// Representing a family of protocols typedef uint32_t ProtocolTypeFamily; - /** - * Unknown protocol (or unsupported by PcapPlusPlus) - */ + /// Unknown protocol (or unsupported by PcapPlusPlus) const ProtocolType UnknownProtocol = 0; - /** - * Ethernet protocol - */ + /// Ethernet protocol const ProtocolType Ethernet = 1; - /** - * IPv4 protocol - */ + /// IPv4 protocol const ProtocolType IPv4 = 2; - /** - * IPv6 protocol - */ + /// IPv6 protocol const ProtocolType IPv6 = 3; - /** - * IP protocol family (IPv4 and IPv6 protocols) - */ + /// IP protocol family (IPv4 and IPv6 protocols) const ProtocolTypeFamily IP = 0x203; - /** - * TCP protocol - */ + /// TCP protocol const ProtocolType TCP = 4; - /** - * UDP protocol - */ + /// UDP protocol const ProtocolType UDP = 5; - /** - * HTTP request protocol - */ + /// HTTP request protocol const ProtocolType HTTPRequest = 6; - /** - * HTTP response protocol - */ + /// HTTP response protocol const ProtocolType HTTPResponse = 7; - /** - * HTTP protocol family (HTTP request and HTTP response protocols) - */ + /// HTTP protocol family (HTTP request and HTTP response protocols) const ProtocolTypeFamily HTTP = 0x607; - /** - * ARP protocol - */ + /// ARP protocol const ProtocolType ARP = 8; - /** - * VLAN protocol - */ + /// VLAN protocol const ProtocolType VLAN = 9; - /** - * ICMP protocol - */ + /// ICMP protocol const ProtocolType ICMP = 10; - /** - * PPPoE session protocol - */ + /// PPPoE session protocol const ProtocolType PPPoESession = 11; - /** - * PPPoE discovery protocol - */ + /// PPPoE discovery protocol const ProtocolType PPPoEDiscovery = 12; - /** - * PPPoE protocol family (PPPoESession and PPPoEDiscovery protocols) - */ + /// PPPoE protocol family (PPPoESession and PPPoEDiscovery protocols) const ProtocolTypeFamily PPPoE = 0xb0c; - /** - * DNS protocol - */ + /// DNS protocol const ProtocolType DNS = 13; - /** - * MPLS protocol - */ + /// MPLS protocol const ProtocolType MPLS = 14; - /** - * GRE version 0 protocol - */ + /// GRE version 0 protocol const ProtocolType GREv0 = 15; - /** - * GRE version 1 protocol - */ + /// GRE version 1 protocol const ProtocolType GREv1 = 16; - /** - * GRE protocol family (GREv0 and GREv1 protocols) - */ + /// GRE protocol family (GREv0 and GREv1 protocols) const ProtocolTypeFamily GRE = 0xf10; - /** - * PPP for PPTP protocol - */ + /// PPP for PPTP protocol const ProtocolType PPP_PPTP = 17; - /** - * SSL/TLS protocol - */ + /// SSL/TLS protocol const ProtocolType SSL = 18; - /** - * SLL (Linux cooked capture) protocol - */ + /// SLL (Linux cooked capture) protocol const ProtocolType SLL = 19; - /** - * DHCP/BOOTP protocol - */ + /// DHCP/BOOTP protocol const ProtocolType DHCP = 20; - /** - * Null/Loopback protocol - */ + /// Null/Loopback protocol const ProtocolType NULL_LOOPBACK = 21; - /** - * IGMPv1 protocol - */ + /// IGMPv1 protocol const ProtocolType IGMPv1 = 22; - /** - * IGMPv2 protocol - */ + /// IGMPv2 protocol const ProtocolType IGMPv2 = 23; - /** - * IGMPv3 protocol - */ + /// IGMPv3 protocol const ProtocolType IGMPv3 = 24; - /** - * IGMP protocol family (IGMPv1, IGMPv2, IGMPv3) - */ + /// IGMP protocol family (IGMPv1, IGMPv2, IGMPv3) const ProtocolTypeFamily IGMP = 0x161718; - /** - * Generic payload (no specific protocol) - */ + /// Generic payload (no specific protocol) const ProtocolType GenericPayload = 25; - /** - * VXLAN protocol - */ + /// VXLAN protocol const ProtocolType VXLAN = 26; - /** - * SIP request protocol - */ + /// SIP request protocol const ProtocolType SIPRequest = 27; - /** - * SIP response protocol - */ + /// SIP response protocol const ProtocolType SIPResponse = 28; - /** - * SIP protocol family (SIPRequest and SIPResponse protocols) - */ + /// SIP protocol family (SIPRequest and SIPResponse protocols) const ProtocolTypeFamily SIP = 0x1b1c; - /** - * SDP protocol - */ + /// SDP protocol const ProtocolType SDP = 29; - /** - * Packet trailer - */ + /// Packet trailer const ProtocolType PacketTrailer = 30; - /** - * RADIUS protocol - */ + /// RADIUS protocol const ProtocolType Radius = 31; - /** - * GTPv1 protocol - */ + /// GTPv1 protocol const ProtocolType GTPv1 = 32; - /** - * GTP protocol family (GTPv1 and GTPv2) - */ + /// GTP protocol family (GTPv1 and GTPv2) const ProtocolTypeFamily GTP = 0x2039; - /** - * IEEE 802.3 Ethernet protocol - */ + /// IEEE 802.3 Ethernet protocol const ProtocolType EthernetDot3 = 33; - /** - * Border Gateway Protocol (BGP) version 4 protocol - */ + /// Border Gateway Protocol (BGP) version 4 protocol const ProtocolType BGP = 34; - /** - * SSH version 2 protocol - */ + /// SSH version 2 protocol const ProtocolType SSH = 35; - /** - * IPSec Authentication Header (AH) protocol - */ + /// IPSec Authentication Header (AH) protocol const ProtocolType AuthenticationHeader = 36; - /** - * IPSec Encapsulating Security Payload (ESP) protocol - */ + /// IPSec Encapsulating Security Payload (ESP) protocol const ProtocolType ESP = 37; - /** - * IPSec protocol family (AH and ESP protocols) - */ + /// IPSec protocol family (AH and ESP protocols) const ProtocolTypeFamily IPSec = 0x2425; - /** - * Dynamic Host Configuration Protocol version 6 (DHCPv6) protocol - */ + /// Dynamic Host Configuration Protocol version 6 (DHCPv6) protocol const ProtocolType DHCPv6 = 38; - /** - * Network Time (NTP) Protocol - */ + /// Network Time (NTP) Protocol const ProtocolType NTP = 39; - /** - * Telnet Protocol - */ + /// Telnet Protocol const ProtocolType Telnet = 40; - /** - * File Transfer (FTP) Protocol - */ + /// File Transfer (FTP) Protocol const ProtocolType FTP = 41; - /** - * ICMPv6 protocol - */ + /// ICMPv6 protocol const ProtocolType ICMPv6 = 42; - /** - * Spanning Tree Protocol - */ + /// Spanning Tree Protocol const ProtocolType STP = 43; - /** - * Logical Link Control (LLC) - */ + /// Logical Link Control (LLC) const ProtocolType LLC = 44; - /** - * SOME/IP Base protocol - */ + /// SOME/IP Base protocol const ProtocolType SomeIP = 45; - /** - * Wake On LAN (WOL) Protocol - */ + /// Wake On LAN (WOL) Protocol const ProtocolType WakeOnLan = 46; - /** - * NFLOG (Linux Netfilter NFLOG) Protocol - */ + /// NFLOG (Linux Netfilter NFLOG) Protocol const ProtocolType NFLOG = 47; - /** - * TPKT protocol - */ + /// TPKT protocol const ProtocolType TPKT = 48; - /** - * VRRP version 2 protocol - */ + /// VRRP version 2 protocol const ProtocolType VRRPv2 = 49; - /** - * VRRP version 3 protocol - */ + /// VRRP version 3 protocol const ProtocolType VRRPv3 = 50; - /** - * VRRP protocol family (VRRPv2 and VRRPv3 protocols) - */ + /// VRRP protocol family (VRRPv2 and VRRPv3 protocols) const ProtocolTypeFamily VRRP = 0x3132; - /** - * COTP protocol - */ + /// COTP protocol const ProtocolType COTP = 51; - /** - * SLL2 protocol - */ + /// SLL2 protocol const ProtocolType SLL2 = 52; - /** - * S7COMM protocol - */ + /// S7COMM protocol const ProtocolType S7COMM = 53; - /* - * SMTP protocol - */ + /// SMTP protocol const ProtocolType SMTP = 54; - /* - * LDAP protocol - */ + /// LDAP protocol const ProtocolType LDAP = 55; - /* - * WireGuard protocol - */ + /// WireGuard protocol const ProtocolType WireGuard = 56; - /** - * GTPv2 protocol - */ + /// GTPv2 protocol const ProtocolType GTPv2 = 57; - /** - * An enum representing OSI model layers - */ + /// An enum representing OSI model layers enum OsiModelLayer { - /** Physical layer (layer 1) */ + /// Physical layer (layer 1) OsiModelPhysicalLayer = 1, - /** Data link layer (layer 2) */ + /// Data link layer (layer 2) OsiModelDataLinkLayer = 2, - /** Network layer (layer 3) */ + /// Network layer (layer 3) OsiModelNetworkLayer = 3, - /** Transport layer (layer 4) */ + /// Transport layer (layer 4) OsiModelTransportLayer = 4, - /** Session layer (layer 5) */ + /// Session layer (layer 5) OsiModelSesionLayer = 5, - /** Presentation layer (layer 6) */ + /// Presentation layer (layer 6) OsiModelPresentationLayer = 6, - /** Application layer (layer 7) */ + /// Application layer (layer 7) OsiModelApplicationLayer = 7, - /** Unknown / null layer */ + /// Unknown / null layer OsiModelLayerUnknown = 8 }; - } // namespace pcpp diff --git a/Packet++/header/RadiusLayer.h b/Packet++/header/RadiusLayer.h index c7ab300175..f65fb66b66 100644 --- a/Packet++/header/RadiusLayer.h +++ b/Packet++/header/RadiusLayer.h @@ -5,50 +5,39 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct radius_header - * Represents a RADIUS protocol header - */ + /// @struct radius_header + /// Represents a RADIUS protocol header #pragma pack(push, 1) struct radius_header { - /** RADIUS message code */ + /// RADIUS message code uint8_t code; - /** RADIUS message ID */ + /// RADIUS message ID uint8_t id; - /** RADIUS message length */ + /// RADIUS message length uint16_t length; - /** Used to authenticate the reply from the RADIUS server and to encrypt passwords */ + /// Used to authenticate the reply from the RADIUS server and to encrypt passwords uint8_t authenticator[16]; }; #pragma pack(pop) static_assert(sizeof(radius_header) == 20, "radius_header size is not 20 bytes"); - /** - * @class RadiusAttribute - * A wrapper class for RADIUS attributes. This class does not create or modify RADIUS attribute records, but rather - * serves as a wrapper and provides useful methods for retrieving data from them - */ + /// @class RadiusAttribute + /// A wrapper class for RADIUS attributes. This class does not create or modify RADIUS attribute records, but rather + /// serves as a wrapper and provides useful methods for retrieving data from them class RadiusAttribute : public TLVRecord { public: - /** - * A c'tor for this class that gets a pointer to the attribute raw data (byte array) - * @param[in] attrRawData A pointer to the attribute raw data - */ + /// A c'tor for this class that gets a pointer to the attribute raw data (byte array) + /// @param[in] attrRawData A pointer to the attribute raw data explicit RadiusAttribute(uint8_t* attrRawData) : TLVRecord(attrRawData) {} - /** - * A d'tor for this class, currently does nothing - */ + /// A d'tor for this class, currently does nothing ~RadiusAttribute() override = default; // implement abstract methods @@ -70,99 +59,77 @@ namespace pcpp } }; - /** - * @class RadiusAttributeBuilder - * A class for building RADIUS attributes. This builder receives the attribute parameters in its c'tor, - * builds the RADIUS attribute raw buffer and provides a build() method to get a RadiusAttribute object out of it - */ + /// @class RadiusAttributeBuilder + /// A class for building RADIUS attributes. This builder receives the attribute parameters in its c'tor, + /// builds the RADIUS attribute raw buffer and provides a build() method to get a RadiusAttribute object out of it class RadiusAttributeBuilder : public TLVRecordBuilder { public: - /** - * A c'tor for building RADIUS attributes which their value is a byte array. The RadiusAttribute object can - * later be retrieved by calling build() - * @param[in] attrType RADIUS attribute type - * @param[in] attrValue A buffer containing the attribute value. This buffer is read-only and isn't modified in - * any way - * @param[in] attrValueLen Attribute value length in bytes - */ + /// A c'tor for building RADIUS attributes which their value is a byte array. The RadiusAttribute object can + /// later be retrieved by calling build() + /// @param[in] attrType RADIUS attribute type + /// @param[in] attrValue A buffer containing the attribute value. This buffer is read-only and isn't modified in + /// any way + /// @param[in] attrValueLen Attribute value length in bytes RadiusAttributeBuilder(uint8_t attrType, const uint8_t* attrValue, uint8_t attrValueLen) : TLVRecordBuilder(attrType, attrValue, attrValueLen) {} - /** - * A c'tor for building RADIUS attributes which have a 1-byte value. The RadiusAttribute object can later be - * retrieved by calling build() - * @param[in] attrType RADIUS attribute type - * @param[in] attrValue A 1-byte attribute value - */ + /// A c'tor for building RADIUS attributes which have a 1-byte value. The RadiusAttribute object can later be + /// retrieved by calling build() + /// @param[in] attrType RADIUS attribute type + /// @param[in] attrValue A 1-byte attribute value RadiusAttributeBuilder(uint8_t attrType, uint8_t attrValue) : TLVRecordBuilder(attrType, attrValue) {} - /** - * A c'tor for building RADIUS attributes which have a 2-byte value. The RadiusAttribute object can later be - * retrieved by calling build() - * @param[in] attrType RADIUS attribute type - * @param[in] attrValue A 2-byte attribute value - */ + /// A c'tor for building RADIUS attributes which have a 2-byte value. The RadiusAttribute object can later be + /// retrieved by calling build() + /// @param[in] attrType RADIUS attribute type + /// @param[in] attrValue A 2-byte attribute value RadiusAttributeBuilder(uint8_t attrType, uint16_t attrValue) : TLVRecordBuilder(attrType, attrValue) {} - /** - * A c'tor for building RADIUS attributes which have a 4-byte value. The RadiusAttribute object can later be - * retrieved by calling build() - * @param[in] attrType RADIUS attribute type - * @param[in] attrValue A 4-byte attribute value - */ + /// A c'tor for building RADIUS attributes which have a 4-byte value. The RadiusAttribute object can later be + /// retrieved by calling build() + /// @param[in] attrType RADIUS attribute type + /// @param[in] attrValue A 4-byte attribute value RadiusAttributeBuilder(uint8_t attrType, uint32_t attrValue) : TLVRecordBuilder(attrType, attrValue) {} - /** - * A c'tor for building RADIUS attributes which have an IPv4Address value. The RadiusAttribute object can later - * be retrieved by calling build() - * @param[in] attrType RADIUS attribute type - * @param[in] attrValue The IPv4 address attribute value - */ + /// A c'tor for building RADIUS attributes which have an IPv4Address value. The RadiusAttribute object can later + /// be retrieved by calling build() + /// @param[in] attrType RADIUS attribute type + /// @param[in] attrValue The IPv4 address attribute value RadiusAttributeBuilder(uint8_t attrType, const IPv4Address& attrValue) : TLVRecordBuilder(attrType, attrValue) {} - /** - * A c'tor for building RADIUS attributes which have a string value. The RadiusAttribute object can later be - * retrieved by calling build() - * @param[in] attrType RADIUS attribute type - * @param[in] attrValue The string attribute value - */ + /// A c'tor for building RADIUS attributes which have a string value. The RadiusAttribute object can later be + /// retrieved by calling build() + /// @param[in] attrType RADIUS attribute type + /// @param[in] attrValue The string attribute value RadiusAttributeBuilder(uint8_t attrType, const std::string& attrValue) : TLVRecordBuilder(attrType, attrValue) {} - /** - * A copy c'tor which copies all the data from another instance of RadiusAttributeBuilder - * @param[in] other The instance to copy from - */ + /// A copy c'tor which copies all the data from another instance of RadiusAttributeBuilder + /// @param[in] other The instance to copy from RadiusAttributeBuilder(const RadiusAttributeBuilder& other) : TLVRecordBuilder(other) {} - /** - * Assignment operator that copies all data from another instance of RadiusAttributeBuilder - * @param[in] other The instance to assign from - */ + /// Assignment operator that copies all data from another instance of RadiusAttributeBuilder + /// @param[in] other The instance to assign from RadiusAttributeBuilder& operator=(const RadiusAttributeBuilder& other) { TLVRecordBuilder::operator=(other); return *this; } - /** - * Build the RadiusAttribute object out of the parameters defined in the c'tor - * @return The RadiusAttribute object - */ + /// Build the RadiusAttribute object out of the parameters defined in the c'tor + /// @return The RadiusAttribute object RadiusAttribute build() const; }; - /** - * @class RadiusLayer - * Represents a RADIUS (Remote Authentication Dial-In User Service) protocol layer - */ + /// @class RadiusLayer + /// Represents a RADIUS (Remote Authentication Dial-In User Service) protocol layer class RadiusLayer : public Layer { private: @@ -176,163 +143,121 @@ namespace pcpp RadiusAttribute addAttrAt(const RadiusAttributeBuilder& attrBuilder, int offset); public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in RadiusLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, Radius) {} - /** - * A constructor that creates a new layer from scratch - * @param[in] code The RADIUS message code - * @param[in] id The RADIUS message ID - * @param[in] authenticator A pointer to a byte array containing the authenticator value - * @param[in] authenticatorArrSize The authenticator byte array size. A valid size of the authenticator field is - * 16 bytes. If the provided size is less than that then the byte array will be copied to the packet but the - * missing bytes will stay zero. If the size is more than 16 bytes, only the first 16 bytes will be copied to - * the packet - */ + /// A constructor that creates a new layer from scratch + /// @param[in] code The RADIUS message code + /// @param[in] id The RADIUS message ID + /// @param[in] authenticator A pointer to a byte array containing the authenticator value + /// @param[in] authenticatorArrSize The authenticator byte array size. A valid size of the authenticator field + /// is 16 bytes. If the provided size is less than that then the byte array will be copied to the packet but the + /// missing bytes will stay zero. If the size is more than 16 bytes, only the first 16 bytes will be copied to + /// the packet RadiusLayer(uint8_t code, uint8_t id, const uint8_t* authenticator, uint8_t authenticatorArrSize); - /** - * A constructor that creates a new layer from scratch - * @param[in] code The RADIUS message code - * @param[in] id The RADIUS message ID - * @param[in] authenticator A hex string representing the authenticator value. A valid size of the authenticator - * field is 16 bytes. If the hex string represents an array that is smaller than this then the missing bytes in - * the packet's authenticator field will stay zero. If the hex string represents an array that is larger than 16 - * bytes, only the first 16 bytes will be copied to the packet - */ + /// A constructor that creates a new layer from scratch + /// @param[in] code The RADIUS message code + /// @param[in] id The RADIUS message ID + /// @param[in] authenticator A hex string representing the authenticator value. A valid size of the + /// authenticator field is 16 bytes. If the hex string represents an array that is smaller than this then the + /// missing bytes in the packet's authenticator field will stay zero. If the hex string represents an array that + /// is larger than 16 bytes, only the first 16 bytes will be copied to the packet RadiusLayer(uint8_t code, uint8_t id, const std::string& authenticator); - /** - * A d'tor for this layer, currently does nothing - */ + /// A d'tor for this layer, currently does nothing ~RadiusLayer() override = default; - /** - * Get a pointer to the RADIUS header. Notice this points directly to the data, so every change will change the - * actual packet data - * @return A pointer to the radius_header object - */ + /// Get a pointer to the RADIUS header. Notice this points directly to the data, so every change will change the + /// actual packet data + /// @return A pointer to the radius_header object radius_header* getRadiusHeader() const { return reinterpret_cast(m_Data); } - /** - * @return A hex string representation of the radius_header#authenticator byte array value - */ + /// @return A hex string representation of the radius_header#authenticator byte array value std::string getAuthenticatorValue() const; - /** - * Setter for radius_header#authenticator - * @param[in] authValue A hex string representing the requested authenticator value - */ + /// Setter for radius_header#authenticator + /// @param[in] authValue A hex string representing the requested authenticator value void setAuthenticatorValue(const std::string& authValue); - /** - * A static method that returns the RADIUS message string for a give message code. For example: the string - * "Access-Request" will be returned for code 1 - * @param[in] radiusMessageCode RADIUS message code - * @return RADIUS message string - */ + /// A static method that returns the RADIUS message string for a give message code. For example: the string + /// "Access-Request" will be returned for code 1 + /// @param[in] radiusMessageCode RADIUS message code + /// @return RADIUS message string static std::string getRadiusMessageString(uint8_t radiusMessageCode); - /** - * @return The first RADIUS attribute in the packet. If there are no attributes the returned value will contain - * a logical null (RadiusAttribute#isNull() == true) - */ + /// @return The first RADIUS attribute in the packet. If there are no attributes the returned value will contain + /// a logical null (RadiusAttribute#isNull() == true) RadiusAttribute getFirstAttribute() const; - /** - * Get the RADIUS attribute that comes after a given attribute. If the given attribute was the last one, the - * returned value will contain a logical null (RadiusAttribute#isNull() == true) - * @param[in] attr A given attribute - * @return A RadiusAttribute object containing the attribute data that comes next, or logical null if the - * given attribute: (1) was the last one; (2) contains a logical null or (3) doesn't belong to this packet - */ + /// Get the RADIUS attribute that comes after a given attribute. If the given attribute was the last one, the + /// returned value will contain a logical null (RadiusAttribute#isNull() == true) + /// @param[in] attr A given attribute + /// @return A RadiusAttribute object containing the attribute data that comes next, or logical null if the + /// given attribute: (1) was the last one; (2) contains a logical null or (3) doesn't belong to this packet RadiusAttribute getNextAttribute(RadiusAttribute& attr) const; - /** - * Get a RADIUS attribute by attribute type - * @param[in] attrType RADIUS attribute type - * @return A RadiusAttribute object containing the first attribute data that matches this type, or logical - * null (RadiusAttribute#isNull() == true) if no such attribute found - */ + /// Get a RADIUS attribute by attribute type + /// @param[in] attrType RADIUS attribute type + /// @return A RadiusAttribute object containing the first attribute data that matches this type, or logical + /// null (RadiusAttribute#isNull() == true) if no such attribute found RadiusAttribute getAttribute(uint8_t attrType) const; - /** - * @return The number of RADIUS attributes in the packet - */ + /// @return The number of RADIUS attributes in the packet size_t getAttributeCount() const; - /** - * Add a new RADIUS attribute at the end of the layer - * @param[in] attrBuilder A RadiusAttributeBuilder object that contains the requested attribute data to add - * @return A RadiusAttribute object containing the newly added RADIUS attribute data or logical null - * (RadiusAttribute#isNull() == true) if addition failed - */ + /// Add a new RADIUS attribute at the end of the layer + /// @param[in] attrBuilder A RadiusAttributeBuilder object that contains the requested attribute data to add + /// @return A RadiusAttribute object containing the newly added RADIUS attribute data or logical null + /// (RadiusAttribute#isNull() == true) if addition failed RadiusAttribute addAttribute(const RadiusAttributeBuilder& attrBuilder); - /** - * Add a new RADIUS attribute after an existing one - * @param[in] attrBuilder A RadiusAttributeBuilder object that contains the requested attribute data to add - * @param[in] prevAttrType The RADIUS attribute which the newly added attribute will come after - * @return A RadiusAttribute object containing the newly added RADIUS attribute data or logical null - * (RadiusAttribute#isNull() == true) if addition failed - */ + /// Add a new RADIUS attribute after an existing one + /// @param[in] attrBuilder A RadiusAttributeBuilder object that contains the requested attribute data to add + /// @param[in] prevAttrType The RADIUS attribute which the newly added attribute will come after + /// @return A RadiusAttribute object containing the newly added RADIUS attribute data or logical null + /// (RadiusAttribute#isNull() == true) if addition failed RadiusAttribute addAttributeAfter(const RadiusAttributeBuilder& attrBuilder, uint8_t prevAttrType); - /** - * Remove an existing RADIUS attribute from the layer - * @param[in] attrType The RADIUS attribute type to remove - * @return True if the RADIUS attribute was successfully removed or false if type wasn't found or if removal - * failed - */ + /// Remove an existing RADIUS attribute from the layer + /// @param[in] attrType The RADIUS attribute type to remove + /// @return True if the RADIUS attribute was successfully removed or false if type wasn't found or if removal + /// failed bool removeAttribute(uint8_t attrType); - /** - * Remove all RADIUS attributes in this layer - * @return True if all attributes were successfully removed or false if removal failed for some reason - */ + /// Remove all RADIUS attributes in this layer + /// @return True if all attributes were successfully removed or false if removal failed for some reason bool removeAllAttributes(); - /** - * The static method makes validation of UDP data - * @param[in] udpData The pointer to the UDP payload data. It points to the first byte of RADIUS header. - * @param[in] udpDataLen The payload data size - * @return True if the data is valid and can represent the RADIUS packet - */ + /// The static method makes validation of UDP data + /// @param[in] udpData The pointer to the UDP payload data. It points to the first byte of RADIUS header. + /// @param[in] udpDataLen The payload data size + /// @return True if the data is valid and can represent the RADIUS packet static bool isDataValid(const uint8_t* udpData, size_t udpDataLen); - /** - * A static method that checks whether the port is considered as RADIUS - * @param[in] port The port number to be checked - */ + /// A static method that checks whether the port is considered as RADIUS + /// @param[in] port The port number to be checked static inline bool isRadiusPort(uint16_t port); // implement abstract methods - /** - * @return The size written in radius_header#length - */ + /// @return The size written in radius_header#length size_t getHeaderLen() const override; - /** - * Does nothing for this layer, RADIUS is always last - */ + /// Does nothing for this layer, RADIUS is always last void parseNextLayer() override {} - /** - * Calculate and store the value of radius_header#length according to the layer size - */ + /// Calculate and store the value of radius_header#length according to the layer size void computeCalculateFields() override; std::string toString() const override; diff --git a/Packet++/header/RawPacket.h b/Packet++/header/RawPacket.h index d3136ed9c8..0cdf34efe0 100644 --- a/Packet++/header/RawPacket.h +++ b/Packet++/header/RawPacket.h @@ -11,260 +11,250 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * An enum describing all known link layer type. Taken from: http://www.tcpdump.org/linktypes.html . - */ + /// An enum describing all known link layer type. Taken from: http://www.tcpdump.org/linktypes.html . enum LinkLayerType { - /** BSD loopback encapsulation */ + /// BSD loopback encapsulation LINKTYPE_NULL = 0, - /** IEEE 802.3 Ethernet */ + /// IEEE 802.3 Ethernet LINKTYPE_ETHERNET = 1, - /** AX.25 packet */ + /// AX.25 packet LINKTYPE_AX25 = 3, - /** IEEE 802.5 Token Ring */ + /// IEEE 802.5 Token Ring LINKTYPE_IEEE802_5 = 6, - /** ARCNET Data Packets */ + /// ARCNET Data Packets LINKTYPE_ARCNET_BSD = 7, - /** SLIP, encapsulated with a LINKTYPE_SLIP header */ + /// SLIP, encapsulated with a LINKTYPE_SLIP header LINKTYPE_SLIP = 8, - /** PPP, as per RFC 1661 and RFC 1662 */ + /// PPP, as per RFC 1661 and RFC 1662 LINKTYPE_PPP = 9, - /** FDDI, as specified by ANSI INCITS 239-1994 */ + /// FDDI, as specified by ANSI INCITS 239-1994 LINKTYPE_FDDI = 10, - /** Raw IP */ + /// Raw IP LINKTYPE_DLT_RAW1 = 12, - /** Raw IP (OpenBSD) */ + /// Raw IP (OpenBSD) LINKTYPE_DLT_RAW2 = 14, - /** PPP in HDLC-like framing, as per RFC 1662, or Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547 - */ + /// PPP in HDLC-like framing, as per RFC 1662, or Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547 LINKTYPE_PPP_HDLC = 50, - /** PPPoE */ + /// PPPoE LINKTYPE_PPP_ETHER = 51, - /** RFC 1483 LLC/SNAP-encapsulated ATM */ + /// RFC 1483 LLC/SNAP-encapsulated ATM LINKTYPE_ATM_RFC1483 = 100, - /** Raw IP */ + /// Raw IP LINKTYPE_RAW = 101, - /** Cisco PPP with HDLC framing */ + /// Cisco PPP with HDLC framing LINKTYPE_C_HDLC = 104, - /** IEEE 802.11 wireless LAN */ + /// IEEE 802.11 wireless LAN LINKTYPE_IEEE802_11 = 105, - /** Frame Relay */ + /// Frame Relay LINKTYPE_FRELAY = 107, - /** OpenBSD loopback encapsulation */ + /// OpenBSD loopback encapsulation LINKTYPE_LOOP = 108, - /** Linux "cooked" capture encapsulation */ + /// Linux "cooked" capture encapsulation LINKTYPE_LINUX_SLL = 113, - /** Apple LocalTalk */ + /// Apple LocalTalk LINKTYPE_LTALK = 114, - /** OpenBSD pflog */ + /// OpenBSD pflog LINKTYPE_PFLOG = 117, - /** Prism monitor mode information followed by an 802.11 header */ + /// Prism monitor mode information followed by an 802.11 header LINKTYPE_IEEE802_11_PRISM = 119, - /** RFC 2625 IP-over-Fibre Channel */ + /// RFC 2625 IP-over-Fibre Channel LINKTYPE_IP_OVER_FC = 122, - /** ATM traffic, encapsulated as per the scheme used by SunATM devices */ + /// ATM traffic, encapsulated as per the scheme used by SunATM devices LINKTYPE_SUNATM = 123, - /** Radiotap link-layer information followed by an 802.11 header */ + /// Radiotap link-layer information followed by an 802.11 header LINKTYPE_IEEE802_11_RADIOTAP = 127, - /** ARCNET Data Packets, as described by the ARCNET Trade Association standard ATA 878.1-1999 */ + /// ARCNET Data Packets, as described by the ARCNET Trade Association standard ATA 878.1-1999 LINKTYPE_ARCNET_LINUX = 129, - /** Apple IP-over-IEEE 1394 cooked header */ + /// Apple IP-over-IEEE 1394 cooked header LINKTYPE_APPLE_IP_OVER_IEEE1394 = 138, - /** Signaling System 7 Message Transfer Part Level 2 */ + /// Signaling System 7 Message Transfer Part Level 2 LINKTYPE_MTP2_WITH_PHDR = 139, - /** Signaling System 7 Message Transfer Part Level 2 */ + /// Signaling System 7 Message Transfer Part Level 2 LINKTYPE_MTP2 = 140, - /** Signaling System 7 Message Transfer Part Level 3 */ + /// Signaling System 7 Message Transfer Part Level 3 LINKTYPE_MTP3 = 141, - /** Signaling System 7 Signalling Connection Control Part */ + /// Signaling System 7 Signalling Connection Control Part LINKTYPE_SCCP = 142, - /** Signaling System 7 Signalling Connection Control Part */ + /// Signaling System 7 Signalling Connection Control Part LINKTYPE_DOCSIS = 143, - /** Linux-IrDA packets */ + /// Linux-IrDA packets LINKTYPE_LINUX_IRDA = 144, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER0 = 147, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER1 = 148, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER2 = 149, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER3 = 150, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER4 = 151, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER5 = 152, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER6 = 153, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER7 = 154, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER8 = 155, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER9 = 156, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER10 = 157, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER11 = 158, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER12 = 159, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER13 = 160, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER14 = 161, - /** Reserved for private use */ + /// Reserved for private use LINKTYPE_USER15 = 162, - /** AVS monitor mode information followed by an 802.11 header */ + /// AVS monitor mode information followed by an 802.11 header LINKTYPE_IEEE802_11_AVS = 163, - /** BACnet MS/TP frames */ + /// BACnet MS/TP frames LINKTYPE_BACNET_MS_TP = 165, - /** PPP in HDLC-like encapsulation, like LINKTYPE_PPP_HDLC, but with the 0xff address byte replaced by a - * direction indication - 0x00 for incoming and 0x01 for outgoing */ + /// PPP in HDLC-like encapsulation, like LINKTYPE_PPP_HDLC, but with the 0xff address byte replaced by a + /// direction indication - 0x00 for incoming and 0x01 for outgoing LINKTYPE_PPP_PPPD = 166, - /** General Packet Radio Service Logical Link Control */ + /// General Packet Radio Service Logical Link Control LINKTYPE_GPRS_LLC = 169, - /** Transparent-mapped generic framing procedure */ + /// Transparent-mapped generic framing procedure LINKTYPE_GPF_T = 170, - /** Frame-mapped generic framing procedure */ + /// Frame-mapped generic framing procedure LINKTYPE_GPF_F = 171, - /** Link Access Procedures on the D Channel (LAPD) frames */ + /// Link Access Procedures on the D Channel (LAPD) frames LINKTYPE_LINUX_LAPD = 177, - /** Bluetooth HCI UART transport layer */ + /// Bluetooth HCI UART transport layer LINKTYPE_BLUETOOTH_HCI_H4 = 187, - /** USB packets, beginning with a Linux USB header */ + /// USB packets, beginning with a Linux USB header LINKTYPE_USB_LINUX = 189, - /** Per-Packet Information information */ + /// Per-Packet Information information LINKTYPE_PPI = 192, - /** IEEE 802.15.4 wireless Personal Area Network */ + /// IEEE 802.15.4 wireless Personal Area Network LINKTYPE_IEEE802_15_4 = 195, - /** Various link-layer types, with a pseudo-header, for SITA */ + /// Various link-layer types, with a pseudo-header, for SITA LINKTYPE_SITA = 196, - /** Various link-layer types, with a pseudo-header, for Endace DAG cards; encapsulates Endace ERF record */ + /// Various link-layer types, with a pseudo-header, for Endace DAG cards; encapsulates Endace ERF record LINKTYPE_ERF = 197, - /** Bluetooth HCI UART transport layer */ + /// Bluetooth HCI UART transport layer LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR = 201, - /** AX.25 packet, with a 1-byte KISS header containing a type indicator */ + /// AX.25 packet, with a 1-byte KISS header containing a type indicator LINKTYPE_AX25_KISS = 202, - /** Link Access Procedures on the D Channel (LAPD) frames */ + /// Link Access Procedures on the D Channel (LAPD) frames LINKTYPE_LAPD = 203, - /** PPP, as per RFC 1661 and RFC 1662, preceded with a one-byte pseudo-header with a zero value meaning - * "received by this host" and a non-zero value meaning "sent by this host" */ + /// PPP, as per RFC 1661 and RFC 1662, preceded with a one-byte pseudo-header with a zero value meaning + /// "received by this host" and a non-zero value meaning "sent by this host" LINKTYPE_PPP_WITH_DIR = 204, - /** Cisco PPP with HDLC framing */ + /// Cisco PPP with HDLC framing LINKTYPE_C_HDLC_WITH_DIR = 205, - /** Frame Relay */ + /// Frame Relay LINKTYPE_FRELAY_WITH_DIR = 206, - /** IPMB over an I2C circuit */ + /// IPMB over an I2C circuit LINKTYPE_IPMB_LINUX = 209, - /** IEEE 802.15.4 wireless Personal Area Network */ + /// IEEE 802.15.4 wireless Personal Area Network LINKTYPE_IEEE802_15_4_NONASK_PHY = 215, - /** USB packets, beginning with a Linux USB header */ + /// USB packets, beginning with a Linux USB header LINKTYPE_USB_LINUX_MMAPPED = 220, - /** Fibre Channel FC-2 frames, beginning with a Frame_Header */ + /// Fibre Channel FC-2 frames, beginning with a Frame_Header LINKTYPE_FC_2 = 224, - /** Fibre Channel FC-2 frames */ + /// Fibre Channel FC-2 frames LINKTYPE_FC_2_WITH_FRAME_DELIMS = 225, - /** Solaris ipnet pseudo-header */ + /// Solaris ipnet pseudo-header LINKTYPE_IPNET = 226, - /** CAN (Controller Area Network) frames, with a pseudo-header as supplied by Linux SocketCAN */ + /// CAN (Controller Area Network) frames, with a pseudo-header as supplied by Linux SocketCAN LINKTYPE_CAN_SOCKETCAN = 227, - /** Raw IPv4; the packet begins with an IPv4 header */ + /// Raw IPv4; the packet begins with an IPv4 header LINKTYPE_IPV4 = 228, - /** Raw IPv6; the packet begins with an IPv6 header */ + /// Raw IPv6; the packet begins with an IPv6 header LINKTYPE_IPV6 = 229, - /** IEEE 802.15.4 wireless Personal Area Network, without the FCS at the end of the frame */ + /// IEEE 802.15.4 wireless Personal Area Network, without the FCS at the end of the frame LINKTYPE_IEEE802_15_4_NOFCS = 230, - /** Raw D-Bus messages, starting with the endianness flag, followed by the message type, etc., but without the - * authentication handshake before the message sequence */ + /// Raw D-Bus messages, starting with the endianness flag, followed by the message type, etc., but without the + /// authentication handshake before the message sequence LINKTYPE_DBUS = 231, - /** DVB-CI (DVB Common Interface for communication between a PC Card module and a DVB receiver), with the - * message format specified by the PCAP format for DVB-CI specification */ + /// DVB-CI (DVB Common Interface for communication between a PC Card module and a DVB receiver), with the + /// message format specified by the PCAP format for DVB-CI specification LINKTYPE_DVB_CI = 235, - /** Variant of 3GPP TS 27.010 multiplexing protocol (similar to, but not the same as, 27.010) */ + /// Variant of 3GPP TS 27.010 multiplexing protocol (similar to, but not the same as, 27.010) LINKTYPE_MUX27010 = 236, - /** D_PDUs as described by NATO standard STANAG 5066, starting with the synchronization sequence, and including - * both header and data CRCs */ + /// D_PDUs as described by NATO standard STANAG 5066, starting with the synchronization sequence, and including + /// both header and data CRCs LINKTYPE_STANAG_5066_D_PDU = 237, - /** Linux netlink NETLINK NFLOG socket log messages */ + /// Linux netlink NETLINK NFLOG socket log messages LINKTYPE_NFLOG = 239, - /** Pseudo-header for Hilscher Gesellschaft für Systemautomation mbH netANALYZER devices, followed by an - * Ethernet frame, beginning with the MAC header and ending with the FCS */ + /// Pseudo-header for Hilscher Gesellschaft für Systemautomation mbH netANALYZER devices, followed by an + /// Ethernet frame, beginning with the MAC header and ending with the FCS LINKTYPE_NETANALYZER = 240, - /** Pseudo-header for Hilscher Gesellschaft für Systemautomation mbH netANALYZER devices, followed by an - * Ethernet frame, beginning with the preamble, SFD, and MAC header, and ending with the FCS */ + /// Pseudo-header for Hilscher Gesellschaft für Systemautomation mbH netANALYZER devices, followed by an + /// Ethernet frame, beginning with the preamble, SFD, and MAC header, and ending with the FCS LINKTYPE_NETANALYZER_TRANSPARENT = 241, - /** IP-over-InfiniBand, as specified by RFC 4391 section 6 */ + /// IP-over-InfiniBand, as specified by RFC 4391 section 6 LINKTYPE_IPOIB = 242, - /** MPEG-2 Transport Stream transport packets, as specified by ISO 13818-1/ITU-T Recommendation H.222.0 */ + /// MPEG-2 Transport Stream transport packets, as specified by ISO 13818-1/ITU-T Recommendation H.222.0 LINKTYPE_MPEG_2_TS = 243, - /** Pseudo-header for ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as used by their ng40 - * protocol tester */ + /// Pseudo-header for ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as used by their ng40 + /// protocol tester LINKTYPE_NG40 = 244, - /** Pseudo-header for NFC LLCP packet captures, followed by frame data for the LLCP Protocol as specified by - * NFCForum-TS-LLCP_1.1 */ + /// Pseudo-header for NFC LLCP packet captures, followed by frame data for the LLCP Protocol as specified by + /// NFCForum-TS-LLCP_1.1 LINKTYPE_NFC_LLCP = 245, - /** Raw InfiniBand frames, starting with the Local Routing Header */ + /// Raw InfiniBand frames, starting with the Local Routing Header LINKTYPE_INFINIBAND = 247, - /** SCTP packets, as defined by RFC 4960, with no lower-level protocols such as IPv4 or IPv6 */ + /// SCTP packets, as defined by RFC 4960, with no lower-level protocols such as IPv4 or IPv6 LINKTYPE_SCTP = 248, - /** USB packets, beginning with a USBPcap header */ + /// USB packets, beginning with a USBPcap header LINKTYPE_USBPCAP = 249, - /** Serial-line packet header for the Schweitzer Engineering Laboratories "RTAC" product */ + /// Serial-line packet header for the Schweitzer Engineering Laboratories "RTAC" product LINKTYPE_RTAC_SERIAL = 250, - /** Bluetooth Low Energy air interface Link Layer packets */ + /// Bluetooth Low Energy air interface Link Layer packets LINKTYPE_BLUETOOTH_LE_LL = 251, - /** Linux Netlink capture encapsulation */ + /// Linux Netlink capture encapsulation LINKTYPE_NETLINK = 253, - /** Bluetooth Linux Monitor encapsulation of traffic for the BlueZ stack */ + /// Bluetooth Linux Monitor encapsulation of traffic for the BlueZ stack LINKTYPE_BLUETOOTH_LINUX_MONITOR = 254, - /** Bluetooth Basic Rate and Enhanced Data Rate baseband packets */ + /// Bluetooth Basic Rate and Enhanced Data Rate baseband packets LINKTYPE_BLUETOOTH_BREDR_BB = 255, - /** Bluetooth Low Energy link-layer packets */ + /// Bluetooth Low Energy link-layer packets LINKTYPE_BLUETOOTH_LE_LL_WITH_PHDR = 256, - /** PROFIBUS data link layer packets, as specified by IEC standard 61158-6-3 */ + /// PROFIBUS data link layer packets, as specified by IEC standard 61158-6-3 LINKTYPE_PROFIBUS_DL = 257, - /** Apple PKTAP capture encapsulation */ + /// Apple PKTAP capture encapsulation LINKTYPE_PKTAP = 258, - /** Ethernet-over-passive-optical-network packets */ + /// Ethernet-over-passive-optical-network packets LINKTYPE_EPON = 259, - /** IPMI trace packets, as specified by Table 3-20 "Trace Data Block Format" in the PICMG HPM.2 specification */ + /// IPMI trace packets, as specified by Table 3-20 "Trace Data Block Format" in the PICMG HPM.2 specification LINKTYPE_IPMI_HPM_2 = 260, - /** Per Joshua Wright , formats for Z-Wave RF profiles R1 and R2 captures */ + /// Per Joshua Wright , formats for Z-Wave RF profiles R1 and R2 captures LINKTYPE_ZWAVE_R1_R2 = 261, - /** Per Joshua Wright , formats for Z-Wave RF profile R3 captures */ + /// Per Joshua Wright , formats for Z-Wave RF profile R3 captures LINKTYPE_ZWAVE_R3 = 262, - /** Formats for WattStopper Digital Lighting Management (DLM) and Legrand Nitoo Open protocol common packet - * structure captures */ + /// Formats for WattStopper Digital Lighting Management (DLM) and Legrand Nitoo Open protocol common packet + /// structure captures LINKTYPE_WATTSTOPPER_DLM = 263, - /** Messages between ISO 14443 contactless smartcards (Proximity Integrated Circuit Card, PICC) and card readers - * (Proximity Coupling Device, PCD), with the message format specified by the PCAP format for ISO14443 - * specification */ + /// Messages between ISO 14443 contactless smartcards (Proximity Integrated Circuit Card, PICC) and card readers + /// (Proximity Coupling Device, PCD), with the message format specified by the PCAP format for ISO14443 + /// specification LINKTYPE_ISO_14443 = 264, - /** Linux "cooked" capture encapsulation v2 */ + /// Linux "cooked" capture encapsulation v2 LINKTYPE_LINUX_SLL2 = 276, - /** Set if interface ID for a packet of a pcapng file is too high */ + /// Set if interface ID for a packet of a pcapng file is too high LINKTYPE_INVALID = 0xFFFF }; - /** - * Max packet size supported - */ + /// Max packet size supported #define PCPP_MAX_PACKET_SIZE 65536 - /** - * @class RawPacket - * This class holds the packet as raw (not parsed) data. The data is held as byte array. In addition to the data - * itself every instance also holds a timestamp representing the time the packet was received by the NIC. RawPacket - * instance isn't read only. The user can change the packet data, add or remove data, etc. - */ + /// @class RawPacket + /// This class holds the packet as raw (not parsed) data. The data is held as byte array. In addition to the data + /// itself every instance also holds a timestamp representing the time the packet was received by the NIC. RawPacket + /// instance isn't read only. The user can change the packet data, add or remove data, etc. class RawPacket { protected: @@ -279,247 +269,197 @@ namespace pcpp void copyDataFrom(const RawPacket& other, bool allocateData = true); public: - /** - * A constructor that receives a pointer to the raw data (allocated elsewhere). This constructor is usually used - * when packet is captured using a packet capturing engine (like libPcap. WinPcap, Npcap, PF_RING, etc.). The - * capturing engine allocates the raw data memory and give the user a pointer to it + a timestamp it has arrived - * to the device - * @param[in] pRawData A pointer to the raw data - * @param[in] rawDataLen The raw data length in bytes - * @param[in] timestamp The timestamp packet was received by the NIC (in usec precision) - * @param[in] deleteRawDataAtDestructor An indicator whether raw data pointer should be freed when the instance - * is freed or not. If set to 'true' than pRawData will be freed when instanced is being freed - * @param[in] layerType The link layer type of this raw packet. The default is Ethernet - */ + /// A constructor that receives a pointer to the raw data (allocated elsewhere). This constructor is usually + /// used when packet is captured using a packet capturing engine (like libPcap. WinPcap, Npcap, PF_RING, etc.). + /// The capturing engine allocates the raw data memory and give the user a pointer to it + a timestamp it has + /// arrived to the device + /// @param[in] pRawData A pointer to the raw data + /// @param[in] rawDataLen The raw data length in bytes + /// @param[in] timestamp The timestamp packet was received by the NIC (in usec precision) + /// @param[in] deleteRawDataAtDestructor An indicator whether raw data pointer should be freed when the instance + /// is freed or not. If set to 'true' than pRawData will be freed when instanced is being freed + /// @param[in] layerType The link layer type of this raw packet. The default is Ethernet RawPacket(const uint8_t* pRawData, int rawDataLen, timeval timestamp, bool deleteRawDataAtDestructor, LinkLayerType layerType = LINKTYPE_ETHERNET); - /** - * A constructor that receives a pointer to the raw data (allocated elsewhere). This constructor is usually used - * when packet is captured using a packet capturing engine (like libPcap. WinPcap, Npcap, PF_RING, etc.). The - * capturing engine allocates the raw data memory and give the user a pointer to it + a timestamp it has arrived - * to the device - * @param[in] pRawData A pointer to the raw data - * @param[in] rawDataLen The raw data length in bytes - * @param[in] timestamp The timestamp packet was received by the NIC (in nsec precision) - * @param[in] deleteRawDataAtDestructor An indicator whether raw data pointer should be freed when the instance - * is freed or not. If set to 'true' than pRawData will be freed when instanced is being freed - * @param[in] layerType The link layer type of this raw packet. The default is Ethernet - */ + /// A constructor that receives a pointer to the raw data (allocated elsewhere). This constructor is usually + /// used when packet is captured using a packet capturing engine (like libPcap. WinPcap, Npcap, PF_RING, etc.). + /// The capturing engine allocates the raw data memory and give the user a pointer to it + a timestamp it has + /// arrived to the device + /// @param[in] pRawData A pointer to the raw data + /// @param[in] rawDataLen The raw data length in bytes + /// @param[in] timestamp The timestamp packet was received by the NIC (in nsec precision) + /// @param[in] deleteRawDataAtDestructor An indicator whether raw data pointer should be freed when the instance + /// is freed or not. If set to 'true' than pRawData will be freed when instanced is being freed + /// @param[in] layerType The link layer type of this raw packet. The default is Ethernet RawPacket(const uint8_t* pRawData, int rawDataLen, timespec timestamp, bool deleteRawDataAtDestructor, LinkLayerType layerType = LINKTYPE_ETHERNET); - /** - * A default constructor that initializes class'es attributes to default value: - * - data pointer is set to nullptr - * - data length is set to 0 - * - deleteRawDataAtDestructor is set to 'true' - * @todo timestamp isn't set here to a default value - */ + /// A default constructor that initializes class'es attributes to default value: + /// - data pointer is set to nullptr + /// - data length is set to 0 + /// - deleteRawDataAtDestructor is set to 'true' + /// @todo timestamp isn't set here to a default value RawPacket(); - /** - * A destructor for this class. Frees the raw data if deleteRawDataAtDestructor was set to 'true' - */ + /// A destructor for this class. Frees the raw data if deleteRawDataAtDestructor was set to 'true' virtual ~RawPacket(); - /** - * A copy constructor that copies all data from another instance. Notice all raw data is copied (using memcpy), - * so when the original or the other instance are freed, the other won't be affected - * @param[in] other The instance to copy from - */ + /// A copy constructor that copies all data from another instance. Notice all raw data is copied (using memcpy), + /// so when the original or the other instance are freed, the other won't be affected + /// @param[in] other The instance to copy from RawPacket(const RawPacket& other); - /** - * Assignment operator overload for this class. When using this operator on an already initialized RawPacket - * instance, the original raw data is freed first. Then the other instance is copied to this instance, the same - * way the copy constructor works - * @todo free raw data only if deleteRawDataAtDestructor was set to 'true' - * @param[in] other The instance to copy from - */ + /// Assignment operator overload for this class. When using this operator on an already initialized RawPacket + /// instance, the original raw data is freed first. Then the other instance is copied to this instance, the same + /// way the copy constructor works + /// @todo free raw data only if deleteRawDataAtDestructor was set to 'true' + /// @param[in] other The instance to copy from RawPacket& operator=(const RawPacket& other); - /** - * @brief Clones the current packet. Caller is responsible for deallocation of the memory. - * @return A pointer to the new RawPacket object which is a clone of this object - */ + /// @brief Clones the current packet. Caller is responsible for deallocation of the memory. + /// @return A pointer to the new RawPacket object which is a clone of this object virtual RawPacket* clone() const; - /** - * @return RawPacket object type. Each derived class should return a different value - */ + /// @return RawPacket object type. Each derived class should return a different value virtual uint8_t getObjectType() const { return 0; } - /** - * Set a raw data. If data was already set and deleteRawDataAtDestructor was set to 'true' the old data will be - * freed first - * @param[in] pRawData A pointer to the new raw data - * @param[in] rawDataLen The new raw data length in bytes - * @param[in] timestamp The timestamp packet was received by the NIC (in usec precision) - * @param[in] layerType The link layer type for this raw data - * @param[in] frameLength When reading from pcap files, sometimes the captured length is different from the - * actual packet length. This parameter represents the packet length. This parameter is optional, if not set or - * set to -1 it is assumed both lengths are equal - * @return True if raw data was set successfully, false otherwise - */ + /// Set a raw data. If data was already set and deleteRawDataAtDestructor was set to 'true' the old data will be + /// freed first + /// @param[in] pRawData A pointer to the new raw data + /// @param[in] rawDataLen The new raw data length in bytes + /// @param[in] timestamp The timestamp packet was received by the NIC (in usec precision) + /// @param[in] layerType The link layer type for this raw data + /// @param[in] frameLength When reading from pcap files, sometimes the captured length is different from the + /// actual packet length. This parameter represents the packet length. This parameter is optional, if not set or + /// set to -1 it is assumed both lengths are equal + /// @return True if raw data was set successfully, false otherwise virtual bool setRawData(const uint8_t* pRawData, int rawDataLen, timeval timestamp, LinkLayerType layerType = LINKTYPE_ETHERNET, int frameLength = -1); - /** - * Set a raw data. If data was already set and deleteRawDataAtDestructor was set to 'true' the old data will be - * freed first - * @param[in] pRawData A pointer to the new raw data - * @param[in] rawDataLen The new raw data length in bytes - * @param[in] timestamp The timestamp packet was received by the NIC (in nsec precision) - * @param[in] layerType The link layer type for this raw data - * @param[in] frameLength When reading from pcap files, sometimes the captured length is different from the - * actual packet length. This parameter represents the packet length. This parameter is optional, if not set or - * set to -1 it is assumed both lengths are equal - * @return True if raw data was set successfully, false otherwise - */ + /// Set a raw data. If data was already set and deleteRawDataAtDestructor was set to 'true' the old data will be + /// freed first + /// @param[in] pRawData A pointer to the new raw data + /// @param[in] rawDataLen The new raw data length in bytes + /// @param[in] timestamp The timestamp packet was received by the NIC (in nsec precision) + /// @param[in] layerType The link layer type for this raw data + /// @param[in] frameLength When reading from pcap files, sometimes the captured length is different from the + /// actual packet length. This parameter represents the packet length. This parameter is optional, if not set or + /// set to -1 it is assumed both lengths are equal + /// @return True if raw data was set successfully, false otherwise virtual bool setRawData(const uint8_t* pRawData, int rawDataLen, timespec timestamp, LinkLayerType layerType = LINKTYPE_ETHERNET, int frameLength = -1); - /** - * Initialize a raw packet with data. The main difference between this method and setRawData() is that - * setRawData() is meant for replacing the data in an existing raw packet, whereas this method is meant to be - * used right after constructing a raw packet using the default c'tor, before setting any data - * @param pRawData A pointer to the new raw data - * @param rawDataLen The new raw data length in bytes - * @param timestamp The timestamp packet was received by the NIC (in nsec precision) - * @param layerType The link layer type for this raw data - * @return True if raw data was set successfully, false otherwise - */ + /// Initialize a raw packet with data. The main difference between this method and setRawData() is that + /// setRawData() is meant for replacing the data in an existing raw packet, whereas this method is meant to be + /// used right after constructing a raw packet using the default c'tor, before setting any data + /// @param pRawData A pointer to the new raw data + /// @param rawDataLen The new raw data length in bytes + /// @param timestamp The timestamp packet was received by the NIC (in nsec precision) + /// @param layerType The link layer type for this raw data + /// @return True if raw data was set successfully, false otherwise bool initWithRawData(const uint8_t* pRawData, int rawDataLen, timespec timestamp, LinkLayerType layerType = LINKTYPE_ETHERNET); - /** - * Get raw data pointer - * @return A read-only pointer to the raw data - */ + /// Get raw data pointer + /// @return A read-only pointer to the raw data const uint8_t* getRawData() const { return m_RawData; } - /** - * Get the link layer type - * @return the type of the link layer - */ + /// Get the link layer type + /// @return the type of the link layer LinkLayerType getLinkLayerType() const { return m_LinkLayerType; } - /** - * This static method validates whether a link type integer value is valid - * @param[in] linkTypeValue Link type integer value - * @return True if the link type value is valid and can be casted into LinkLayerType enum, false otherwise - */ + /// This static method validates whether a link type integer value is valid + /// @param[in] linkTypeValue Link type integer value + /// @return True if the link type value is valid and can be casted into LinkLayerType enum, false otherwise static bool isLinkTypeValid(int linkTypeValue); - /** - * Get raw data length in bytes - * @return Raw data length in bytes - */ + /// Get raw data length in bytes + /// @return Raw data length in bytes int getRawDataLen() const { return m_RawDataLen; } - /** - * Get frame length in bytes - * @return frame length in bytes - */ + /// Get frame length in bytes + /// @return frame length in bytes int getFrameLength() const { return m_FrameLength; } - /** - * Get raw data timestamp - * @return Raw data timestamp - */ + /// Get raw data timestamp + /// @return Raw data timestamp timespec getPacketTimeStamp() const { return m_TimeStamp; } - /** - * Set raw packet timestamp with usec precision - * @param[in] timestamp The timestamp to set (with usec precision) - * @return True if timestamp was set successfully, false otherwise - */ + /// Set raw packet timestamp with usec precision + /// @param[in] timestamp The timestamp to set (with usec precision) + /// @return True if timestamp was set successfully, false otherwise virtual bool setPacketTimeStamp(timeval timestamp); - /** - * Set raw packet timestamp with nsec precision - * @param[in] timestamp The timestamp to set (with nsec precision) - * @return True if timestamp was set successfully, false otherwise - */ + /// Set raw packet timestamp with nsec precision + /// @param[in] timestamp The timestamp to set (with nsec precision) + /// @return True if timestamp was set successfully, false otherwise virtual bool setPacketTimeStamp(timespec timestamp); - /** - * Get an indication whether raw data was already set for this instance. - * @return True if raw data was set for this instance. Raw data can be set using the non-default constructor, - * using setRawData(), using the copy constructor or using the assignment operator. Returns false otherwise, for - * example: if the instance was created using the default constructor or clear() was called - */ + /// Get an indication whether raw data was already set for this instance. + /// @return True if raw data was set for this instance. Raw data can be set using the non-default constructor, + /// using setRawData(), using the copy constructor or using the assignment operator. Returns false otherwise, + /// for example: if the instance was created using the default constructor or clear() was called bool isPacketSet() const { return m_RawPacketSet; } - /** - * Clears all members of this instance, meaning setting raw data to nullptr, raw data length to 0, etc. - * Currently raw data is always freed, even if deleteRawDataAtDestructor was set to 'false' - * @todo deleteRawDataAtDestructor was set to 'true', don't free the raw data - * @todo set timestamp to a default value as well - */ + /// Clears all members of this instance, meaning setting raw data to nullptr, raw data length to 0, etc. + /// Currently raw data is always freed, even if deleteRawDataAtDestructor was set to 'false' + /// @todo deleteRawDataAtDestructor was set to 'true', don't free the raw data + /// @todo set timestamp to a default value as well virtual void clear(); - /** - * Append data to the end of current data. This method works without allocating more memory, it just uses - * memcpy() to copy dataToAppend at the end of the current data. This means that the method assumes this memory - * was already allocated by the user. If it isn't the case then this method will cause memory corruption - * @param[in] dataToAppend A pointer to the data to append to current raw data - * @param[in] dataToAppendLen Length in bytes of dataToAppend - */ + /// Append data to the end of current data. This method works without allocating more memory, it just uses + /// memcpy() to copy dataToAppend at the end of the current data. This means that the method assumes this memory + /// was already allocated by the user. If it isn't the case then this method will cause memory corruption + /// @param[in] dataToAppend A pointer to the data to append to current raw data + /// @param[in] dataToAppendLen Length in bytes of dataToAppend virtual void appendData(const uint8_t* dataToAppend, size_t dataToAppendLen); - /** - * Insert new data at some index of the current data and shift the remaining old data to the end. This method - * works without allocating more memory, it just copies dataToAppend at the relevant index and shifts the - * remaining data to the end. This means that the method assumes this memory was already allocated by the user. - * If it isn't the case then this method will cause memory corruption - * @param[in] atIndex The index to insert the new data to - * @param[in] dataToInsert A pointer to the new data to insert - * @param[in] dataToInsertLen Length in bytes of dataToInsert - */ + /// Insert new data at some index of the current data and shift the remaining old data to the end. This method + /// works without allocating more memory, it just copies dataToAppend at the relevant index and shifts the + /// remaining data to the end. This means that the method assumes this memory was already allocated by the user. + /// If it isn't the case then this method will cause memory corruption + /// @param[in] atIndex The index to insert the new data to + /// @param[in] dataToInsert A pointer to the new data to insert + /// @param[in] dataToInsertLen Length in bytes of dataToInsert virtual void insertData(int atIndex, const uint8_t* dataToInsert, size_t dataToInsertLen); - /** - * Remove certain number of bytes from current raw data buffer. All data after the removed bytes will be shifted - * back - * @param[in] atIndex The index to start removing bytes from - * @param[in] numOfBytesToRemove Number of bytes to remove - * @return True if all bytes were removed successfully, or false if atIndex+numOfBytesToRemove is out-of-bounds - * of the raw data buffer - */ + /// Remove certain number of bytes from current raw data buffer. All data after the removed bytes will be + /// shifted back + /// @param[in] atIndex The index to start removing bytes from + /// @param[in] numOfBytesToRemove Number of bytes to remove + /// @return True if all bytes were removed successfully, or false if atIndex+numOfBytesToRemove is out-of-bounds + /// of the raw data buffer virtual bool removeData(int atIndex, size_t numOfBytesToRemove); - /** - * Re-allocate raw packet buffer meaning add size to it without losing the current packet data. This method - * allocates the required buffer size as instructed by the use and then copies the raw data from the current - * allocated buffer to the new one. This method can become useful if the user wants to insert or append data to - * the raw data, and the previous allocated buffer is too small, so the user wants to allocate a larger buffer - * and get RawPacket instance to point to it - * @param[in] newBufferLength The new buffer length as required by the user. The method is responsible to - * allocate the memory - * @return True if data was reallocated successfully, false otherwise - */ + /// Re-allocate raw packet buffer meaning add size to it without losing the current packet data. This method + /// allocates the required buffer size as instructed by the use and then copies the raw data from the current + /// allocated buffer to the new one. This method can become useful if the user wants to insert or append data to + /// the raw data, and the previous allocated buffer is too small, so the user wants to allocate a larger buffer + /// and get RawPacket instance to point to it + /// @param[in] newBufferLength The new buffer length as required by the user. The method is responsible to + /// allocate the memory + /// @return True if data was reallocated successfully, false otherwise virtual bool reallocateData(size_t newBufferLength); }; diff --git a/Packet++/header/S7CommLayer.h b/Packet++/header/S7CommLayer.h index 7afac7d51b..6a65e7913b 100644 --- a/Packet++/header/S7CommLayer.h +++ b/Packet++/header/S7CommLayer.h @@ -3,50 +3,46 @@ #include "EthLayer.h" #include "Layer.h" +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { -/** - * @struct s7commhdr - * Represents a S7COMM protocol header - */ + /// @struct s7commhdr + /// Represents a S7COMM protocol header #pragma pack(push, 1) typedef struct { - /** protocol id */ + /// protocol id uint8_t protocolId; - /** message type */ + /// message type uint8_t msgType; - /** redundancy identification (reserved) */ + /// redundancy identification (reserved) uint16_t reserved; - /** protocol data unit reference */ + /// protocol data unit reference uint16_t pduRef; - /** parameter length */ + /// parameter length uint16_t paramLength; - /** data length */ + /// data length uint16_t dataLength; } s7commhdr; #pragma pack(pop) static_assert(sizeof(s7commhdr) == 10, "s7commhdr size is not 10 bytes"); -/** - * @struct s7comm_ack_data_hdr - * Represents a S7COMM protocol header with Ack-Data header - */ + /// @struct s7comm_ack_data_hdr + /// Represents a S7COMM protocol header with Ack-Data header #pragma pack(push, 1) struct s7comm_ack_data_hdr : s7commhdr { - /** error class */ + /// error class uint8_t errorClass; - /** error code */ + /// error code uint8_t errorCode; }; #pragma pack(pop) static_assert(sizeof(s7comm_ack_data_hdr) == 12, "s7comm_ack_data_hdr size is not 12 bytes"); - /** - * @class S7CommParameter - * Represents a S7COMM (S7 Communication) protocol Parameter - */ + /// @class S7CommParameter + /// Represents a S7COMM (S7 Communication) protocol Parameter class S7CommParameter { friend class S7CommLayer; @@ -57,16 +53,12 @@ namespace pcpp virtual ~S7CommParameter() = default; - /** - * @return The data of the Parameter - */ + /// @return The data of the Parameter uint8_t* getData() const { return m_Data; } - /** - * @return The length of the Parameter data - */ + /// @return The length of the Parameter data size_t getDataLength() const { return m_DataLen; @@ -78,32 +70,26 @@ namespace pcpp uint8_t* m_Data; size_t m_DataLen; }; - /** - * @class S7CommLayer - * Represents a S7COMM (S7 Communication) protocol - */ + /// @class S7CommLayer + /// Represents a S7COMM (S7 Communication) protocol class S7CommLayer : public Layer { public: - /** - * A constructor that allocates a new S7comm header - * @param[in] msgType The general type of the message - * @param[in] pduRef Link responses to their requests - * @param[in] paramLength The length of the parameter field - * @param[in] dataLength The length of the data field - * @param[in] errorClass The value of the error class - * @param[in] errorCode The value of the error code - */ + /// A constructor that allocates a new S7comm header + /// @param[in] msgType The general type of the message + /// @param[in] pduRef Link responses to their requests + /// @param[in] paramLength The length of the parameter field + /// @param[in] dataLength The length of the data field + /// @param[in] errorClass The value of the error class + /// @param[in] errorCode The value of the error code S7CommLayer(uint8_t msgType, uint16_t pduRef, uint16_t paramLength, uint16_t dataLength, uint8_t errorClass = 0, uint8_t errorCode = 0); - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to @ref s7commhdr) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to @ref s7commhdr) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in S7CommLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, S7COMM) { @@ -116,95 +102,63 @@ namespace pcpp delete m_Parameter; } - /** - * @return S7comm protocol id - */ + /// @return S7comm protocol id uint8_t getProtocolId() const; - /** - * @return S7comm message type - */ + /// @return S7comm message type uint8_t getMsgType() const; - /** - * @return S7comm PDU ref - */ + /// @return S7comm PDU ref uint16_t getPduRef() const; - /** - * @return S7comm parameter length - */ + /// @return S7comm parameter length uint16_t getParamLength() const; - /** - * @return S7comm data length - */ + /// @return S7comm data length uint16_t getDataLength() const; - /** - * @return S7comm error code - */ + /// @return S7comm error code uint8_t getErrorCode() const; - /** - * @return S7comm error class - */ + /// @return S7comm error class uint8_t getErrorClass() const; - /** - * @return S7comm parameter - */ + /// @return S7comm parameter const S7CommParameter* getParameter(); - /** - * Set the value of the message type - * @param[in] msgType The value of the message type - */ + /// Set the value of the message type + /// @param[in] msgType The value of the message type void setMsgType(uint8_t msgType) const; - /** - * Set the value of the PDU ref - * @param[in] pduRef The value of the PDU ref - */ + /// Set the value of the PDU ref + /// @param[in] pduRef The value of the PDU ref void setPduRef(uint16_t pduRef) const; - /** - * Set the value of the error code - * @param[in] errorCode The value of the error code - */ + /// Set the value of the error code + /// @param[in] errorCode The value of the error code void setErrorCode(uint8_t errorCode) const; - /** - * Set the value of the error class - * @param[in] errorClass The value of the error class - */ + /// Set the value of the error class + /// @param[in] errorClass The value of the error class void setErrorClass(uint8_t errorClass) const; - /** - * @return Size of S7CommLayer - */ + /// @return Size of S7CommLayer size_t getHeaderLen() const override { return m_DataLen; } - /** - * Does nothing for this layer (S7CommLayer is always last) - */ + /// Does nothing for this layer (S7CommLayer is always last) void computeCalculateFields() override {} - /** - * Does nothing for this layer (S7CommLayer is always last) - */ + /// Does nothing for this layer (S7CommLayer is always last) void parseNextLayer() override {} - /** - * A static method that takes a byte array and detects whether it is a S7COMM - * @param[in] data A byte array - * @param[in] dataSize The byte array size (in bytes) - * @return True if the data looks like a valid S7COMM layer - */ + /// A static method that takes a byte array and detects whether it is a S7COMM + /// @param[in] data A byte array + /// @param[in] dataSize The byte array size (in bytes) + /// @return True if the data looks like a valid S7COMM layer static bool isDataValid(const uint8_t* data, size_t dataSize); std::string toString() const override; diff --git a/Packet++/header/SSHLayer.h b/Packet++/header/SSHLayer.h index 84a03f2430..ef07f14d5f 100644 --- a/Packet++/header/SSHLayer.h +++ b/Packet++/header/SSHLayer.h @@ -2,97 +2,93 @@ #include "Layer.h" -/** - * @file - * This file introduces classes and structures that represent the SSH (Secure Shell) protocol. - * - * An overview of this protocol can be found here: https://en.wikipedia.org/wiki/Ssh_(Secure_Shell) - * - * For more details please refer to RFC 4253: https://tools.ietf.org/html/rfc4253 - * - * These current implementation supports parsing of SSH packets when possible (meaning when they are not encrypted). - * Creation and editing of SSH packets is currently __not supported__. - * - * SSH typically uses TCP port 22 so PcapPlusPlus assumes all traffic on this port is SSH traffic. - * PcapPlusPlus uses some heuristics to determine the type of the SSH message (which will be covered later). - * If it doesn't find a match to one of the other SSH messages, it assumes it is an encrypted SSH message. - * - * Following is an overview of the SSH protocol classes currently supported in PcapPlusPlus. They cover the different - * messages of the SSH protocol: - * - @verbatim - - +----------------------------+ SSH version identification - +---| SSHIdentificationMessage | ===> as described here: - | +----------------------------+ https://tools.ietf.org/html/rfc4253#section-4.2 - | - +------------+ | +----------------------------+ SSH handshake message - | SSHLayer |---------+---| SSHHandshakeMessage | ===> which is typically one of the messages described here: - | (abstract) | | +----------------------------+ https://tools.ietf.org/html/rfc4253#section-12 - +------------+ | | - | | +----------------------------+ - | +-----| SSHKeyExchangeInitMessage | ===> SSH Key Exchange message - | +----------------------------+ as described here: - | https://tools.ietf.org/html/rfc4253#section-7 - | - | +----------------------------+ - +---| SSHEncryptedMessage | ===> An encrypted SSH message - +----------------------------+ - - @endverbatim - - * The following points describe the heuristics for deciding the message type for each packet: - * 1. If the data starts with the characters "SSH-" and ends with "\n" (or "\r\n") it's assumed the message is of type - * pcpp#SSHIdentificationMessage - * 2. Try to determine if this is a non-encrypted SSH handshake message: - * - Look at the first 4 bytes of the data which may contain the packet length and see if the value is smaller of - * equal than the entire layer length. - * - The next byte contains the padding length, check if it's smaller or equal than the packet length - * - The next byte contains the message type, check if the value is a valid message type as described in: - * - * - * If all of these condition are met, this message is either pcpp#SSHKeyExchangeInitMessage (if message type is - * pcpp#SSHHandshakeMessage#SSH_MSG_KEX_INIT) or pcpp#SSHHandshakeMessage (for all other message types) - * 3. If non of these conditions are met, it is assumed this is an encrypted message (pcpp#SSHEncryptedMessage) - */ - -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @file +/// This file introduces classes and structures that represent the SSH (Secure Shell) protocol. +/// +/// An overview of this protocol can be found here: https://en.wikipedia.org/wiki/Ssh_(Secure_Shell) +/// +/// For more details please refer to RFC 4253: https://tools.ietf.org/html/rfc4253 +/// +/// These current implementation supports parsing of SSH packets when possible (meaning when they are not encrypted). +/// Creation and editing of SSH packets is currently __not supported__. +/// +/// SSH typically uses TCP port 22 so PcapPlusPlus assumes all traffic on this port is SSH traffic. +/// PcapPlusPlus uses some heuristics to determine the type of the SSH message (which will be covered later). +/// If it doesn't find a match to one of the other SSH messages, it assumes it is an encrypted SSH message. +/// +/// Following is an overview of the SSH protocol classes currently supported in PcapPlusPlus. They cover the different +/// messages of the SSH protocol: +/// +/// @code{.unparsed} +/// +----------------------------+ SSH version identification +/// +---| SSHIdentificationMessage | ===> as described here: +/// | +----------------------------+ https://tools.ietf.org/html/rfc4253#section-4.2 +/// | +/// +------------+ | +----------------------------+ SSH handshake message +/// | SSHLayer |------+---| SSHHandshakeMessage | ===> which is typically one of the messages described here: +/// | (abstract) | | +----------------------------+ https://tools.ietf.org/html/rfc4253#section-12 +/// +------------+ | | +/// | | +----------------------------+ +/// | +-----| SSHKeyExchangeInitMessage | ===> SSH Key Exchange message +/// | +----------------------------+ as described here: +/// | https://tools.ietf.org/html/rfc4253#section-7 +/// | +/// | +----------------------------+ +/// +---| SSHEncryptedMessage | ===> An encrypted SSH message +/// +----------------------------+ +/// +/// @endcode +/// The following points describe the heuristics for deciding the +/// message type for each packet: +/// 1. If the data starts with the characters "SSH-" and ends with +/// "\n" (or "\r\n") it's assumed the message is of type +/// pcpp#SSHIdentificationMessage +/// 2. Try to determine if this is a non-encrypted SSH handshake +/// message: +/// - Look at the first 4 bytes of the data which may contain +/// the packet length and see if the value is smaller of +/// equal than the entire layer length. +/// - The next byte contains the padding length, check if it's +/// smaller or equal than the packet length +/// - The next byte contains the message type, check if the +/// value is a valid message type as described in: +/// +/// +/// If all of these condition are met, this message is either +/// pcpp#SSHKeyExchangeInitMessage (if message type is +/// pcpp#SSHHandshakeMessage#SSH_MSG_KEX_INIT) or +/// pcpp#SSHHandshakeMessage (for all other message types) +/// 3. If non of these conditions are met, it is assumed this is an +/// encrypted message (pcpp#SSHEncryptedMessage) + +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @class SSHLayer - * This is the base class for the SSH layer. It is an abstract class that cannot be instantiated. - * It holds some common functionality, but its most important method is createSSHMessage() - * which takes raw data and creates an SSH message according to the heuristics described - * in the SSHLayer.h file description - */ + /// @class SSHLayer + /// This is the base class for the SSH layer. It is an abstract class that cannot be instantiated. + /// It holds some common functionality, but its most important method is createSSHMessage() + /// which takes raw data and creates an SSH message according to the heuristics described + /// in the SSHLayer.h file description class SSHLayer : public Layer { public: - /** - * A static method that takes raw packet data and uses the heuristics described in the - * SSHLayer.h file description to create an SSH layer instance. This method assumes the data is - * indeed SSH data and not some other arbitrary data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - * @return An instance of one of the classes that inherit SSHLayer as described in the - * SSHLayer.h file description - */ + /// A static method that takes raw packet data and uses the heuristics described in the + /// SSHLayer.h file description to create an SSH layer instance. This method assumes the data is + /// indeed SSH data and not some other arbitrary data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in + /// @return An instance of one of the classes that inherit SSHLayer as described in the + /// SSHLayer.h file description static SSHLayer* createSSHMessage(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * A static method that takes src and dst ports and determines whether it's SSH traffic or not. - * @param[in] portSrc The source TCP port to examine - * @param[in] portDst The dest TCP port to examine - * @return Currently the implementation is very simple and returns "true" if either src or dst ports - * are equal to 22, "false" otherwise - */ + /// A static method that takes src and dst ports and determines whether it's SSH traffic or not. + /// @param[in] portSrc The source TCP port to examine + /// @param[in] portDst The dest TCP port to examine + /// @return Currently the implementation is very simple and returns "true" if either src or dst ports + /// are equal to 22, "false" otherwise static bool isSSHPort(uint16_t portSrc, uint16_t portDst) { return portSrc == 22 || portDst == 22; @@ -100,15 +96,11 @@ namespace pcpp // implement abstract methods - /** - * Several SSH records can reside in a single packets. This method examins the remaining data and creates - * additional SSH records if applicable - */ + /// Several SSH records can reside in a single packets. This method examins the remaining data and creates + /// additional SSH records if applicable void parseNextLayer() override; - /** - * Does nothing for this layer - */ + /// Does nothing for this layer void computeCalculateFields() override {} @@ -128,39 +120,31 @@ namespace pcpp SSHLayer(); }; - /** - * @class SSHIdentificationMessage - * A class that represents SSH identification message as described in RFC 4253: - * - * - * The message content is typically a string that contains the protocol version, software version and a few more - * details. This string can be retrieved using the getIdentificationMessage() method - */ + /// @class SSHIdentificationMessage + /// A class that represents SSH identification message as described in RFC 4253: + /// + /// + /// The message content is typically a string that contains the protocol version, software version and a few more + /// details. This string can be retrieved using the getIdentificationMessage() method class SSHIdentificationMessage : public SSHLayer { public: - /** - * @return The SSH identification message which is typically the content of this message - */ + /// @return The SSH identification message which is typically the content of this message std::string getIdentificationMessage(); - /** - * A static method that takes raw data and tries to parse it as an SSH identification message using the - * heuristics described in the SSHLayer.h file description. It returns a SSHIdentificationMessage instance if - * such a message can be identified or nullptr otherwise. - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - * @return An instance of SSHIdentificationMessage or nullptr if this is not an identification message - */ + /// A static method that takes raw data and tries to parse it as an SSH identification message using the + /// heuristics described in the SSHLayer.h file description. It returns a SSHIdentificationMessage instance if + /// such a message can be identified or nullptr otherwise. + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in + /// @return An instance of SSHIdentificationMessage or nullptr if this is not an identification message static SSHIdentificationMessage* tryParse(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); // implement abstract methods - /** - * @return The size of the identification message - */ + /// @return The size of the identification message size_t getHeaderLen() const override { return m_DataLen; @@ -178,108 +162,88 @@ namespace pcpp {} }; - /** - * @class SSHHandshakeMessage - * A class representing all of the non-encrypted SSH handshake messages. - * An handshake message typically has the following structure: - * - @verbatim - 0 1 2 3 4 5 6 - +---------+---------+---------+---------+---------+---------+----------- ---------+ - | Packet Length | Padding | Message | Message .... Padding | - | | Length | Type | Content .... | - +---------------------------------------+---------+---------+----------- ---------+ - @endverbatim - * - * The first 4 bytes hold the packet length, followed by 1 byte that holds the padding length (which comes at the - * end of the message), then 1 byte that holds the message type (which can be of type - * SSHHandshakeMessage#SSHHandshakeMessageType) and then the message content. At the end of the content there is - * typically padding. - * - * This class provides access to all of these values. The message content itself is not parse with the exception of - * SSHKeyExchangeInitMessage - * which inherits from this class and provides parsing of the Key Exchange Init message. - */ + /// @class SSHHandshakeMessage + /// A class representing all of the non-encrypted SSH handshake messages. + /// An handshake message typically has the following structure: + /// + /// @code{.unparsed} + /// 0 1 2 3 4 5 6 + /// +---------+---------+---------+---------+---------+---------+----------- ---------+ + /// | Packet Length | Padding | Message | Message .... Padding | + /// | | Length | Type | Content .... | + /// +---------------------------------------+---------+---------+----------- ---------+ + /// @endcode + /// + /// The first 4 bytes hold the packet length, followed by 1 byte that holds the padding length (which comes at the + /// end of the message), then 1 byte that holds the message type (which can be of type + /// SSHHandshakeMessage#SSHHandshakeMessageType) and then the message content. At the end of the content there is + /// typically padding. + /// + /// This class provides access to all of these values. The message content itself is not parse with the exception of + /// SSHKeyExchangeInitMessage + /// which inherits from this class and provides parsing of the Key Exchange Init message. class SSHHandshakeMessage : public SSHLayer { public: - /** - * An enum that represents SSH non-encrypted message types - */ + /// An enum that represents SSH non-encrypted message types enum SSHHandshakeMessageType { - /** Key Exchange Init message */ + /// Key Exchange Init message SSH_MSG_KEX_INIT = 20, - /** New Keys message */ + /// New Keys message SSH_MSG_NEW_KEYS = 21, - /** Diffie-Hellman Key Exchange Init message */ + /// Diffie-Hellman Key Exchange Init message SSH_MSG_KEX_DH_INIT = 30, - /** message */ + /// message SSH_MSG_KEX_DH_REPLY = 31, - /** Diffie-Hellman Group Exchange Init message */ + /// Diffie-Hellman Group Exchange Init message SSH_MSG_KEX_DH_GEX_INIT = 32, - /** "Diffie-Hellman Group Exchange Reply message */ + /// "Diffie-Hellman Group Exchange Reply message SSH_MSG_KEX_DH_GEX_REPLY = 33, - /** Diffie-Hellman Group Exchange Request message */ + /// Diffie-Hellman Group Exchange Request message SSH_MSG_KEX_DH_GEX_REQUEST = 34, - /** Unknown message */ + /// Unknown message SSH_MSG_UNKNOWN = 999 }; - /** - * @return The message type - */ + /// @return The message type SSHHandshakeMessageType getMessageType() const; - /** - * @return A string representation of the message type - */ + /// @return A string representation of the message type std::string getMessageTypeStr() const; - /** - * @return A raw byte stream of the message content - */ + /// @return A raw byte stream of the message content uint8_t* getSSHHandshakeMessage() const; - /** - * @return The message content length in [bytes] which is calculated by the overall packet length - * minus the message header (which includes packet length, padding length and message type) and - * minus the padding bytes - */ + /// @return The message content length in [bytes] which is calculated by the overall packet length + /// minus the message header (which includes packet length, padding length and message type) and + /// minus the padding bytes size_t getSSHHandshakeMessageLength() const; - /** - * @return The padding length in [bytes] - */ + /// @return The padding length in [bytes] size_t getPaddingLength() const; - /** - * A static method that takes raw packet data and uses some heuristics described in the - * SSHLayer.h file description to parse it as SSH handshake message instance - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - * @return Upon successful parsing the return value would be an instance of SSHKeyExchangeInitMessage - * for Key Exchange Init message or SSHHandshakeMessage for any other message type. If parsing fails nullptr - * will be returned - */ + /// A static method that takes raw packet data and uses some heuristics described in the + /// SSHLayer.h file description to parse it as SSH handshake message instance + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in + /// @return Upon successful parsing the return value would be an instance of SSHKeyExchangeInitMessage + /// for Key Exchange Init message or SSHHandshakeMessage for any other message type. If parsing fails nullptr + /// will be returned static SSHHandshakeMessage* tryParse(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); // implement abstract methods - /** - * @return The size of the SSH handshake message including the padding and message header - */ + /// @return The size of the SSH handshake message including the padding and message header size_t getHeaderLen() const override; std::string toString() const override; protected: #pragma pack(push, 1) - /** - * An internal struct representing the SSH handshake message header - */ + /// An internal struct representing the SSH handshake message header struct ssh_message_base { uint32_t packetLength; @@ -303,136 +267,107 @@ namespace pcpp } }; - /** - * @class SSHKeyExchangeInitMessage - * A class representing the SSH Key Exchange Init message. This is a non-encrypted message that contains information - * about the algorithms used for key exchange, encryption, MAC and compression. This class provides methods to - * access these details - */ + /// @class SSHKeyExchangeInitMessage + /// A class representing the SSH Key Exchange Init message. This is a non-encrypted message that contains + /// information about the algorithms used for key exchange, encryption, MAC and compression. This class provides + /// methods to access these details class SSHKeyExchangeInitMessage : public SSHHandshakeMessage { public: - /** - * A c'tor for this class that accepts raw message data. Please avoid using it as it's used internally - * when parsing SSH handshake messages in SSHHandshakeMessage#tryParse() - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A c'tor for this class that accepts raw message data. Please avoid using it as it's used internally + /// when parsing SSH handshake messages in SSHHandshakeMessage#tryParse() + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in SSHKeyExchangeInitMessage(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * Each SSH Key Exchange Init message contains a random 16-byte value generated by the sender. - * This method returns a pointer to this 16-byte cookie. To get the value as a hex string - * please refer to getCookieAsHexStream() - * @return A pointer to the 16-byte cookie value or nullptr if the message is malformed - */ + /// Each SSH Key Exchange Init message contains a random 16-byte value generated by the sender. + /// This method returns a pointer to this 16-byte cookie. To get the value as a hex string + /// please refer to getCookieAsHexStream() + /// @return A pointer to the 16-byte cookie value or nullptr if the message is malformed uint8_t* getCookie(); - /** - * Each SSH Key Exchange Init message contains a random 16-byte value generated by the sender. - * This method returns the 16-byte cookie as a hex stream. To get the raw data please refer to - * getCookie() - * @return A hex stream of the 16-byte cookie value or an empty string if the message is malformed - */ + /// Each SSH Key Exchange Init message contains a random 16-byte value generated by the sender. + /// This method returns the 16-byte cookie as a hex stream. To get the raw data please refer to + /// getCookie() + /// @return A hex stream of the 16-byte cookie value or an empty string if the message is malformed std::string getCookieAsHexStream(); - /** - * @return A comma-separated list of the key exchange algorithms used in this session. - * Can be empty if the value is missing or the message is malformed - */ + /// @return A comma-separated list of the key exchange algorithms used in this session. + /// Can be empty if the value is missing or the message is malformed std::string getKeyExchangeAlgorithms() { return getFieldValue(0); } - /** - * @return A comma-separated list of the algorithms supported for the server host key. - * Can be empty if the value is missing or the message is malformed - */ + /// @return A comma-separated list of the algorithms supported for the server host key. + /// Can be empty if the value is missing or the message is malformed std::string getServerHostKeyAlgorithms() { return getFieldValue(1); } - /** - * @return A comma-separated list of acceptable symmetric encryption algorithms (also known as ciphers) - * from the client to the server. Can be empty if the value is missing or the message is malformed - */ + /// @return A comma-separated list of acceptable symmetric encryption algorithms (also known as ciphers) + /// from the client to the server. Can be empty if the value is missing or the message is malformed std::string getEncryptionAlgorithmsClientToServer() { return getFieldValue(2); } - /** - * @return A comma-separated list of acceptable symmetric encryption algorithms (also known as ciphers) - * from the server to the client. Can be empty if the value is missing or the message is malformed - */ + /// @return A comma-separated list of acceptable symmetric encryption algorithms (also known as ciphers) + /// from the server to the client. Can be empty if the value is missing or the message is malformed std::string getEncryptionAlgorithmsServerToClient() { return getFieldValue(3); } - /** - * @return A comma-separated list of acceptable MAC algorithms from the client to the server. - * Can be empty if the value is missing or the message is malformed - */ + /// @return A comma-separated list of acceptable MAC algorithms from the client to the server. + /// Can be empty if the value is missing or the message is malformed std::string getMacAlgorithmsClientToServer() { return getFieldValue(4); } - /** - * @return A comma-separated list of acceptable MAC algorithms from the server to the client. - * Can be empty if the value is missing or the message is malformed - */ + /// @return A comma-separated list of acceptable MAC algorithms from the server to the client. + /// Can be empty if the value is missing or the message is malformed std::string getMacAlgorithmsServerToClient() { return getFieldValue(5); } - /** - * @return A comma-separated list of acceptable compression algorithms from the client to the server. - * Can be empty if the value is missing or the message is malformed - */ + /// @return A comma-separated list of acceptable compression algorithms from the client to the server. + /// Can be empty if the value is missing or the message is malformed std::string getCompressionAlgorithmsClientToServer() { return getFieldValue(6); } - /** - * @return A comma-separated list of acceptable compression algorithms from the server to the client. - * Can be empty if the value is missing or the message is malformed - */ + /// @return A comma-separated list of acceptable compression algorithms from the server to the client. + /// Can be empty if the value is missing or the message is malformed std::string getCompressionAlgorithmsServerToClient() { return getFieldValue(7); } - /** - * @return A comma-separated list of language tags from the client to the server. - * Can be empty if the value is missing or the message is malformed - */ + /// @return A comma-separated list of language tags from the client to the server. + /// Can be empty if the value is missing or the message is malformed std::string getLanguagesClientToServer() { return getFieldValue(8); } - /** - * @return A comma-separated list of language tags from the server to the client. - * Can be empty if the value is missing or the message is malformed - */ + /// @return A comma-separated list of language tags from the server to the client. + /// Can be empty if the value is missing or the message is malformed + std::string getLanguagesServerToClient() { return getFieldValue(9); } - /** - * @return Indicates whether a guessed key exchange packet follows. If a - * guessed packet will be sent, the return value is true. If no guessed - * packet will be sent or if this value is missing, the return value is false. - */ + /// @return Indicates whether a guessed key exchange packet follows. If a + /// guessed packet will be sent, the return value is true. If no guessed + /// packet will be sent or if this value is missing, the return value is false. bool isFirstKexPacketFollows(); private: @@ -444,31 +379,25 @@ namespace pcpp std::string getFieldValue(int fieldOffsetIndex); }; - /** - * @class SSHEncryptedMessage - * A class representing an SSH encrypted message. In such messages there is very little information to extract from - * the packet, hence this class doesn't expose any methods or getters, other than the ones inherited from parent - * classes. - * - * It is assumed that any SSH message which does not fit to any of the other SSH message types, according to the - * heuristics described in the SSHLayer.h file description, is considered as an encrypted message. - */ + /// @class SSHEncryptedMessage + /// A class representing an SSH encrypted message. In such messages there is very little information to extract from + /// the packet, hence this class doesn't expose any methods or getters, other than the ones inherited from parent + /// classes. + /// + /// It is assumed that any SSH message which does not fit to any of the other SSH message types, according to the + /// heuristics described in the SSHLayer.h file description, is considered as an encrypted message. class SSHEncryptedMessage : public SSHLayer { public: - /** - * A c'tor for this class that accepts raw message data. Please avoid using it as it's used internally - * when parsing SSH messages in SSHLayer#createSSHMessage() - */ + /// A c'tor for this class that accepts raw message data. Please avoid using it as it's used internally + /// when parsing SSH messages in SSHLayer#createSSHMessage() SSHEncryptedMessage(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : SSHLayer(data, dataLen, prevLayer, packet) {} // implement abstract methods - /** - * @return The size of the message which is equal to the size of the layer - */ + /// @return The size of the message which is equal to the size of the layer size_t getHeaderLen() const override { return m_DataLen; diff --git a/Packet++/header/SSLCommon.h b/Packet++/header/SSLCommon.h index bf5ef916a8..4a54d1506e 100644 --- a/Packet++/header/SSLCommon.h +++ b/Packet++/header/SSLCommon.h @@ -3,208 +3,179 @@ #include #include -/** - * @file - * See detailed explanation of the TLS/SSL protocol support in PcapPlusPlus in SSLLayer.h - */ +/// @file +/// See detailed explanation of the TLS/SSL protocol support in PcapPlusPlus in SSLLayer.h -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct ssl_tls_record_layer - * The common part of all SSL/TLS messages - */ + /// @struct ssl_tls_record_layer + /// The common part of all SSL/TLS messages #pragma pack(push, 1) struct ssl_tls_record_layer { - /** Message (record) type (one of ::SSLRecordType) */ + /// Message (record) type (one of ::SSLRecordType) uint8_t recordType; - /** Message (record) version (one of SSLVersion::SSLVersionEnum) */ + /// Message (record) version (one of SSLVersion::SSLVersionEnum) uint16_t recordVersion; - /** Message (record) length in bytes */ + /// Message (record) length in bytes uint16_t length; }; #pragma pack(pop) static_assert(sizeof(ssl_tls_record_layer) == 5, "ssl_tls_record_layer size is not 5 bytes"); - /** - * @struct ssl_tls_handshake_layer - * The common part of all SSL/TLS handshake message types - */ + /// @struct ssl_tls_handshake_layer + /// The common part of all SSL/TLS handshake message types #pragma pack(push, 1) struct ssl_tls_handshake_layer { - /** Type of the handshake message (one of ::SSLHandshakeType) */ + /// Type of the handshake message (one of ::SSLHandshakeType) uint8_t handshakeType; - /** Length of the message. Length is 3-Byte long, This is the MSB byte */ + /// Length of the message. Length is 3-Byte long, This is the MSB byte uint8_t length1; - /** Length of the message. Length is 3-Byte long, This is the 2 LSB bytes */ + /// Length of the message. Length is 3-Byte long, This is the 2 LSB bytes uint16_t length2; }; #pragma pack(pop) static_assert(sizeof(ssl_tls_handshake_layer) == 4, "ssl_tls_handshake_layer size is not 4 bytes"); - /** - * @struct ssl_tls_client_server_hello - * The common header part of client-hello and server-hello handshake messages - */ + /// @struct ssl_tls_client_server_hello + /// The common header part of client-hello and server-hello handshake messages #pragma pack(push, 1) struct ssl_tls_client_server_hello : ssl_tls_handshake_layer { - /** SSL/TLS handshake version (one of SSLVersion::SSLVersionEnum) */ + /// SSL/TLS handshake version (one of SSLVersion::SSLVersionEnum) uint16_t handshakeVersion; - /** 32-bytes random number */ + /// 32-bytes random number uint8_t random[32]; }; #pragma pack(pop) static_assert(sizeof(ssl_tls_client_server_hello) == 38, "ssl_tls_client_server_hello size is not 38 bytes"); - /** - * @struct ssl_tls_change_cipher_spec - * SSL/TLS change-cipher-spec message structure - */ + /// @struct ssl_tls_change_cipher_spec + /// SSL/TLS change-cipher-spec message structure #pragma pack(push, 1) struct ssl_tls_change_cipher_spec { - /** Unused byte */ + /// Unused byte uint8_t changeCipherSpec; }; #pragma pack(pop) static_assert(sizeof(ssl_tls_change_cipher_spec) == 1, "ssl_tls_change_cipher_spec size is not 1 byte"); - /** - * @struct ssl_tls_alert - * SSL/TLS alert message structure - */ + /// @struct ssl_tls_alert + /// SSL/TLS alert message structure #pragma pack(push, 1) struct ssl_tls_alert { - /** Alert level (one of ::SSLAlertLevel) */ + /// Alert level (one of ::SSLAlertLevel) uint8_t alertLevel; - /** Alert description (one of ::SSLAlertDescription) */ + /// Alert description (one of ::SSLAlertDescription) uint8_t alertDescription; }; #pragma pack(pop) static_assert(sizeof(ssl_tls_alert) == 2, "ssl_tls_alert size is not 2 bytes"); - /** - * SSL/TLS message types - */ + /// SSL/TLS message types enum SSLRecordType { - /** Change-cipher-spec message */ + /// Change-cipher-spec message SSL_CHANGE_CIPHER_SPEC = 20, - /** SSL alert message */ + /// SSL alert message SSL_ALERT = 21, - /** SSL handshake message */ + /// SSL handshake message SSL_HANDSHAKE = 22, - /** SSL data message */ + /// SSL data message SSL_APPLICATION_DATA = 23 }; - /** - * @class SSLVersion - * A wrapper class for SSL/TLS versions. The SSL/TLS version is typically represented by a 2-byte number, - * for example TLS 1.2 is represented by 0x0303. - * This class wraps the numeric value and provides methods to convert it into an enum, string, etc. - */ + /// @class SSLVersion + /// A wrapper class for SSL/TLS versions. The SSL/TLS version is typically represented by a 2-byte number, + /// for example TLS 1.2 is represented by 0x0303. + /// This class wraps the numeric value and provides methods to convert it into an enum, string, etc. class SSLVersion { public: - /** - * SSL/TLS versions enum - */ + /// SSL/TLS versions enum enum SSLVersionEnum { - /** SSL 2.0 */ + /// SSL 2.0 SSL2 = 0x0200, - /** SSL 3.0 */ + /// SSL 3.0 SSL3 = 0x0300, - /** TLS 1.0 */ + /// TLS 1.0 TLS1_0 = 0x0301, - /** TLS 1.1 */ + /// TLS 1.1 TLS1_1 = 0x0302, - /** TLS 1.2 */ + /// TLS 1.2 TLS1_2 = 0x0303, - /** TLS 1.3 */ + /// TLS 1.3 TLS1_3 = 0x0304, - /** TLS 1.3 (draft 14) */ + /// TLS 1.3 (draft 14) TLS1_3_D14 = 0x7f0e, - /** TLS 1.3 (draft 15) */ + /// TLS 1.3 (draft 15) TLS1_3_D15 = 0x7f0f, - /** TLS 1.3 (draft 16) */ + /// TLS 1.3 (draft 16) TLS1_3_D16 = 0x7f10, - /** TLS 1.3 (draft 17) */ + /// TLS 1.3 (draft 17) TLS1_3_D17 = 0x7f11, - /** TLS 1.3 (draft 18) */ + /// TLS 1.3 (draft 18) TLS1_3_D18 = 0x7f12, - /** TLS 1.3 (draft 19) */ + /// TLS 1.3 (draft 19) TLS1_3_D19 = 0x7f13, - /** TLS 1.3 (draft 20) */ + /// TLS 1.3 (draft 20) TLS1_3_D20 = 0x7f14, - /** TLS 1.3 (draft 21) */ + /// TLS 1.3 (draft 21) TLS1_3_D21 = 0x7f15, - /** TLS 1.3 (draft 22) */ + /// TLS 1.3 (draft 22) TLS1_3_D22 = 0x7f16, - /** TLS 1.3 (draft 23) */ + /// TLS 1.3 (draft 23) TLS1_3_D23 = 0x7f17, - /** TLS 1.3 (draft 24) */ + /// TLS 1.3 (draft 24) TLS1_3_D24 = 0x7f18, - /** TLS 1.3 (draft 25) */ + /// TLS 1.3 (draft 25) TLS1_3_D25 = 0x7f19, - /** TLS 1.3 (draft 26) */ + /// TLS 1.3 (draft 26) TLS1_3_D26 = 0x7f1a, - /** TLS 1.3 (draft 27) */ + /// TLS 1.3 (draft 27) TLS1_3_D27 = 0x7f1b, - /** TLS 1.3 (draft 28) */ + /// TLS 1.3 (draft 28) TLS1_3_D28 = 0x7f1c, - /** TLS 1.3 (Facebook draft 23) */ + /// TLS 1.3 (Facebook draft 23) TLS1_3_FBD23 = 0xfb17, - /** TLS 1.3 (Facebook draft 26) */ + /// TLS 1.3 (Facebook draft 26) TLS1_3_FBD26 = 0xfb1a, - /** Unknown value */ + /// Unknown value Unknown = 0 }; - /** - * A c'tor for this class. - * @param[in] sslVersionValue The numeric value representing this SSL/TLS version. For example: - * for TLS 1.2 this would be 0x0303. - */ + /// A c'tor for this class. + /// @param[in] sslVersionValue The numeric value representing this SSL/TLS version. For example: + /// for TLS 1.2 this would be 0x0303. explicit SSLVersion(uint16_t sslVersionValue) { m_SSLVersionValue = sslVersionValue; } - /** - * @return An enum value of type SSLVersion::SSLVersionEnum representing the SSL/TLS version. - * If the numeric value is an invalid SSL/TLS version SSLVersion::Unknown will be returned. - * @param[in] countTlsDraftsAs1_3 A flag indicating whether to return the enum value SSLVersion::TLS1_3 for all - * TLS 1.3 drafts. If set to "true" all TLS 1.3 draft values (i.e 0x7f0e - 0x7f1c, 0xfb17, 0xfb1a) will return - * SSLVersion::TLS1_3, otherwise the corresponding enum values will be returned. The default value is "false". - */ + /// @return An enum value of type SSLVersion::SSLVersionEnum representing the SSL/TLS version. + /// If the numeric value is an invalid SSL/TLS version SSLVersion::Unknown will be returned. + /// @param[in] countTlsDraftsAs1_3 A flag indicating whether to return the enum value SSLVersion::TLS1_3 for all + /// TLS 1.3 drafts. If set to "true" all TLS 1.3 draft values (i.e 0x7f0e - 0x7f1c, 0xfb17, 0xfb1a) will return + /// SSLVersion::TLS1_3, otherwise the corresponding enum values will be returned. The default value is "false". SSLVersionEnum asEnum(bool countTlsDraftsAs1_3 = false); - /** - * @return The numeric value of the SSL/TLs version - */ + /// @return The numeric value of the SSL/TLs version uint16_t asUInt() { return m_SSLVersionValue; } - /** - * @return A string representation of the SSL/TLS version. For example: for TLS 1.2 the string "TLS 1.2" is - * returned. If the numeric value is an invalid SSL/TLS version the string "Unknown" will be returned. - * @param[in] countTlsDraftsAs1_3 A flag indicating whether to return the string value "TLS 1.3" for all TLS 1.3 - * drafts. If set to "true" all TLS 1.3 draft values (i.e 0x7f0e - 0x7f1c, 0xfb17, 0xfb1a) will return - * "TLS 1.3", otherwise the corresponding string values will be returned. The default value is "false". - */ + /// @return A string representation of the SSL/TLS version. For example: for TLS 1.2 the string "TLS 1.2" is + /// returned. If the numeric value is an invalid SSL/TLS version the string "Unknown" will be returned. + /// @param[in] countTlsDraftsAs1_3 A flag indicating whether to return the string value "TLS 1.3" for all + /// TLS 1.3 drafts. If set to "true" all TLS 1.3 draft values (i.e 0x7f0e - 0x7f1c, 0xfb17, 0xfb1a) will return + /// "TLS 1.3", otherwise the corresponding string values will be returned. The default value is "false". std::string toString(bool countTlsDraftsAs1_3 = false); private: @@ -214,401 +185,382 @@ namespace pcpp SSLVersion(); }; - /** - * SSL/TLS handshake message types - */ + /// SSL/TLS handshake message types enum SSLHandshakeType { - /** Hello-request message type */ + /// Hello-request message type SSL_HELLO_REQUEST = 0, - /** Client-hello message type */ + /// Client-hello message type SSL_CLIENT_HELLO = 1, - /** Server-hello message type */ + /// Server-hello message type SSL_SERVER_HELLO = 2, - /** New-session-ticket message type */ + /// New-session-ticket message type SSL_NEW_SESSION_TICKET = 4, - /** End-of-early-data message type (TLS 1.3) */ + /// End-of-early-data message type (TLS 1.3) SSL_END_OF_EARLY_DATE = 5, - /** Encrypted-extensions message type (TLS 1.3) */ + /// Encrypted-extensions message type (TLS 1.3) SSL_ENCRYPTED_EXTENSIONS = 8, - /** Certificate message type */ + /// Certificate message type SSL_CERTIFICATE = 11, - /** Server-key-exchange message type */ + /// Server-key-exchange message type SSL_SERVER_KEY_EXCHANGE = 12, - /** Certificate-request message type */ + /// Certificate-request message type SSL_CERTIFICATE_REQUEST = 13, - /** Server-hello-done message type */ + /// Server-hello-done message type SSL_SERVER_DONE = 14, - /** Certificate-verify message type */ + /// Certificate-verify message type SSL_CERTIFICATE_VERIFY = 15, - /** Client-key-exchange message type */ + /// Client-key-exchange message type SSL_CLIENT_KEY_EXCHANGE = 16, - /** Finish message type */ + /// Finish message type SSL_FINISHED = 20, - /** Key-update message type (TLS 1.3) */ + /// Key-update message type (TLS 1.3) SSL_KEY_UPDATE = 24, - /** Unknown SSL handshake message */ + /// Unknown SSL handshake message SSL_HANDSHAKE_UNKNOWN = 255 }; - /** - * SSL/TLS alert levels - */ + /// SSL/TLS alert levels enum SSLAlertLevel { - /** Warning level alert */ + /// Warning level alert SSL_ALERT_LEVEL_WARNING = 1, - /** Fatal level alert */ + /// Fatal level alert SSL_ALERT_LEVEL_FATAL = 2, - /** For encrypted alerts the level is unknown so this type will be returned */ + /// For encrypted alerts the level is unknown so this type will be returned SSL_ALERT_LEVEL_ENCRYPTED = 255 }; - /** - * SSL/TLS alert description types - */ + /// SSL/TLS alert description types enum SSLAlertDescription { - /** Close notify alert */ + /// Close notify alert SSL_ALERT_CLOSE_NOTIFY = 0, - /** Unexpected message alert */ + /// Unexpected message alert SSL_ALERT_UNEXPECTED_MESSAGE = 10, - /** Bad record MAC alert */ + /// Bad record MAC alert SSL_ALERT_BAD_RECORD_MAC = 20, - /** Decryption failed alert */ + /// Decryption failed alert SSL_ALERT_DECRYPTION_FAILED = 21, - /** */ + /// SSL_ALERT_RECORD_OVERFLOW = 22, - /** Decompression failure alert */ + /// Decompression failure alert SSL_ALERT_DECOMPRESSION_FAILURE = 30, - /** Handshake failure alert */ + /// Handshake failure alert SSL_ALERT_HANDSHAKE_FAILURE = 40, - /** No certificate alert */ + /// No certificate alert SSL_ALERT_NO_CERTIFICATE = 41, - /** Bad certificate alert */ + /// Bad certificate alert SSL_ALERT_BAD_CERTIFICATE = 42, - /** Unsupported certificate */ + /// Unsupported certificate SSL_ALERT_UNSUPPORTED_CERTIFICATE = 43, - /** Certificate revoked alert */ + /// Certificate revoked alert SSL_ALERT_CERTIFICATE_REVOKED = 44, - /** Certificate expired alert */ + /// Certificate expired alert SSL_ALERT_CERTIFICATE_EXPIRED = 45, - /** Certificate unknown alert */ + /// Certificate unknown alert SSL_ALERT_CERTIFICATE_UNKNOWN = 46, - /** Illegal parameter alert */ + /// Illegal parameter alert SSL_ALERT_ILLEGAL_PARAMETER = 47, - /** Unknown CA alert */ + /// Unknown CA alert SSL_ALERT_UNKNOWN_CA = 48, - /** Access denied alert */ + /// Access denied alert SSL_ALERT_ACCESS_DENIED = 49, - /** Decode error alert */ + /// Decode error alert SSL_ALERT_DECODE_ERROR = 50, - /** Decrypt error alert */ + /// Decrypt error alert SSL_ALERT_DECRYPT_ERROR = 51, - /** Export restriction alert */ + /// Export restriction alert SSL_ALERT_EXPORT_RESTRICTION = 60, - /** Protocol version alert */ + /// Protocol version alert SSL_ALERT_PROTOCOL_VERSION = 70, - /** Insufficient security alert */ + /// Insufficient security alert SSL_ALERT_INSUFFICIENT_SECURITY = 71, - /** Internal error alert */ + /// Internal error alert SSL_ALERT_INTERNAL_ERROR = 80, - /** User cancelled alert */ + /// User cancelled alert SSL_ALERT_USER_CANCELLED = 90, - /** No negotiation alert */ + /// No negotiation alert SSL_ALERT_NO_RENEGOTIATION = 100, - /** Unsupported extension alert */ + /// Unsupported extension alert SSL_ALERT_UNSUPPORTED_EXTENSION = 110, - /** Encrtpyed alert (cannot determine its type) */ + /// Encrtpyed alert (cannot determine its type) SSL_ALERT_ENCRYPTED = 255 }; - /** - * SSL/TLS key exchange algorithms - */ + /// SSL/TLS key exchange algorithms enum SSLKeyExchangeAlgorithm { - /** Null value */ + /// Null value SSL_KEYX_NULL, - /** RSA (Rivest-Shamir-Adleman) */ + /// RSA (Rivest-Shamir-Adleman) SSL_KEYX_RSA, - /** Diffie-Hellman */ + /// Diffie-Hellman SSL_KEYX_DH, - /** Diffie-Hellman ephemeral */ + /// Diffie-Hellman ephemeral SSL_KEYX_DHE, - /** Elliptic curve Diffie�Hellman */ + /// Elliptic curve Diffie�Hellman SSL_KEYX_ECDH, - /** Elliptic curve Diffie�Hellman ephemeral */ + /// Elliptic curve Diffie�Hellman ephemeral SSL_KEYX_ECDHE, - /** Fortezza Crypto Card */ + /// Fortezza Crypto Card SSL_KEYX_FORTEZZA, - /** Kerberos 5 */ + /// Kerberos 5 SSL_KEYX_KRB5, - /** Pre-Shared Key */ + /// Pre-Shared Key SSL_KEYX_PSK, - /** GOST */ + /// GOST SSL_KEYX_GOST, - /** Secure Remote Password */ + /// Secure Remote Password SSL_KEYX_SRP, - /** PCT */ + /// PCT SSL_KEYX_PCT, - /** Unknown algorithm */ + /// Unknown algorithm SSL_KEYX_Unknown }; - /** - * SSL/TLS authentication algorithms - */ + /// SSL/TLS authentication algorithms enum SSLAuthenticationAlgorithm { - /** Null value */ + /// Null value SSL_AUTH_NULL, - /** RSA (Rivest-Shamir-Adleman) */ + /// RSA (Rivest-Shamir-Adleman) SSL_AUTH_RSA, - /** Digital Signature Standard */ + /// Digital Signature Standard SSL_AUTH_DSS, - /** Anonymous */ + /// Anonymous SSL_AUTH_anon, - /** Diffie-Hellman based key-exchange protocol */ + /// Diffie-Hellman based key-exchange protocol SSL_AUTH_KEA, - /** Kerberos 5 */ + /// Kerberos 5 SSL_AUTH_KRB5, - /** Pre-Shared Key */ + /// Pre-Shared Key SSL_AUTH_PSK, - /** Elliptic Curve Digital Signature Algorithm */ + /// Elliptic Curve Digital Signature Algorithm SSL_AUTH_ECDSA, - /** GOST */ + /// GOST SSL_AUTH_GOST, - /** SHA-1 (Secure Hash Algorithm) */ + /// SHA-1 (Secure Hash Algorithm) SSL_AUTH_SHA, - /** PCT */ + /// PCT SSL_AUTH_PCT, - /** Diffie-Hellman ephemeral */ + /// Diffie-Hellman ephemeral SSL_AUTH_DHE, - /** Unknown algorithm */ + /// Unknown algorithm SSL_AUTH_Unknown }; - /** - * SSL/TLS symmetric encryption algorithms - */ + /// SSL/TLS symmetric encryption algorithms enum SSLSymetricEncryptionAlgorithm { - /** Null value */ + /// Null value SSL_SYM_NULL, - /** RC4_40 */ + /// RC4_40 SSL_SYM_RC4_40, - /** RC4_128 */ + /// RC4_128 SSL_SYM_RC4_128, - /** RC2_CBC_40 */ + /// RC2_CBC_40 SSL_SYM_RC2_CBC_40, - /** IDEA_CBC */ + /// IDEA_CBC SSL_SYM_IDEA_CBC, - /** DES40_CBC */ + /// DES40_CBC SSL_SYM_DES40_CBC, - /** DES_CBC */ + /// DES_CBC SSL_SYM_DES_CBC, - /** 3DES_EDE_CBC */ + /// 3DES_EDE_CBC SSL_SYM_3DES_EDE_CBC, - /** FORTEZZA_CBC */ + /// FORTEZZA_CBC SSL_SYM_FORTEZZA_CBC, - /** DES_CBC_40 */ + /// DES_CBC_40 SSL_SYM_DES_CBC_40, - /** AES_128_CBC */ + /// AES_128_CBC SSL_SYM_AES_128_CBC, - /** AES_256_CBC */ + /// AES_256_CBC SSL_SYM_AES_256_CBC, - /** CAMELLIA_128_CBC */ + /// CAMELLIA_128_CBC SSL_SYM_CAMELLIA_128_CBC, - /** CAMELLIA_128_GCM */ + /// CAMELLIA_128_GCM SSL_SYM_CAMELLIA_128_GCM, - /** CAMELLIA_256_GCM */ + /// CAMELLIA_256_GCM SSL_SYM_CAMELLIA_256_GCM, - /** RC4_56 */ + /// RC4_56 SSL_SYM_RC4_56, - /** RC2_CBC_56 */ + /// RC2_CBC_56 SSL_SYM_RC2_CBC_56, - /** GOST28147 */ + /// GOST28147 SSL_SYM_GOST28147, - /** CAMELLIA_256_CBC */ + /// CAMELLIA_256_CBC SSL_SYM_CAMELLIA_256_CBC, - /** SEED_CBC */ + /// SEED_CBC SSL_SYM_SEED_CBC, - /** AES_128 */ + /// AES_128 SSL_SYM_AES_128, - /** AES_256 */ + /// AES_256 SSL_SYM_AES_256, - /** SSL_SYM_AES_128_GCM */ + /// SSL_SYM_AES_128_GCM SSL_SYM_AES_128_GCM, - /** AES_256_GCM */ + /// AES_256_GCM SSL_SYM_AES_256_GCM, - /** RC4_128_EXPORT40 */ + /// RC4_128_EXPORT40 SSL_SYM_RC4_128_EXPORT40, - /** RC2_CBC_128_CBC */ + /// RC2_CBC_128_CBC SSL_SYM_RC2_CBC_128_CBC, - /** IDEA_128_CBC */ + /// IDEA_128_CBC SSL_SYM_IDEA_128_CBC, - /** DES_64_CBC */ + /// DES_64_CBC SSL_SYM_DES_64_CBC, - /** DES_192_EDE3_CBC */ + /// DES_192_EDE3_CBC SSL_SYM_DES_192_EDE3_CBC, - /** RC4_64 */ + /// RC4_64 SSL_SYM_RC4_64, - /** ARIA_128_CBC*/ + /// ARIA_128_CBC SSL_SYM_ARIA_128_CBC, - /** ARIA_256_CBC */ + /// ARIA_256_CBC SSL_SYM_ARIA_256_CBC, - /** ARIA_128_GCM */ + /// ARIA_128_GCM SSL_SYM_ARIA_128_GCM, - /** ARIA_256_GCM */ + /// ARIA_256_GCM SSL_SYM_ARIA_256_GCM, - /** CHACHA20_POLY1305 */ + /// CHACHA20_POLY1305 SSL_SYM_CHACHA20_POLY1305, - /** AES_128_CCM */ + /// AES_128_CCM SSL_SYM_AES_128_CCM, - /** AES_128_CCM_8 */ + /// AES_128_CCM_8 SSL_SYM_AES_128_CCM_8, - /** Unknown algorithm */ + /// Unknown algorithm SSL_SYM_Unknown }; - /** - * SSL/TLS hashing algorithms - */ + /// SSL/TLS hashing algorithms enum SSLHashingAlgorithm { - /** Null value */ + /// Null value SSL_HASH_NULL, - /** Message-Digest Algorithm */ + /// Message-Digest Algorithm SSL_HASH_MD5, - /** SHA-1 (Secure Hash Algorithm) */ + /// SHA-1 (Secure Hash Algorithm) SSL_HASH_SHA, - /** SHA-256 (Secure Hash Algorithm) */ + /// SHA-256 (Secure Hash Algorithm) SSL_HASH_SHA256, - /** GOST 28147 */ + /// GOST 28147 SSL_HASH_GOST28147, - /** GOST R 34.11 */ + /// GOST R 34.11 SSL_HASH_GOSTR3411, - /** SHA-384 (Secure Hash Algorithm) */ + /// SHA-384 (Secure Hash Algorithm) SSL_HASH_SHA384, - /** CCM mode (Counter with CBC-MAC) */ + /// CCM mode (Counter with CBC-MAC) SSL_HASH_CCM, - /** CCM mode (Counter with CBC-MAC) */ + /// CCM mode (Counter with CBC-MAC) SSL_HASH_CCM_8, - /** Unknown algorithm */ + /// Unknown algorithm SSL_HASH_Unknown }; - /** - * SSL/TLS extension types - */ + /// SSL/TLS extension types enum SSLExtensionType { - /** Server Name Indication extension */ + /// Server Name Indication extension SSL_EXT_SERVER_NAME = 0, - /** Maximum Fragment Length Negotiation extension */ + /// Maximum Fragment Length Negotiation extension SSL_EXT_MAX_FRAGMENT_LENGTH = 1, - /** Client Certificate URLs extension */ + /// Client Certificate URLs extension SSL_EXT_CLIENT_CERTIFICATE_URL = 2, - /** Trusted CA Indication extension */ + /// Trusted CA Indication extension SSL_EXT_TRUSTED_CA_KEYS = 3, - /** Truncated HMAC extension */ + /// Truncated HMAC extension SSL_EXT_TRUNCATED_HMAC = 4, - /** Certificate Status Request extension */ + /// Certificate Status Request extension SSL_EXT_STATUS_REQUEST = 5, - /** TLS User Mapping extension */ + /// TLS User Mapping extension SSL_EXT_USER_MAPPING = 6, - /** Client Authorization extension */ + /// Client Authorization extension SSL_EXT_CLIENT_AUTHZ = 7, - /** Server Authorization extension */ + /// Server Authorization extension SSL_EXT_SERVER_AUTHZ = 8, - /** Certificate Type extension */ + /// Certificate Type extension SSL_EXT_CERT_TYPE = 9, - /** Supported Groups extension (renamed from "elliptic curves") */ + /// Supported Groups extension (renamed from "elliptic curves") SSL_EXT_SUPPORTED_GROUPS = 10, - /** Elliptic Curves Point Format extension */ + /// Elliptic Curves Point Format extension SSL_EXT_EC_POINT_FORMATS = 11, - /** Secure Remote Password extension */ + /// Secure Remote Password extension SSL_EXT_SRP = 12, - /** Signature Algorithms extension */ + /// Signature Algorithms extension SSL_EXT_SIGNATURE_ALGORITHMS = 13, - /** Use Secure Real-time Transport Protocol extension */ + /// Use Secure Real-time Transport Protocol extension SSL_EXT_USE_SRTP = 14, - /** TLS Heartbit extension */ + /// TLS Heartbit extension SSL_EXT_HEARTBEAT = 15, - /** Application Layer Protocol Negotiation (ALPN) extension */ + /// Application Layer Protocol Negotiation (ALPN) extension SSL_EXT_APPLICATION_LAYER_PROTOCOL_NEGOTIATION = 16, - /** Status Request extension */ + /// Status Request extension SSL_EXT_STATUS_REQUEST_V2 = 17, - /** Signed Certificate Timestamp extension */ + /// Signed Certificate Timestamp extension SSL_EXT_SIGNED_CERTIFICATE_TIMESTAMP = 18, - /** Client Certificate Type extension */ + /// Client Certificate Type extension SSL_EXT_CLIENT_CERTIFICATE_TYPE = 19, - /** Server Certificate Type extension */ + /// Server Certificate Type extension SSL_EXT_SERVER_CERTIFICATE_TYPE = 20, - /** ClientHello Padding extension */ + /// ClientHello Padding extension SSL_EXT_PADDING = 21, - /** Encrypt-then-MAC extension */ + /// Encrypt-then-MAC extension SSL_EXT_ENCRYPT_THEN_MAC = 22, - /** Extended Master Secret extension */ + /// Extended Master Secret extension SSL_EXT_EXTENDED_MASTER_SECRET = 23, - /** Token Binding extension */ + /// Token Binding extension SSL_EXT_TOKEN_BINDING = 24, - /** SessionTicket TLS extension */ + /// SessionTicket TLS extension SSL_EXT_SESSIONTICKET_TLS = 35, - /** Pre-shared key (PSK) extension (TLS 1.3) */ + /// Pre-shared key (PSK) extension (TLS 1.3) SSL_EXT_PRE_SHARED_KEY = 41, - /** Early data extension (TLS 1.3) */ + /// Early data extension (TLS 1.3) SSL_EXT_EARLY_DATA = 42, - /** Supported versions extension (TLS 1.3) */ + /// Supported versions extension (TLS 1.3) SSL_EXT_SUPPORTED_VERSIONS = 43, - /** Cookie extension (TLS 1.3) */ + /// Cookie extension (TLS 1.3) SSL_EXT_COOKIE = 44, - /** Pre-Shared Key Exchange Modes extension (TLS 1.3) */ + /// Pre-Shared Key Exchange Modes extension (TLS 1.3) SSL_EXT_PSK_KEY_EXCHANGE_MODES = 45, - /** Certificate authorities extension (TLS 1.3) */ + /// Certificate authorities extension (TLS 1.3) SSL_EXT_CERTIFICATE_AUTHORITIES = 47, - /** Old filters extension (TLS 1.3) */ + /// Old filters extension (TLS 1.3) SSL_EXT_OLD_FILTERS = 48, - /** Post handshake auth extension (TLS 1.3) */ + /// Post handshake auth extension (TLS 1.3) SSL_EXT_POST_HANDSHAKE_AUTH = 49, - /** Signature algorithm cert extension (TLS 1.3) */ + /// Signature algorithm cert extension (TLS 1.3) SSL_EXT_SIGNATURE_ALGORITHM_CERT = 50, - /** Key share extension (TLS 1.3) */ + /// Key share extension (TLS 1.3) SSL_EXT_KEY_SHARE = 51, - /** Renegotiation Indication extension */ + /// Renegotiation Indication extension SSL_EXT_RENEGOTIATION_INFO = 65281, - /** Unknown extension */ + /// Unknown extension SSL_EXT_Unknown }; - /** - * SSL/TLS client certificate types - */ + /// SSL/TLS client certificate types enum SSLClientCertificateType { - /** RSA_SIGN */ + /// RSA_SIGN SSL_CCT_RSA_SIGN = 1, - /** DSS_SIGN */ + /// DSS_SIGN SSL_CCT_DSS_SIGN = 2, - /** RSA_FIXED_DH */ + /// RSA_FIXED_DH SSL_CCT_RSA_FIXED_DH = 3, - /** DSS_FIXED_DH */ + /// DSS_FIXED_DH SSL_CCT_DSS_FIXED_DH = 4, - /** RSA_EPHEMERAL_DH_RESERVED */ + /// RSA_EPHEMERAL_DH_RESERVED SSL_CCT_RSA_EPHEMERAL_DH_RESERVED = 5, - /** DSS_EPHEMERAL_DH_RESERVED */ + /// DSS_EPHEMERAL_DH_RESERVED SSL_CCT_DSS_EPHEMERAL_DH_RESERVED = 6, - /** FORTEZZA_DMS_RESERVED */ + /// FORTEZZA_DMS_RESERVED SSL_CCT_FORTEZZA_DMS_RESERVED = 20, - /** ECDSA_SIGN */ + /// ECDSA_SIGN SSL_CCT_ECDSA_SIGN = 64, - /** FIXED_ECDH */ + /// FIXED_ECDH SSL_CCT_RSA_FIXED_ECDH = 65, - /** ECDSA_FIXED_ECDH */ + /// ECDSA_FIXED_ECDH SSL_CCT_ECDSA_FIXED_ECDH = 66, - /** Unknown client certificate type */ + /// Unknown client certificate type SSL_CCT_UNKNOWN }; - } // namespace pcpp diff --git a/Packet++/header/SSLHandshake.h b/Packet++/header/SSLHandshake.h index 9c41752e2b..04b31dec04 100644 --- a/Packet++/header/SSLHandshake.h +++ b/Packet++/header/SSLHandshake.h @@ -5,104 +5,79 @@ #include "PointerVector.h" #include "Asn1Codec.h" -/** - * @file - * See detailed explanation of the TLS/SSL protocol support in PcapPlusPlus in SSLLayer.h - */ - -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @file +/// See detailed explanation of the TLS/SSL protocol support in PcapPlusPlus in SSLLayer.h + +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @class SSLCipherSuite - * Represents a cipher-suite and enables access all information about it such as all algorithms it encapsulates, - * its ID (as appears in the client-hello or server-hello messages), - * its name (e.g "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA") etc. PcapPlusPlus contains static instances of this type - * for all known cipher-suites and enables access to them through name or ID (see getCipherSuiteByID() and - * getCipherSuiteByName() ). List of cipher-suite was taken from here: - * http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml - */ + /// @class SSLCipherSuite + /// Represents a cipher-suite and enables access all information about it such as all algorithms it encapsulates, + /// its ID (as appears in the client-hello or server-hello messages), + /// its name (e.g "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA") etc. PcapPlusPlus contains static instances of this type + /// for all known cipher-suites and enables access to them through name or ID (see getCipherSuiteByID() and + /// getCipherSuiteByName() ). List of cipher-suite was taken from here: + /// http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml class SSLCipherSuite { public: - /** - * A c'tor for this class, should never be used by a user - * @param[in] id Cipher-suite ID - * @param[in] keyExAlg Key-exchange algorithm used in this cipher-suite - * @param[in] authAlg Authentication algorithm used in this cipher-suite - * @param[in] symKeyAlg Symmetric key algorithm used in this cipher-suite - * @param[in] MACAlg MAC algorithm used in this cipher-suite - * @param[in] name String representation of this cipher-suite - */ + /// A c'tor for this class, should never be used by a user + /// @param[in] id Cipher-suite ID + /// @param[in] keyExAlg Key-exchange algorithm used in this cipher-suite + /// @param[in] authAlg Authentication algorithm used in this cipher-suite + /// @param[in] symKeyAlg Symmetric key algorithm used in this cipher-suite + /// @param[in] MACAlg MAC algorithm used in this cipher-suite + /// @param[in] name String representation of this cipher-suite SSLCipherSuite(uint16_t id, SSLKeyExchangeAlgorithm keyExAlg, SSLAuthenticationAlgorithm authAlg, SSLSymetricEncryptionAlgorithm symKeyAlg, SSLHashingAlgorithm MACAlg, const char* name) : m_Id(id), m_KeyExAlg(keyExAlg), m_AuthAlg(authAlg), m_SymKeyAlg(symKeyAlg), m_MACAlg(MACAlg), m_Name(name) {} - /** - * @return Cipher-suite ID - */ + /// @return Cipher-suite ID uint16_t getID() const { return m_Id; } - /** - * @return String representation of this cipher-suite - */ + /// @return String representation of this cipher-suite std::string asString() const { return m_Name; } - /** - * @return Key-exchange algorithm used in this cipher-suite - */ + /// @return Key-exchange algorithm used in this cipher-suite SSLKeyExchangeAlgorithm getKeyExchangeAlg() const { return m_KeyExAlg; } - /** - * @return Authentication algorithm used in this cipher-suite - */ + /// @return Authentication algorithm used in this cipher-suite SSLAuthenticationAlgorithm getAuthAlg() const { return m_AuthAlg; } - /** - * @return Symmetric key algorithm used in this cipher-suite - */ + /// @return Symmetric key algorithm used in this cipher-suite SSLSymetricEncryptionAlgorithm getSymKeyAlg() const { return m_SymKeyAlg; } - /** - * @return MAC algorithm used in this cipher-suite - */ + /// @return MAC algorithm used in this cipher-suite SSLHashingAlgorithm getMACAlg() const { return m_MACAlg; } - /** - * A static method that returns a cipher-suite instance by ID - * @param[in] id Cipher-suite ID - * @return A cipher-suite instance matching this ID or nullptr if ID not found - */ + /// A static method that returns a cipher-suite instance by ID + /// @param[in] id Cipher-suite ID + /// @return A cipher-suite instance matching this ID or nullptr if ID not found static SSLCipherSuite* getCipherSuiteByID(uint16_t id); - /** - * A static method that returns a cipher-suite instance by name - * @param[in] name Cipher-suite name (e.g "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA") - * @return A cipher-suite instance matching this name or nullptr if name not found - */ + /// A static method that returns a cipher-suite instance by name + /// @param[in] name Cipher-suite name (e.g "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA") + /// @return A cipher-suite instance matching this name or nullptr if name not found static SSLCipherSuite* getCipherSuiteByName(std::string name); private: @@ -114,60 +89,44 @@ namespace pcpp std::string m_Name; }; - /** - * @class SSLExtension - * Represents a SSL/TLS extension. This is a base class that can represent any type of extension. Inherited classes - * may contain parsing logic for specific extensions. This class provides capabilities such as getting the extension - * type, length and viewing the extension data as raw (byte array) - */ + /// @class SSLExtension + /// Represents a SSL/TLS extension. This is a base class that can represent any type of extension. Inherited classes + /// may contain parsing logic for specific extensions. This class provides capabilities such as getting the + /// extension type, length and viewing the extension data as raw (byte array) class SSLExtension { public: - /** - * C'tor for this class - * @param[in] data The raw data for the extension - */ + /// C'tor for this class + /// @param[in] data The raw data for the extension explicit SSLExtension(uint8_t* data); virtual ~SSLExtension() = default; - /** - * @return The type of the extension as enum - */ + /// @return The type of the extension as enum SSLExtensionType getType() const; - /** - * @return The type of the extension as a numeric value - */ + /// @return The type of the extension as a numeric value uint16_t getTypeAsInt() const; - /** - * @return The length of the extension data in bytes (not including the type and length fields) - */ + /// @return The length of the extension data in bytes (not including the type and length fields) uint16_t getLength() const; - /** - * @return The total length of the extension, including type and length fields and the extension data field - */ + /// @return The total length of the extension, including type and length fields and the extension data field uint16_t getTotalLength() const; - /** - * @return A pointer to the raw data of the extension - */ + /// @return A pointer to the raw data of the extension uint8_t* getData() const; protected: - /** - * @struct SSLExtensionStruct - * Represents the common fields of the extension - */ + /// @struct SSLExtensionStruct + /// Represents the common fields of the extension struct SSLExtensionStruct { - /** Extension type */ + /// Extension type uint16_t extensionType; - /** Extension length */ + /// Extension length uint16_t extensionDataLength; - /** Extension data as raw (byte array) */ + /// Extension data as raw (byte array) uint8_t extensionData[]; }; @@ -179,139 +138,103 @@ namespace pcpp } }; - /** - * @class SSLServerNameIndicationExtension - * Represents SSL/TLS Server Name Indication extension. Inherits from SSLExtension and add parsing of the hostname - * written in the extension data - */ + /// @class SSLServerNameIndicationExtension + /// Represents SSL/TLS Server Name Indication extension. Inherits from SSLExtension and add parsing of the hostname + /// written in the extension data class SSLServerNameIndicationExtension : public SSLExtension { public: - /** - * C'tor for this class - * @param[in] data The raw data for the extension - */ + /// C'tor for this class + /// @param[in] data The raw data for the extension explicit SSLServerNameIndicationExtension(uint8_t* data) : SSLExtension(data) {} - /** - * @return The hostname written in the extension data - */ + /// @return The hostname written in the extension data std::string getHostName() const; }; - /** - * @class SSLSupportedVersionsExtension - * Represents TLS Supported Versions extension. Inherits from SSLExtension and adds parsing of the list - * of supported versions mentioned in the extension data - */ + /// @class SSLSupportedVersionsExtension + /// Represents TLS Supported Versions extension. Inherits from SSLExtension and adds parsing of the list + /// of supported versions mentioned in the extension data class SSLSupportedVersionsExtension : public SSLExtension { public: - /** - * C'tor for this class - * @param[in] data The raw data for the extension - */ + /// C'tor for this class + /// @param[in] data The raw data for the extension explicit SSLSupportedVersionsExtension(uint8_t* data) : SSLExtension(data) {} - /** - * @return The list of supported versions mentioned in the extension data - */ + /// @return The list of supported versions mentioned in the extension data std::vector getSupportedVersions() const; }; - /** - * @class TLSSupportedGroupsExtension - * Represents TLS Supported Groups extension. Inherits from SSLExtension and adds parsing of the - * supported groups (Elliptic Curves) mentioned in the extension data - */ + /// @class TLSSupportedGroupsExtension + /// Represents TLS Supported Groups extension. Inherits from SSLExtension and adds parsing of the + /// supported groups (Elliptic Curves) mentioned in the extension data class TLSSupportedGroupsExtension : public SSLExtension { public: - /** - * C'tor for this class - * @param[in] data The raw data for the extension - */ + /// C'tor for this class + /// @param[in] data The raw data for the extension explicit TLSSupportedGroupsExtension(uint8_t* data) : SSLExtension(data) {} - /** - * @return A vector of the supported groups (also known as "Elliptic Curves") - */ + /// @return A vector of the supported groups (also known as "Elliptic Curves") std::vector getSupportedGroups() const; }; - /** - * @class TLSECPointFormatExtension - * Represents TLS EC (Elliptic Curves) Point Format extension. Inherits from SSLExtension and adds parsing of the - * EC point formats mentioned in the extension data - */ + /// @class TLSECPointFormatExtension + /// Represents TLS EC (Elliptic Curves) Point Format extension. Inherits from SSLExtension and adds parsing of the + /// EC point formats mentioned in the extension data class TLSECPointFormatExtension : public SSLExtension { public: - /** - * C'tor for this class - * @param[in] data The raw data for the extension - */ + /// C'tor for this class + /// @param[in] data The raw data for the extension explicit TLSECPointFormatExtension(uint8_t* data) : SSLExtension(data) {} - /** - * @return A vector of the elliptic curves point formats - */ + /// @return A vector of the elliptic curves point formats std::vector getECPointFormatList() const; }; - /** - * @class SSLx509Certificate - * Represents a x509v3 certificate. the SSLCertificateMessage class returns an instance of this class as the - * certificate. Currently this class doesn't do much as it doesn't parse the certificate. It only acts as container - * to the raw data and returns general info as data as raw, length, etc. In the future I may add full parsing of the - * certificate - */ + /// @class SSLx509Certificate + /// Represents a x509v3 certificate. the SSLCertificateMessage class returns an instance of this class as the + /// certificate. Currently this class doesn't do much as it doesn't parse the certificate. It only acts as container + /// to the raw data and returns general info as data as raw, length, etc. In the future I may add full parsing of + /// the certificate class SSLx509Certificate { public: - /** - * C'tor for this class - * @param[in] data The raw data of the certificate - * @param[in] dataLen The length in bytes of the raw data - * @param[in] allDataExists Certificate messages usually spread on more than 1 packet. So a certificate is - * likely to split between 2 packets or more. This field indicates whether the raw data contains all - * certificate data of just a part of it - */ + /// C'tor for this class + /// @param[in] data The raw data of the certificate + /// @param[in] dataLen The length in bytes of the raw data + /// @param[in] allDataExists Certificate messages usually spread on more than 1 packet. So a certificate is + /// likely to split between 2 packets or more. This field indicates whether the raw data contains all + /// certificate data of just a part of it SSLx509Certificate(uint8_t* data, size_t dataLen, bool allDataExists) : m_Data(data), m_DataLen(dataLen), m_AllDataExists(allDataExists) {} - /** - * @return A pointer to the raw data - */ + /// @return A pointer to the raw data uint8_t* getData() const { return m_Data; } - /** - * @return Raw data length - */ + /// @return Raw data length size_t getDataLength() const { return m_DataLen; } - /** - * @return The root ASN.1 record of the certificate data. All of the certificate data will be under this record. - * If the Root ASN.1 record is malformed, an exception is thrown - */ + /// @return The root ASN.1 record of the certificate data. All of the certificate data will be under this + /// record. If the Root ASN.1 record is malformed, an exception is thrown Asn1SequenceRecord* getRootAsn1Record(); - /** - * Certificate messages usually spread on more than 1 packet. So a certificate is likely to split between 2 - * packets or more. This method provides an indication whether all certificate data exists or only part of it - * @return True if this data contains all certificate data, false otherwise - */ + /// Certificate messages usually spread on more than 1 packet. So a certificate is likely to split between 2 + /// packets or more. This method provides an indication whether all certificate data exists or only part of it + /// @return True if this data contains all certificate data, false otherwise bool allDataExists() const { return m_AllDataExists; @@ -326,58 +249,45 @@ namespace pcpp class SSLHandshakeLayer; - /** - * @class SSLHandshakeMessage - * A base class for SSL/TLS handshake messages. This is an abstract class and cannot be instantiated. SSL/TLS - * handshake messages are contained in SSLHandshakeLayer, meaning a SSLHandshakeLayer instance can contain one or - * more SSLHandshakeMessage instances. For example: one SSLHandshakeLayer may contain a server-hello, certificate, - * server-key-exchange, and server-hello-done messages (although it's not such a common case, most handshake layers - * contain 1 handshake message only) - */ + /// @class SSLHandshakeMessage + /// A base class for SSL/TLS handshake messages. This is an abstract class and cannot be instantiated. SSL/TLS + /// handshake messages are contained in SSLHandshakeLayer, meaning a SSLHandshakeLayer instance can contain one or + /// more SSLHandshakeMessage instances. For example: one SSLHandshakeLayer may contain a server-hello, certificate, + /// server-key-exchange, and server-hello-done messages (although it's not such a common case, most handshake layers + /// contain 1 handshake message only) class SSLHandshakeMessage { public: virtual ~SSLHandshakeMessage() = default; - /** - * A factory method for creating instances of handshake messages from raw data - * @param[in] data The raw data containing 1 handshake message - * @param[in] dataLen Raw data length in bytes - * @param[in] container A pointer to the SSLHandshakeLayer instance which will contain the created message. - * This parameter is required because the handshake message includes a pointer to its container - */ + /// A factory method for creating instances of handshake messages from raw data + /// @param[in] data The raw data containing 1 handshake message + /// @param[in] dataLen Raw data length in bytes + /// @param[in] container A pointer to the SSLHandshakeLayer instance which will contain the created message. + /// This parameter is required because the handshake message includes a pointer to its container static SSLHandshakeMessage* createHandshakeMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container); - /** - * @return The handshake message type - */ + /// @return The handshake message type virtual SSLHandshakeType getHandshakeType() const; - /** - * @return The handshake message length in bytes. Notice that sometimes the handshake message is divided between - * several packets, in this case this method will return the length of part of the message in the current packet - */ + /// @return The handshake message length in bytes. Notice that sometimes the handshake message is divided + /// between several packets, in this case this method will return the length of part of the message in the + /// current packet virtual size_t getMessageLength() const; - /** - * @return True if current packet contains the entire message or false otherwise. This method is important - * because sometimes handshake messages are divided in consequent packets (happens a lot in certificate messages - * which usually contain several KB of data which is larger than standard packet size, so the message is divided - * between several packets) - */ + /// @return True if current packet contains the entire message or false otherwise. This method is important + /// because sometimes handshake messages are divided in consequent packets (happens a lot in certificate + /// messages which usually contain several KB of data which is larger than standard packet size, so the message + /// is divided between several packets) virtual bool isMessageComplete() const; - /** - * @return A pointer to the SSLHandshakeLayer instance containing this message - */ + /// @return A pointer to the SSLHandshakeLayer instance containing this message SSLHandshakeLayer* getContainingLayer() const { return m_Container; } - /** - * @return A string representation of the message type (e.g "Client Hello message") - */ + /// @return A string representation of the message type (e.g "Client Hello message") virtual std::string toString() const = 0; protected: @@ -388,183 +298,141 @@ namespace pcpp SSLHandshakeLayer* m_Container; }; - /** - * @class SSLClientHelloMessage - * Represents a client-hello message (type 1). Inherits from SSLHandshakeMessage and adds parsing of all fields - * of this message including the message extensions, cipher-suite list, etc. - */ + /// @class SSLClientHelloMessage + /// Represents a client-hello message (type 1). Inherits from SSLHandshakeMessage and adds parsing of all fields + /// of this message including the message extensions, cipher-suite list, etc. class SSLClientHelloMessage : public SSLHandshakeMessage { public: - /** - * @struct ClientHelloTLSFingerprint - * A struct that contains all the elements needed for creating a Client Hello TLS fingerprinting: - * TLS version, a list of Cipher Suite IDs, a list of Extensions IDs, a list of support groups and a list of - * EC point formats. - * You can read more about this in SSLClientHelloMessage#generateTLSFingerprint(). - * This struct contains methods to extract the TLS fingerprint itself: toString() and toMD5() - */ + /// @struct ClientHelloTLSFingerprint + /// A struct that contains all the elements needed for creating a Client Hello TLS fingerprinting: + /// TLS version, a list of Cipher Suite IDs, a list of Extensions IDs, a list of support groups and a list of + /// EC point formats. + /// You can read more about this in SSLClientHelloMessage#generateTLSFingerprint(). + /// This struct contains methods to extract the TLS fingerprint itself: toString() and toMD5() struct ClientHelloTLSFingerprint { - /** TLS version */ + /// TLS version uint16_t tlsVersion; - /** A list of Cipher Suite IDs */ + /// A list of Cipher Suite IDs std::vector cipherSuites; - /** A list of extension IDs */ + /// A list of extension IDs std::vector extensions; - /** A list of Suppotred Groups taken from the "supported groups" TLS extension (if exist in the message) */ + /// A list of Suppotred Groups taken from the "supported groups" TLS extension (if exist in the message) std::vector supportedGroups; - /** A list of EC point formats taken from the "EC point formats" TLS extension (if exist in the message) */ + /// A list of EC point formats taken from the "EC point formats" TLS extension (if exist in the message) std::vector ecPointFormats; - /** - * @return A string representing the TLS fingerprint, for example: - * 771,4866-4867-4865-255,0-11-10-35-22-23-13-43-45-51,29-23-30-25-24,0-1-2 - * - * This string has the following format: - * TLSVersion,CipherSuiteIDs,ExtensionIDs,SupportedGroups,ECPointFormats - * - * The extension IDs, supported groups and EC point formats are each separated by a "-". - * If the message doesn't include the "supported groups" or "EC point formats" extensions, they will be - * replaced by an empty string for example: 771,4866-4867-4865-255,0-11-10-35-22-23-13-43-45-51,, - */ + /// @return A string representing the TLS fingerprint, for example: + /// 771,4866-4867-4865-255,0-11-10-35-22-23-13-43-45-51,29-23-30-25-24,0-1-2 + /// + /// This string has the following format: + /// TLSVersion,CipherSuiteIDs,ExtensionIDs,SupportedGroups,ECPointFormats + /// + /// The extension IDs, supported groups and EC point formats are each separated by a "-". + /// If the message doesn't include the "supported groups" or "EC point formats" extensions, they will be + /// replaced by an empty string for example: 771,4866-4867-4865-255,0-11-10-35-22-23-13-43-45-51,, std::string toString(); - /** - * @return An MD5 hash of the string generated by toString() - */ + /// @return An MD5 hash of the string generated by toString() std::string toMD5(); - /** - * @return A pair of the string and MD5 hash (string is first, MD5 is second). - * If you want both this method is more efficient than calling toString() and toMD5() separately - */ + /// @return A pair of the string and MD5 hash (string is first, MD5 is second). + /// If you want both this method is more efficient than calling toString() and toMD5() separately std::pair toStringAndMD5(); }; - /** - * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and shouldn't be - * used by a user - * @param[in] data The message as raw data - * @param[in] dataLen Message raw data length in bytes - * @param[in] container The SSL handshake layer which shall contain this message - */ + /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and shouldn't + /// be used by a user + /// @param[in] data The message as raw data + /// @param[in] dataLen Message raw data length in bytes + /// @param[in] container The SSL handshake layer which shall contain this message SSLClientHelloMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container); ~SSLClientHelloMessage() override = default; - /** - * @return A struct containing common fields for client-hello and server-hello messages. Notice this points - * directly to the data, so every change will change the actual packet data - */ + /// @return A struct containing common fields for client-hello and server-hello messages. Notice this points + /// directly to the data, so every change will change the actual packet data ssl_tls_client_server_hello* getClientHelloHeader() const { return reinterpret_cast(m_Data); } - /** - * @return Handshake SSL/TLS version (notice it may be different than SSLLayer#getRecordVersion(). Each - * client-hello or server-hello message has both record version and handshake version and they may differ from - * one another) - */ + /// @return Handshake SSL/TLS version (notice it may be different than SSLLayer#getRecordVersion(). Each + /// client-hello or server-hello message has both record version and handshake version and they may differ from + /// one another) SSLVersion getHandshakeVersion() const; - /** - * @return Session ID length in bytes. If server-hello message doesn't include session ID 0 will be returned - */ + /// @return Session ID length in bytes. If server-hello message doesn't include session ID 0 will be returned uint8_t getSessionIDLength() const; - /** - * @return Session ID as byte array. If server-hello message doesn't include session ID nullptr will be returned - */ + /// @return Session ID as byte array. If server-hello message doesn't include session ID nullptr will be + /// returned uint8_t* getSessionID() const; - /** - * @return The number of cipher-suites included in this message - */ + /// @return The number of cipher-suites included in this message int getCipherSuiteCount() const; - /** - * Get a pointer to a cipher-suite by index. The cipher-suites are numbered according to their order of - * appearance in the message. If index is out of bounds (less than 0 or larger than total amount of cipher - * suites) nullptr will be returned. nullptr will also be returned if the cipher-suite ID is unknown. If you - * still want to get the cipher-suite ID you can use getCipherSuiteID() - * @param[in] index The index of the cipher-suite to return - * @return The pointer to the cipher-suite object or nullptr if index is out of bounds - */ + /// Get a pointer to a cipher-suite by index. The cipher-suites are numbered according to their order of + /// appearance in the message. If index is out of bounds (less than 0 or larger than total amount of cipher + /// suites) nullptr will be returned. nullptr will also be returned if the cipher-suite ID is unknown. If you + /// still want to get the cipher-suite ID you can use getCipherSuiteID() + /// @param[in] index The index of the cipher-suite to return + /// @return The pointer to the cipher-suite object or nullptr if index is out of bounds SSLCipherSuite* getCipherSuite(int index) const; - /** - * Get the cipher-suite ID by index. This method just parses the ID from the client-hello message and returns - * it. To get more information on the cipher-suite you can use the getCipherSuite() method - * @param[in] index The index of the cipher-suite to return - * @param[out] isValid Set to "true" if parsing succeeded and the return value is valid or "false" if: - * (1) the index is out-of-bounds (less than 0 or larger than total amount of cipher suites) or (2) the parsing - * failed. If the value is "false" the return value can be ignored - * @return The cipher-suite ID if "isValid" is set to "true". If "isValid" is set to "false" the return value - * can be ignored - */ + /// Get the cipher-suite ID by index. This method just parses the ID from the client-hello message and returns + /// it. To get more information on the cipher-suite you can use the getCipherSuite() method + /// @param[in] index The index of the cipher-suite to return + /// @param[out] isValid Set to "true" if parsing succeeded and the return value is valid or "false" if: + /// (1) the index is out-of-bounds (less than 0 or larger than total amount of cipher suites) or (2) the parsing + /// failed. If the value is "false" the return value can be ignored + /// @return The cipher-suite ID if "isValid" is set to "true". If "isValid" is set to "false" the return value + /// can be ignored uint16_t getCipherSuiteID(int index, bool& isValid) const; - /** - * @return The value of the compression method byte - */ + /// @return The value of the compression method byte uint8_t getCompressionMethodsValue() const; - /** - * @return The number of extensions in this message - */ + /// @return The number of extensions in this message int getExtensionCount() const; - /** - * @return The size (in bytes) of all extensions data in this message. Extracted from the "extensions length" - * field - */ + /// @return The size (in bytes) of all extensions data in this message. Extracted from the "extensions length" + /// field uint16_t getExtensionsLength() const; - /** - * Get a pointer to an extension by index. The extensions are numbered according to their order of appearance - * in the message. If index is out of bounds (less than 0 or larger than total amount of extensions) nullptr - * will be returned - * @param[in] index The index of the extension to return - * @return The pointer to the extension or nullptr if index is out of bounds - */ + /// Get a pointer to an extension by index. The extensions are numbered according to their order of appearance + /// in the message. If index is out of bounds (less than 0 or larger than total amount of extensions) nullptr + /// will be returned + /// @param[in] index The index of the extension to return + /// @return The pointer to the extension or nullptr if index is out of bounds SSLExtension* getExtension(int index) const; - /** - * Get a pointer to an extension by numeric type field. Every extension has a 2-byte numeric value representing - * its type (for example: renegotiation info extension type is 0x1ff). This method gets the type and returns a - * pointer to the extension object - * @param[in] type The 2-byte numeric type of the extension - * @return A pointer to the extension object of nullptr if this type doesn't exist in this message - */ + /// Get a pointer to an extension by numeric type field. Every extension has a 2-byte numeric value representing + /// its type (for example: renegotiation info extension type is 0x1ff). This method gets the type and returns a + /// pointer to the extension object + /// @param[in] type The 2-byte numeric type of the extension + /// @return A pointer to the extension object of nullptr if this type doesn't exist in this message SSLExtension* getExtensionOfType(uint16_t type) const; - /** - * Get a pointer to an extension by its enum type - * @param[in] type The type of extension to return - * @return A pointer to the extension object or nullptr if this type doesn't exist in this message - */ + /// Get a pointer to an extension by its enum type + /// @param[in] type The type of extension to return + /// @return A pointer to the extension object or nullptr if this type doesn't exist in this message SSLExtension* getExtensionOfType(SSLExtensionType type) const; - /** - * Get a pointer to an extension by its class type. This is a templated method that is used with the type of the - * requested extension and returns the first extension instance of this type - * @return A pointer to the extension object or nullptr if this extension type doesn't exist in this message - * - */ + /// Get a pointer to an extension by its class type. This is a templated method that is used with the type of + /// the requested extension and returns the first extension instance of this type + /// @return A pointer to the extension object or nullptr if this extension type doesn't exist in this message template TExtension* getExtensionOfType() const; - /** - * TLS fingerprinting is a way to identify client applications using the details in the TLS Client Hello packet. - * It was initially introduced by Lee Brotherston in his 2015 research: - * This implementation of TLS fingerprint is a C++ version of - * Salesforce's JA3 open source project (originally written in Python and Zeek): - * - * @return A SSLClientHelloMessage#ClientHelloTLSFingerprint struct that contains all the elements needed for - * creating a TLS fingerprint out of this Client Hello message. This struct has also methods to extract the TLS - * fingerprint itself in a string or MD5 formats - */ + /// TLS fingerprinting is a way to identify client applications using the details in the TLS Client Hello + /// packet. It was initially introduced by Lee Brotherston in his 2015 research: + /// This implementation of TLS fingerprint is a C++ version + /// of Salesforce's JA3 open source project (originally written in Python and Zeek): + /// + /// @return A SSLClientHelloMessage#ClientHelloTLSFingerprint struct that contains all the elements needed for + /// creating a TLS fingerprint out of this Client Hello message. This struct has also methods to extract the TLS + /// fingerprint itself in a string or MD5 formats ClientHelloTLSFingerprint generateTLSFingerprint() const; // implement abstract methods @@ -575,170 +443,130 @@ namespace pcpp PointerVector m_ExtensionList; }; - /** - * @class SSLServerHelloMessage - * Represents SSL/TLS server-hello message (type 2). Inherits from SSLHandshakeMessage and adds parsing of all - * fields of this message including the message extensions, cipher-suite, etc. - */ + /// @class SSLServerHelloMessage + /// Represents SSL/TLS server-hello message (type 2). Inherits from SSLHandshakeMessage and adds parsing of all + /// fields of this message including the message extensions, cipher-suite, etc. class SSLServerHelloMessage : public SSLHandshakeMessage { public: - /** - * @struct ServerHelloTLSFingerprint - * A struct that contains all the elements needed for creating a Server Hello TLS fingerprinting: - * TLS version, Cipher Suite ID, and a list of Extensions IDs. - * You can read more about this in SSLServerHelloMessage#generateTLSFingerprint(). - * This struct contains methods to extract the TLS fingerprint itself: toString() and toMD5() - */ + /// @struct ServerHelloTLSFingerprint + /// A struct that contains all the elements needed for creating a Server Hello TLS fingerprinting: + /// TLS version, Cipher Suite ID, and a list of Extensions IDs. + /// You can read more about this in SSLServerHelloMessage#generateTLSFingerprint(). + /// This struct contains methods to extract the TLS fingerprint itself: toString() and toMD5() struct ServerHelloTLSFingerprint { - /** TLS version */ + /// TLS version uint16_t tlsVersion; - /** Cipher Suite ID */ + /// Cipher Suite ID uint16_t cipherSuite; - /** A list of extension IDs */ + /// A list of extension IDs std::vector extensions; - /** - * @return A string representing the TLS fingerprint, for example: 771,49195,65281-16-11 - * - * This string has the following format: TLSVersion,Cipher,Extensions - * - * The extension ID are separated with a "-" - */ + /// @return A string representing the TLS fingerprint, for example: 771,49195,65281-16-11 + /// + /// This string has the following format: TLSVersion,Cipher,Extensions + /// + /// The extension ID are separated with a "-" std::string toString(); - /** - * @return An MD5 hash of the string generated by toString() - */ + /// @return An MD5 hash of the string generated by toString() std::string toMD5(); - /** - * @return A pair of the string and MD5 hash (string is first, MD5 is second). - * If you want both this method is more efficient than calling toString() and toMD5() separately - */ + /// @return A pair of the string and MD5 hash (string is first, MD5 is second). + /// If you want both this method is more efficient than calling toString() and toMD5() separately std::pair toStringAndMD5(); }; - /** - * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and shouldn't be - * used by a user - * @param[in] data The message as raw data - * @param[in] dataLen Message raw data length in bytes - * @param[in] container The SSL handshake layer which shall contain this message - */ + /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and shouldn't + /// be used by a user + /// @param[in] data The message as raw data + /// @param[in] dataLen Message raw data length in bytes + /// @param[in] container The SSL handshake layer which shall contain this message SSLServerHelloMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container); ~SSLServerHelloMessage() override = default; - /** - * @return A struct containing common fields for client-hello and server-hello messages. Notice this points - * directly to the data, so every change will change the actual packet data - */ + /// @return A struct containing common fields for client-hello and server-hello messages. Notice this points + /// directly to the data, so every change will change the actual packet data ssl_tls_client_server_hello* getServerHelloHeader() const { return reinterpret_cast(m_Data); } - /** - * @return Handshake SSL/TLS version (notice it may be different than SSLLayer#getRecordVersion(). Each - * client-hello or server-hello message has both record version and handshake version and they may differ from - * one another). - * - * NOTE: for TLS 1.3 the handshake version written in ssl_tls_client_server_hello::handshakeVersion is - * still TLS 1.2, so a special check is made here see if a SupportedVersions extension exists and if so extract - * the version from it. This is the most straight-forward way to detect TLS 1.3. - */ + /// @return Handshake SSL/TLS version (notice it may be different than SSLLayer#getRecordVersion(). Each + /// client-hello or server-hello message has both record version and handshake version and they may differ from + /// one another). + /// + /// NOTE: for TLS 1.3 the handshake version written in ssl_tls_client_server_hello::handshakeVersion is + /// still TLS 1.2, so a special check is made here see if a SupportedVersions extension exists and if so extract + /// the version from it. This is the most straight-forward way to detect TLS 1.3. SSLVersion getHandshakeVersion() const; - /** - * @return Session ID length in bytes. If server-hello message doesn't include session ID 0 will be returned - */ + /// @return Session ID length in bytes. If server-hello message doesn't include session ID 0 will be returned uint8_t getSessionIDLength() const; - /** - * @return Session ID as byte array. If server-hello message doesn't include session ID nullptr will be returned - */ + /// @return Session ID as byte array. If server-hello message doesn't include session ID nullptr will be + /// returned uint8_t* getSessionID() const; - /** - * @return A pointer to the cipher suite encapsulated in this message (server-hello message contains one - * cipher-suite, the one that will be used to for encryption between client and server). May return nullptr - * if the parsing of the message failed or the cipher-suite ID is unknown. If you still want to get the - * cipher-suite ID you can use the getCipherSuiteID() method - */ + /// @return A pointer to the cipher suite encapsulated in this message (server-hello message contains one + /// cipher-suite, the one that will be used to for encryption between client and server). May return nullptr + /// if the parsing of the message failed or the cipher-suite ID is unknown. If you still want to get the + /// cipher-suite ID you can use the getCipherSuiteID() method SSLCipherSuite* getCipherSuite() const; - /** - * Get the cipher-suite ID. This method just parses the ID from the server-hello message and returns it. - * To get more information on the cipher-suite you can use the getCipherSuite() method - * @param[out] isValid Set to "true" if parsing succeeded and the return value is valid or "false" otherwise. - * If the value is "false" the return value can be ignored - * @return The cipher-suite ID if "isValid" is set to "true". If "isValid" is set to "false" the return value - * can be ignored - */ + /// Get the cipher-suite ID. This method just parses the ID from the server-hello message and returns it. + /// To get more information on the cipher-suite you can use the getCipherSuite() method + /// @param[out] isValid Set to "true" if parsing succeeded and the return value is valid or "false" otherwise. + /// If the value is "false" the return value can be ignored + /// @return The cipher-suite ID if "isValid" is set to "true". If "isValid" is set to "false" the return value + /// can be ignored uint16_t getCipherSuiteID(bool& isValid) const; - /** - * @return The value of the compression method byte - */ + /// @return The value of the compression method byte uint8_t getCompressionMethodsValue() const; - /** - * @return The number of extensions in this message - */ + /// @return The number of extensions in this message int getExtensionCount() const; - /** - * @return The size (in bytes) of all extensions data in this message. Extracted from the "extensions length" - * field - */ + /// @return The size (in bytes) of all extensions data in this message. Extracted from the "extensions length" + /// field uint16_t getExtensionsLength() const; - /** - * Get a pointer to an extension by index. The extensions are numbered according to their order of appearance - * in the message. If index is out of bounds (less than 0 or larger than total amount of extensions) nullptr - * will be returned - * @param[in] index The index of the extension to return - * @return The pointer to the extension or nullptr if index is out of bounds - */ + /// Get a pointer to an extension by index. The extensions are numbered according to their order of appearance + /// in the message. If index is out of bounds (less than 0 or larger than total amount of extensions) nullptr + /// will be returned + /// @param[in] index The index of the extension to return + /// @return The pointer to the extension or nullptr if index is out of bounds SSLExtension* getExtension(int index) const; - /** - * Get a pointer to an extension by numeric type field. Every extension has a 2-byte numeric value representing - * its type (for example: renegotiation info extension type is 0x1ff). This method gets the type and returns a - * pointer to the extension object - * @param[in] type The 2-byte numeric type of the extension - * @return A pointer to the extension object of nullptr if this type doesn't exist in this message - */ + /// Get a pointer to an extension by numeric type field. Every extension has a 2-byte numeric value representing + /// its type (for example: renegotiation info extension type is 0x1ff). This method gets the type and returns a + /// pointer to the extension object + /// @param[in] type The 2-byte numeric type of the extension + /// @return A pointer to the extension object of nullptr if this type doesn't exist in this message SSLExtension* getExtensionOfType(uint16_t type) const; - /** - * Get a pointer to an extension by its enum type - * @param[in] type The type of extension to return - * @return A pointer to the extension object or nullptr if this type doesn't exist in this message - */ + /// Get a pointer to an extension by its enum type + /// @param[in] type The type of extension to return + /// @return A pointer to the extension object or nullptr if this type doesn't exist in this message SSLExtension* getExtensionOfType(SSLExtensionType type) const; - /** - * Get a pointer to an extension by its class type. This is a templated method that is used with the type of the - * requested extension and returns the first extension instance of this type - * @return A pointer to the extension object or nullptr if this extension type doesn't exist in this message - * - */ + /// Get a pointer to an extension by its class type. This is a templated method that is used with the type of + /// the requested extension and returns the first extension instance of this type + /// @return A pointer to the extension object or nullptr if this extension type doesn't exist in this message template TExtension* getExtensionOfType() const; - /** - * ServerHello TLS fingerprinting is a way to fingerprint TLS Server Hello messages. In conjunction with - * ClientHello TLS fingerprinting it can assist in identifying specific client-server communication (for - * example: a malware connecting to its backend server). - * ServerHello TLS fingerprinting was introduced in Salesforce's JA3S open source project: - * - * This implementation is a C++ version of Salesforce's JAS3 (originally written in Python and Zeek) - * @return A SSLServerHelloMessage#ServerHelloTLSFingerprint struct that contains all the elements needed for - * creating a TLS fingerprint out of this Server Hello message. This struct has also methods to extract the TLS - * fingerprint itself in a string or MD5 formats - */ + /// ServerHello TLS fingerprinting is a way to fingerprint TLS Server Hello messages. In conjunction with + /// ClientHello TLS fingerprinting it can assist in identifying specific client-server communication (for + /// example: a malware connecting to its backend server). + /// ServerHello TLS fingerprinting was introduced in Salesforce's JA3S open source project: + /// + /// This implementation is a C++ version of Salesforce's JAS3 (originally written in Python and Zeek) + /// @return A SSLServerHelloMessage#ServerHelloTLSFingerprint struct that contains all the elements needed for + /// creating a TLS fingerprint out of this Server Hello message. This struct has also methods to extract the TLS + /// fingerprint itself in a string or MD5 formats ServerHelloTLSFingerprint generateTLSFingerprint() const; // implement abstract methods @@ -749,43 +577,35 @@ namespace pcpp PointerVector m_ExtensionList; }; - /** - * @class SSLCertificateMessage - * Represents SSL/TLS certificate message (type 11). Inherits from SSLHandshakeMessage and adds parsing - * functionality such as extracting the certificates data. Notice that in most cases this message is spread over - * more than 1 packet as its size is too big for a single packet. So SSLCertificateMessage instance will be created - * just for the first part of the message - the one encapsulated in the first packet. Other parts (encapsulated in - * the following packets) won't be recognized as SSLCertificateMessage messages - */ + /// @class SSLCertificateMessage + /// Represents SSL/TLS certificate message (type 11). Inherits from SSLHandshakeMessage and adds parsing + /// functionality such as extracting the certificates data. Notice that in most cases this message is spread over + /// more than 1 packet as its size is too big for a single packet. So SSLCertificateMessage instance will be created + /// just for the first part of the message - the one encapsulated in the first packet. Other parts (encapsulated in + /// the following packets) won't be recognized as SSLCertificateMessage messages class SSLCertificateMessage : public SSLHandshakeMessage { public: - /** - * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be - * used by a user - * @param[in] data The message as raw data - * @param[in] dataLen Message raw data length in bytes - * @param[in] container The SSL handshake layer which shall contain this message - */ + /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be + /// used by a user + /// @param[in] data The message as raw data + /// @param[in] dataLen Message raw data length in bytes + /// @param[in] container The SSL handshake layer which shall contain this message SSLCertificateMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container); ~SSLCertificateMessage() override = default; - /** - * @return The number of certificates encapsulated in this message (as written in the 'length' field of the - * message). Notice that because the message may spread over several packets, not all certificates will - * necessarily be in this packet. So, for example, there may be a case where this method return 3 (message - * contains 3 certificates) but this message actually contains only 1 certificate as the other 2 are spread over - * the other packets - */ + /// @return The number of certificates encapsulated in this message (as written in the 'length' field of the + /// message). Notice that because the message may spread over several packets, not all certificates will + /// necessarily be in this packet. So, for example, there may be a case where this method return 3 (message + /// contains 3 certificates) but this message actually contains only 1 certificate as the other 2 are spread + /// over the other packets int getNumOfCertificates() const; - /** - * Get a certificate by index - * @param[in] index The index of the certificate to retrieve - * @return A pointer to the certificate object. Notice that if index < 0 or index > num of certificates - * encapsulated in current packet a nullptr value will be returned - */ + /// Get a certificate by index + /// @param[in] index The index of the certificate to retrieve + /// @return A pointer to the certificate object. Notice that if index < 0 or index > num of certificates + /// encapsulated in current packet a nullptr value will be returned SSLx509Certificate* getCertificate(int index) const; // implement abstract methods @@ -796,21 +616,17 @@ namespace pcpp PointerVector m_CertificateList; }; - /** - * @class SSLHelloRequestMessage - * Represents SSL/TLS hello-request message (type 0). This message has no additional payload except for the common - * payload described in SSLHandshakeMessage - */ + /// @class SSLHelloRequestMessage + /// Represents SSL/TLS hello-request message (type 0). This message has no additional payload except for the common + /// payload described in SSLHandshakeMessage class SSLHelloRequestMessage : public SSLHandshakeMessage { public: - /** - * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be - * used by a user - * @param[in] data The message as raw data - * @param[in] dataLen Message raw data length in bytes - * @param[in] container The SSL handshake layer which shall contain this message - */ + /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be + /// used by a user + /// @param[in] data The message as raw data + /// @param[in] dataLen Message raw data length in bytes + /// @param[in] container The SSL handshake layer which shall contain this message SSLHelloRequestMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {} @@ -822,41 +638,33 @@ namespace pcpp std::string toString() const override; }; - /** - * @class SSLServerKeyExchangeMessage - * Represents SSL/TLS server-key-exchange message (type 12). Inherits from SSLHandshakeMessage and adds parsing - * functionality such as getting the server key exchange params as raw data (parsing of this may be added in the - * future) - */ + /// @class SSLServerKeyExchangeMessage + /// Represents SSL/TLS server-key-exchange message (type 12). Inherits from SSLHandshakeMessage and adds parsing + /// functionality such as getting the server key exchange params as raw data (parsing of this may be added in the + /// future) class SSLServerKeyExchangeMessage : public SSLHandshakeMessage { public: - /** - * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be - * used by a user - * @param[in] data The message as raw data - * @param[in] dataLen Message raw data length in bytes - * @param[in] container The SSL handshake layer which shall contain this message - */ + /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be + /// used by a user + /// @param[in] data The message as raw data + /// @param[in] dataLen Message raw data length in bytes + /// @param[in] container The SSL handshake layer which shall contain this message SSLServerKeyExchangeMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {} ~SSLServerKeyExchangeMessage() override = default; - /** - * @return A pointer to the raw data of the server key exchange params. Currently this data can only returned as - * raw, parsing may be added in the future. Notice that if the message is spread over more than 1 packet in a - * way params doesn't exist in the first packet, nullptr will be returned - */ + /// @return A pointer to the raw data of the server key exchange params. Currently this data can only returned + /// as raw, parsing may be added in the future. Notice that if the message is spread over more than 1 packet in + /// a way params doesn't exist in the first packet, nullptr will be returned uint8_t* getServerKeyExchangeParams() const; - /** - * @return The size of the params field. Notice that if the message is spread over more than 1 packet in a way - * the ssl_tls_handshake_layer cannot be parsed from the packet, 0 will be returned. Also, if only part of the - * params exist in current packet (and the rest are on consequent packets), the size that will be returned is - * the size of the part that exists in the current packet (and not total size of params) - */ + /// @return The size of the params field. Notice that if the message is spread over more than 1 packet in a way + /// the ssl_tls_handshake_layer cannot be parsed from the packet, 0 will be returned. Also, if only part of the + /// params exist in current packet (and the rest are on consequent packets), the size that will be returned is + /// the size of the part that exists in the current packet (and not total size of params) size_t getServerKeyExchangeParamsLength() const; // implement abstract methods @@ -864,41 +672,33 @@ namespace pcpp std::string toString() const override; }; - /** - * @class SSLClientKeyExchangeMessage - * Represents SSL/TLS client-key-exchange message (type 16). Inherits from SSLHandshakeMessage and adds parsing - * functionality such as getting the server key exchange params as raw data (parsing of this may be added in the - * future) - */ + /// @class SSLClientKeyExchangeMessage + /// Represents SSL/TLS client-key-exchange message (type 16). Inherits from SSLHandshakeMessage and adds parsing + /// functionality such as getting the server key exchange params as raw data (parsing of this may be added in the + /// future) class SSLClientKeyExchangeMessage : public SSLHandshakeMessage { public: - /** - * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be - * used by a user - * @param[in] data The message as raw data - * @param[in] dataLen Message raw data length in bytes - * @param[in] container The SSL handshake layer which shall contain this message - */ + /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be + /// used by a user + /// @param[in] data The message as raw data + /// @param[in] dataLen Message raw data length in bytes + /// @param[in] container The SSL handshake layer which shall contain this message SSLClientKeyExchangeMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {} ~SSLClientKeyExchangeMessage() override = default; - /** - * @return A pointer to the raw data of the server key exchange params. Currently this data can only be returned - * as raw, parsing may be added in the future. Notice that if the message is spread over more than 1 packet in - * a way params doesn't exist in the first packet, nullptr will be returned - */ + /// @return A pointer to the raw data of the server key exchange params. Currently this data can only be + /// returned as raw, parsing may be added in the future. Notice that if the message is spread over more than 1 + /// packet in a way params doesn't exist in the first packet, nullptr will be returned uint8_t* getClientKeyExchangeParams() const; - /** - * @return The size of the params field. Notice that if the message is spread over more than 1 packet in a way - * the ssl_tls_handshake_layer cannot be parsed from the packet, 0 will be returned. Also, if only part of the - * params exist in current packet (and the rest are on consequent packets), the size that will be returned is - * the size of the part that exists in the current packet (and not the total size of params) - */ + /// @return The size of the params field. Notice that if the message is spread over more than 1 packet in a way + /// the ssl_tls_handshake_layer cannot be parsed from the packet, 0 will be returned. Also, if only part of the + /// params exist in current packet (and the rest are on consequent packets), the size that will be returned is + /// the size of the part that exists in the current packet (and not the total size of params) size_t getClientKeyExchangeParamsLength() const; // implement abstract methods @@ -906,43 +706,33 @@ namespace pcpp std::string toString() const override; }; - /** - * @class SSLCertificateRequestMessage - * Represents SSL/TLS certificate-request message (type 13). Inherits from SSLHandshakeMessage and adds parsing - * functionality such as retrieving client certificate types and authority data - */ + /// @class SSLCertificateRequestMessage + /// Represents SSL/TLS certificate-request message (type 13). Inherits from SSLHandshakeMessage and adds parsing + /// functionality such as retrieving client certificate types and authority data class SSLCertificateRequestMessage : public SSLHandshakeMessage { public: - /** - * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be - * used by a user - * @param[in] data The message as raw data - * @param[in] dataLen Message raw data length in bytes - * @param[in] container The SSL handshake layer which shall contain this message - */ + /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be + /// used by a user + /// @param[in] data The message as raw data + /// @param[in] dataLen Message raw data length in bytes + /// @param[in] container The SSL handshake layer which shall contain this message SSLCertificateRequestMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container); ~SSLCertificateRequestMessage() override = default; - /** - * @return A reference to a vector containing all client certificate types exist in this message - */ + /// @return A reference to a vector containing all client certificate types exist in this message std::vector& getCertificateTypes(); - /** - * @return A pointer to the certificate authority data as raw data (byte array). Parsing of this data may be - * added in the future. Notice that if this message is spread over several packets in a way none of the - * certificate authority data exists in this packet, nullptr will be returned - */ + /// @return A pointer to the certificate authority data as raw data (byte array). Parsing of this data may be + /// added in the future. Notice that if this message is spread over several packets in a way none of the + /// certificate authority data exists in this packet, nullptr will be returned uint8_t* getCertificateAuthorityData() const; - /** - * @return The length of certificate authority data returned by getCertificateAuthorityData(). Notice that if - * this message is spread over several packets in a way none of certificate authority data exists in the current - * packet, 0 will be returned. Also, if some of the data exists in the consequent packets, the length that will - * be returned is the length of data exists in the current packet only (and not the total length) - */ + /// @return The length of certificate authority data returned by getCertificateAuthorityData(). Notice that if + /// this message is spread over several packets in a way none of certificate authority data exists in the + /// current packet, 0 will be returned. Also, if some of the data exists in the consequent packets, the length + /// that will be returned is the length of data exists in the current packet only (and not the total length) size_t getCertificateAuthorityLength() const; // implement abstract methods @@ -953,21 +743,17 @@ namespace pcpp std::vector m_ClientCertificateTypes; }; - /** - * @class SSLServerHelloDoneMessage - * Represents SSL/TLS server-hello-done message (type 14). This message has no additional payload except for the - * common payload described in SSLHandshakeMessage - */ + /// @class SSLServerHelloDoneMessage + /// Represents SSL/TLS server-hello-done message (type 14). This message has no additional payload except for the + /// common payload described in SSLHandshakeMessage class SSLServerHelloDoneMessage : public SSLHandshakeMessage { public: - /** - * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be - * used by a user - * @param[in] data The message as raw data - * @param[in] dataLen Message raw data length in bytes - * @param[in] container The SSL handshake layer which shall contain this message - */ + /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be + /// used by a user + /// @param[in] data The message as raw data + /// @param[in] dataLen Message raw data length in bytes + /// @param[in] container The SSL handshake layer which shall contain this message SSLServerHelloDoneMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {} @@ -979,41 +765,33 @@ namespace pcpp std::string toString() const override; }; - /** - * @class SSLCertificateVerifyMessage - * Represents SSL/TLS certificate-verify message (type 15). Inherits from SSLHandshakeMessage and adds parsing - * functionality such as retrieving signed hash data as raw data (parsing may be added in the future) - * @todo This message type wasn't tested in unit-tests - */ + /// @class SSLCertificateVerifyMessage + /// Represents SSL/TLS certificate-verify message (type 15). Inherits from SSLHandshakeMessage and adds parsing + /// functionality such as retrieving signed hash data as raw data (parsing may be added in the future) + /// @todo This message type wasn't tested in unit-tests class SSLCertificateVerifyMessage : public SSLHandshakeMessage { public: - /** - * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be - * used by a user - * @param[in] data The message as raw data - * @param[in] dataLen Message raw data length in bytes - * @param[in] container The SSL handshake layer which shall contain this message - */ + /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be + /// used by a user + /// @param[in] data The message as raw data + /// @param[in] dataLen Message raw data length in bytes + /// @param[in] container The SSL handshake layer which shall contain this message SSLCertificateVerifyMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {} ~SSLCertificateVerifyMessage() override = default; - /** - * @return A pointer to the signed hash data as raw data (byte array). Parsing of this data may be added - * in the future. Notice that if this message is spread over several packets in a way none of the signed hash - * data exists in this packet, nullptr will be returned - */ + /// @return A pointer to the signed hash data as raw data (byte array). Parsing of this data may be added + /// in the future. Notice that if this message is spread over several packets in a way none of the signed hash + /// data exists in this packet, nullptr will be returned uint8_t* getSignedHash() const; - /** - * @return The length of signed hash data returned by getSignedHash(). Notice that if this message is spread - * over several packets in a way none of this data exists in the current packet, 0 will be returned. Also, if - * some of the data exists in the consequent packets, the length that will be returned will be the length of - * data exists in the current packet only (and not the total length) - */ + /// @return The length of signed hash data returned by getSignedHash(). Notice that if this message is spread + /// over several packets in a way none of this data exists in the current packet, 0 will be returned. Also, if + /// some of the data exists in the consequent packets, the length that will be returned will be the length of + /// data exists in the current packet only (and not the total length) size_t getSignedHashLength() const; // implement abstract methods @@ -1021,41 +799,33 @@ namespace pcpp std::string toString() const override; }; - /** - * @class SSLFinishedMessage - * Represents SSL/TLS finished message (type 20). Inherits from SSLHandshakeMessage and adds parsing - * functionality such as retrieving signed hash data as raw data (parsing may be added in the future) - * @todo This message type wasn't tested in unit-tests - */ + /// @class SSLFinishedMessage + /// Represents SSL/TLS finished message (type 20). Inherits from SSLHandshakeMessage and adds parsing + /// functionality such as retrieving signed hash data as raw data (parsing may be added in the future) + /// @todo This message type wasn't tested in unit-tests class SSLFinishedMessage : public SSLHandshakeMessage { public: - /** - * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be - * used by a user - * @param[in] data The message as raw data - * @param[in] dataLen Message raw data length in bytes - * @param[in] container The SSL handshake layer which shall contain this message - */ + /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be + /// used by a user + /// @param[in] data The message as raw data + /// @param[in] dataLen Message raw data length in bytes + /// @param[in] container The SSL handshake layer which shall contain this message SSLFinishedMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {} ~SSLFinishedMessage() override = default; - /** - * @return A pointer to the signed hash data as raw data (byte array). Parsing of this data may be added - * in the future. Notice that if this message is spread over several packets in a way none of the signed hash - * data exists in this packet, nullptr will be returned - */ + /// @return A pointer to the signed hash data as raw data (byte array). Parsing of this data may be added + /// in the future. Notice that if this message is spread over several packets in a way none of the signed hash + /// data exists in this packet, nullptr will be returned uint8_t* getSignedHash() const; - /** - * @return The length of signed hash data returned by getSignedHash(). Notice that if the message is spread over - * several packets in a way none of this data exists in the current packet, 0 will be returned. Also, if some of - * the data exists in the consequent packets, the length that will be returned will be the length of data exists - * in the current packet only (and not the total length) - */ + /// @return The length of signed hash data returned by getSignedHash(). Notice that if the message is spread + /// over several packets in a way none of this data exists in the current packet, 0 will be returned. Also, if + /// some of the data exists in the consequent packets, the length that will be returned will be the length of + /// data exists in the current packet only (and not the total length) size_t getSignedHashLength() const; // implement abstract methods @@ -1063,40 +833,32 @@ namespace pcpp std::string toString() const override; }; - /** - * @class SSLNewSessionTicketMessage - * Represents SSL/TLS new-session-ticket message (type 4). Inherits from SSLHandshakeMessage and adds parsing - * functionality such as retrieving session ticket data as raw data (parsing may be added in the future) - */ + /// @class SSLNewSessionTicketMessage + /// Represents SSL/TLS new-session-ticket message (type 4). Inherits from SSLHandshakeMessage and adds parsing + /// functionality such as retrieving session ticket data as raw data (parsing may be added in the future) class SSLNewSessionTicketMessage : public SSLHandshakeMessage { public: - /** - * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be - * used by a user - * @param[in] data The message as raw data - * @param[in] dataLen Message raw data length in bytes - * @param[in] container The SSL handshake layer which shall contain this message - */ + /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be + /// used by a user + /// @param[in] data The message as raw data + /// @param[in] dataLen Message raw data length in bytes + /// @param[in] container The SSL handshake layer which shall contain this message SSLNewSessionTicketMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {} ~SSLNewSessionTicketMessage() override = default; - /** - * @return A pointer to the session ticket data as raw data (byte array). Parsing of this data may be added - * in the future. Notice that if this message is spread over several packets in a way none of the signed hash - * data exists in current packet, nullptr will be returned - */ + /// @return A pointer to the session ticket data as raw data (byte array). Parsing of this data may be added + /// in the future. Notice that if this message is spread over several packets in a way none of the signed hash + /// data exists in current packet, nullptr will be returned uint8_t* getSessionTicketData() const; - /** - * @return The length of session ticket data returned by getSessionTicketData(). Notice that if this message is - * spread over several packets in a way none of this data exists in the current packet, 0 will be returned. - * Also, if some of the data exist in the consequent packets, the length that will be returned will be the - * length of the data existing in the current packet only (and not the total length) - */ + /// @return The length of session ticket data returned by getSessionTicketData(). Notice that if this message is + /// spread over several packets in a way none of this data exists in the current packet, 0 will be returned. + /// Also, if some of the data exist in the consequent packets, the length that will be returned will be the + /// length of the data existing in the current packet only (and not the total length) size_t getSessionTicketDataLength() const; // implement abstract methods @@ -1104,22 +866,18 @@ namespace pcpp std::string toString() const override; }; - /** - * @class SSLUnknownMessage - * Represents an unknown type of message or an encrypted message that PcapPlusPlus can't determine its type. In - * these cases length can't always be determined from the message itself (especially if the message is encrypted), - * so the length of this message will always be the size counted from message start until the end of the layer - */ + /// @class SSLUnknownMessage + /// Represents an unknown type of message or an encrypted message that PcapPlusPlus can't determine its type. In + /// these cases length can't always be determined from the message itself (especially if the message is encrypted), + /// so the length of this message will always be the size counted from message start until the end of the layer class SSLUnknownMessage : public SSLHandshakeMessage { public: - /** - * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be - * used by a user - * @param[in] data The message as raw data - * @param[in] dataLen Message raw data length in bytes - * @param[in] container The SSL handshake layer which shall contain this message - */ + /// C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandshakeMessage() and should be + /// used by a user + /// @param[in] data The message as raw data + /// @param[in] dataLen Message raw data length in bytes + /// @param[in] container The SSL handshake layer which shall contain this message SSLUnknownMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {} @@ -1128,16 +886,12 @@ namespace pcpp // implement virtual and abstract methods - /** - * @return Always ::SSL_HANDSHAKE_UNKNOWN (overridden from SSLHandshakeMessage) - */ + /// @return Always ::SSL_HANDSHAKE_UNKNOWN (overridden from SSLHandshakeMessage) SSLHandshakeType getHandshakeType() const override; - /** - * @return The length of the data from message start until the end of the layer. Since it's an unknown type - * or an encrypted message the length parsed from the message can't be guaranteed to be the correct length. - * That's why the length returned is the size until the end of the layer - */ + /// @return The length of the data from message start until the end of the layer. Since it's an unknown type + /// or an encrypted message the length parsed from the message can't be guaranteed to be the correct length. + /// That's why the length returned is the size until the end of the layer size_t getMessageLength() const override; std::string toString() const override; @@ -1168,5 +922,4 @@ namespace pcpp return nullptr; } - } // namespace pcpp diff --git a/Packet++/header/SSLLayer.h b/Packet++/header/SSLLayer.h index adf70a17ba..5c7a5fc010 100644 --- a/Packet++/header/SSLLayer.h +++ b/Packet++/header/SSLLayer.h @@ -1,259 +1,246 @@ -#pragma once +#pragma once #include "PointerVector.h" #include "Layer.h" #include "SSLCommon.h" #include "SSLHandshake.h" -/** - * @file - * This file as well as SSLCommon.h and SSLHandshake.h provide structures that represent SSL/TLS protocol. - * Main features: - * - All common SSL/TLS version are supported from SSL 3.0 to TLS 1.3 - * - All SSL/TLS message types are supported (at least the message types that are not encrypted) - * - More than 300 cipher-suites are supported - * - Only parsing capabilities exist, editing and creation of messages are not supported - * - X509 certificate parsing is not supported - * - *

- * - * __SSL Records:__
- * - * The SSL/TLS protocol has 4 types of records: - * - Handshake record type - * - Change cipher spec record type - * - Alert record type - * - Application data record type - * - * Each record type corresponds to a layer class, and these classes inherit from one base class which is pcpp::SSLLayer. - * The pcpp::SSLLayer is an abstract class which cannot be instantiated. Only its 4 derived classes can be instantiated. - * This means you'll never see a layer of type pcpp::SSLLayer, you'll only see the type of the derived classes. - * A basic class diagram looks like this: - @verbatim - +----------------------------+ - +---| SSLHandshakeLayer | ===> Handshake record type - | +----------------------------+ - | - | +----------------------------+ - +---| SSLChangeCipherSpecLayer | ===> Change cipher spec record type - | +----------------------------+ - | - +------------+ | +----------------------------+ - | SSLLayer |-------------+---| SSLAlertLayer | ===> Alert record type - | (abstract) | | +----------------------------+ - +------------+ | - | +----------------------------+ - +---| SSLApplicationDataLayer | ===> Application data record type - +----------------------------+ - - @endverbatim - * - * A single packet may include several SSL/TLS records, meaning several layer instances of these types, for example: - * - @verbatim - - +--------------------------+ - | EthLayer | - +--------------------------+ - | IPv4Layer | - +--------------------------+ - | TcpLayer | - +--------------------------+ - | SSLHandshakeLayer | \ - +--------------------------+ \ - | SSLChangeCipherSpecLayer | -------- 3 SSL/TLS records in the same packet! - +--------------------------+ / - | SSLHandshakeLayer | / - +--------------------------+ - - @endverbatim - * - *

- * - * __SSL/TLS Handshake records:__
- * - * The SSL/TLS handshake records are the most complex ones. These type of records encapsulate all messages between - * client and server during SSL/TLS connection establishment. To accomplish that a SSL/TLS handshake record holds - * zero or more handshake messages (usually it holds 1 message). These messages form the handshake negotiation between - * the client and the server. There are several types of handshake messages. Some of the are sent from client to server - * and some from server to client. PcapPlusPlus supports 11 of these types (definitely the most common ones). For each - * message there is a designated class which parses the message and exposes its attributes in an easy-to-use manner. - * Here are the list of supported messages: - * - Client-hello - * - Server-hello - * - Certificate - * - Hello-request - * - Server-key-exchange - * - Client-key-exchange - * - Certificate-request - * - Server-hello-done - * - Certificate-verify - * - Finished - * - New-session-ticket - * - * All handshake messages classes inherit from a base abstract class: pcpp::SSLHandshakeMessage which cannot be - * instantiated. - * Also, all of them reside in SSLHandshake.h. Following is a simple diagram of these classes: - * - @verbatim - - SSLHandshakeMessage - | - +-------------------------------+ |--- SSLClientHelloMessage ==> Client-hello message - | SSLHandshakeLayer | | - +-------------------------------+ |--- SSLServerHelloMessage ==> Server-hello message - | -List of SSLHandshakeMessage | | - | Message1 | |---SSLCertificateMessage ==> Certificate message - | Message2 | | - | ... | |---SSLHelloRequestMessage ==> Hello-request message - | | | - +-------------------------------+ |---SSLServerKeyExchangeMessage ==> Server-key-exchange message - | - |---SSLClientKeyExchangeMessage ==> Client-key-exchange message - | - |---SSLCertificateRequestMessage ==> Certificate-request message - | - |---SSLServerHelloDoneMessage ==> Server-hello-done message - | - |---SSLCertificateVerifyMessage ==> Certificate-verify message - | - |---SSLFinishedMessage ==> Finished message - | - |---SSLNewSessionTicketMessage ==> New-session-ticket message - - @endverbatim - * - * In addition, for all handshake messages which aren't supported in PcapPlusPlus or for encrypted handshake messages - * There is another class: pcpp::SSLUnknownMessage - * - *

- * - * __Cipher suites:__
- * - * Cipher suites are named combinations of authentication, encryption, message authentication code (MAC) and key - * exchange algorithms used to negotiate the security settings for a network connection using SSL/TLS. - * There are many known cipher-suites. PcapPlusPlus support above 300 of them, according to this list: - * http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml - * There is a designated class in PcapPlusPlus called pcpp::SSLCipherSuite which represents the cipher-suites and - * provides access to their attributes. Then there is a static instance of this class for each one of the supported - * cipher-suites. - * This means there are 300+ static instances of pcpp::SSLCipherSuite representing the different cipher suites. The user - * can access them through static methods in pcpp::SSLCipherSuite or from client-hello and server-hello messages where - * they appear. - * - *

- * - * __SSL/TLS extensions:__
- * - * SSL/TLS handshake messages, specifically client-hello and server-hello usually include extensions. There are various - * types of extensions - some are more broadly used, some are less. In PcapPlusPlus there is a base class for all - * extensions: pcpp::SSLExtension. This class is instantiable and represents a generic extension, which means extension - * data isn't parsed and given to the user as raw data. Currently there are only two extension that are fully parsed - * which are server-name-indication (pcpp::SSLServerNameIndicationExtension) and SupportedVersions - * (pcpp::SSLSupportedVersionsExtension). - * Both inherit from pcpp::SSLExtension and add additional parsing relevant for the specific extension. - * All other extensions aren't parsed and are represented by instance of pcpp::SSLExtension. - * Access to extensions is done through the handshake messages classes, specifically pcpp::SSLClientHelloMessage and - * pcpp::SSLServerHelloMessage - */ - -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcomment" +#endif +/// @file +/// This file as well as SSLCommon.h and SSLHandshake.h provide structures that represent SSL/TLS protocol. +/// Main features: +/// - All common SSL/TLS version are supported from SSL 3.0 to TLS 1.3 +/// - All SSL/TLS message types are supported (at least the message types that are not encrypted) +/// - More than 300 cipher-suites are supported +/// - Only parsing capabilities exist, editing and creation of messages are not supported +/// - X509 certificate parsing is not supported +/// +///

+/// +/// __SSL Records:__
+/// +/// The SSL/TLS protocol has 4 types of records: +/// - Handshake record type +/// - Change cipher spec record type +/// - Alert record type +/// - Application data record type +/// +/// Each record type corresponds to a layer class, and these classes inherit from one base class which is +/// pcpp::SSLLayer. The pcpp::SSLLayer is an abstract class which cannot be instantiated. Only its 4 derived classes can +/// be instantiated. This means you'll never see a layer of type pcpp::SSLLayer, you'll only see the type of the derived +/// classes. A basic class diagram looks like this: +/// @code{.unparsed} +/// +----------------------------+ +/// +---| SSLHandshakeLayer | ===> Handshake record type +/// | +----------------------------+ +/// | +/// | +----------------------------+ +/// +---| SSLChangeCipherSpecLayer | ===> Change cipher spec record type +/// | +----------------------------+ +/// | +/// +------------+ | +----------------------------+ +/// | SSLLayer |----------+---| SSLAlertLayer | ===> Alert record type +/// | (abstract) | | +----------------------------+ +/// +------------+ | +/// | +----------------------------+ +/// +---| SSLApplicationDataLayer | ===> Application data record type +/// +----------------------------+ +/// @endcode +/// +/// A single packet may include several SSL/TLS records, meaning +/// several layer instances of these types, for example: +/// +/// @code{.unparsed} +/// +--------------------------+ +/// | EthLayer | +/// +--------------------------+ +/// | IPv4Layer | +/// +--------------------------+ +/// | TcpLayer | +/// +--------------------------+ +/// | SSLHandshakeLayer | --+ +/// +--------------------------+ | +/// | SSLChangeCipherSpecLayer | --+----- 3 SSL/TLS records in the same packet! +/// +--------------------------+ | +/// | SSLHandshakeLayer | --+ +/// +--------------------------+ +/// @endcode +/// +///

+/// +/// __SSL/TLS Handshake records:__
+/// +/// The SSL/TLS handshake records are the most complex ones. These type +/// of records encapsulate all messages between client and server during +/// SSL/TLS connection establishment. To accomplish that a SSL/TLS +/// handshake record holds zero or more handshake messages (usually it +/// holds 1 message). These messages form the handshake negotiation +/// between the client and the server. There are several types of +/// handshake messages. Some of the are sent from client to server and +/// some from server to client. PcapPlusPlus supports 11 of these types +/// (definitely the most common ones). For each message there is a +/// designated class which parses the message and exposes its attributes +/// in an easy-to-use manner. Here are the list of supported messages: +/// - Client-hello +/// - Server-hello +/// - Certificate +/// - Hello-request +/// - Server-key-exchange +/// - Client-key-exchange +/// - Certificate-request +/// - Server-hello-done +/// - Certificate-verify +/// - Finished +/// - New-session-ticket +/// +/// All handshake messages classes inherit from a base abstract class: +/// pcpp::SSLHandshakeMessage which cannot be instantiated. Also, all of +/// them reside in SSLHandshake.h. Following is a simple diagram of these +/// classes: +/// +/// @code{.unparsed} +/// SSLHandshakeMessage +/// | +/// +-------------------------------+ |--- SSLClientHelloMessage ==> Client-hello message +/// | SSLHandshakeLayer | | +/// +-------------------------------+ |--- SSLServerHelloMessage ==> Server-hello message +/// | -List of SSLHandshakeMessage | | +/// | Message1 | |---SSLCertificateMessage ==> Certificate message +/// | Message2 | | +/// | ... | |---SSLHelloRequestMessage ==> Hello-request message +/// | | | +/// +-------------------------------+ |---SSLServerKeyExchangeMessage ==> Server-key-exchange message +/// | +/// |---SSLClientKeyExchangeMessage ==> Client-key-exchange message +/// | +/// |---SSLCertificateRequestMessage ==> Certificate-request message +/// | +/// |---SSLServerHelloDoneMessage ==> Server-hello-done message +/// | +/// |---SSLCertificateVerifyMessage ==> Certificate-verify message +/// | +/// |---SSLFinishedMessage ==> Finished message +/// | +/// |---SSLNewSessionTicketMessage ==> New-session-ticket message +/// @endcode +/// +/// In addition, for all handshake messages which aren't supported in PcapPlusPlus or for encrypted +/// handshake messages There is another class: pcpp::SSLUnknownMessage +/// +///

+/// +/// __Cipher suites:__
+/// +/// Cipher suites are named combinations of authentication, encryption, message authentication code +/// (MAC) and key exchange algorithms used to negotiate the security settings for a network connection +/// using SSL/TLS. There are many known cipher-suites. PcapPlusPlus support above 300 of them, +/// according to this list: http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml There +/// is a designated class in PcapPlusPlus called pcpp::SSLCipherSuite which represents the +/// cipher-suites and provides access to their attributes. Then there is a static instance of this +/// class for each one of the supported cipher-suites. This means there are 300+ static instances of +/// pcpp::SSLCipherSuite representing the different cipher suites. The user can access them through +/// static methods in pcpp::SSLCipherSuite or from client-hello and server-hello messages where they +/// appear. +/// +///

+/// +/// __SSL/TLS extensions:__
+/// +/// SSL/TLS handshake messages, specifically client-hello and server-hello usually include extensions. +/// There are various types of extensions - some are more broadly used, some are less. In PcapPlusPlus +/// there is a base class for all extensions: pcpp::SSLExtension. This class is instantiable and +/// represents a generic extension, which means extension data isn't parsed and given to the user as +/// raw data. Currently there are only two extension that are fully parsed which are +/// server-name-indication (pcpp::SSLServerNameIndicationExtension) and SupportedVersions +/// (pcpp::SSLSupportedVersionsExtension). +/// Both inherit from pcpp::SSLExtension and add additional parsing relevant for the specific +/// extension. All other extensions aren't parsed and are represented by instance of +/// pcpp::SSLExtension. Access to extensions is done through the handshake messages classes, +/// specifically pcpp::SSLClientHelloMessage and pcpp::SSLServerHelloMessage +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif + +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @class SSLLayer - * The base class for the 4 record type classes. Each record type is represented as a layer. See SSLLayer.h for - * detailed explanation of the TLS/SSL protocol support in PcapPlusPlus. - * This class provides the common functionality used by all record types and also contains static methods for - * identifying an creating SSL/TLS record type layers - */ + /// @class SSLLayer + /// The base class for the 4 record type classes. Each record type is represented as a layer. See SSLLayer.h for + /// detailed explanation of the TLS/SSL protocol support in PcapPlusPlus. + /// This class provides the common functionality used by all record types and also contains static methods for + /// identifying an creating SSL/TLS record type layers class SSLLayer : public Layer { public: - /** - * A static method that checks whether the port is considered as SSL/TLS - * @param[in] port The port number to be checked - */ + /// A static method that checks whether the port is considered as SSL/TLS + /// @param[in] port The port number to be checked static inline bool isSSLPort(uint16_t port); - /** - * A static methods that gets raw data of a layer and checks whether this data is a SSL/TLS record or not. This - * check is done using the source/dest port and matching of a legal record type in the raw data. The list of - * ports identified as SSL/TLS is hard-coded and includes the following ports: - * - Port 443 [HTTPS] - * - Port 261 [NSIIOPS] - * - Port 448 [DDM-SSL] - * - Port 563 [NNTPS] - * - Port 614 [SSHELL] - * - Port 465 [SMTPS] - * - Port 636 [LDAPS] - * - Port 989 [FTPS - data] - * - Port 990 [FTPS - control] - * - Port 992 [Telnet over TLS/SSL] - * - Port 993 [IMAPS] - * - Port 994 [IRCS] - * - Port 995 [POP3S] - * @param[in] srcPort The source port of the packet that contains the raw data. Source port (or dest port) are a - * criteria to identify SSL/TLS packets - * @param[in] dstPort The dest port of the packet that contains the raw data. Dest port (or source port) are a - * criteria to identify SSL/TLS packets - * @param[in] data The data to check - * @param[in] dataLen Length (in bytes) of the data - * @param[in] ignorePorts SSL/TLS ports are only relevant for parsing the first SSL/TLS message, but are not - * relevant for parsing subsequent messages. This parameter can be set to "true" to skip SSL/TLS ports check. - * This is an optional parameter and its default is "false" - */ + /// A static methods that gets raw data of a layer and checks whether this data is a SSL/TLS record or not. This + /// check is done using the source/dest port and matching of a legal record type in the raw data. The list of + /// ports identified as SSL/TLS is hard-coded and includes the following ports: + /// - Port 443 [HTTPS] + /// - Port 261 [NSIIOPS] + /// - Port 448 [DDM-SSL] + /// - Port 563 [NNTPS] + /// - Port 614 [SSHELL] + /// - Port 465 [SMTPS] + /// - Port 636 [LDAPS] + /// - Port 989 [FTPS - data] + /// - Port 990 [FTPS - control] + /// - Port 992 [Telnet over TLS/SSL] + /// - Port 993 [IMAPS] + /// - Port 994 [IRCS] + /// - Port 995 [POP3S] + /// @param[in] srcPort The source port of the packet that contains the raw data. Source port (or dest port) are + /// a criteria to identify SSL/TLS packets + /// @param[in] dstPort The dest port of the packet that contains the raw data. Dest port (or source port) are a + /// criteria to identify SSL/TLS packets + /// @param[in] data The data to check + /// @param[in] dataLen Length (in bytes) of the data + /// @param[in] ignorePorts SSL/TLS ports are only relevant for parsing the first SSL/TLS message, but are not + /// relevant for parsing subsequent messages. This parameter can be set to "true" to skip SSL/TLS ports check. + /// This is an optional parameter and its default is "false" static bool IsSSLMessage(uint16_t srcPort, uint16_t dstPort, uint8_t* data, size_t dataLen, bool ignorePorts = false); - /** - * A static method that creates SSL/TLS layers by raw data. This method parses the raw data, finds if and which - * SSL/TLS record it is and creates the corresponding record layer. It's the responsibility of the user to free - * the created object when done using it - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - * @return A pointer to the newly created record layer. If no SSL/TLS record could be identified from the raw - * data nullptr is returned - */ + /// A static method that creates SSL/TLS layers by raw data. This method parses the raw data, finds if and which + /// SSL/TLS record it is and creates the corresponding record layer. It's the responsibility of the user to free + /// the created object when done using it + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in + /// @return A pointer to the newly created record layer. If no SSL/TLS record could be identified from the raw + /// data nullptr is returned static SSLLayer* createSSLMessage(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * Get a pointer to the record header. Notice this points directly to the data, so every change will change the - * actual packet data - * @return A pointer to the @ref ssl_tls_record_layer - */ + /// Get a pointer to the record header. Notice this points directly to the data, so every change will change the + /// actual packet data + /// @return A pointer to the @ref ssl_tls_record_layer ssl_tls_record_layer* getRecordLayer() const { return reinterpret_cast(m_Data); } - /** - * @return The SSL/TLS version used in this record (parsed from the record) - */ + /// @return The SSL/TLS version used in this record (parsed from the record) SSLVersion getRecordVersion() const; - /** - * @return The SSL/TLS record type as parsed from the record - */ + /// @return The SSL/TLS record type as parsed from the record SSLRecordType getRecordType() const; // implement abstract methods - /** - * @return The record size as extracted from the record data (in ssl_tls_record_layer#length) - */ + /// @return The record size as extracted from the record data (in ssl_tls_record_layer#length) size_t getHeaderLen() const override; - /** - * Several SSL/TLS records can reside in a single packets. So this method checks the remaining data and if it's - * identified as SSL/TLS it creates another SSL/TLS record layer as the next layer - */ + /// Several SSL/TLS records can reside in a single packets. So this method checks the remaining data and if it's + /// identified as SSL/TLS it creates another SSL/TLS record layer as the next layer void parseNextLayer() override; OsiModelLayer getOsiModelLayer() const override @@ -270,96 +257,83 @@ namespace pcpp // The graph below will break the code formatting, so it's disabled. // clang-format off - /** - * @class SSLHandshakeLayer - * Represents SSL/TLS handshake layer. This layer may contain one or more handshake messages (all of them inherit - * from the base class SSLHandshakeMessage) which are the SSL/TLS handshake message sent between a client and a - * server until they establish a secure connection (e.g client-hello, server-hello, certificate, - * client-key-exchange, server-key-exchange, etc.). - * Usually this layer will contain just one message (as the first example below - * demonstrates). But there are cases a layer may contain more than 1 message. To better explain this layer - * structure. We'll use 2 examples. The first will be client-hello message. The layer structure will look like this: - @verbatim - - |------------------- SSLHandshakeLayer ----------------------| - +----------------------+-------------------------------------+ - | ssl_tls_record_layer | SSLClientHelloMessage | - | struct | | - +----------------------+-------------------------------------+ - / | \ | \ \ \ - / version \ | handshake \ \ \ - / TLS1_0 \ type \ \ rest of - type \ | SSL_CLIENT_HELLO \ \ message fields... - SSL_HANDSHAKE length handshake \ - (22) xxx | version message - TLS1_2 length - | yyy - @endverbatim - - * Second example is a multiple-message handshake layer comprises of server-hello, certificate and - * server-key-exchange messages: - - @verbatim - - |---------------------------------------------- SSLHandshakeLayer -----------------------------------------------------| - +----------------------+-------------------------------------+---------------------------+-----------------------------+ - | ssl_tls_record_layer | SSLServerHelloMessage | SSLCertificateMessage | SSLServerKeyExchangeMessage | - | struct | | | | - +----------------------+-------------------------------------+---------------------------+-----------------------------+ - / | \ | \ \ | \ | \ - / version \ | handshake \ rest of | | rest | | rest - / TLS1_0 \ type \ message handshake of fields... handshake of fields... - type \ | SSL_SERVER_HELLO \ fields...| type | type - SSL_HANDSHAKE length handshake SSL_CERTIFICATE SSL_SERVER_KEY_EXCHANGE - (22) xxx | version,length | | - @endverbatim - */ + /// @class SSLHandshakeLayer + /// Represents SSL/TLS handshake layer. This layer may contain one or more handshake messages (all of them inherit + /// from the base class SSLHandshakeMessage) which are the SSL/TLS handshake message sent between a client and a + /// server until they establish a secure connection (e.g client-hello, server-hello, certificate, + /// client-key-exchange, server-key-exchange, etc.). + /// Usually this layer will contain just one message (as the first example below + /// demonstrates). But there are cases a layer may contain more than 1 message. To better explain this layer + /// structure. We'll use 2 examples. The first will be client-hello message. The layer structure will look like this: + /// + /// @code{.unparsed} + /// |----------------------------- SSLHandshakeLayer ----------------------------------------| + /// +--------------------------------+-------------------------------------------------------+ + /// | ssl_tls_record_layer | SSLClientHelloMessage | + /// | struct | | + /// +--------------------------------+-------------------------------------------------------+ + /// | / | \ | \ \ \ | + /// | / version \ | handshake \ \ \ | + /// | / TLS1_0 \ type \ \ rest of | + /// | type \ | SSL_CLIENT_HELLO \ \ message fields... | + /// | SSL_HANDSHAKE length handshake \ | + /// | (22) xxx | version message | + /// | TLS1_2 length | + /// | | yyy | + /// @endcode + /// + /// Second example is a multiple-message handshake layer comprises of server-hello, certificate and + /// server-key-exchange messages: + /// + /// @code{.unparsed} + /// |------------------------------------------------------- SSLHandshakeLayer ------------------------------------------------------| + /// +--------------------------------+-------------------------------------+---------------------------+-----------------------------+ + /// | ssl_tls_record_layer | SSLServerHelloMessage | SSLCertificateMessage | SSLServerKeyExchangeMessage | + /// | struct | | | | + /// +--------------------------------+-------------------------------------+---------------------------+-----------------------------+ + /// | / | \ | \ \ | \ | \ | + /// | / version \ | handshake \ rest of | | rest | | rest | + /// | / TLS1_0 \ type \ message handshake of fields... handshake of fields... | + /// | type \ | SSL_SERVER_HELLO \ fields...| type | type | + /// | SSL_HANDSHAKE length handshake SSL_CERTIFICATE SSL_SERVER_KEY_EXCHANGE | + /// | (22) xxx | version,length | | | + /// @endcode // clang-format on class SSLHandshakeLayer : public SSLLayer { public: - /** - * C'tor for this class that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// C'tor for this class that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in SSLHandshakeLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * @return The number of messages in this layer instance - */ + /// @return The number of messages in this layer instance size_t getHandshakeMessagesCount() const { return m_MessageList.size(); } - /** - * Get a pointer to an handshake message by index. The message are numbered according to their order of - * appearance in the layer. If index is out of bounds (less than 0 or larger than total amount of message) - * nullptr will be returned - * @param[in] index The index of the message to return - * @return The pointer to the message object or nullptr if index is out of bounds - */ + /// Get a pointer to an handshake message by index. The message are numbered according to their order of + /// appearance in the layer. If index is out of bounds (less than 0 or larger than total amount of message) + /// nullptr will be returned + /// @param[in] index The index of the message to return + /// @return The pointer to the message object or nullptr if index is out of bounds SSLHandshakeMessage* getHandshakeMessageAt(int index) const; - /** - * A templated method to get a message of a certain type. If no message of such type is found, nullptr is - * returned - * @return A pointer to the message of the requested type, nullptr if not found - */ + /// A templated method to get a message of a certain type. If no message of such type is found, nullptr is + /// returned + /// @return A pointer to the message of the requested type, nullptr if not found template THandshakeMessage* getHandshakeMessageOfType() const; - /** - * A templated method to get the first message of a certain type, starting to search from a certain message. - * For example: if the layer looks like: HelloRequest(1) -> HelloRequest(2) - * and the user put HelloRequest(1) as a parameter and wishes to search for an HelloRequest message, the - * HelloRequest(2) will be returned.
- * If no layer of such type is found, nullptr is returned - * @param[in] after A pointer to the message to start search from - * @return A pointer to the message of the requested type, nullptr if not found - */ + /// A templated method to get the first message of a certain type, starting to search from a certain message. + /// For example: if the layer looks like: HelloRequest(1) -> HelloRequest(2) + /// and the user put HelloRequest(1) as a parameter and wishes to search for an HelloRequest message, the + /// HelloRequest(2) will be returned.
+ /// If no layer of such type is found, nullptr is returned + /// @param[in] after A pointer to the message to start search from + /// @return A pointer to the message of the requested type, nullptr if not found template THandshakeMessage* getNextHandshakeMessageOfType(const SSLHandshakeMessage* after) const; @@ -367,9 +341,7 @@ namespace pcpp std::string toString() const override; - /** - * There are no calculated fields for this layer - */ + /// There are no calculated fields for this layer void computeCalculateFields() override {} @@ -377,21 +349,17 @@ namespace pcpp PointerVector m_MessageList; }; // class SSLHandshakeLayer - /** - * @class SSLChangeCipherSpecLayer - * Represents SSL/TLS change-cipher-spec layer. This layer has no additional fields besides common fields described - * in SSLLayer - */ + /// @class SSLChangeCipherSpecLayer + /// Represents SSL/TLS change-cipher-spec layer. This layer has no additional fields besides common fields described + /// in SSLLayer class SSLChangeCipherSpecLayer : public SSLLayer { public: - /** - * C'tor for this class that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// C'tor for this class that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in SSLChangeCipherSpecLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : SSLLayer(data, dataLen, prevLayer, packet) {} @@ -402,94 +370,72 @@ namespace pcpp std::string toString() const override; - /** - * There are no calculated fields for this layer - */ + /// There are no calculated fields for this layer void computeCalculateFields() override {} }; // class SSLChangeCipherSpecLayer - /** - * @class SSLAlertLayer - * Represents SSL/TLS alert layer. Inherits from SSLLayer and adds parsing functionality such as retrieving the - * alert level and description - */ + /// @class SSLAlertLayer + /// Represents SSL/TLS alert layer. Inherits from SSLLayer and adds parsing functionality such as retrieving the + /// alert level and description class SSLAlertLayer : public SSLLayer { public: - /** - * C'tor for this class that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// C'tor for this class that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in SSLAlertLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : SSLLayer(data, dataLen, prevLayer, packet) {} ~SSLAlertLayer() override = default; - /** - * @return SSL/TLS alert level. Will return ::SSL_ALERT_LEVEL_ENCRYPTED if alert is encrypted - */ + /// @return SSL/TLS alert level. Will return ::SSL_ALERT_LEVEL_ENCRYPTED if alert is encrypted SSLAlertLevel getAlertLevel() const; - /** - * @return SSL/TLS alert description. Will return ::SSL_ALERT_ENCRYPTED if alert is encrypted - */ + /// @return SSL/TLS alert description. Will return ::SSL_ALERT_ENCRYPTED if alert is encrypted SSLAlertDescription getAlertDescription(); // implement abstract methods std::string toString() const override; - /** - * There are no calculated fields for this layer - */ + /// There are no calculated fields for this layer void computeCalculateFields() override {} }; // class SSLAlertLayer - /** - * @class SSLApplicationDataLayer - * Represents SSL/TLS application data layer. This message contains the encrypted data transferred from client to - * server and vice-versa after the SSL/TLS handshake was completed successfully - */ + /// @class SSLApplicationDataLayer + /// Represents SSL/TLS application data layer. This message contains the encrypted data transferred from client to + /// server and vice-versa after the SSL/TLS handshake was completed successfully class SSLApplicationDataLayer : public SSLLayer { public: - /** - * C'tor for this class that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// C'tor for this class that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in SSLApplicationDataLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : SSLLayer(data, dataLen, prevLayer, packet) {} ~SSLApplicationDataLayer() override = default; - /** - * @return A pointer to the encrypted data. This data can be decrypted only if you have the symmetric key - * that was agreed between the client and the server during SSL/TLS handshake process - */ + /// @return A pointer to the encrypted data. This data can be decrypted only if you have the symmetric key + /// that was agreed between the client and the server during SSL/TLS handshake process uint8_t* getEncryptedData() const; - /** - * @return The length in bytes of the encrypted data returned in getEncryptedData() - */ + /// @return The length in bytes of the encrypted data returned in getEncryptedData() size_t getEncryptedDataLen() const; // implement abstract methods std::string toString() const override; - /** - * There are no calculated fields for this layer - */ + /// There are no calculated fields for this layer void computeCalculateFields() override {} }; // class SSLApplicationDataLayer @@ -563,5 +509,4 @@ namespace pcpp return false; } } // isSSLPort - } // namespace pcpp diff --git a/Packet++/header/SdpLayer.h b/Packet++/header/SdpLayer.h index 74e6e3d0fc..3e83a09c38 100644 --- a/Packet++/header/SdpLayer.h +++ b/Packet++/header/SdpLayer.h @@ -6,158 +6,139 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { -/** Protocol version (v) */ +/// Protocol version (v) #define PCPP_SDP_PROTOCOL_VERSION_FIELD "v" -/** Originator and session identifier (o) */ +/// Originator and session identifier (o) #define PCPP_SDP_ORIGINATOR_FIELD "o" -/** Session name (s) */ +/// Session name (s) #define PCPP_SDP_SESSION_NAME_FIELD "s" -/** Session title, media title or short information (i) */ +/// Session title, media title or short information (i) #define PCPP_SDP_INFO_FIELD "i" -/** URI of description (u) */ +/// URI of description (u) #define PCPP_SDP_URI_FIELD "u" -/** Email address with optional name of contacts (e) */ +/// Email address with optional name of contacts (e) #define PCPP_SDP_EMAIL_FIELD "e" -/** Phone number with optional name of contacts (p) */ +/// Phone number with optional name of contacts (p) #define PCPP_SDP_PHONE_FIELD "p" -/** Connection information (c) */ +/// Connection information (c) #define PCPP_SDP_CONNECTION_INFO_FIELD "c" -/** Bandwidth information (b) */ +/// Bandwidth information (b) #define PCPP_SDP_BANDWIDTH_FIELD "b" -/** Time the session is active (t) */ +/// Time the session is active (t) #define PCPP_SDP_TIME_FIELD "t" -/** Repeat times (r) */ +/// Repeat times (r) #define PCPP_SDP_REPEAT_TIMES_FIELD "r" -/** Time zone adjustments (z) */ +/// Time zone adjustments (z) #define PCPP_SDP_TIME_ZONE_FIELD "z" -/** Encryption key (k) */ +/// Encryption key (k) #define PCPP_SDP_ENCRYPTION_KEY_FIELD "k" -/** Media attribute (a) */ +/// Media attribute (a) #define PCPP_SDP_MEDIA_ATTRIBUTE_FIELD "a" -/** Media name and transport address (m) */ +/// Media name and transport address (m) #define PCPP_SDP_MEDIA_NAME_FIELD "m" - /** - * @class SdpLayer - * Represents a SDP (Session Description Protocol) message. SDP is a text-based protocol described by a series of - * fields, one per line (lines are separated by CRLF). The form of each field is as follows:
- * @code - * [character]=[value] - * @endcode - * Each character represents a certain type of field. All field type are represented as macros in SdpLayer.h file - * (for example: PCPP_SDP_ORIGINATOR_FIELD is a macro for the originator field (o=) ).
- * For more details about SDP structure please refer to its Wikipedia page: - * https://en.wikipedia.org/wiki/Session_Description_Protocol - */ + /// @class SdpLayer + /// Represents a SDP (Session Description Protocol) message. SDP is a text-based protocol described by a series of + /// fields, one per line (lines are separated by CRLF). The form of each field is as follows:
+ /// @code + /// [character]=[value] + /// @endcode + /// Each character represents a certain type of field. All field type are represented as macros in SdpLayer.h file + /// (for example: PCPP_SDP_ORIGINATOR_FIELD is a macro for the originator field (o=) ).
+ /// For more details about SDP structure please refer to its Wikipedia page: + /// https://en.wikipedia.org/wiki/Session_Description_Protocol class SdpLayer : public TextBasedProtocolMessage { public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in SdpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * An empty c'tor which initialize an empty message with no fields - */ + /// An empty c'tor which initialize an empty message with no fields SdpLayer(); - /** - * A c'tor which initializes a message with the minimum required fields.
- * After this c'tor the message will look like this: - * - * @code - * v=0 - * o=[username] [sessionID] [sessionVersion] IN IP4 [ipAddress] - * s=[sessionName] - * c=IN IP4 [ipAddress] - * t=[startTime] [endTime] - * @endcode - * - * @param[in] username User's login on the originating host - * @param[in] sessionID A globally unique identifier for the session - * @param[in] sessionVersion A version number for this session description - * @param[in] ipAddress The address of the machine from which the session is created - * @param[in] sessionName A textual session name - * @param[in] startTime The start time of the session - * @param[in] stopTime The stop time of the session - */ + /// A c'tor which initializes a message with the minimum required fields.
+ /// After this c'tor the message will look like this: + /// + /// @code + /// v=0 + /// o=[username] [sessionID] [sessionVersion] IN IP4 [ipAddress] + /// s=[sessionName] + /// c=IN IP4 [ipAddress] + /// t=[startTime] [endTime] + /// @endcode + /// + /// @param[in] username User's login on the originating host + /// @param[in] sessionID A globally unique identifier for the session + /// @param[in] sessionVersion A version number for this session description + /// @param[in] ipAddress The address of the machine from which the session is created + /// @param[in] sessionName A textual session name + /// @param[in] startTime The start time of the session + /// @param[in] stopTime The stop time of the session SdpLayer(const std::string& username, long sessionID, long sessionVersion, IPv4Address ipAddress, const std::string& sessionName, long startTime, long stopTime); ~SdpLayer() override = default; - /** - * A copy constructor for this layer. Inherits the base copy constructor and doesn't add - * anything else - * @param[in] other The instance to copy from - */ + /// A copy constructor for this layer. Inherits the base copy constructor and doesn't add + /// anything else + /// @param[in] other The instance to copy from SdpLayer(const SdpLayer& other) : TextBasedProtocolMessage(other) {} - /** - * An assignment operator overload for this layer. Inherits the base assignment operator - * and doesn't add anything else - * @param[in] other The instance to copy from - */ + /// An assignment operator overload for this layer. Inherits the base assignment operator + /// and doesn't add anything else + /// @param[in] other The instance to copy from SdpLayer& operator=(const SdpLayer& other) { TextBasedProtocolMessage::operator=(other); return *this; } - /** - * The 'originator' field (o=) contains the IP address of the the machine from which the session is created. - * This IP address can be used to track the RTP data relevant for the call. This method extracts this IP address - * from the 'originator' field and returns it. A value of IPv4Address#Zero will be returned in the following - * cases: (1) if 'originator' field doesn't exist; (2) if it doesn't contain the IP address; (3) if it contains - * a non-IPv4 address - * @return The IP address of the the machine from which the session is created - */ + /// The 'originator' field (o=) contains the IP address of the the machine from which the session is created. + /// This IP address can be used to track the RTP data relevant for the call. This method extracts this IP + /// address from the 'originator' field and returns it. A value of IPv4Address#Zero will be returned in the + /// following cases: (1) if 'originator' field doesn't exist; (2) if it doesn't contain the IP address; (3) if + /// it contains a non-IPv4 address + /// @return The IP address of the the machine from which the session is created IPv4Address getOwnerIPv4Address() const; - /** - * The 'media-description' field (m=) contains the transport port to which the media stream is sent. This port - * can be used to track the RTP data relevant for the call. This method extracts this port from the - * 'media-description' field and returns it. Since a SDP message can contain several 'media-description' fields, - * one for each media type (e.g audio, image, etc.), the user is required to provide the media type. A value of - * 0 will be returned in the following cases: (1) if 'media-description' field doesn't exist; (2) if provided - * media type was not found; (3) if 'media-description' field didn't contain a port - * @param[in] mediaType The media type to search in - * @return The transport port to which the media stream is sent - */ + /// The 'media-description' field (m=) contains the transport port to which the media stream is sent. This port + /// can be used to track the RTP data relevant for the call. This method extracts this port from the + /// 'media-description' field and returns it. Since a SDP message can contain several 'media-description' + /// fields, one for each media type (e.g audio, image, etc.), the user is required to provide the media type. A + /// value of 0 will be returned in the following cases: (1) if 'media-description' field doesn't exist; (2) if + /// provided media type was not found; (3) if 'media-description' field didn't contain a port + /// @param[in] mediaType The media type to search in + /// @return The transport port to which the media stream is sent uint16_t getMediaPort(const std::string& mediaType) const; - /** - * Adds a 'media-description' field (m=) with all necessary data and attribute fields (a=) with data relevant - * for this media.
After this method is run the following block of fields will be added at the end of the - * message: - * - * @code - * m=[mediaType] [mediaPort] [mediaProtocol] [mediaFormat] - * a=[1st media attribute] - * a=[2nd media attribute] - * ... - * @endcode - * - * @param[in] mediaType The media type, usually "audio", "video", "text" or "image" - * @param[in] mediaPort The transport port to which the media stream is sent - * @param[in] mediaProtocol The transport protocol, usually "udp", "RTP/AVP" or "RTP/SAVP" - * @param[in] mediaFormat A space-separated list of media format description. For example: "8 96" - * @param[in] mediaAttributes A vector of media attributes. Each string in this vector will be - * translated into a 'media-attribute' field (a=) - * @return True if all fields were added properly or false if at least one field was failed to be added - */ + /// Adds a 'media-description' field (m=) with all necessary data and attribute fields (a=) with data relevant + /// for this media.
After this method is run the following block of fields will be added at the end of the + /// message: + /// + /// @code + /// m=[mediaType] [mediaPort] [mediaProtocol] [mediaFormat] + /// a=[1st media attribute] + /// a=[2nd media attribute] + /// ... + /// @endcode + /// + /// @param[in] mediaType The media type, usually "audio", "video", "text" or "image" + /// @param[in] mediaPort The transport port to which the media stream is sent + /// @param[in] mediaProtocol The transport protocol, usually "udp", "RTP/AVP" or "RTP/SAVP" + /// @param[in] mediaFormat A space-separated list of media format description. For example: "8 96" + /// @param[in] mediaAttributes A vector of media attributes. Each string in this vector will be + /// translated into a 'media-attribute' field (a=) + /// @return True if all fields were added properly or false if at least one field was failed to be added bool addMediaDescription(const std::string& mediaType, uint16_t mediaPort, const std::string& mediaProtocol, const std::string& mediaFormat, const std::vector& mediaAttributes); diff --git a/Packet++/header/SingleCommandTextProtocol.h b/Packet++/header/SingleCommandTextProtocol.h index cee3343f8f..edf4fa88cc 100644 --- a/Packet++/header/SingleCommandTextProtocol.h +++ b/Packet++/header/SingleCommandTextProtocol.h @@ -5,16 +5,11 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * Class for single command text based protocol (FTP, SMTP) messages - */ + /// Class for single command text based protocol (FTP, SMTP) messages class SingleCommandTextProtocol : public Layer { private: @@ -36,21 +31,17 @@ namespace pcpp std::string getCommandOptionInternal() const; public: - /** - * Checks if the current message is a multi-line reply. Multi-line messages are indicated with a Hyphen (-) - * immediately after reply code. - * @return true If this is a multi-line reply - * @return false Otherwise - */ + /// Checks if the current message is a multi-line reply. Multi-line messages are indicated with a Hyphen (-) + /// immediately after reply code. + /// @return true If this is a multi-line reply + /// @return false Otherwise bool isMultiLine() const; - /** - * A static method that takes a byte array and detects whether it is a single command text based message. - * All single command text based message terminated with single "\r\n". - * @param[in] data A byte array - * @param[in] dataSize The byte array size (in bytes) - * @return True if the data is identified as single command text based message - */ + /// A static method that takes a byte array and detects whether it is a single command text based message. + /// All single command text based message terminated with single "\r\n". + /// @param[in] data A byte array + /// @param[in] dataSize The byte array size (in bytes) + /// @return True if the data is identified as single command text based message static bool isDataValid(const uint8_t* data, size_t dataSize); }; } // namespace pcpp diff --git a/Packet++/header/SipLayer.h b/Packet++/header/SipLayer.h index f9ceae6337..bd25e4cd83 100644 --- a/Packet++/header/SipLayer.h +++ b/Packet++/header/SipLayer.h @@ -4,98 +4,91 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { // some popular SIP header fields -/** From field */ +/// From field #define PCPP_SIP_FROM_FIELD "From" -/** To field */ +/// To field #define PCPP_SIP_TO_FIELD "To" -/** Via field */ +/// Via field #define PCPP_SIP_VIA_FIELD "Via" -/** Call-ID field */ +/// Call-ID field #define PCPP_SIP_CALL_ID_FIELD "Call-ID" -/** Content-Type field */ +/// Content-Type field #define PCPP_SIP_CONTENT_TYPE_FIELD "Content-Type" -/** Content-Length field */ +/// Content-Length field #define PCPP_SIP_CONTENT_LENGTH_FIELD "Content-Length" -/** Content-Disposition field */ +/// Content-Disposition field #define PCPP_SIP_CONTENT_DISPOSITION_FIELD "Content-Disposition" -/** Content-Encoding field */ +/// Content-Encoding field #define PCPP_SIP_CONTENT_ENCODING_FIELD "Content-Encoding" -/** Content-Language field */ +/// Content-Language field #define PCPP_SIP_CONTENT_LANGUAGE_FIELD "Content-Language" -/** CSeq field */ +/// CSeq field #define PCPP_SIP_CSEQ_FIELD "CSeq" -/** Contact field */ +/// Contact field #define PCPP_SIP_CONTACT_FIELD "Contact" -/** Max-Forwards field */ +/// Max-Forwards field #define PCPP_SIP_MAX_FORWARDS_FIELD "Max-Forwards" -/** User-Agent field */ +/// User-Agent field #define PCPP_SIP_USER_AGENT_FIELD "User-Agent" -/** Accept field */ +/// Accept field #define PCPP_SIP_ACCEPT_FIELD "Accept" -/** Accept-Encoding field */ +/// Accept-Encoding field #define PCPP_SIP_ACCEPT_ENCODING_FIELD "Accept-Encoding" -/** Accept-Language field */ +/// Accept-Language field #define PCPP_SIP_ACCEPT_LANGUAGE_FIELD "Accept-Language" -/** Allow field */ +/// Allow field #define PCPP_SIP_ALLOW_FIELD "Allow" -/** Authorization field */ +/// Authorization field #define PCPP_SIP_AUTHORIZATION_FIELD "Authorization" -/** Date field */ +/// Date field #define PCPP_SIP_DATE_FIELD "Date" -/** MIME-Version field */ +/// MIME-Version field #define PCPP_SIP_MIME_VERSION_FIELD "MIME-Version" -/** Reason field */ +/// Reason field #define PCPP_SIP_REASON_FIELD "Reason" -/** Supported field */ +/// Supported field #define PCPP_SIP_SUPPORTED_FIELD "Supported" -/** Server field */ +/// Server field #define PCPP_SIP_SERVER_FIELD "Server" -/** WWW-Authenticate fild */ +/// WWW-Authenticate fild #define PCPP_SIP_WWW_AUTHENTICATE_FIELD "WWW-Authenticate" -/** Retry-After field */ +/// Retry-After field #define PCPP_SIP_RETRY_AFTER_FIELD "Retry-After" -/** Record-Route field */ +/// Record-Route field #define PCPP_SIP_RECORD_ROUTE_FIELD "Record-Route" - /** - * @class SipLayer - * Represents a general SIP message. It's an abstract class and cannot be instantiated. It's inherited by - * SipRequestLayer and SipResponseLayer - */ + /// @class SipLayer + /// Represents a general SIP message. It's an abstract class and cannot be instantiated. It's inherited by + /// SipRequestLayer and SipResponseLayer class SipLayer : public TextBasedProtocolMessage { public: - /** - * The length of the body of many SIP response messages is determined by a SIP header field called - * "Content-Length". This method parses this field, extracts its value and return it. If this field doesn't - * exist 0 is returned - * @return SIP response body length determined by "Content-Length" field - */ + /// The length of the body of many SIP response messages is determined by a SIP header field called + /// "Content-Length". This method parses this field, extracts its value and return it. If this field doesn't + /// exist 0 is returned + /// @return SIP response body length determined by "Content-Length" field int getContentLength() const; - /** - * The length of the body of many SIP messages is determined by a header field called "Content-Length". This - * method sets The content-length field value. The method supports several cases: - * - If the "Content-Length" field exists - the method will only replace the existing value with the new value - * - If the "Content-Length" field doesn't exist - the method will create this field and put the value in it. - * Here are also 2 cases: - * - If prevFieldName is specified - the new "Content-Length" field will be created after it - * - If prevFieldName isn't specified or doesn't exist - the new "Content-Length" field will be created as the - * last field before end-of-header field - * - * @param[in] contentLength The content length value to set - * @param[in] prevFieldName Optional parameter, if specified and "Content-Length" field doesn't exist, it will - * be created after this field - * @return A pointer to the "Content-Length" field, or nullptr if creation failed - */ + /// The length of the body of many SIP messages is determined by a header field called "Content-Length". This + /// method sets The content-length field value. The method supports several cases: + /// - If the "Content-Length" field exists - the method will only replace the existing value with the new value + /// - If the "Content-Length" field doesn't exist - the method will create this field and put the value in it. + /// Here are also 2 cases: + /// - If prevFieldName is specified - the new "Content-Length" field will be created after it + /// - If prevFieldName isn't specified or doesn't exist - the new "Content-Length" field will be created as + /// the + /// last field before end-of-header field + /// + /// @param[in] contentLength The content length value to set + /// @param[in] prevFieldName Optional parameter, if specified and "Content-Length" field doesn't exist, it will + /// be created after this field + /// @return A pointer to the "Content-Length" field, or nullptr if creation failed HeaderField* setContentLength(int contentLength, const std::string& prevFieldName = ""); // Overridden methods @@ -105,23 +98,17 @@ namespace pcpp return OsiModelSesionLayer; } - /** - * Currently identifies only SDP if content-length field exists and set to a value greater than zero. - * If content-length field doesn't exist or set to zero and still there is data after this layer, a PayloadLayer - * will be created - */ + /// Currently identifies only SDP if content-length field exists and set to a value greater than zero. + /// If content-length field doesn't exist or set to zero and still there is data after this layer, a + /// PayloadLayer will be created void parseNextLayer() override; - /** - * Set the content-length only if a content-length field already exists and if its current value is different - * than the total length of the next layer(s) - */ + /// Set the content-length only if a content-length field already exists and if its current value is different + /// than the total length of the next layer(s) void computeCalculateFields() override; - /** - * A static method that checks whether the port is considered as SIP - * @param[in] port The port number to be checked - */ + /// A static method that checks whether the port is considered as SIP + /// @param[in] port The port number to be checked static bool isSipPort(uint16_t port) { return port == 5060 || port == 5061; @@ -154,93 +141,80 @@ namespace pcpp class SipRequestFirstLine; - /** - * @class SipRequestLayer - * Represents a SIP request header and inherits all basic functionality of SipLayer and TextBasedProtocolMessage. - * The functionality that is added for this class is the SIP first line concept. A SIP request has the following - * first line: INVITE sip:bla@bla.com:12345 SIP/2.0 Since it's not an "ordinary" header field, it requires a - * special treatment and gets a class of it's own: SipRequestFirstLine. In most cases a SIP request will be - * contained in a single packet but for cases it is not, only the first packet will be identified as SIP request - * layer. You can find out whether the header is complete by using SipLayer#isHeaderComplete() - */ + /// @class SipRequestLayer + /// Represents a SIP request header and inherits all basic functionality of SipLayer and TextBasedProtocolMessage. + /// The functionality that is added for this class is the SIP first line concept. A SIP request has the following + /// first line: INVITE sip:bla@bla.com:12345 SIP/2.0 Since it's not an "ordinary" header field, it requires a + /// special treatment and gets a class of it's own: SipRequestFirstLine. In most cases a SIP request will be + /// contained in a single packet but for cases it is not, only the first packet will be identified as SIP request + /// layer. You can find out whether the header is complete by using SipLayer#isHeaderComplete() class SipRequestLayer : public SipLayer { friend class SipRequestFirstLine; public: - /** - * SIP request methods - */ + /// SIP request methods enum SipMethod { - /** INVITE */ + /// INVITE SipINVITE, - /** ACK */ + /// ACK SipACK, - /** BYE */ + /// BYE SipBYE, - /** CANCEL */ + /// CANCEL SipCANCEL, - /** REFISTER */ + /// REFISTER SipREGISTER, - /** PRACK */ + /// PRACK SipPRACK, - /** OPTIONS */ + /// OPTIONS SipOPTIONS, - /** SUBSCRIBE */ + /// SUBSCRIBE SipSUBSCRIBE, - /** NOTIFY */ + /// NOTIFY SipNOTIFY, - /** PUBLISH */ + /// PUBLISH SipPUBLISH, - /** INFO */ + /// INFO SipINFO, - /** REFER */ + /// REFER SipREFER, - /** MESSAGE */ + /// MESSAGE SipMESSAGE, - /** UPDATE */ + /// UPDATE SipUPDATE, - /** Unknown SIP method */ + /// Unknown SIP method SipMethodUnknown }; - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in SipRequestLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * A constructor that allocates a new SIP request with only the first line filled. The request will be created - * without further fields. The user can then add fields using addField() or insertField() methods - * @param[in] method The SIP method to be used in this SIP request - * @param[in] requestUri The URI of the request - * @param[in] version SIP version to be used in this request. Default is "SIP/2.0" - */ + /// A constructor that allocates a new SIP request with only the first line filled. The request will be created + /// without further fields. The user can then add fields using addField() or insertField() methods + /// @param[in] method The SIP method to be used in this SIP request + /// @param[in] requestUri The URI of the request + /// @param[in] version SIP version to be used in this request. Default is "SIP/2.0" SipRequestLayer(SipMethod method, const std::string& requestUri, const std::string& version = "SIP/2.0"); ~SipRequestLayer() override; - /** - * A copy constructor for this layer. Inherits base copy constructor SipLayer and adds the functionality - * of copying the first line - * @param[in] other The instance to copy from - */ + /// A copy constructor for this layer. Inherits base copy constructor SipLayer and adds the functionality + /// of copying the first line + /// @param[in] other The instance to copy from SipRequestLayer(const SipRequestLayer& other); - /** - * An assignment operator overload for this layer. This method inherits base assignment operator - * SipLayer#operator=() and adds the functionality of copying the first line - * @param[in] other The instance to copy from - */ + /// An assignment operator overload for this layer. This method inherits base assignment operator + /// SipLayer#operator=() and adds the functionality of copying the first line + /// @param[in] other The instance to copy from SipRequestLayer& operator=(const SipRequestLayer& other); - /** - * @return A pointer to the first line instance for this message - */ + /// @return A pointer to the first line instance for this message SipRequestFirstLine* getFirstLine() const { return m_FirstLine; @@ -256,262 +230,247 @@ namespace pcpp class SipResponseFirstLine; - /** - * @class SipResponseLayer - * Represents an SIP response message and inherits all basic functionality of SipLayer and TextBasedProtocolMessage. - * The functionality that is added for this class is the SIP first line concept. A SIP response has the following - * first line: 200 OK SIP/2.0 Since it's not an "ordinary" header field, it requires a special treatment and - * gets a class of it's own: SipResponseFirstLine. In most cases a SIP response will be contained in a single packet - * but for cases it is not, only the first packet will be identified as SIP response layer. You can find out whether - * the header is complete by using SipLayer#isHeaderComplete() - */ + /// @class SipResponseLayer + /// Represents an SIP response message and inherits all basic functionality of SipLayer and + /// TextBasedProtocolMessage. The functionality that is added for this class is the SIP first line concept. A SIP + /// response has the following first line: 200 OK SIP/2.0 Since it's not an "ordinary" header field, it + /// requires a special treatment and gets a class of it's own: SipResponseFirstLine. In most cases a SIP response + /// will be contained in a single packet but for cases it is not, only the first packet will be identified as SIP + /// response layer. You can find out whether the header is complete by using SipLayer#isHeaderComplete() class SipResponseLayer : public SipLayer { friend class SipResponseFirstLine; public: - /** - * Enum for SIP response status codes. List is taken from Wikipedia: - * https://en.wikipedia.org/wiki/List_of_SIP_response_codes - */ + /// Enum for SIP response status codes. List is taken from Wikipedia: + /// https://en.wikipedia.org/wiki/List_of_SIP_response_codes enum SipResponseStatusCode { - /** Extended search being performed may take a significant time so a forking proxy must send a 100 Trying - * response */ + /// Extended search being performed may take a significant time so a forking proxy must send a 100 Trying + /// response Sip100Trying, - /** Destination user agent received INVITE, and is alerting user of call */ + /// Destination user agent received INVITE, and is alerting user of call Sip180Ringing, - /** Servers can optionally send this response to indicate a call is being forwarded */ + /// Servers can optionally send this response to indicate a call is being forwarded Sip181CallisBeingForwarded, - /** Indicates that the destination was temporarily unavailable, so the server has queued the call until the - * destination is available. A server may send multiple 182 responses to update progress of the queue */ + /// Indicates that the destination was temporarily unavailable, so the server has queued the call until the + /// destination is available. A server may send multiple 182 responses to update progress of the queue Sip182Queued, - /** This response may be used to send extra information for a call which is still being set up */ + /// This response may be used to send extra information for a call which is still being set up Sip183SessioninProgress, - /** Can be used by User Agent Server to indicate to upstream SIP entities (including the User Agent Client - * (UAC)) that an early dialog has been terminated */ + /// Can be used by User Agent Server to indicate to upstream SIP entities (including the User Agent Client + /// (UAC)) that an early dialog has been terminated Sip199EarlyDialogTerminated, - /** Indicates the request was successful */ + /// Indicates the request was successful Sip200OK, - /** Indicates that the request has been accepted for processing, but the processing has not been completed - */ + /// Indicates that the request has been accepted for processing, but the processing has not been completed Sip202Accepted, - /** Indicates the request was successful, but the corresponding response will not be received */ + /// Indicates the request was successful, but the corresponding response will not be received Sip204NoNotification, - /** The address resolved to one of several options for the user or client to choose between, which are - * listed in the message body or the message's Contact fields */ + /// The address resolved to one of several options for the user or client to choose between, which are + /// listed in the message body or the message's Contact fields Sip300MultipleChoices, - /** The original Request-URI is no longer valid, the new address is given in the Contact header field, and - * the client should update any records of the original Request-URI with the new value */ + /// The original Request-URI is no longer valid, the new address is given in the Contact header field, and + /// the client should update any records of the original Request-URI with the new value Sip301MovedPermanently, - /** The client should try at the address in the Contact field. If an Expires field is present, the client - * may cache the result for that period of time */ + /// The client should try at the address in the Contact field. If an Expires field is present, the client + /// may cache the result for that period of time Sip302MovedTemporarily, - /** The Contact field details a proxy that must be used to access the requested destination */ + /// The Contact field details a proxy that must be used to access the requested destination Sip305UseProxy, - /** The call failed, but alternatives are detailed in the message body */ + /// The call failed, but alternatives are detailed in the message body Sip380AlternativeService, - /** The request could not be understood due to malformed syntax */ + /// The request could not be understood due to malformed syntax Sip400BadRequest, - /** The request requires user authentication. This response is issued by UASs and registrars */ + /// The request requires user authentication. This response is issued by UASs and registrars Sip401Unauthorized, - /** Reserved for future use */ + /// Reserved for future use Sip402PaymentRequired, - /** The server understood the request, but is refusing to fulfill it */ + /// The server understood the request, but is refusing to fulfill it Sip403Forbidden, - /** The server has definitive information that the user does not exist at the domain specified in the - * Request-URI. This status is also returned if the domain in the Request-URI does not match any of the - * domains handled by the recipient of the request */ + /// The server has definitive information that the user does not exist at the domain specified in the + /// Request-URI. This status is also returned if the domain in the Request-URI does not match any of the + /// domains handled by the recipient of the request Sip404NotFound, - /** The method specified in the Request-Line is understood, but not allowed for the address identified by - * the Request-URI */ + /// The method specified in the Request-Line is understood, but not allowed for the address identified by + /// the Request-URI Sip405MethodNotAllowed, - /** The resource identified by the request is only capable of generating response entities that have content - * characteristics but not acceptable according to the Accept header field sent in the request */ + /// The resource identified by the request is only capable of generating response entities that have content + /// characteristics but not acceptable according to the Accept header field sent in the request Sip406NotAcceptable, - /** The request requires user authentication. This response is issued by proxies */ + /// The request requires user authentication. This response is issued by proxies Sip407ProxyAuthenticationRequired, - /** Couldn't find the user in time. The server could not produce a response within a suitable amount of - * time, for example, if it could not determine the location of the user in time. The client MAY repeat the - * request without modifications at any later time */ + /// Couldn't find the user in time. The server could not produce a response within a suitable amount of + /// time, for example, if it could not determine the location of the user in time. The client MAY repeat the + /// request without modifications at any later time Sip408RequestTimeout, - /** User already registered */ + /// User already registered Sip409Conflict, - /** The user existed once, but is not available here any more */ + /// The user existed once, but is not available here any more Sip410Gone, - /** The server will not accept the request without a valid Content-Length */ + /// The server will not accept the request without a valid Content-Length Sip411LengthRequired, - /** The given precondition has not been met */ + /// The given precondition has not been met Sip412ConditionalRequestFailed, - /** Request body too large */ + /// Request body too large Sip413RequestEntityTooLarge, - /** The server is refusing to service the request because the Request-URI is longer than the server is - * willing to interpret */ + /// The server is refusing to service the request because the Request-URI is longer than the server is + /// willing to interpret Sip414RequestURITooLong, - /** Request body in a format not supported */ + /// Request body in a format not supported Sip415UnsupportedMediaType, - /** Request-URI is unknown to the server */ + /// Request-URI is unknown to the server Sip416UnsupportedURIScheme, - /** There was a resource-priority option tag, but no Resource-Priority header */ + /// There was a resource-priority option tag, but no Resource-Priority header Sip417UnknownResourcePriority, - /** Bad SIP Protocol Extension used, not understood by the server */ + /// Bad SIP Protocol Extension used, not understood by the server Sip420BadExtension, - /** The server needs a specific extension not listed in the Supported header */ + /// The server needs a specific extension not listed in the Supported header Sip421ExtensionRequired, - /** The received request contains a Session-Expires header field with a duration below the minimum timer */ + /// The received request contains a Session-Expires header field with a duration below the minimum timer Sip422SessionIntervalTooSmall, - /** Expiration time of the resource is too short */ + /// Expiration time of the resource is too short Sip423IntervalTooBrief, - /** The request's location content was malformed or otherwise unsatisfactory */ + /// The request's location content was malformed or otherwise unsatisfactory Sip424BadLocationInformation, - /** The server rejected a non-interactive emergency call, indicating that the request was malformed enough - * that no reasonable emergency response to the alert can be determined */ + /// The server rejected a non-interactive emergency call, indicating that the request was malformed enough + /// that no reasonable emergency response to the alert can be determined Sip425BadAlertMessage, - /** The server policy requires an Identity header, and one has not been provided */ + /// The server policy requires an Identity header, and one has not been provided Sip428UseIdentityHeader, - /** The server did not receive a valid Referred-By token on the request */ + /// The server did not receive a valid Referred-By token on the request Sip429ProvideReferrerIdentity, - /** A specific flow to a user agent has failed, although other flows may succeed. This response is intended - * for use between proxy devices, and should not be seen by an endpoint (and if it is seen by one, should be - * treated as a 400 Bad Request response) */ + /// A specific flow to a user agent has failed, although other flows may succeed. This response is intended + /// for use between proxy devices, and should not be seen by an endpoint (and if it is seen by one, should + /// be treated as a 400 Bad Request response) Sip430FlowFailed, - /** The request has been rejected because it was anonymous */ + /// The request has been rejected because it was anonymous Sip433AnonymityDisallowed, - /** The request has an Identity-Info header, and the URI scheme in that header cannot be dereferenced */ + /// The request has an Identity-Info header, and the URI scheme in that header cannot be dereferenced Sip436BadIdentityInfo, - /** The server was unable to validate a certificate for the domain that signed the request */ + /// The server was unable to validate a certificate for the domain that signed the request Sip437UnsupportedCertificate, - /** The server obtained a valid certificate that the request claimed was used to sign the request, but was - * unable to verify that signature */ + /// The server obtained a valid certificate that the request claimed was used to sign the request, but was + /// unable to verify that signature Sip438InvalidIdentityHeader, - /** The first outbound proxy the user is attempting to register through does not support the "outbound" - * feature of RFC 5626, although the registrar does */ + /// The first outbound proxy the user is attempting to register through does not support the "outbound" + /// feature of RFC 5626, although the registrar does Sip439FirstHopLacksOutboundSupport, - /** If a SIP proxy determines a response context has insufficient Incoming Max-Breadth to carry out a - * desired parallel fork, and the proxy is unwilling/unable to compensate by forking serially or sending a - * redirect, that proxy MUST return a 440 response. A client receiving a 440 response can infer that its - * request did not reach all possible destinations */ + /// If a SIP proxy determines a response context has insufficient Incoming Max-Breadth to carry out a + /// desired parallel fork, and the proxy is unwilling/unable to compensate by forking serially or sending a + /// redirect, that proxy MUST return a 440 response. A client receiving a 440 response can infer that its + /// request did not reach all possible destinations Sip440MaxBreadthExceeded, - /** If a SIP UA receives an INFO request associated with an Info Package that the UA has not indicated - * willingness to receive, the UA MUST send a 469 response, which contains a Recv-Info header field with - * Info Packages for which the UA is willing to receive INFO requests */ + /// If a SIP UA receives an INFO request associated with an Info Package that the UA has not indicated + /// willingness to receive, the UA MUST send a 469 response, which contains a Recv-Info header field with + /// Info Packages for which the UA is willing to receive INFO requests Sip469BadInfoPackage, - /** The source of the request did not have the permission of the recipient to make such a request */ + /// The source of the request did not have the permission of the recipient to make such a request Sip470ConsentNeeded, - /** Callee currently unavailable */ + /// Callee currently unavailable Sip480TemporarilyUnavailable, - /** Server received a request that does not match any dialog or transaction */ + /// Server received a request that does not match any dialog or transaction Sip481Call_TransactionDoesNotExist, - /** Server has detected a loop */ + /// Server has detected a loop Sip482LoopDetected, - /** Max-Forwards header has reached the value '0' */ + /// Max-Forwards header has reached the value '0' Sip483TooManyHops, - /** Request-URI incomplete */ + /// Request-URI incomplete Sip484AddressIncomplete, - /** Request-URI is ambiguous */ + /// Request-URI is ambiguous Sip485Ambiguous, - /** Callee is busy */ + /// Callee is busy Sip486BusyHere, - /** Request has terminated by bye or cancel */ + /// Request has terminated by bye or cancel Sip487RequestTerminated, - /** Some aspect of the session description or the Request-URI is not acceptable */ + /// Some aspect of the session description or the Request-URI is not acceptable Sip488NotAcceptableHere, - /** The server did not understand an event package specified in an Event header field */ + /// The server did not understand an event package specified in an Event header field Sip489BadEvent, - /** Server has some pending request from the same dialog */ + /// Server has some pending request from the same dialog Sip491RequestPending, - /** Request contains an encrypted MIME body, which recipient can not decrypt */ + /// Request contains an encrypted MIME body, which recipient can not decrypt Sip493Undecipherable, - /** The server has received a request that requires a negotiated security mechanism, and the response - * contains a list of suitable security mechanisms for the requester to choose between, or a digest - * authentication challenge */ + /// The server has received a request that requires a negotiated security mechanism, and the response + /// contains a list of suitable security mechanisms for the requester to choose between, or a digest + /// authentication challenge Sip494SecurityAgreementRequired, - /** The server could not fulfill the request due to some unexpected condition */ + /// The server could not fulfill the request due to some unexpected condition Sip500ServerInternalError, - /** The server does not have the ability to fulfill the request, such as because it does not recognize the - * request method. (Compare with 405 Method Not Allowed, where the server recognizes the method but does not - * allow or support it.) */ + /// The server does not have the ability to fulfill the request, such as because it does not recognize the + /// request method. (Compare with 405 Method Not Allowed, where the server recognizes the method but does + /// not allow or support it.) Sip501NotImplemented, - /** The server is acting as a gateway or proxy, and received an invalid response from a downstream server - * while attempting to fulfill the request */ + /// The server is acting as a gateway or proxy, and received an invalid response from a downstream server + /// while attempting to fulfill the request Sip502BadGateway, - /** The server is undergoing maintenance or is temporarily overloaded and so cannot process the request. A - * "Retry-After" header field may specify when the client may reattempt its request */ + /// The server is undergoing maintenance or is temporarily overloaded and so cannot process the request. A + /// "Retry-After" header field may specify when the client may reattempt its request Sip503ServiceUnavailable, - /** The server attempted to access another server in attempting to process the request, and did not receive - * a prompt response */ + /// The server attempted to access another server in attempting to process the request, and did not receive + /// a prompt response Sip504ServerTimeout, - /** The SIP protocol version in the request is not supported by the server */ + /// The SIP protocol version in the request is not supported by the server Sip505VersionNotSupported, - /** The request message length is longer than the server can process */ + /// The request message length is longer than the server can process Sip513MessageTooLarge, - /** The server does not support the push notification service identified in a 'pn-provider' SIP URI - * parameter */ + /// The server does not support the push notification service identified in a 'pn-provider' SIP URI + /// parameter Sip555PushNotificationServiceNotSupported, - /** The server is unable or unwilling to meet some constraints specified in the offer */ + /// The server is unable or unwilling to meet some constraints specified in the offer Sip580PreconditionFailure, - /** All possible destinations are busy. Unlike the 486 response, this response indicates the destination - * knows there are no alternative destinations (such as a voicemail server) able to accept the call */ + /// All possible destinations are busy. Unlike the 486 response, this response indicates the destination + /// knows there are no alternative destinations (such as a voicemail server) able to accept the call Sip600BusyEverywhere, - /** The destination does not wish to participate in the call, or cannot do so, and additionally the - * destination knows there are no alternative destinations (such as a voicemail server) willing to accept - * the call */ + /// The destination does not wish to participate in the call, or cannot do so, and additionally the + /// destination knows there are no alternative destinations (such as a voicemail server) willing to accept + /// the call Sip603Decline, - /** The server has authoritative information that the requested user does not exist anywhere */ + /// The server has authoritative information that the requested user does not exist anywhere Sip604DoesNotExistAnywhere, - /** The user's agent was contacted successfully but some aspects of the session description such as the - * requested media, bandwidth, or addressing style were not acceptable */ + /// The user's agent was contacted successfully but some aspects of the session description such as the + /// requested media, bandwidth, or addressing style were not acceptable Sip606NotAcceptable, - /** The called party did not want this call from the calling party. Future attempts from the calling party - * are likely to be similarly rejected */ + /// The called party did not want this call from the calling party. Future attempts from the calling party + /// are likely to be similarly rejected Sip607Unwanted, - /** An intermediary machine or process rejected the call attempt */ + /// An intermediary machine or process rejected the call attempt Sip608Rejected, - /** Unknown SIP status code */ + /// Unknown SIP status code SipStatusCodeUnknown }; - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in SipResponseLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * A constructor that allocates a new SIP response with only the first line filled. The request will be created - * without further fields. The user can then add fields using addField() or insertField() methods - * @param[in] statusCode SIP status code to set - * @param[in] statusCodeString Most status codes have their default string, e.g 200 is usually "OK" etc. - * But the user can set a non-default status code string and it will be written in the header first line. Empty - * string ("") means using the default status code string. Also, the default is using the default status code - * string - * @param[in] sipVersion SIP version to set, default is SIP/2.0 - * - */ + /// A constructor that allocates a new SIP response with only the first line filled. The request will be created + /// without further fields. The user can then add fields using addField() or insertField() methods + /// @param[in] statusCode SIP status code to set + /// @param[in] statusCodeString Most status codes have their default string, e.g 200 is usually "OK" etc. + /// But the user can set a non-default status code string and it will be written in the header first line. Empty + /// string ("") means using the default status code string. Also, the default is using the default status code + /// string + /// @param[in] sipVersion SIP version to set, default is SIP/2.0 explicit SipResponseLayer(SipResponseLayer::SipResponseStatusCode statusCode, std::string statusCodeString = "", const std::string& sipVersion = "SIP/2.0"); ~SipResponseLayer() override; - /** - * A copy constructor for this layer. This copy constructor inherits base copy constructor SipLayer and adds the - * functionality of copying the first line as well - * @param[in] other The instance to copy from - */ + /// A copy constructor for this layer. This copy constructor inherits base copy constructor SipLayer and adds + /// the functionality of copying the first line as well + /// @param[in] other The instance to copy from SipResponseLayer(const SipResponseLayer& other); - /** - * An assignment operator overload for this layer. This method inherits base assignment operator - * SipLayer#operator=() and adds the functionality of copying the first line as well - * @param[in] other The instance to copy from - */ + /// An assignment operator overload for this layer. This method inherits base assignment operator + /// SipLayer#operator=() and adds the functionality of copying the first line as well + /// @param[in] other The instance to copy from SipResponseLayer& operator=(const SipResponseLayer& other); - /** - * @return A pointer to the first line instance for this message - */ + /// @return A pointer to the first line instance for this message SipResponseFirstLine* getFirstLine() const { return m_FirstLine; @@ -525,92 +484,72 @@ namespace pcpp SipResponseFirstLine* m_FirstLine; }; - /** - * @class SipRequestFirstLine - * Represents an SIP request first line. The first line includes 3 parameters: SIP method (e.g INVITE, ACK, BYE, - * etc.), URI (e.g sip:bla@bla.com:12345) and SIP version (usually SIP/2.0). All these parameters are included in - * this class, and the user can retrieve or set them. This class cannot be instantiated by users, it's created - * inside SipRequestLayer and user can get a pointer to an instance of it. All "getters" of this class retrieve the - * actual data of the SIP request and the "setters" actually change the packet data. Since SIP is a textual - * protocol, most fields aren't of fixed size and this also applies to the first line parameters. So many "setter" - * methods of this class may need to shorten or extend the data in SipRequestLayer. These methods will return a - * false value if this action failed - */ + /// @class SipRequestFirstLine + /// Represents an SIP request first line. The first line includes 3 parameters: SIP method (e.g INVITE, ACK, BYE, + /// etc.), URI (e.g sip:bla@bla.com:12345) and SIP version (usually SIP/2.0). All these parameters are included in + /// this class, and the user can retrieve or set them. This class cannot be instantiated by users, it's created + /// inside SipRequestLayer and user can get a pointer to an instance of it. All "getters" of this class retrieve the + /// actual data of the SIP request and the "setters" actually change the packet data. Since SIP is a textual + /// protocol, most fields aren't of fixed size and this also applies to the first line parameters. So many "setter" + /// methods of this class may need to shorten or extend the data in SipRequestLayer. These methods will return a + /// false value if this action failed class SipRequestFirstLine { friend class SipRequestLayer; public: - /** - * @return The SIP request method - */ + /// @return The SIP request method SipRequestLayer::SipMethod getMethod() const { return m_Method; } - /** - * Set the SIP request method - * @param[in] newMethod The method to set - * @return False if newMethod is SipRequestLayer#SipMethodUnknown or if shortening/extending the SipRequestLayer - * data failed. True otherwise - */ + /// Set the SIP request method + /// @param[in] newMethod The method to set + /// @return False if newMethod is SipRequestLayer#SipMethodUnknown or if shortening/extending the + /// SipRequestLayer data failed. True otherwise bool setMethod(SipRequestLayer::SipMethod newMethod); - /** - * @return A copied version of the URI (notice changing the return value won't change the actual data of the - * packet) - */ + /// @return A copied version of the URI (notice changing the return value won't change the actual data of the + /// packet) std::string getUri() const; - /** - * Set the URI - * @param[in] newUri The URI to set - * @return False if shortening/extending the SipRequestLayer data failed. True otherwise - */ + /// Set the URI + /// @param[in] newUri The URI to set + /// @return False if shortening/extending the SipRequestLayer data failed. True otherwise bool setUri(const std::string& newUri); - /** - * @return The SIP version - */ + /// @return The SIP version std::string getVersion() const { return m_Version; } - /** - * A static method for parsing the SIP method out of raw data - * @param[in] data The raw data - * @param[in] dataLen The raw data length - * @return The parsed SIP method - */ + /// A static method for parsing the SIP method out of raw data + /// @param[in] data The raw data + /// @param[in] dataLen The raw data length + /// @return The parsed SIP method static SipRequestLayer::SipMethod parseMethod(const char* data, size_t dataLen); - /** - * @return The size in bytes of the SIP request first line - */ + /// @return The size in bytes of the SIP request first line int getSize() const { return m_FirstLineEndOffset; } - /** - * As explained in SipRequestLayer, a SIP message can sometimes spread over more than 1 packet, so when looking - * at a single packet the header can be partial. Same goes for the first line - it can spread over more than 1 - * packet. This method returns an indication whether the first line is partial - * @return False if the first line is partial, true if it's complete - */ + /// As explained in SipRequestLayer, a SIP message can sometimes spread over more than 1 packet, so when looking + /// at a single packet the header can be partial. Same goes for the first line - it can spread over more than 1 + /// packet. This method returns an indication whether the first line is partial + /// @return False if the first line is partial, true if it's complete bool isComplete() const { return m_IsComplete; } - /** - * @class SipRequestFirstLineException - * This exception can be thrown while constructing SipRequestFirstLine (the constructor is private, so the - * construction happens only in SipRequestLayer). This kind of exception is thrown if trying to construct with - * SIP method of SipRequestLayer#SipMethodUnknown or with empty SIP version - */ + /// @class SipRequestFirstLineException + /// This exception can be thrown while constructing SipRequestFirstLine (the constructor is private, so the + /// construction happens only in SipRequestLayer). This kind of exception is thrown if trying to construct with + /// SIP method of SipRequestLayer#SipMethodUnknown or with empty SIP version class SipRequestFirstLineException : public std::exception { public: @@ -646,105 +585,81 @@ namespace pcpp SipRequestFirstLineException m_Exception; }; - /** - * @class SipResponseFirstLine - * Represents an SIP response message first line. The first line includes 2 parameters: status code (e.g 100 Trying - * ,200 OK, etc.), and SIP version (usually SIP/2.0). These 2 parameters are included in this class, and the user - * can retrieve or set them. This class cannot be instantiated by users, it's created inside SipResponseLayer and - * user can get a pointer to an instance of it. The "getter" methods of this class will retrieve the actual data of - * the SIP response and the "setter" methods will change the packet data. Since SIP is a textual protocol, most - * fields aren't of fixed size and this also applies to the first line parameters. So most "setter" methods of this - * class may need to shorten or extend the data in SipResponseLayer. These methods will return a false value if this - * action failed - */ + /// @class SipResponseFirstLine + /// Represents an SIP response message first line. The first line includes 2 parameters: status code (e.g 100 Trying + /// ,200 OK, etc.), and SIP version (usually SIP/2.0). These 2 parameters are included in this class, and the user + /// can retrieve or set them. This class cannot be instantiated by users, it's created inside SipResponseLayer and + /// user can get a pointer to an instance of it. The "getter" methods of this class will retrieve the actual data of + /// the SIP response and the "setter" methods will change the packet data. Since SIP is a textual protocol, most + /// fields aren't of fixed size and this also applies to the first line parameters. So most "setter" methods of this + /// class may need to shorten or extend the data in SipResponseLayer. These methods will return a false value if + /// this action failed class SipResponseFirstLine { friend class SipResponseLayer; public: - /** - * @return The status code as SipResponseLayer#SipResponseStatusCode enum - */ + /// @return The status code as SipResponseLayer#SipResponseStatusCode enum SipResponseLayer::SipResponseStatusCode getStatusCode() const { return m_StatusCode; } - /** - * @return The status code number as integer (e.g 200, 100, etc.) - */ + /// @return The status code number as integer (e.g 200, 100, etc.) int getStatusCodeAsInt() const; - /** - * @return The status code message (e.g "OK", "Trying", etc.) - */ + /// @return The status code message (e.g "OK", "Trying", etc.) std::string getStatusCodeString() const; - /** - * Set the status code - * @param[in] newStatusCode The new status code to set - * @param[in] statusCodeString An optional parameter: set a non-default status code message (e.g "Bla Bla" - * instead of "Not Found"). If this parameter isn't supplied or supplied as empty string (""), the default - * message for the status code will be set - */ + /// Set the status code + /// @param[in] newStatusCode The new status code to set + /// @param[in] statusCodeString An optional parameter: set a non-default status code message (e.g "Bla Bla" + /// instead of "Not Found"). If this parameter isn't supplied or supplied as empty string (""), the default + /// message for the status code will be set bool setStatusCode(SipResponseLayer::SipResponseStatusCode newStatusCode, std::string statusCodeString = ""); - /** - * @return The SIP version - */ + /// @return The SIP version std::string getVersion() const { return m_Version; } - /** - * Set the SIP version. The version to set is expected to be in the format of SIP/x.y otherwise an error will be - * written to log - * @param[in] newVersion The SIP version to set - */ + /// Set the SIP version. The version to set is expected to be in the format of SIP/x.y otherwise an error will + /// be written to log + /// @param[in] newVersion The SIP version to set void setVersion(const std::string& newVersion); - /** - * A static method for parsing the SIP status code out of raw data - * @param[in] data The raw data - * @param[in] dataLen The raw data length - * @return The parsed SIP status code as enum - */ + /// A static method for parsing the SIP status code out of raw data + /// @param[in] data The raw data + /// @param[in] dataLen The raw data length + /// @return The parsed SIP status code as enum static SipResponseLayer::SipResponseStatusCode parseStatusCode(const char* data, size_t dataLen); - /** - * A static method for parsing the SIP version out of raw data - * @param[in] data The raw data - * @param[in] dataLen The raw data length - * @return The parsed SIP version string or an empty string if version cannot be extracted - */ + /// A static method for parsing the SIP version out of raw data + /// @param[in] data The raw data + /// @param[in] dataLen The raw data length + /// @return The parsed SIP version string or an empty string if version cannot be extracted static std::string parseVersion(const char* data, size_t dataLen); - /** - * @return The size in bytes of the SIP response first line - */ + /// @return The size in bytes of the SIP response first line int getSize() const { return m_FirstLineEndOffset; } - /** - * As explained in SipResponseLayer, A SIP message can sometimes spread over more than 1 packet, so when looking - * at a single packet the header can be partial. Same goes for the first line - it can spread over more than 1 - * packet. This method returns an indication whether the first line is partial - * @return False if the first line is partial, true if it's complete - */ + /// As explained in SipResponseLayer, A SIP message can sometimes spread over more than 1 packet, so when + /// looking at a single packet the header can be partial. Same goes for the first line - it can spread over more + /// than 1 packet. This method returns an indication whether the first line is partial + /// @return False if the first line is partial, true if it's complete bool isComplete() const { return m_IsComplete; } - /** - * @class SipResponseFirstLineException - * This exception can be thrown while constructing SipResponseFirstLine (the constructor is private, so the - * construction happens only in SipResponseLayer). This kind of exception will be thrown if trying to construct - * with SIP status code of SipResponseLayer#SipStatusCodeUnknown or with an empty SIP version - */ + /// @class SipResponseFirstLineException + /// This exception can be thrown while constructing SipResponseFirstLine (the constructor is private, so the + /// construction happens only in SipResponseLayer). This kind of exception will be thrown if trying to construct + /// with SIP status code of SipResponseLayer#SipStatusCodeUnknown or with an empty SIP version class SipResponseFirstLineException : public std::exception { public: diff --git a/Packet++/header/Sll2Layer.h b/Packet++/header/Sll2Layer.h index 8bc6d06770..83a55253c2 100644 --- a/Packet++/header/Sll2Layer.h +++ b/Packet++/header/Sll2Layer.h @@ -5,186 +5,137 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @struct sll2_header - * Represents SLL2 header - */ + /// @struct sll2_header + /// Represents SLL2 header #pragma pack(push, 1) struct sll2_header { - /** Contains an Ethernet protocol type of the next layer */ + /// Contains an Ethernet protocol type of the next layer uint16_t protocol_type; - /** The "Reserved (MBZ)" field is reserved, and must be set to zero */ + /// The "Reserved (MBZ)" field is reserved, and must be set to zero uint16_t reserved; - /** The interface index field is a signed integer in network byte - * order and contains the 1-based index of the interface on which the packet was observed - **/ + /// The interface index field is a signed integer in network byte + /// order and contains the 1-based index of the interface on which the packet was observed uint32_t interface_index; - /** Contains a Linux ARPHRD_ value for the link-layer device type */ + /// Contains a Linux ARPHRD_ value for the link-layer device type uint16_t ARPHRD_type; - /** Specifies whether packet was: specifically sent to us by somebody else (value=0); - * broadcast by somebody else (value=1); multicast, but not broadcast, by somebody else (value=2); - * sent to somebody else by somebody else (value=3); sent by us (value=4) - **/ + /// Specifies whether packet was: specifically sent to us by somebody else (value=0); + /// broadcast by somebody else (value=1); multicast, but not broadcast, by somebody else (value=2); + /// sent to somebody else by somebody else (value=3); sent by us (value=4) uint8_t packet_type; - /** Contains the length of the link-layer address of the sender of the packet. That length could be zero */ + /// Contains the length of the link-layer address of the sender of the packet. That length could be zero uint8_t link_layer_addr_len; - /** Contains the link-layer address of the sender of the packet; the number of bytes of that field that are - * meaningful is specified by the link-layer address length field - **/ + /// Contains the link-layer address of the sender of the packet; the number of bytes of that field that are + /// meaningful is specified by the link-layer address length field uint8_t link_layer_addr[8]; }; #pragma pack(pop) static_assert(sizeof(sll2_header) == 20, "sll2_header size is not 20 bytes"); - /** - * @class Sll2Layer - * Represents an SLL2 (Linux cooked capture) protocol layer - */ + /// @class Sll2Layer + /// Represents an SLL2 (Linux cooked capture) protocol layer class Sll2Layer : public Layer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to ether_header) - * @param[in] dataLen Size of the data in bytes - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to ether_header) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] packet A pointer to the Packet instance where layer will be stored in Sll2Layer(uint8_t* data, size_t dataLen, Packet* packet) : Layer(data, dataLen, nullptr, packet, SLL2) {} - /** - * A constructor that creates a new SLL2 header and allocates the data - * @param[in] interfaceIndex The interface index - * @param[in] ARPHRDType The ARPHRD type - * @param[in] packetType The packet type - */ + /// A constructor that creates a new SLL2 header and allocates the data + /// @param[in] interfaceIndex The interface index + /// @param[in] ARPHRDType The ARPHRD type + /// @param[in] packetType The packet type Sll2Layer(uint32_t interfaceIndex, uint16_t ARPHRDType, uint8_t packetType); ~Sll2Layer() override = default; - /** - * Get a pointer to the Sll header. Notice this points directly to the data, so every change will change the - * actual packet data - * @return A pointer to the sll2_header - */ + /// Get a pointer to the Sll header. Notice this points directly to the data, so every change will change the + /// actual packet data + /// @return A pointer to the sll2_header sll2_header* getSll2Header() const { return reinterpret_cast(m_Data); } - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of an IEEE 802.3 Eth packet - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent an IEEE 802.3 Eth packet - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of an IEEE 802.3 Eth packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent an IEEE 802.3 Eth packet static bool isDataValid(const uint8_t* data, size_t dataLen); - /** - * Get a protocol type of this layer - * @return protocol type - */ + /// Get a protocol type of this layer + /// @return protocol type uint16_t getProtocolType() const; - /** - * Set protocol type of this layer - * @param[in] protocolType type to set - */ + /// Set protocol type of this layer + /// @param[in] protocolType type to set void setProtocolType(uint16_t protocolType); - /** - * Get interface index of this layer - * @return interface index - */ + /// Get interface index of this layer + /// @return interface index uint32_t getInterfaceIndex() const; - /** - * Set interface index of this layer - * @param[in] interfaceIndex interface index to set - */ + /// Set interface index of this layer + /// @param[in] interfaceIndex interface index to set void setInterfaceIndex(uint32_t interfaceIndex); - /** - * Get arphrd type of this layer - * @return arphrd type - */ + /// Get arphrd type of this layer + /// @return arphrd type uint16_t getArphrdType() const; - /** - * Set arphrd type of this layer - * @param[in] arphrdType arphrd type to set - */ + /// Set arphrd type of this layer + /// @param[in] arphrdType arphrd type to set void setArphrdType(uint16_t arphrdType); - /** - * Get packet type of this layer - * @return packet type - */ + /// Get packet type of this layer + /// @return packet type uint8_t getPacketType() const; - /** - * Set packet type of this layer - * @param[in] packetType packet type to set - */ + /// Set packet type of this layer + /// @param[in] packetType packet type to set void setPacketType(uint8_t packetType); - /** - * Get link layer address length - * @return link layer address length - */ + /// Get link layer address length + /// @return link layer address length uint8_t getLinkLayerAddrLen() const; - /** - * Get link layer address data pointer - * @return link layer address data pointer - */ + /// Get link layer address data pointer + /// @return link layer address data pointer const uint8_t* getLinkLayerAddr() const; - /** - * A setter for the link layer address field - * @param[in] addr The address to set. Memory will be copied to packet - * @param[in] addrLength Address length, must be lower or equal to 8 (which is max length for SLL2 address) - * @return True if address was set successfully, or false of addrLength is out of bounds (0 or larger than 8) - */ + /// A setter for the link layer address field + /// @param[in] addr The address to set. Memory will be copied to packet + /// @param[in] addrLength Address length, must be lower or equal to 8 (which is max length for SLL2 address) + /// @return True if address was set successfully, or false of addrLength is out of bounds (0 or larger than 8) bool setLinkLayerAddr(const uint8_t* addr, size_t addrLength); - /** - * Get a MAC address in the link layer address field - * @return return macAddress pointer was set successfully, null pointer if d MAC address isn't valid or if set - * failed - */ + /// Get a MAC address in the link layer address field + /// @return return macAddress pointer was set successfully, null pointer if d MAC address isn't valid or if set + /// failed MacAddress getLinkLayerAsMacAddress(); - /** - * Set a MAC address in the link layer address field - * @param[in] macAddr MAC address to set - * @return True if address was set successfully, false if MAC address isn't valid or if set failed - */ + /// Set a MAC address in the link layer address field + /// @param[in] macAddr MAC address to set + /// @return True if address was set successfully, false if MAC address isn't valid or if set failed bool setMacAddressAsLinkLayer(const MacAddress& macAddr); // implement abstract methods - /** - * Currently identifies the following next layers: IPv4Layer, IPv6Layer, ArpLayer, VlanLayer, PPPoESessionLayer, - * PPPoEDiscoveryLayer, MplsLayer. Otherwise sets PayloadLayer - */ + /// Currently identifies the following next layers: IPv4Layer, IPv6Layer, ArpLayer, VlanLayer, + /// PPPoESessionLayer, PPPoEDiscoveryLayer, MplsLayer. Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * Calculate the next protocol type for known protocols: IPv4, IPv6, ARP, VLAN - */ + /// Calculate the next protocol type for known protocols: IPv4, IPv6, ARP, VLAN void computeCalculateFields() override; - /** - * @return Size of sll2_header - */ + /// @return Size of sll2_header size_t getHeaderLen() const override { return sizeof(sll2_header); diff --git a/Packet++/header/SllLayer.h b/Packet++/header/SllLayer.h index cd4d7deb46..a97b83e983 100644 --- a/Packet++/header/SllLayer.h +++ b/Packet++/header/SllLayer.h @@ -5,106 +5,81 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct sll_header - * Represents SLL header - */ + /// @struct sll_header + /// Represents SLL header #pragma pack(push, 1) struct sll_header { - /** Specifies whether packet was: specifically sent to us by somebody else (value=0); - * broadcast by somebody else (value=1); multicast, but not broadcast, by somebody else (value=2); - * sent to somebody else by somebody else (value=3); sent by us (value=4) - **/ + /// Specifies whether packet was: specifically sent to us by somebody else (value=0); + /// broadcast by somebody else (value=1); multicast, but not broadcast, by somebody else (value=2); + /// sent to somebody else by somebody else (value=3); sent by us (value=4) uint16_t packet_type; - /** Contains a Linux ARPHRD_ value for the link-layer device type */ + /// Contains a Linux ARPHRD_ value for the link-layer device type uint16_t ARPHRD_type; - /** Contains the length of the link-layer address of the sender of the packet. That length could be zero */ + /// Contains the length of the link-layer address of the sender of the packet. That length could be zero uint16_t link_layer_addr_len; - /** contains the link-layer address of the sender of the packet; the number of bytes of that field that are - * meaningful is specified by the link-layer address length field - **/ + /// contains the link-layer address of the sender of the packet; the number of bytes of that field that are + /// meaningful is specified by the link-layer address length field uint8_t link_layer_addr[8]; - /** Contains an Ethernet protocol type of the next layer */ + /// Contains an Ethernet protocol type of the next layer uint16_t protocol_type; }; #pragma pack(pop) static_assert(sizeof(sll_header) == 16, "sll_header size is not 16 bytes"); - /** - * @class SllLayer - * Represents an SLL (Linux cooked capture) protocol layer - */ + /// @class SllLayer + /// Represents an SLL (Linux cooked capture) protocol layer class SllLayer : public Layer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to ether_header) - * @param[in] dataLen Size of the data in bytes - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to ether_header) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] packet A pointer to the Packet instance where layer will be stored in SllLayer(uint8_t* data, size_t dataLen, Packet* packet) : Layer(data, dataLen, nullptr, packet, SLL) {} - /** - * A constructor that creates a new SLL header and allocates the data - * @param[in] packetType The packet type - * @param[in] ARPHRDType The ARPHRD type - */ + /// A constructor that creates a new SLL header and allocates the data + /// @param[in] packetType The packet type + /// @param[in] ARPHRDType The ARPHRD type SllLayer(uint16_t packetType, uint16_t ARPHRDType); ~SllLayer() override = default; - /** - * Get a pointer to the Sll header. Notice this points directly to the data, so every change will change the - * actual packet data - * @return A pointer to the sll_header - */ + /// Get a pointer to the Sll header. Notice this points directly to the data, so every change will change the + /// actual packet data + /// @return A pointer to the sll_header sll_header* getSllHeader() const { return reinterpret_cast(m_Data); } - /** - * A setter for the link layer address field - * @param[in] addr The address to set. Memory will be copied to packet - * @param[in] addrLength Address length, must be lower or equal to 8 (which is max length for SLL address) - * @return True if address was set successfully, or false of addrLength is out of bounds (0 or larger than 8) - */ + /// A setter for the link layer address field + /// @param[in] addr The address to set. Memory will be copied to packet + /// @param[in] addrLength Address length, must be lower or equal to 8 (which is max length for SLL address) + /// @return True if address was set successfully, or false of addrLength is out of bounds (0 or larger than 8) bool setLinkLayerAddr(uint8_t* addr, size_t addrLength); - /** - * Set a MAC address in the link layer address field - * @param[in] macAddr MAC address to set - * @return True if address was set successfully, false if MAC address isn't valid or if set failed - */ + /// Set a MAC address in the link layer address field + /// @param[in] macAddr MAC address to set + /// @return True if address was set successfully, false if MAC address isn't valid or if set failed bool setMacAddressAsLinkLayer(const MacAddress& macAddr); - /** - * Currently identifies the following next layers: IPv4Layer, IPv6Layer, ArpLayer, VlanLayer, PPPoESessionLayer, - * PPPoEDiscoveryLayer, MplsLayer. Otherwise sets PayloadLayer - */ + /// Currently identifies the following next layers: IPv4Layer, IPv6Layer, ArpLayer, VlanLayer, + /// PPPoESessionLayer, PPPoEDiscoveryLayer, MplsLayer. Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * @return Size of sll_header - */ + /// @return Size of sll_header size_t getHeaderLen() const override { return sizeof(sll_header); } - /** - * Calculate the next protocol type for known protocols: IPv4, IPv6, ARP, VLAN - */ + /// Calculate the next protocol type for known protocols: IPv4, IPv6, ARP, VLAN void computeCalculateFields() override; std::string toString() const override; diff --git a/Packet++/header/SmtpLayer.h b/Packet++/header/SmtpLayer.h index b5ffbaf80f..871a597233 100644 --- a/Packet++/header/SmtpLayer.h +++ b/Packet++/header/SmtpLayer.h @@ -6,15 +6,11 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * Class for general SMTP message - */ + /// Class for general SMTP message class SmtpLayer : public SingleCommandTextProtocol { protected: @@ -25,11 +21,9 @@ namespace pcpp : SingleCommandTextProtocol(command, option, SMTP) {}; public: - /** - * A static method that checks whether the port is considered as SMTP control - * @param[in] port The port number to be checked - * @return True if this an SMTP port (25 or 587) - */ + /// A static method that checks whether the port is considered as SMTP control + /// @param[in] port The port number to be checked + /// @return True if this an SMTP port (25 or 587) static bool isSmtpPort(uint16_t port) { return port == 25 || port == 587; @@ -41,9 +35,7 @@ namespace pcpp void parseNextLayer() override {} - /** - * @return Get the size of the layer - */ + /// @return Get the size of the layer size_t getHeaderLen() const override { return m_DataLen; @@ -53,24 +45,18 @@ namespace pcpp void computeCalculateFields() override {} - /** - * @return The OSI layer level of SMTP (Application Layer). - */ + /// @return The OSI layer level of SMTP (Application Layer). OsiModelLayer getOsiModelLayer() const override { return OsiModelApplicationLayer; } }; - /** - * Class for representing the request messages of SMTP Layer - */ + /// Class for representing the request messages of SMTP Layer class SmtpRequestLayer : public SmtpLayer { public: - /** - * Enum for SMTP command codes - */ + /// Enum for SMTP command codes enum class SmtpCommand : uint64_t { /// Unknown command @@ -126,87 +112,64 @@ namespace pcpp XGEN = ('X') | ('G' << 8) | ('E' << 16) | ('N' << 24) }; - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in SmtpRequestLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : SmtpLayer(data, dataLen, prevLayer, packet) {}; - /** - * A constructor that creates layer with provided input values - * @param[in] command SMTP command - * @param[in] option Argument of the command - */ + /// A constructor that creates layer with provided input values + /// @param[in] command SMTP command + /// @param[in] option Argument of the command explicit SmtpRequestLayer(const SmtpCommand& command, const std::string& option = "") : SmtpLayer(getCommandAsString(command), option) {}; - /** - * Set the command of request message - * @param[in] code Value to set command - * @return True if the operation is successful, false otherwise - */ + /// Set the command of request message + /// @param[in] code Value to set command + /// @return True if the operation is successful, false otherwise bool setCommand(SmtpCommand code); - /** - * Get the command of request message - * @return Value of the command - */ + /// Get the command of request message + /// @return Value of the command SmtpCommand getCommand() const; - /** - * Get the command of request message as string - * @return Value of the command as string - */ + /// Get the command of request message as string + /// @return Value of the command as string std::string getCommandString() const; - /** - * Set the command argument of request message - * @param[in] value Value to set command argument - * @return True if the operation is successful, false otherwise - */ + /// Set the command argument of request message + /// @param[in] value Value to set command argument + /// @return True if the operation is successful, false otherwise bool setCommandOption(const std::string& value); - /** - * Get the command argument of request message - * @param[in] removeEscapeCharacters Whether non-alphanumerical characters should be removed or not - * @return Value of command argument - */ + /// Get the command argument of request message + /// @param[in] removeEscapeCharacters Whether non-alphanumerical characters should be removed or not + /// @return Value of command argument std::string getCommandOption(bool removeEscapeCharacters = true) const; - /** - * Convert the command info to readable string - * @param[in] code Command code to convert - * @return Returns the command info as readable string - */ + /// Convert the command info to readable string + /// @param[in] code Command code to convert + /// @return Returns the command info as readable string static std::string getCommandInfo(SmtpCommand code); - /** - * Convert the command to readable string - * @param[in] code Command code to convert - * @return Returns the command as readable string - */ + /// Convert the command to readable string + /// @param[in] code Command code to convert + /// @return Returns the command as readable string static std::string getCommandAsString(SmtpCommand code); // overridden methods - /** - * @return Returns the protocol info as readable string - */ + /// @return Returns the protocol info as readable string std::string toString() const override; }; - /** - * Class for representing the response messages of SMTP Layer - */ + /// Class for representing the response messages of SMTP Layer class SmtpResponseLayer : public SmtpLayer { public: - /** - * Enum for SMTP response codes - */ + /// Enum for SMTP response codes enum class SmtpStatusCode : int { /// System status, or system help reply @@ -279,70 +242,53 @@ namespace pcpp DOMAIN_NOT_ACCEPT = 556 }; - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in SmtpResponseLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : SmtpLayer(data, dataLen, prevLayer, packet) {}; - /** - * A constructor that creates layer with provided input values - * @param[in] code Status code - * @param[in] option Argument of the status code - */ + /// A constructor that creates layer with provided input values + /// @param[in] code Status code + /// @param[in] option Argument of the status code explicit SmtpResponseLayer(const SmtpStatusCode& code, const std::string& option = "") : SmtpLayer(std::to_string(int(code)), option) {}; - /** - * Set the status code of response message - * @param[in] code Value to set status code - * @return True if the operation is successful, false otherwise - */ + /// Set the status code of response message + /// @param[in] code Value to set status code + /// @return True if the operation is successful, false otherwise bool setStatusCode(SmtpStatusCode code); - /** - * Get the status code of response message - * @return Value of the status code - */ + /// Get the status code of response message + /// @return Value of the status code SmtpStatusCode getStatusCode() const; - /** - * Get the status code of response message as string - * @return Value of the status code as string - */ + /// Get the status code of response message as string + /// @return Value of the status code as string std::string getStatusCodeString() const; - /** - * Set the argument of response message - * @param[in] value Value to set argument - * @return True if the operation is successful, false otherwise - */ + /// Set the argument of response message + /// @param[in] value Value to set argument + /// @return True if the operation is successful, false otherwise bool setStatusOption(const std::string& value); - /** - * Get the argument of response message - * @param[in] removeEscapeCharacters Whether non-alphanumerical characters should be removed or not - * @return Value of argument - */ + /// Get the argument of response message + /// @param[in] removeEscapeCharacters Whether non-alphanumerical characters should be removed or not + /// @return Value of argument std::string getStatusOption(bool removeEscapeCharacters = true) const; - /** - * Convert the status code to readable string - * @param[in] code Status code to convert - * @return Returns the status info as readable string - */ + /// Convert the status code to readable string + /// @param[in] code Status code to convert + /// @return Returns the status info as readable string static std::string getStatusCodeAsString(SmtpStatusCode code); // overridden methods - /** - * @return Returns the protocol info as readable string - */ + /// @return Returns the protocol info as readable string std::string toString() const override; }; } // namespace pcpp -#endif /* PACKETPP_SMTP_LAYER */ +#endif // PACKETPP_SMTP_LAYER diff --git a/Packet++/header/SomeIpLayer.h b/Packet++/header/SomeIpLayer.h index d588ddd594..1f67adb9f0 100644 --- a/Packet++/header/SomeIpLayer.h +++ b/Packet++/header/SomeIpLayer.h @@ -5,354 +5,265 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @class SomeIpLayer - * Represents a SOME/IP protocol layer - */ + /// @class SomeIpLayer + /// Represents a SOME/IP protocol layer class SomeIpLayer : public Layer { public: - /** - * SOME/IP message types - */ + /// SOME/IP message types enum class MsgType : uint8_t { - /** A request expecting a response (even void) */ + /// A request expecting a response (even void) REQUEST = 0x00, - /** Acknowledgment for REQUEST(optional) */ + /// Acknowledgment for REQUEST(optional) REQUEST_ACK = 0x40, - /** A fire&forget request */ + /// A fire&forget request REQUEST_NO_RETURN = 0x01, - /** Acknowledgment for REQUEST_NO_RETURN(informational) */ + /// Acknowledgment for REQUEST_NO_RETURN(informational) REQUEST_NO_RETURN_ACK = 0x41, - /** A request of a notification expecting no response */ + /// A request of a notification expecting no response NOTIFICATION = 0x02, - /** Acknowledgment for NOTIFICATION(informational) */ + /// Acknowledgment for NOTIFICATION(informational) NOTIFICATION_ACK = 0x42, - /** The response message */ + /// The response message RESPONSE = 0x80, - /** The Acknowledgment for RESPONSE(informational) */ + /// The Acknowledgment for RESPONSE(informational) RESPONSE_ACK = 0xC0, - /** The response containing an error */ + /// The response containing an error ERRORS = 0x81, - /** Acknowledgment for ERROR(informational) */ + /// Acknowledgment for ERROR(informational) ERROR_ACK = 0xC1, - /** A TP request expecting a response (even void) */ + /// A TP request expecting a response (even void) TP_REQUEST = 0x20, - /** A TP fire&forget request */ + /// A TP fire&forget request TP_REQUEST_NO_RETURN = 0x21, - /** A TP request of a notification/event callback expecting no response */ + /// A TP request of a notification/event callback expecting no response TP_NOTIFICATION = 0x22, - /** The TP response message */ + /// The TP response message TP_RESPONSE = 0xa0, - /** The TP response containing an error */ + /// The TP response containing an error TP_ERROR = 0xa1, }; - /** - * @struct someiphdr - * Represents a SOME/IP protocol header - */ + /// @struct someiphdr + /// Represents a SOME/IP protocol header #pragma pack(push, 1) struct someiphdr { - /** Service ID */ + /// Service ID uint16_t serviceID; - /** Method ID. Most significant bit 0 when E2E communication. 1 when SOME/IP event */ + /// Method ID. Most significant bit 0 when E2E communication. 1 when SOME/IP event uint16_t methodID; - /** Length. Also covers payload. Excludes serviceID, methodID and length field itself */ + /// Length. Also covers payload. Excludes serviceID, methodID and length field itself uint32_t length; - /** Client ID */ + /// Client ID uint16_t clientID; - /** Session ID */ + /// Session ID uint16_t sessionID; - /** Protocol Version */ + /// Protocol Version uint8_t protocolVersion; - /** Interface Version */ + /// Interface Version uint8_t interfaceVersion; - /** Message Type */ + /// Message Type uint8_t msgType; - /** Return Code */ + /// Return Code uint8_t returnCode; }; #pragma pack(pop) static_assert(sizeof(someiphdr) == 16, "someiphdr size is not 16 bytes"); - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to someiphdr) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to someiphdr) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in SomeIpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, SomeIP) {} - /** - * Construct a new layer object - * @param[in] serviceID Service ID - * @param[in] methodID Method ID - * @param[in] clientID Client ID - * @param[in] sessionID Session ID - * @param[in] interfaceVersion Interface Version - * @param[in] type Type of the message - * @param[in] returnCode Return Code - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * holds the reference to a data buffer. This option can be used to reduce the number of copies to generate - * packets. - */ + /// Construct a new layer object + /// @param[in] serviceID Service ID + /// @param[in] methodID Method ID + /// @param[in] clientID Client ID + /// @param[in] sessionID Session ID + /// @param[in] interfaceVersion Interface Version + /// @param[in] type Type of the message + /// @param[in] returnCode Return Code + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// holds the reference to a data buffer. This option can be used to reduce the number of copies to generate + /// packets. SomeIpLayer(uint16_t serviceID, uint16_t methodID, uint16_t clientID, uint16_t sessionID, uint8_t interfaceVersion, MsgType type, uint8_t returnCode, const uint8_t* const data = nullptr, size_t dataLen = 0); - /** - * Destroy the layer object - */ + /// Destroy the layer object ~SomeIpLayer() override = default; - /** - * A static method that creates a SOME/IP or SOME/IP-TP layer from packet raw data. Returns PayloadLayer if data - * is not valid. - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored - * @return Layer* A newly allocated layer - */ + /// A static method that creates a SOME/IP or SOME/IP-TP layer from packet raw data. Returns PayloadLayer if + /// data is not valid. + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored + /// @return Layer* A newly allocated layer static Layer* parseSomeIpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * Get a pointer to the basic SOME/IP header. Notice this points directly to the data, so every change will - * change the actual packet data - * @return A pointer to the someiphdr - */ + /// Get a pointer to the basic SOME/IP header. Notice this points directly to the data, so every change will + /// change the actual packet data + /// @return A pointer to the someiphdr someiphdr* getSomeIpHeader() const { return reinterpret_cast(m_Data); } - /** - * Checks if given port is a SOME/IP protocol port (only Service Discovery ports are checked for now) - * @param[in] port Port to check - * @return true if SOME/IP protocol port, false if not - */ + /// Checks if given port is a SOME/IP protocol port (only Service Discovery ports are checked for now) + /// @param[in] port Port to check + /// @return true if SOME/IP protocol port, false if not static bool isSomeIpPort(uint16_t port); - /** - * Adds port to a list of ports where pcap checks for SOME/IP communication. - * Each port must be removed at the end in order to have no memory leak. - * @param[in] port Port to add - */ + /// Adds port to a list of ports where pcap checks for SOME/IP communication. + /// Each port must be removed at the end in order to have no memory leak. + /// @param[in] port Port to add static void addSomeIpPort(uint16_t port); - /** - * Removes port from a list of ports where pcap checks for SOME/IP communication. - * @param[in] port Port to remove - */ + /// Removes port from a list of ports where pcap checks for SOME/IP communication. + /// @param[in] port Port to remove static void removeSomeIpPort(uint16_t port); - /** - * Removes all ports from a list of ports where pcap checks for SOME/IP communication. - */ + /// Removes all ports from a list of ports where pcap checks for SOME/IP communication. static void removeAllSomeIpPorts(); - /** - * Get the messageID - * @return uint32_t returned in host endian - */ + /// Get the messageID + /// @return uint32_t returned in host endian uint32_t getMessageID() const; - /** - * Set the Message ID - * @param[in] messageID messageID to set - */ + /// Set the Message ID + /// @param[in] messageID messageID to set void setMessageID(uint32_t messageID); - /** - * Get the serviceID - * @return uint16_t returned in host endian - */ + /// Get the serviceID + /// @return uint16_t returned in host endian uint16_t getServiceID() const; - /** - * Set the Service ID - * @param[in] serviceID serviceID to set - */ + /// Set the Service ID + /// @param[in] serviceID serviceID to set void setServiceID(uint16_t serviceID); - /** - * Get the methodID - * @return uint16_t returned in host endian - */ + /// Get the methodID + /// @return uint16_t returned in host endian uint16_t getMethodID() const; - /** - * Set the Method ID - * @param[in] methodID methodID to set - */ + /// Set the Method ID + /// @param[in] methodID methodID to set void setMethodID(uint16_t methodID); - /** - * Get the Length Field of the SOME/IP header - * @return uint32_t The length field of the SOME/IP header - */ + /// Get the Length Field of the SOME/IP header + /// @return uint32_t The length field of the SOME/IP header uint32_t getLengthField() const; - /** - * Get the requestID - * @return uint32_t returned in host endian - */ + /// Get the requestID + /// @return uint32_t returned in host endian uint32_t getRequestID() const; - /** - * Set the Request ID - * @param[in] requestID requestID to set - */ + /// Set the Request ID + /// @param[in] requestID requestID to set void setRequestID(uint32_t requestID); - /** - * Get the sessionID - * @return uint16_t returned in host endian - */ + /// Get the sessionID + /// @return uint16_t returned in host endian uint16_t getSessionID() const; - /** - * Set the Session ID - * @param[in] sessionID sessionID to set - */ + /// Set the Session ID + /// @param[in] sessionID sessionID to set void setSessionID(uint16_t sessionID); - /** - * Get the clientID - * @return uint16_t returned in host endian - */ + /// Get the clientID + /// @return uint16_t returned in host endian uint16_t getClientID() const; - /** - * Set the Client ID - * @param[in] clientID clientID to set - */ + /// Set the Client ID + /// @param[in] clientID clientID to set void setClientID(uint16_t clientID); - /** - * Get the protocolVersion - * @return uint8_t - */ + /// Get the protocolVersion + /// @return uint8_t uint8_t getProtocolVersion() const; - /** - * Set the Protocol Version - * @param[in] version version to set - */ + /// Set the Protocol Version + /// @param[in] version version to set void setProtocolVersion(uint8_t version); - /** - * Get the interfaceVersion - * @return uint8_t - */ + /// Get the interfaceVersion + /// @return uint8_t uint8_t getInterfaceVersion() const; - /** - * Set the Interface Version - * @param[in] version version to set - */ + /// Set the Interface Version + /// @param[in] version version to set void setInterfaceVersion(uint8_t version); - /** - * Get the message type - * @return uint8_t - */ + /// Get the message type + /// @return uint8_t uint8_t getMessageTypeAsInt() const; - /** - * Get the message type - * @return SomeIpLayer::MsgType - */ + /// Get the message type + /// @return SomeIpLayer::MsgType SomeIpLayer::MsgType getMessageType() const; - /** - * Set the Message Type - * @param[in] type Type to set - */ + /// Set the Message Type + /// @param[in] type Type to set void setMessageType(MsgType type); - /** - * Set the Message Type - * @param[in] type Type to set - */ + /// Set the Message Type + /// @param[in] type Type to set void setMessageType(uint8_t type); - /** - * Get the returnCode - * @return uint8_t - */ + /// Get the returnCode + /// @return uint8_t uint8_t getReturnCode() const; - /** - * Set the returnCode - * @param[in] returnCode ReturnCode to set - */ + /// Set the returnCode + /// @param[in] returnCode ReturnCode to set void setReturnCode(uint8_t returnCode); - /** - * Set the length field of the SOME/IP header - * @param[in] payloadLength Length of the payload - */ + /// Set the length field of the SOME/IP header + /// @param[in] payloadLength Length of the payload void setPayloadLength(uint32_t payloadLength); - /** - * @return A pointer for the layer payload, meaning the first byte after the header - */ + /// @return A pointer for the layer payload, meaning the first byte after the header uint8_t* getPduPayload() const { return m_Data + getSomeIpHeaderLen(); } - /** - * @return The size in bytes of the payload - */ + /// @return The size in bytes of the payload size_t getPduPayloadSize() const { return getHeaderLen() - getSomeIpHeaderLen(); } - /** - * Get the Length of the SOME/IP header inc payload - * @return size_t - */ + /// Get the Length of the SOME/IP header inc payload + /// @return size_t size_t getHeaderLen() const override { return sizeof(uint32_t) * 2 + getLengthField(); } - /** - * Does nothing for this layer - */ + /// Does nothing for this layer virtual void computeCalculateFields() override {} - /** - * Identifies the following next layers: SomeIpLayer, SomeIpTpLayer, SomeIpSdLayer. Otherwise sets PayloadLayer - */ + /// Identifies the following next layers: SomeIpLayer, SomeIpTpLayer, SomeIpSdLayer. Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * @return The string representation of the SOME/IP layer - */ + /// @return The string representation of the SOME/IP layer virtual std::string toString() const override; - /** - * @return The OSI model layer of this layer - */ + /// @return The OSI model layer of this layer OsiModelLayer getOsiModelLayer() const override { return OsiModelApplicationLayer; @@ -369,108 +280,84 @@ namespace pcpp return sizeof(someiphdr); } - /* Using unordered_set since insertion and search should be almost constant time */ + // Using unordered_set since insertion and search should be almost constant time static std::unordered_set m_SomeIpPorts; }; - /** - * @class SomeIpTpLayer - * Represents an SOME/IP Transport Protocol Layer - */ + /// @class SomeIpTpLayer + /// Represents an SOME/IP Transport Protocol Layer class SomeIpTpLayer : public SomeIpLayer { public: - /** - * @struct someiptphdr - * Represents an SOME/IP-TP protocol header. - */ + /// @struct someiptphdr + /// Represents an SOME/IP-TP protocol header. #pragma pack(push, 1) struct someiptphdr : someiphdr { - /** Contains the offset and the more segments flag. 28 bit offset field measured in 16 bytes + 3 bit - * reserved + 1 bit more segments flag */ + /// Contains the offset and the more segments flag. 28 bit offset field measured in 16 bytes + 3 bit + /// reserved + 1 bit more segments flag uint32_t offsetAndFlag; }; #pragma pack(pop) static_assert(sizeof(someiptphdr) == 20, "someiptphdr size is not 20 bytes"); - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to @ref someiptphdr) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to @ref someiptphdr) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in SomeIpTpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : SomeIpLayer(data, dataLen, prevLayer, packet) {} - /** - * A constructor that creates empty layer and sets values - * @param[in] serviceID Service ID - * @param[in] methodID Method ID - * @param[in] clientID Client ID - * @param[in] sessionID Session ID - * @param[in] interfaceVersion Interface Version - * @param[in] type Type of the message - * @param[in] returnCode Return Code - * @param[in] offset Offset indicating the data offset in increments of 16 bytes - * @param[in] moreSegmentsFlag Flag indicating whether more SOME/IP-TP Packets will follow - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - */ + /// A constructor that creates empty layer and sets values + /// @param[in] serviceID Service ID + /// @param[in] methodID Method ID + /// @param[in] clientID Client ID + /// @param[in] sessionID Session ID + /// @param[in] interfaceVersion Interface Version + /// @param[in] type Type of the message + /// @param[in] returnCode Return Code + /// @param[in] offset Offset indicating the data offset in increments of 16 bytes + /// @param[in] moreSegmentsFlag Flag indicating whether more SOME/IP-TP Packets will follow + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes SomeIpTpLayer(uint16_t serviceID, uint16_t methodID, uint16_t clientID, uint16_t sessionID, uint8_t interfaceVersion, MsgType type, uint8_t returnCode, uint32_t offset, bool moreSegmentsFlag, const uint8_t* const data = nullptr, size_t dataLen = 0); - /** - * Destroy the layer object - */ + /// Destroy the layer object ~SomeIpTpLayer() override = default; - /** - * Get a pointer to the basic SOME/IP-TP header. Notice this points directly to the data, so every change will - * change the actual packet data - * @return A pointer to the @ref someiptphdr - */ + /// Get a pointer to the basic SOME/IP-TP header. Notice this points directly to the data, so every change will + /// change the actual packet data + /// @return A pointer to the @ref someiptphdr someiptphdr* getSomeIpTpHeader() const { return reinterpret_cast(m_Data); } - /** - * Get the Offset. Offset is returned in multiple of 16 bytes. - * @return The offset value - */ + /// Get the Offset. Offset is returned in multiple of 16 bytes. + /// @return The offset value uint32_t getOffset() const; - /** - * Set the Offset. Already has to be in multiples of 16 bytes. - * If 32 bytes have already been transmitted, the offset has to be set to 2. - * @param[in] offset Offset to set. Already has to be in multiples of 16 bytes. - */ + /// Set the Offset. Already has to be in multiples of 16 bytes. + /// If 32 bytes have already been transmitted, the offset has to be set to 2. + /// @param[in] offset Offset to set. Already has to be in multiples of 16 bytes. void setOffset(uint32_t offset); - /** - * Get the More Segments Flag - * @return true if the More Segments Flag is set, false if it is not set - */ + /// Get the More Segments Flag + /// @return true if the More Segments Flag is set, false if it is not set bool getMoreSegmentsFlag() const; - /** - * Set the More Segments Flag - * @param[in] flag True if the More Segments Flag shall be set, false for resetting - */ + /// Set the More Segments Flag + /// @param[in] flag True if the More Segments Flag shall be set, false for resetting void setMoreSegmentsFlag(bool flag); - /** - * Sets the message type in this layer with enabling the TP flag - */ + /// Sets the message type in this layer with enabling the TP flag void computeCalculateFields() override; - /** - * @return The string representation of the SOME/IP-TP layer - */ + /// @return The string representation of the SOME/IP-TP layer std::string toString() const override; private: diff --git a/Packet++/header/SomeIpSdLayer.h b/Packet++/header/SomeIpSdLayer.h index 8301abccc9..5ea4cc1123 100644 --- a/Packet++/header/SomeIpSdLayer.h +++ b/Packet++/header/SomeIpSdLayer.h @@ -12,106 +12,86 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * Types of protocols that can be referenced in SOME/IP-SD - */ + /// Types of protocols that can be referenced in SOME/IP-SD enum SomeIpSdProtocolType : uint8_t { - /** TCP */ + /// TCP SD_TCP = 0x06, - /** UDP */ + /// UDP SD_UDP = 0x11 }; class SomeIpSdLayer; - /** - * @class SomeIpSdOption - * Base class of the SOME/IP-SD options. Cannot be instantiated. - */ + /// @class SomeIpSdOption + /// Base class of the SOME/IP-SD options. Cannot be instantiated. class SomeIpSdOption { public: friend class SomeIpSdLayer; - /** - * Types of options currently available for the SOME/IP-SD protocol - */ + /// Types of options currently available for the SOME/IP-SD protocol enum class OptionType : uint8_t { - /** Unknown Option Type */ + /// Unknown Option Type Unknown = 0x00, - /** Configuration Option */ + /// Configuration Option ConfigurationString = 0x01, - /** Load Balancing Option */ + /// Load Balancing Option LoadBalancing = 0x02, - /** IPv4 Endpoint Option */ + /// IPv4 Endpoint Option IPv4Endpoint = 0x04, - /** IPv6 Endpoint Option */ + /// IPv6 Endpoint Option IPv6Endpoint = 0x06, - /** IPv4 Multicast Option */ + /// IPv4 Multicast Option IPv4Multicast = 0x14, - /** IPv6 Multicast Option */ + /// IPv6 Multicast Option IPv6Multicast = 0x16, - /** IPv4 SD Endpoint Option */ + /// IPv4 SD Endpoint Option IPv4SdEndpoint = 0x24, - /** IPv6 SD Endpoint Option */ + /// IPv6 SD Endpoint Option IPv6SdEndpoint = 0x26 }; - /** - * @struct someipsdhdroptionsbase - * Represents the common base for SOME/IP-SD header options - */ + /// @struct someipsdhdroptionsbase + /// Represents the common base for SOME/IP-SD header options #pragma pack(push, 1) struct someipsdhdroptionsbase { - /** Length - excluding the 16 bit Length field and the 8 bit type flag */ + /// Length - excluding the 16 bit Length field and the 8 bit type flag uint16_t length; - /** Type */ + /// Type uint8_t type; - /** Reserved */ + /// Reserved uint8_t reserved; }; #pragma pack(pop) static_assert(sizeof(someipsdhdroptionsbase) == 4, "someipsdhdroptionsbase size is not 4 bytes"); - /** - * Destroy the SOME/IP-SD Option object and delete allocated data if it has been allocated by a constructor - */ + /// Destroy the SOME/IP-SD Option object and delete allocated data if it has been allocated by a constructor virtual ~SomeIpSdOption(); - /** - * Get the Option Type - * @return OptionType - */ + /// Get the Option Type + /// @return OptionType OptionType getType() const; - /** - * Get the Length of the SOME/IP-SD option - * @return size_t - */ + /// Get the Length of the SOME/IP-SD option + /// @return size_t size_t getLength() const { return m_DataLen; } - /** - * Get the internal data of the SOME/IP-SD Option - * @return uint8_t* - */ + /// Get the internal data of the SOME/IP-SD Option + /// @return uint8_t* uint8_t* getDataPtr() const; - /** - * Get a pointer to the SOME/IP-SD Option base header - * @return someipsdhdroptionsbase* - */ + /// Get a pointer to the SOME/IP-SD Option base header + /// @return someipsdhdroptionsbase* someipsdhdroptionsbase* getSomeIpSdOptionHeader() const; protected: @@ -133,484 +113,378 @@ namespace pcpp SomeIpSdOption& operator=(const SomeIpSdOption&) = delete; }; - /** - * @class SomeIpSdIPv4Option - * Implements the following SOME/IP-SD Options: IPv4 Endpoint, IPv4 Multicast, IPv4 SD Endpoint - */ + /// @class SomeIpSdIPv4Option + /// Implements the following SOME/IP-SD Options: IPv4 Endpoint, IPv4 Multicast, IPv4 SD Endpoint class SomeIpSdIPv4Option : public SomeIpSdOption { public: friend class SomeIpSdLayer; - /** - * Types of options which are implemented with this class - */ + /// Types of options which are implemented with this class enum IPv4OptionType { - /** IPv4 Endpoint Option */ + /// IPv4 Endpoint Option IPv4Endpoint, - /** IPv4 Multicast Option */ + /// IPv4 Multicast Option IPv4Multicast, - /** IPv4 SD Endpoint Option */ + /// IPv4 SD Endpoint Option IPv4SdEndpoint, }; - /** - * Construct a new SomeIpSdIPv4 Option object - * @param[in] type IPv4 Option type - * @param[in] ipAddress Ipv4 address to use - * @param[in] port Port to use - * @param[in] l4Protocol Protocol to use - */ + /// Construct a new SomeIpSdIPv4 Option object + /// @param[in] type IPv4 Option type + /// @param[in] ipAddress Ipv4 address to use + /// @param[in] port Port to use + /// @param[in] l4Protocol Protocol to use SomeIpSdIPv4Option(IPv4OptionType type, IPv4Address ipAddress, uint16_t port, SomeIpSdProtocolType l4Protocol); - /** - * Construct a new SomeIpSdIPv4 Option object from already existing memory - * @param[in] dataContainer Data containing the SomeIpSdIPv4 Option object - * @param[in] offset Offset for dataContainer - */ + /// Construct a new SomeIpSdIPv4 Option object from already existing memory + /// @param[in] dataContainer Data containing the SomeIpSdIPv4 Option object + /// @param[in] offset Offset for dataContainer SomeIpSdIPv4Option(const IDataContainer* dataContainer, size_t offset); - /** - * Get the Ip Address - * @return IPv4Address - */ + /// Get the Ip Address + /// @return IPv4Address IPv4Address getIpAddress() const; - /** - * Get the Port - * @return uint16_t - */ + /// Get the Port + /// @return uint16_t uint16_t getPort() const; - /** - * Get the Protocol - * @return SomeIpSdProtocolType - */ + /// Get the Protocol + /// @return SomeIpSdProtocolType SomeIpSdProtocolType getProtocol() const; private: - /** - * @struct someipsdhdroptionsipv4 - * Represents the IPv4 option types for the SOME/IP-SD header - */ + /// @struct someipsdhdroptionsipv4 + /// Represents the IPv4 option types for the SOME/IP-SD header #pragma pack(push, 1) struct someipsdhdroptionsipv4 : someipsdhdroptionsbase { - /* IPv4-Address field */ + /// IPv4-Address field uint32_t ipv4Address; - /* Reserved */ // cppcheck-suppress duplInheritedMember + /// Reserved uint8_t reserved; - /* Layer 4 Protocol field (L4-Proto) - Either UDP or TCP */ + /// Layer 4 Protocol field (L4-Proto) - Either UDP or TCP SomeIpSdProtocolType l4Protocol; - /* Port number of UDP or TCP */ + /// Port number of UDP or TCP uint16_t portNumber; }; #pragma pack(pop) static_assert(sizeof(someipsdhdroptionsipv4) == 12, "someipsdhdroptionsipv4 size is not 12 bytes"); }; - /** - * @class SomeIpSdIPv6Option - * Implements the following SOME/IP-SD Options: IPv6 Endpoint, IPv6 Multicast, IPv6 SD Endpoint - */ + /// @class SomeIpSdIPv6Option + /// Implements the following SOME/IP-SD Options: IPv6 Endpoint, IPv6 Multicast, IPv6 SD Endpoint class SomeIpSdIPv6Option : public SomeIpSdOption { public: friend class SomeIpSdLayer; - /** - * Types of options which are implemented with this class - */ + /// Types of options which are implemented with this class enum IPv6OptionType { - /** IPv6 Endpoint Option */ + /// IPv6 Endpoint Option IPv6Endpoint, - /** IPv6 Multicast Option */ + /// IPv6 Multicast Option IPv6Multicast, - /** IPv6 SD Endpoint Option */ + /// IPv6 SD Endpoint Option IPv6SdEndpoint, }; - /** - * Construct a new SomeIpSdIPv6 Option object - * @param[in] type IPv6 Option type - * @param[in] ipAddress Ipv6 address to use - * @param[in] port Port to use - * @param[in] l4Protocol Protocol to use - */ + /// Construct a new SomeIpSdIPv6 Option object + /// @param[in] type IPv6 Option type + /// @param[in] ipAddress Ipv6 address to use + /// @param[in] port Port to use + /// @param[in] l4Protocol Protocol to use SomeIpSdIPv6Option(IPv6OptionType type, IPv6Address ipAddress, uint16_t port, SomeIpSdProtocolType l4Protocol); - /** - * Construct a new SomeIpSdIPv6 Option object from already existing memory - * @param[in] dataContainer Data containing the SomeIpSdIPv6 Option object - * @param[in] offset Offset for dataContainer - */ + /// Construct a new SomeIpSdIPv6 Option object from already existing memory + /// @param[in] dataContainer Data containing the SomeIpSdIPv6 Option object + /// @param[in] offset Offset for dataContainer SomeIpSdIPv6Option(const IDataContainer* dataContainer, size_t offset); - /** - * Get the Ip Address - * @return IPv6Address - */ + /// Get the Ip Address + /// @return IPv6Address IPv6Address getIpAddress() const; - /** - * Get the Port - * @return uint16_t - */ + /// Get the Port + /// @return uint16_t uint16_t getPort() const; - /** - * Get the Protocol - * @return SomeIpSdProtocolType - */ + /// Get the Protocol + /// @return SomeIpSdProtocolType SomeIpSdProtocolType getProtocol() const; private: - /** - * @struct someipsdhdroptionsipv6 - * Represents the IPv6 option types for the SOME/IP-SD header - */ + /// @struct someipsdhdroptionsipv6 + /// Represents the IPv6 option types for the SOME/IP-SD header #pragma pack(push, 1) struct someipsdhdroptionsipv6 : someipsdhdroptionsbase { - /* IPv6-Address field */ + /// IPv6-Address field uint8_t ipv6Address[16]; - /* Reserved */ // cppcheck-suppress duplInheritedMember + /// Reserved uint8_t reserved; - /* Layer 4 Protocol field (L4-Proto) - Either UDP or TCP */ + /// Layer 4 Protocol field (L4-Proto) - Either UDP or TCP SomeIpSdProtocolType l4Protocol; - /* Port number of UDP or TCP */ + /// Port number of UDP or TCP uint16_t portNumber; }; #pragma pack(pop) static_assert(sizeof(someipsdhdroptionsipv6) == 24, "someipsdhdroptionsipv6 size is not 24 bytes"); }; - /** - * @class SomeIpSdConfigurationOption - * Implements the Configuration option of SOME/IP-SD protocol - */ + /// @class SomeIpSdConfigurationOption + /// Implements the Configuration option of SOME/IP-SD protocol class SomeIpSdConfigurationOption : public SomeIpSdOption { public: friend class SomeIpSdLayer; - /** - * Construct a new Configuration Option object - * @param[in] configurationString the configuration string - */ + /// Construct a new Configuration Option object + /// @param[in] configurationString the configuration string explicit SomeIpSdConfigurationOption(const std::string& configurationString); - /** - * Construct a new Configuration Option object from already existing memory - * @param[in] dataContainer Data containing the Configuration Option object - * @param[in] offset Offset for dataContainer - */ + /// Construct a new Configuration Option object from already existing memory + /// @param[in] dataContainer Data containing the Configuration Option object + /// @param[in] offset Offset for dataContainer SomeIpSdConfigurationOption(const IDataContainer* dataContainer, size_t offset); - /** - * Get the configuration string - * @return std::string - */ + /// Get the configuration string + /// @return std::string std::string getConfigurationString() const; }; - /** - * @class SomeIpSdLoadBalancingOption - * Implements the Load Balancing option of SOME/IP-SD protocol - */ + /// @class SomeIpSdLoadBalancingOption + /// Implements the Load Balancing option of SOME/IP-SD protocol class SomeIpSdLoadBalancingOption : public SomeIpSdOption { public: friend class SomeIpSdLayer; - /** - * Construct a new Load Balancing object - * @param[in] priority Priority of this instance - * @param[in] weight Weight of this instance - */ + /// Construct a new Load Balancing object + /// @param[in] priority Priority of this instance + /// @param[in] weight Weight of this instance SomeIpSdLoadBalancingOption(uint16_t priority, uint16_t weight); - /** - * Construct a new Option object from already existing memory - * @param[in] dataContainer Data containing the option object - * @param[in] offset Offset for dataContainer - */ + /// Construct a new Option object from already existing memory + /// @param[in] dataContainer Data containing the option object + /// @param[in] offset Offset for dataContainer SomeIpSdLoadBalancingOption(const IDataContainer* dataContainer, size_t offset); - /** - * Get the priority fild - * @return uint16_t - */ + /// Get the priority fild + /// @return uint16_t uint16_t getPriority() const; - /** - * Get the weight field - * @return uint16_t - */ + /// Get the weight field + /// @return uint16_t uint16_t getWeight() const; private: - /** - * @struct someipsdhdroptionsload - * Represents the Load Balancing option header for SOME/IP-SD - */ + /// @struct someipsdhdroptionsload + /// Represents the Load Balancing option header for SOME/IP-SD #pragma pack(push, 1) struct someipsdhdroptionsload : someipsdhdroptionsbase { - /* Priority field */ + /// Priority field uint16_t priority; - /* Weight field */ + /// Weight field uint16_t weight; }; #pragma pack(pop) static_assert(sizeof(someipsdhdroptionsload) == 8, "someipsdhdroptionsload size is not 8 bytes"); }; - /** - * @class SomeIpSdEntry - * Implementation of the SOME/IP-SD Service Entry and Eventgroup Entry Type - */ + /// @class SomeIpSdEntry + /// Implementation of the SOME/IP-SD Service Entry and Eventgroup Entry Type class SomeIpSdEntry { public: friend class SomeIpSdLayer; - /** - * Types of entries that can occur in SOME/IP-SD - */ + /// Types of entries that can occur in SOME/IP-SD enum class EntryType : uint8_t { - /** Find Service */ + /// Find Service FindService, - /** Offer Service */ + /// Offer Service OfferService, - /** Stop Offer Service */ + /// Stop Offer Service StopOfferService, - /** Subscribe Eventgroup */ + /// Subscribe Eventgroup SubscribeEventgroup, - /** Stop Subscribe Eventgroup */ + /// Stop Subscribe Eventgroup StopSubscribeEventgroup, - /** Subscribe Eventgroup Acknowledgment */ + /// Subscribe Eventgroup Acknowledgment SubscribeEventgroupAck, - /** Subscribe Eventgroup Negative Acknowledgement */ + /// Subscribe Eventgroup Negative Acknowledgement SubscribeEventgroupNack, - /** Unknown Entry Type */ + /// Unknown Entry Type UnknownEntryType }; - /** - * @struct someipsdhdrentry - * Represents the Service Entry Type and Eventgroup Entry Type - */ + /// @struct someipsdhdrentry + /// Represents the Service Entry Type and Eventgroup Entry Type #pragma pack(push, 1) struct someipsdhdrentry { - /** Type */ + /// Type uint8_t type; - /** Index 1st option */ + /// Index 1st option uint8_t indexFirstOption; - /** Index 2nd option */ + /// Index 2nd option uint8_t indexSecondOption; #if (BYTE_ORDER == LITTLE_ENDIAN) uint8_t - /** Numbers of Option #2 (4bit) */ + /// Numbers of Option #2 (4bit) nrOpt2 : 4, - /** Numbers of Option #1 (4bit) */ + /// Numbers of Option #1 (4bit) nrOpt1 : 4; #else uint8_t - /** Numbers of Option #1 (4bit) */ + /// Numbers of Option #1 (4bit) nrOpt1 : 4, - /** Numbers of Option #2 (4bit) */ + /// Numbers of Option #2 (4bit) nrOpt2 : 4; #endif - /** Service ID */ + /// Service ID uint16_t serviceID; - /** Instance ID */ + /// Instance ID uint16_t instanceID; - /** Major Version (8 bit) + TTL (24 bit) */ + /// Major Version (8 bit) + TTL (24 bit) uint32_t majorVersion_ttl; - /** Minor Version (Service Entry Type) or Counter + Eventgroup ID (Eventgroup Entry Type) */ + /// Minor Version (Service Entry Type) or Counter + Eventgroup ID (Eventgroup Entry Type) uint32_t data; }; #pragma pack(pop) static_assert(sizeof(someipsdhdrentry) == 16, "someipsdhdrentry size is not 16 bytes"); - /** - * Construct a new SOME/IP-SD Service Entry Type - * @param[in] type Type to create - * @param[in] serviceID ServiceID to use - * @param[in] instanceID InstanceID to use - * @param[in] majorVersion MajorVersion to use - * @param[in] TTL TTL to use. Has to be 0 for all Stop* entry types - * @param[in] minorVersion MinorVersion to use - */ + /// Construct a new SOME/IP-SD Service Entry Type + /// @param[in] type Type to create + /// @param[in] serviceID ServiceID to use + /// @param[in] instanceID InstanceID to use + /// @param[in] majorVersion MajorVersion to use + /// @param[in] TTL TTL to use. Has to be 0 for all Stop* entry types + /// @param[in] minorVersion MinorVersion to use SomeIpSdEntry(EntryType type, uint16_t serviceID, uint16_t instanceID, uint8_t majorVersion, uint32_t TTL, uint32_t minorVersion); - /** - * Construct a new SOME/IP-SD Eventgroup Entry Type - * @param[in] type Type to create - * @param[in] serviceID ServiceID to use - * @param[in] instanceID InstanceID to use - * @param[in] majorVersion MajorVersion to use - * @param[in] TTL TTL to use. Has to be 0 for all Stop* entry types - * @param[in] counter Counter value to use - * @param[in] eventGroupID EventgroupId to use - */ + /// Construct a new SOME/IP-SD Eventgroup Entry Type + /// @param[in] type Type to create + /// @param[in] serviceID ServiceID to use + /// @param[in] instanceID InstanceID to use + /// @param[in] majorVersion MajorVersion to use + /// @param[in] TTL TTL to use. Has to be 0 for all Stop* entry types + /// @param[in] counter Counter value to use + /// @param[in] eventGroupID EventgroupId to use SomeIpSdEntry(EntryType type, uint16_t serviceID, uint16_t instanceID, uint8_t majorVersion, uint32_t TTL, uint8_t counter, uint16_t eventGroupID); - /** - * Construct a new SomeIpSdEntry object from existing data - * @param[in] pSomeIpSdLayer Layer that this entry is created for - * @param[in] offset Offset for pSomeIpSdLayer - */ + /// Construct a new SomeIpSdEntry object from existing data + /// @param[in] pSomeIpSdLayer Layer that this entry is created for + /// @param[in] offset Offset for pSomeIpSdLayer SomeIpSdEntry(const SomeIpSdLayer* pSomeIpSdLayer, size_t offset); - /** - * Destroy the SomeIpSd Entry object and delete allocated data if it has been allocated by a constructor - */ + /// Destroy the SomeIpSd Entry object and delete allocated data if it has been allocated by a constructor ~SomeIpSdEntry(); - /** - * Get the internal data of the SOME/IP-SD Entry - * @return uint8_t* - */ + /// Get the internal data of the SOME/IP-SD Entry + /// @return uint8_t* uint8_t* getDataPtr() const; - /** - * Get a pointer to the SOME/IP-SD Entry header - * @return someipsdhdrentry* - */ + /// Get a pointer to the SOME/IP-SD Entry header + /// @return someipsdhdrentry* someipsdhdrentry* getSomeIpSdEntryHeader() const; - /** - * Get the Entry Type - * @return EntryType - */ + /// Get the Entry Type + /// @return EntryType EntryType getType() const { return m_EntryType; } - /** - * Get the Length of the SomeIpSd Entry - * @return size_t - */ + /// Get the Length of the SomeIpSd Entry + /// @return size_t size_t getLength() const { return sizeof(someipsdhdrentry); } - /** - * Get the number of Options of this Entry - * @return uint32_t - */ + /// Get the number of Options of this Entry + /// @return uint32_t uint32_t getNumOptions() const; - /** - * Get the Service Id in host endianness - * @return uint16_t - */ + /// Get the Service Id in host endianness + /// @return uint16_t uint16_t getServiceId() const; - /** - * Set the Service Id - * @param[in] serviceId - */ + /// Set the Service Id + /// @param[in] serviceId void setServiceId(uint16_t serviceId); - /** - * Get the Instance Id in host endianness - * @return uint16_t - */ + /// Get the Instance Id in host endianness + /// @return uint16_t uint16_t getInstanceId() const; - /** - * Set the Instance Id - * @param[in] instanceId - */ + /// Set the Instance Id + /// @param[in] instanceId void setInstanceId(uint16_t instanceId); - /** - * Get the Major version field in host endianness - * @return uint16_t - */ + /// Get the Major version field in host endianness + /// @return uint16_t uint8_t getMajorVersion() const; - /** - * Set the Major Version - * @param[in] majorVersion - */ + /// Set the Major Version + /// @param[in] majorVersion void setMajorVersion(uint8_t majorVersion); - /** - * Get the Ttl field - * @return uint32_t - */ + /// Get the Ttl field + /// @return uint32_t uint32_t getTtl() const; - /** - * Set the Ttl field - * @param[in] ttl - */ + /// Set the Ttl field + /// @param[in] ttl void setTtl(uint32_t ttl); - /** - * Get the minor version - * @return uint32_t - */ + /// Get the minor version + /// @return uint32_t uint32_t getMinorVersion() const; - /** - * Set the minor version - * @param[in] minorVersion - */ + /// Set the minor version + /// @param[in] minorVersion void setMinorVersion(uint32_t minorVersion); - /** - * Get the counter value - * @return uint32_t - */ + /// Get the counter value + /// @return uint32_t uint8_t getCounter() const; - /** - * Set the counter value - * @param[in] counter - */ + /// Set the counter value + /// @param[in] counter void setCounter(uint8_t counter); - /** - * Get the eventgroup id - * @return uint32_t - */ + /// Get the eventgroup id + /// @return uint32_t uint16_t getEventgroupId() const; - /** - * Set the eventgroup id - * @param[in] eventgroupID - */ + /// Set the eventgroup id + /// @param[in] eventgroupID void setEventgroupId(uint16_t eventgroupID); private: - /** - * These are the entry types used by SOME/IP-SD. They cannot be used for parameter passing since the values - * are not unique. - */ + /// These are the entry types used by SOME/IP-SD. They cannot be used for parameter passing since the values + /// are not unique. enum class TypeInternal : uint8_t { - /** Find Service */ + /// Find Service FindService_Internal = 0x00, - /** Offer Service / Stop Offer Service */ + /// Offer Service / Stop Offer Service OfferService_Internal = 0x01, - /** Subscribe Eventgroup & Stop Subscribe Eventgroup */ + /// Subscribe Eventgroup & Stop Subscribe Eventgroup SubscribeEventgroup_Internal = 0x06, - /** Subscribe Eventgroup Acknowledgment / Negative Acknowledgement */ + /// Subscribe Eventgroup Acknowledgment / Negative Acknowledgement SubscribeEventgroupAck_Internal = 0x07, }; @@ -627,10 +501,8 @@ namespace pcpp static const uint32_t SOMEIPSD_HDR_ENTRY_MASK_TTL = 0x00FFFFFF; }; - /** - * @class SomeIpSdLayer - * Implementation of the SOME/IP-SD protocol - */ + /// @class SomeIpSdLayer + /// Implementation of the SOME/IP-SD protocol class SomeIpSdLayer : public SomeIpLayer { public: @@ -641,137 +513,103 @@ namespace pcpp typedef SomeIpSdOption* OptionPtr; typedef std::vector OptionsVec; - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in SomeIpSdLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * Construct a new SomeIpSdLayer object - * @param[in] serviceID Service ID - * @param[in] methodID Method ID - * @param[in] clientID Client ID - * @param[in] sessionID Session ID - * @param[in] interfaceVersion Interface Version - * @param[in] type Type of the message - * @param[in] returnCode Return Code - * @param[in] flags Flags that shall be used in the header - */ + /// Construct a new SomeIpSdLayer object + /// @param[in] serviceID Service ID + /// @param[in] methodID Method ID + /// @param[in] clientID Client ID + /// @param[in] sessionID Session ID + /// @param[in] interfaceVersion Interface Version + /// @param[in] type Type of the message + /// @param[in] returnCode Return Code + /// @param[in] flags Flags that shall be used in the header SomeIpSdLayer(uint16_t serviceID, uint16_t methodID, uint16_t clientID, uint16_t sessionID, uint8_t interfaceVersion, MsgType type, uint8_t returnCode, uint8_t flags); - /** - * Destroy the layer object - */ + /// Destroy the layer object ~SomeIpSdLayer() override = default; - /** - * Checks if given port is a SOME/IP-SD protocol port - * @param[in] port Port to check - * @return true if SOME/IP-SD protocol port, false if not - */ + /// Checks if given port is a SOME/IP-SD protocol port + /// @param[in] port Port to check + /// @return true if SOME/IP-SD protocol port, false if not static bool isSomeIpSdPort(uint16_t port) { return port == 30490; } - /** - * The static method makes validation of input data - * @param[in] data The pointer to the beginning of byte stream of IP packet - * @param[in] dataLen The length of byte stream - * @return True if the data is valid and can represent the packet - */ + /// The static method makes validation of input data + /// @param[in] data The pointer to the beginning of byte stream of IP packet + /// @param[in] dataLen The length of byte stream + /// @return True if the data is valid and can represent the packet static bool isDataValid(const uint8_t* data, size_t dataLen); - /** - * Get the Flags of the layer - * @return uint8_t Flags - */ + /// Get the Flags of the layer + /// @return uint8_t Flags uint8_t getFlags() const; - /** - * Set the Flags of the layer - * @param[in] flags Flags to set - */ + /// Set the Flags of the layer + /// @param[in] flags Flags to set void setFlags(uint8_t flags); - /** - * Get the number of entries in this layer - * @return uint32_t - */ + /// Get the number of entries in this layer + /// @return uint32_t uint32_t getNumEntries() const; - /** - * Get the number of options in this layer - * @return uint32_t - */ + /// Get the number of options in this layer + /// @return uint32_t uint32_t getNumOptions() const; - /** - * Get the Entries from this layer - * @return EntriesVec Vector holding pointers to the options - */ + /// Get the Entries from this layer + /// @return EntriesVec Vector holding pointers to the options const EntriesVec getEntries() const; - /** - * Get the Options from this layer - * @return OptionsVec Vector holding pointers to the options - */ + /// Get the Options from this layer + /// @return OptionsVec Vector holding pointers to the options const OptionsVec getOptions() const; - /** - * Get the Options from a specific Entry - * @param[in] index Index of the Entry, starting with 0. - * @return OptionsVec Vector holding pointers to the options - */ + /// Get the Options from a specific Entry + /// @param[in] index Index of the Entry, starting with 0. + /// @return OptionsVec Vector holding pointers to the options const OptionsVec getOptionsFromEntry(uint32_t index) const; - /** - * Adds a given entry to the layer and returns the index of the entry - * @param[in] entry Pointer to the entry that shall be added to the layer - * @return uint32_t Returns the index of the entry starting with 0 - */ + /// Adds a given entry to the layer and returns the index of the entry + /// @param[in] entry Pointer to the entry that shall be added to the layer + /// @return uint32_t Returns the index of the entry starting with 0 uint32_t addEntry(const SomeIpSdEntry& entry); - /** - * Adds an option to an entry that has already been added to the layer by using addEntry(). The option - * is also added to the layer itself. If the option cannot by assigned to the entry, the option is not - * copied into the layer. - * @param[in] indexEntry Index of the entry where the option shall be added. First Entry has index 0 - * @param[in] option Pointer to the option that shall be added - * @return True if the option could be assigned to the entry and was copied into the layer, false otherwise - */ + /// Adds an option to an entry that has already been added to the layer by using addEntry(). The option + /// is also added to the layer itself. If the option cannot by assigned to the entry, the option is not + /// copied into the layer. + /// @param[in] indexEntry Index of the entry where the option shall be added. First Entry has index 0 + /// @param[in] option Pointer to the option that shall be added + /// @return True if the option could be assigned to the entry and was copied into the layer, false otherwise bool addOptionTo(uint32_t indexEntry, const SomeIpSdOption& option); - /** - * Does nothing for this layer - */ + /// Does nothing for this layer void computeCalculateFields() override {}; - /** - * @return The string representation of the SOME/IP-SD layer - */ + /// @return The string representation of the SOME/IP-SD layer std::string toString() const override; private: - /** - * @struct someipsdhdr - * Represents an SOME/IP-SD protocol header - */ + /// @struct someipsdhdr + /// Represents an SOME/IP-SD protocol header #pragma pack(push, 1) struct someipsdhdr : someiphdr { - /** Flags (8 bit) */ + /// Flags (8 bit) uint8_t flags; - /** Reserved1 field (Bits 0-7 of 24-bits reserved field) */ + /// Reserved1 field (Bits 0-7 of 24-bits reserved field) uint8_t reserved1; - /** Reserved2 field (Bits 8-15 of 24-bits reserved field) */ + /// Reserved2 field (Bits 8-15 of 24-bits reserved field) uint8_t reserved2; - /** Reserved3 field (Bits 16-23 of 24-bits reserved field) */ + /// Reserved3 field (Bits 16-23 of 24-bits reserved field) uint8_t reserved3; }; #pragma pack(pop) @@ -792,5 +630,4 @@ namespace pcpp void setLenEntries(uint32_t length); void setLenOptions(uint32_t length); }; - } // namespace pcpp diff --git a/Packet++/header/StpLayer.h b/Packet++/header/StpLayer.h index 0eb323247b..3b15fcbcfe 100644 --- a/Packet++/header/StpLayer.h +++ b/Packet++/header/StpLayer.h @@ -6,17 +6,12 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - -/** - * @struct stp_tcn_bpdu - * Represents payload of network changes announcements of BPDU - */ + /// @struct stp_tcn_bpdu + /// Represents payload of network changes announcements of BPDU #pragma pack(push, 1) struct stp_tcn_bpdu { @@ -34,10 +29,8 @@ namespace pcpp typedef stp_tcn_bpdu stp_header; static_assert(sizeof(stp_header) == 4, "stp_header size is not 4 bytes"); -/** - * @struct stp_conf_bpdu - * Represents payload configuration of BPDU for STP - */ + /// @struct stp_conf_bpdu + /// Represents payload configuration of BPDU for STP #pragma pack(push, 1) struct stp_conf_bpdu : stp_tcn_bpdu { @@ -63,10 +56,8 @@ namespace pcpp #pragma pack(pop) static_assert(sizeof(stp_conf_bpdu) == 35, "stp_conf_bpdu size is not 35 bytes"); -/** - * @struct rstp_conf_bpdu - * Represents payload configuration of BPDU for Rapid STP (RSTP) - */ + /// @struct rstp_conf_bpdu + /// Represents payload configuration of BPDU for Rapid STP (RSTP) #pragma pack(push, 1) struct rstp_conf_bpdu : stp_conf_bpdu { @@ -76,10 +67,8 @@ namespace pcpp #pragma pack(pop) static_assert(sizeof(rstp_conf_bpdu) == 36, "rstp_conf_bpdu size is not 36 bytes"); -/** - * @struct mstp_conf_bpdu - * Represents payload configuration of BPDU for Multiple STP (MSTP) - */ + /// @struct mstp_conf_bpdu + /// Represents payload configuration of BPDU for Multiple STP (MSTP) #pragma pack(push, 1) struct mstp_conf_bpdu : rstp_conf_bpdu { @@ -103,10 +92,9 @@ namespace pcpp #pragma pack(pop) static_assert(sizeof(mstp_conf_bpdu) == 102, "mstp_conf_bpdu size is not 102 bytes"); -/** - * @struct msti_conf_msg - * Represents MSTI configuration messages. Each message contains 16 bytes and MSTP can contain 0 to 64 MSTI messages. - */ + /// @struct msti_conf_msg + /// Represents MSTI configuration messages. Each message contains 16 bytes and MSTP can contain 0 to 64 MSTI + /// messages. #pragma pack(push, 1) struct msti_conf_msg { @@ -126,10 +114,8 @@ namespace pcpp #pragma pack(pop) static_assert(sizeof(msti_conf_msg) == 16, "msti_conf_msg size is not 16 bytes"); - /** - * @class StpLayer - * Represents an Spanning Tree Protocol Layer - */ + /// @class StpLayer + /// Represents an Spanning Tree Protocol Layer class StpLayer : public Layer { protected: @@ -154,64 +140,51 @@ namespace pcpp /// STP Uplink Fast protocol uses "01:00:0C:CD:CD:CD" as destination MAC static pcpp::MacAddress StpUplinkFastMulticastDstMAC; - /** - * Get a pointer to base Spanning tree header - * @return A pointer to spanning tree header - */ + /// Get a pointer to base Spanning tree header + /// @return A pointer to spanning tree header stp_header* getStpHeader() const { return reinterpret_cast(m_Data); } - /** - * Returns the protocol id. Fixed at 0x0 for STP messages which represents IEEE 802.1d - * @return ID of the protocol - */ + /// Returns the protocol id. Fixed at 0x0 for STP messages which represents IEEE 802.1d + /// @return ID of the protocol uint16_t getProtoId() const { return getStpHeader()->protoId; } - /** - * Sets the protocol id - * @param[in] value ID of the protocol - */ + /// Sets the protocol id + /// @param[in] value ID of the protocol + void setProtoId(uint16_t value) { getStpHeader()->protoId = value; } - /** - * Returns the version. Fixed at 0x0 for STP messages - * @return Version number - */ + /// Returns the version. Fixed at 0x0 for STP messages + /// @return Version number uint8_t getVersion() const { return getStpHeader()->version; } - /** - * Sets the version - * @param[in] value Version number - */ + /// Sets the version + /// @param[in] value Version number void setVersion(uint8_t value) { getStpHeader()->version = value; } - /** - * Returns the type of configuration message. - * @return Type of configuration message - */ + /// Returns the type of configuration message. + /// @return Type of configuration message uint8_t getType() const { return getStpHeader()->type; } - /** - * Sets the type of configuration message - * @param[in] value Type of configuration message - */ + /// Sets the type of configuration message + /// @param[in] value Type of configuration message void setType(uint8_t value) { getStpHeader()->type = value; @@ -219,9 +192,7 @@ namespace pcpp // overridden methods - /** - * @return The size of STP packet - */ + /// @return The size of STP packet size_t getHeaderLen() const override { return m_DataLen; @@ -231,38 +202,30 @@ namespace pcpp void computeCalculateFields() override {} - /** - * @return The OSI layer level of STP (Data Link Layer). - */ + /// @return The OSI layer level of STP (Data Link Layer). OsiModelLayer getOsiModelLayer() const override { return OsiModelDataLinkLayer; } - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of an Spanning Tree packet - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent an Spanning Tree packet - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of an Spanning Tree packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent an Spanning Tree packet static bool isDataValid(const uint8_t* data, size_t dataLen); - /** - * A method to create STP layer from existing packet - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored - * @return A newly allocated STP layer of one of the following types (according to the message type): - * StpConfigurationBPDULayer, StpTopologyChangeBPDULayer, RapidStpLayer, MultipleStpLayer - */ + /// A method to create STP layer from existing packet + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored + /// @return A newly allocated STP layer of one of the following types (according to the message type): + /// StpConfigurationBPDULayer, StpTopologyChangeBPDULayer, RapidStpLayer, MultipleStpLayer static StpLayer* parseStpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); }; - /** - * @class StpTopologyChangeBPDULayer - * Represents network topology change BPDU message of Spanning Tree Protocol - */ + /// @class StpTopologyChangeBPDULayer + /// Represents network topology change BPDU message of Spanning Tree Protocol class StpTopologyChangeBPDULayer : public StpLayer { protected: @@ -270,27 +233,21 @@ namespace pcpp {} public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in StpTopologyChangeBPDULayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : StpLayer(data, dataLen, prevLayer, packet) {} - /** - * Empty c'tor to create a new network topology change (TCN) BPDU layer. - * Initializes the protocol identifier, version and STP type fields with correct values - */ + /// Empty c'tor to create a new network topology change (TCN) BPDU layer. + /// Initializes the protocol identifier, version and STP type fields with correct values StpTopologyChangeBPDULayer(); - /** - * Get a pointer to network topology change (TCN) BPDU message - * @return A pointer to TCN BPDU message - */ + /// Get a pointer to network topology change (TCN) BPDU message + /// @return A pointer to TCN BPDU message stp_tcn_bpdu* getStpTcnHeader() { return getStpHeader(); @@ -298,9 +255,7 @@ namespace pcpp // overridden methods - /** - * @return The size of STP TCN message - */ + /// @return The size of STP TCN message size_t getHeaderLen() const override { return sizeof(stp_tcn_bpdu); @@ -309,30 +264,25 @@ namespace pcpp /// Parses next layer void parseNextLayer() override; - /** - * @return Returns the protocol info as readable string - */ + /// @return Returns the protocol info as readable string std::string toString() const override { return "Spanning Tree Topology Change Notification"; } - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of an Spanning Tree Topology Change BPDU packet - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent an Spanning Tree packet - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of an Spanning Tree Topology Change BPDU + /// packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent an Spanning Tree packet static bool isDataValid(const uint8_t* data, size_t dataLen) { return data && dataLen >= sizeof(stp_tcn_bpdu); } }; - /** - * @class StpConfigurationBPDULayer - * Represents configuration BPDU message of Spanning Tree Protocol - */ + /// @class StpConfigurationBPDULayer + /// Represents configuration BPDU message of Spanning Tree Protocol class StpConfigurationBPDULayer : public StpTopologyChangeBPDULayer { protected: @@ -340,229 +290,161 @@ namespace pcpp {} public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in StpConfigurationBPDULayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : StpTopologyChangeBPDULayer(data, dataLen, prevLayer, packet) {} - /** - * Empty c'tor to create a new configuration BPDU layer. - * Initializes the protocol identifier, version and STP type fields with correct values - */ + /// Empty c'tor to create a new configuration BPDU layer. + /// Initializes the protocol identifier, version and STP type fields with correct values StpConfigurationBPDULayer(); - /** - * Get a pointer to configuration BPDU message - * @return A pointer to configuration BPDU message - */ + /// Get a pointer to configuration BPDU message + /// @return A pointer to configuration BPDU message stp_conf_bpdu* getStpConfHeader() const { return reinterpret_cast(m_Data); } - /** - * Returns the flags of configuration message which indicates purpose of BPDU - * @return Flags of the configuration message - */ + /// Returns the flags of configuration message which indicates purpose of BPDU + /// @return Flags of the configuration message uint8_t getFlag() const { return getStpConfHeader()->flag; } - /** - * Returns the flags of configuration message which indicates purpose of BPDU - * @param[in] value Flags of the configuration message - */ + /// Returns the flags of configuration message which indicates purpose of BPDU + /// @param[in] value Flags of the configuration message void setFlag(uint8_t value) { getStpConfHeader()->flag = value; } - /** - * Returns the root bridge identifier - * @return Root bridge identifier - */ + /// Returns the root bridge identifier + /// @return Root bridge identifier uint64_t getRootId() const; - /** - * Sets the root bridge identifier - * @param[in] value Root bridge identifier - */ + /// Sets the root bridge identifier + /// @param[in] value Root bridge identifier void setRootId(uint64_t value); - /** - * Returns the priority of root bridge - * @return Priority of root bridge - */ + /// Returns the priority of root bridge + /// @return Priority of root bridge uint16_t getRootPriority() const; - /** - * Sets the priority of root bridge - * @param[in] value Priority of root bridge - */ + /// Sets the priority of root bridge + /// @param[in] value Priority of root bridge void setRootPriority(uint16_t value); - /** - * Returns the system identifier extension of root bridge - * @return System extension of root bridge - */ + /// Returns the system identifier extension of root bridge + /// @return System extension of root bridge uint16_t getRootSystemIDExtension() const; - /** - * Sets the system identifier extension of root bridge - * @param[in] value System extension of root bridge - */ + /// Sets the system identifier extension of root bridge + /// @param[in] value System extension of root bridge void setRootSystemIDExtension(uint16_t value); - /** - * Returns the system identifier of root bridge - * @return System identifier of root bridge - */ + /// Returns the system identifier of root bridge + /// @return System identifier of root bridge pcpp::MacAddress getRootSystemID() const { return IDtoMacAddress(getRootId()); } - /** - * Sets the system identifier of root bridge - * @param[in] value System identifier of root bridge - */ + /// Sets the system identifier of root bridge + /// @param[in] value System identifier of root bridge void setRootSystemID(const pcpp::MacAddress& value); - /** - * Returns the value of the cost of path - * @return Cost of path - */ + /// Returns the value of the cost of path + /// @return Cost of path uint32_t getPathCost() const; - /** - * Sets the value of the cost of path - * @param[in] value Cost of path - */ + /// Sets the value of the cost of path + /// @param[in] value Cost of path void setPathCost(uint32_t value); - /** - * Returns the bridge identifier - * @return Bridge identifier - */ + /// Returns the bridge identifier + /// @return Bridge identifier uint64_t getBridgeId() const; - /** - * Sets the bridge identifier - * @param[in] value Bridge identifier - */ + /// Sets the bridge identifier + /// @param[in] value Bridge identifier void setBridgeId(uint64_t value); - /** - * Returns the priority of bridge - * @return Priority of bridge - */ + /// Returns the priority of bridge + /// @return Priority of bridge uint16_t getBridgePriority() const; - /** - * Sets the priority of bridge - * @param[in] value Priority of bridge - */ + /// Sets the priority of bridge + /// @param[in] value Priority of bridge void setBridgePriority(uint16_t value); - /** - * Returns the system identifier extension of bridge - * @return System extension of bridge - */ + /// Returns the system identifier extension of bridge + /// @return System extension of bridge uint16_t getBridgeSystemIDExtension() const; - /** - * Sets the system identifier extension of bridge - * @param[in] value System extension of bridge - */ + /// Sets the system identifier extension of bridge + /// @param[in] value System extension of bridge void setBridgeSystemIDExtension(uint16_t value); - /** - * Returns the system identifier of bridge - * @return System identifier of bridge - */ + /// Returns the system identifier of bridge + /// @return System identifier of bridge pcpp::MacAddress getBridgeSystemID() const { return IDtoMacAddress(getBridgeId()); } - /** - * Sets the system identifier of bridge - * @param[in] value System identifier of bridge - */ + /// Sets the system identifier of bridge + /// @param[in] value System identifier of bridge void setBridgeSystemID(const pcpp::MacAddress& value); - /** - * Returns the port identifier - * @return Port identifier - */ + /// Returns the port identifier + /// @return Port identifier uint16_t getPortId() const; - /** - * Sets the port identifier - * @param[in] value Port identifier - */ + /// Sets the port identifier + /// @param[in] value Port identifier void setPortId(uint16_t value); - /** - * Returns age of the BPDU message - * @return Age of BPDU in seconds - */ + /// Returns age of the BPDU message + /// @return Age of BPDU in seconds double getMessageAge() const; - /** - * Sets age of the BPDU message - * @param[in] value Age of BPDU in seconds - */ + /// Sets age of the BPDU message + /// @param[in] value Age of BPDU in seconds void setMessageAge(double value); - /** - * Returns maximum age of the BPDU message - * @return Maximum age of BPDU in seconds - */ + /// Returns maximum age of the BPDU message + /// @return Maximum age of BPDU in seconds double getMaximumAge() const; - /** - * Sets maximum age of the BPDU message - * @param[in] value Maximum age of BPDU in seconds - */ + /// Sets maximum age of the BPDU message + /// @param[in] value Maximum age of BPDU in seconds void setMaximumAge(double value); - /** - * Returns the BPDU transmission interval - * @return Value of the transmission interval in seconds - */ + /// Returns the BPDU transmission interval + /// @return Value of the transmission interval in seconds double getTransmissionInterval() const; - /** - * Sets the BPDU transmission interval - * @param[in] value Value of the transmission interval in seconds - */ + /// Sets the BPDU transmission interval + /// @param[in] value Value of the transmission interval in seconds void setTransmissionInterval(double value); - /** - * Returns the delay for STP message - * @return Value of the forward delay in seconds - */ + /// Returns the delay for STP message + /// @return Value of the forward delay in seconds double getForwardDelay() const; - /** - * Sets the delay for STP message - * @param[in] value Value of the forward delay in seconds - */ + /// Sets the delay for STP message + /// @param[in] value Value of the forward delay in seconds void setForwardDelay(double value); // overridden methods - /** - * @return The size of STP configuration BPDU message - */ + /// @return The size of STP configuration BPDU message size_t getHeaderLen() const override { return sizeof(stp_conf_bpdu); @@ -571,30 +453,24 @@ namespace pcpp /// Parses next layer void parseNextLayer() override; - /** - * @return Returns the protocol info as readable string - */ + /// @return Returns the protocol info as readable string std::string toString() const override { return "Spanning Tree Configuration"; } - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of an Spanning Tree Configuration BPDU packet - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent an Spanning Tree packet - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of an Spanning Tree Configuration BPDU packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent an Spanning Tree packet static bool isDataValid(const uint8_t* data, size_t dataLen) { return data && dataLen >= sizeof(stp_conf_bpdu); } }; - /** - * @class RapidStpLayer - * Represents Rapid Spanning Tree Protocol (RSTP) - */ + /// @class RapidStpLayer + /// Represents Rapid Spanning Tree Protocol (RSTP) class RapidStpLayer : public StpConfigurationBPDULayer { protected: @@ -602,45 +478,35 @@ namespace pcpp {} public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in RapidStpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : StpConfigurationBPDULayer(data, dataLen, prevLayer, packet) {} - /** - * Empty c'tor to create a new Rapid STP layer. - * Initializes the protocol identifier, version and STP type fields with correct values - */ + /// Empty c'tor to create a new Rapid STP layer. + /// Initializes the protocol identifier, version and STP type fields with correct values RapidStpLayer(); - /** - * Get a pointer to Rapid STP header - * @return A pointer to Rapid STP header - */ + /// Get a pointer to Rapid STP header + /// @return A pointer to Rapid STP header rstp_conf_bpdu* getRstpConfHeader() const { return reinterpret_cast(m_Data); } - /** - * Returns the length of version1 field. Fixed at 0x0 for Rapid STP - * @return Length of the version1 field - */ + /// Returns the length of version1 field. Fixed at 0x0 for Rapid STP + /// @return Length of the version1 field uint8_t getVersion1Len() const { return getRstpConfHeader()->version1Len; } - /** - * Returns the length of version1 field - * @param[in] value Length of the version1 field - */ + /// Returns the length of version1 field + /// @param[in] value Length of the version1 field void setVersion1Len(uint8_t value) { getRstpConfHeader()->version1Len = value; @@ -648,9 +514,7 @@ namespace pcpp // overridden methods - /** - * @return The size of Rapid STP message - */ + /// @return The size of Rapid STP message size_t getHeaderLen() const override { return sizeof(rstp_conf_bpdu); @@ -659,226 +523,166 @@ namespace pcpp /// Parses next layer void parseNextLayer() override; - /** - * @return Returns the protocol info as readable string - */ + /// @return Returns the protocol info as readable string std::string toString() const override { return "Rapid Spanning Tree"; } - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of an Rapid STP packet - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent an Spanning Tree packet - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of an Rapid STP packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent an Spanning Tree packet static bool isDataValid(const uint8_t* data, size_t dataLen) { return data && dataLen >= sizeof(rstp_conf_bpdu); } }; - /** - * @class MultipleStpLayer - * Represents Multiple Spanning Tree Protocol (MSTP). It has limited capabilities (no crafting / limited editing) - * over MSTI configuration - */ + /// @class MultipleStpLayer + /// Represents Multiple Spanning Tree Protocol (MSTP). It has limited capabilities (no crafting / limited editing) + /// over MSTI configuration class MultipleStpLayer : public RapidStpLayer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in MultipleStpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : RapidStpLayer(data, dataLen, prevLayer, packet) {} - /** - * Empty c'tor to create a new Multiple STP layer. - * Initializes the protocol identifier, version and STP type fields with correct values - */ + /// Empty c'tor to create a new Multiple STP layer. + /// Initializes the protocol identifier, version and STP type fields with correct values MultipleStpLayer(); - /** - * Get a pointer to Multiple STP header - * @return A pointer to Multiple STP header - */ + /// Get a pointer to Multiple STP header + /// @return A pointer to Multiple STP header mstp_conf_bpdu* getMstpHeader() const { return reinterpret_cast(m_Data); } - /** - * @return Length of version3 field - */ + /// @return Length of version3 field uint16_t getVersion3Len() const; - /** - * Sets the length of version3 field - * @param[in] value Length of version3 field - */ + /// Sets the length of version3 field + /// @param[in] value Length of version3 field void setVersion3Len(uint16_t value); - /** - * Returns the configuration ID format selector - * @return Configuration ID of format selector - */ + /// Returns the configuration ID format selector + /// @return Configuration ID of format selector uint8_t getMstConfigurationFormatSelector() const { return getMstpHeader()->mstConfigFormatSelector; } - /** - * Sets the configuration ID format selector - * @param[in] value Configuration ID of format selector - */ + /// Sets the configuration ID format selector + /// @param[in] value Configuration ID of format selector void setMstConfigurationFormatSelector(uint8_t value) { getMstpHeader()->mstConfigFormatSelector = value; } - /** - * Returns the pointer to configuration name field - * @return Configuration name - */ + /// Returns the pointer to configuration name field + /// @return Configuration name std::string getMstConfigurationName() const; - /** - * Sets the configuration name field - * @param[in] value Configuration name. Length should be less than 32, if longer value provided first 32 - * characters are used - */ + /// Sets the configuration name field + /// @param[in] value Configuration name. Length should be less than 32, if longer value provided first 32 + /// characters are used void setMstConfigurationName(const std::string& value); - /** - * Returns the revision of configuration ID - * @return Revision of configuration ID - */ + /// Returns the revision of configuration ID + /// @return Revision of configuration ID uint16_t getMstConfigRevision() const; - /** - * Sets the revision of configuration ID - * @param[in] value Revision of configuration ID - */ + /// Sets the revision of configuration ID + /// @param[in] value Revision of configuration ID void setMstConfigRevision(uint16_t value); - /** - * Returns the pointer to configuration message digest. The field itself always 16 bytes long. - * @return A pointer to configuration digest - */ + /// Returns the pointer to configuration message digest. The field itself always 16 bytes long. + /// @return A pointer to configuration digest uint8_t* getMstConfigDigest() const { return getMstpHeader()->mstConfigDigest; } - /** - * Sets the pointer to configuration message digest. The field itself always 16 bytes long. - * @param[in] value Pointer to digest - * @param[in] len Length of the digest, should be less than 16. If longer first 16 bytes are used - */ + /// Sets the pointer to configuration message digest. The field itself always 16 bytes long. + /// @param[in] value Pointer to digest + /// @param[in] len Length of the digest, should be less than 16. If longer first 16 bytes are used void setMstConfigDigest(const uint8_t* value, uint8_t len); - /** - * Returns CIST internal root path cost - * @return Value of the internal root path cost - */ + /// Returns CIST internal root path cost + /// @return Value of the internal root path cost uint32_t getCISTIrpc() const; - /** - * Sets CIST internal root path cost - * @param[in] value Value of the internal root path cost - */ + /// Sets CIST internal root path cost + /// @param[in] value Value of the internal root path cost void setCISTIrpc(uint32_t value); - /** - * Returns CIST bridge identifier - * @return Value of the bridge identifier - */ + /// Returns CIST bridge identifier + /// @return Value of the bridge identifier uint64_t getCISTBridgeId() const; - /** - * Sets CIST bridge identifier - * @param[in] value Value of the bridge identifier - */ + /// Sets CIST bridge identifier + /// @param[in] value Value of the bridge identifier void setCISTBridgeId(uint64_t value); - /** - * Returns the priority of CIST bridge - * @return Priority of CIST bridge - */ + /// Returns the priority of CIST bridge + /// @return Priority of CIST bridge uint16_t getCISTBridgePriority() const; - /** - * Sets the priority of CIST bridge - * @param[in] value Priority of CIST bridge - */ + /// Sets the priority of CIST bridge + /// @param[in] value Priority of CIST bridge void setCISTBridgePriority(uint16_t value); - /** - * Returns the system identifier extension of CIST bridge - * @return System extension of CIST bridge - */ + /// Returns the system identifier extension of CIST bridge + /// @return System extension of CIST bridge uint16_t getCISTBridgeSystemIDExtension() const; - /** - * Sets the system identifier extension of CIST bridge - * @param[in] value System extension of CIST bridge - */ + /// Sets the system identifier extension of CIST bridge + /// @param[in] value System extension of CIST bridge void setCISTBridgeSystemIDExtension(uint16_t value); - /** - * Returns the system identifier of CIST bridge - * @return System identifier of CIST bridge - */ + /// Returns the system identifier of CIST bridge + /// @return System identifier of CIST bridge pcpp::MacAddress getCISTBridgeSystemID() const { return IDtoMacAddress(getCISTBridgeId()); } - /** - * Sets the system identifier of CIST bridge - * @param[in] value System identifier of CIST bridge - */ + /// Sets the system identifier of CIST bridge + /// @param[in] value System identifier of CIST bridge void setCISTBridgeSystemID(const pcpp::MacAddress& value); - /** - * Returns the remaining hop count - * @return Value of remaining hop count - */ + /// Returns the remaining hop count + /// @return Value of remaining hop count uint8_t getRemainingHopCount() const { return getMstpHeader()->remainId; } - /** - * Returns the remaining hop count - * @param[in] value Value of remaining hop count - */ + /// Returns the remaining hop count + /// @param[in] value Value of remaining hop count void setRemainingHopCount(uint8_t value) { getMstpHeader()->remainId = value; } - /** - * Returns the total number of MSTI configuration messages - * @return Number of MSTI configuration messages. Can be between 0 and 64. - */ + /// Returns the total number of MSTI configuration messages + /// @return Number of MSTI configuration messages. Can be between 0 and 64. uint8_t getNumberOfMSTIConfMessages() const { return (getVersion3Len() - (sizeof(mstp_conf_bpdu) - sizeof(rstp_conf_bpdu) - sizeof(uint16_t))) / sizeof(msti_conf_msg); } - /** - * Returns a reference to MSTI configuration messages. An MSTP packet can contain between 0 to 64 MSTI messages. - * The number of messages can be obtained by using getNumberOfMSTIConfMessages() - * @return An array pointer to MSTI configuration messages. Returns nullptr if there is no MSTI message. - */ + /// Returns a reference to MSTI configuration messages. An MSTP packet can contain between 0 to 64 MSTI + /// messages. The number of messages can be obtained by using getNumberOfMSTIConfMessages() + /// @return An array pointer to MSTI configuration messages. Returns nullptr if there is no MSTI message. msti_conf_msg* getMstiConfMessages() const; // overridden methods @@ -887,20 +691,16 @@ namespace pcpp void parseNextLayer() override {} - /** - * @return Returns the protocol info as readable string - */ + /// @return Returns the protocol info as readable string std::string toString() const override { return "Multiple Spanning Tree"; } - /** - * A static method that validates the input data - * @param[in] data The pointer to the beginning of a byte stream of an Multiple STP packet - * @param[in] dataLen The length of the byte stream - * @return True if the data is valid and can represent an Spanning Tree packet - */ + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of an Multiple STP packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent an Spanning Tree packet static bool isDataValid(const uint8_t* data, size_t dataLen) { return data && dataLen >= sizeof(mstp_conf_bpdu); diff --git a/Packet++/header/TLVData.h b/Packet++/header/TLVData.h index b94867edf2..b24dd6f708 100644 --- a/Packet++/header/TLVData.h +++ b/Packet++/header/TLVData.h @@ -6,31 +6,27 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @class TLVRecord - * A wrapper class for a Type-Length-Value (TLV) record. This class does not create or modify TLV records, but - * rather serves as a wrapper and provides useful methods for retrieving data from them. This class has several - * abstract methods that should be implemented in derived classes. These methods are for record length value - * calculation (the 'L' in TLV) which is implemented differently in different protocols - */ + /// @class TLVRecord + /// A wrapper class for a Type-Length-Value (TLV) record. This class does not create or modify TLV records, but + /// rather serves as a wrapper and provides useful methods for retrieving data from them. This class has several + /// abstract methods that should be implemented in derived classes. These methods are for record length value + /// calculation (the 'L' in TLV) which is implemented differently in different protocols template class TLVRecord { protected: - /** A struct representing the TLV construct */ + /// A struct representing the TLV construct #pragma pack(push, 1) struct TLVRawData { - /** Record type */ + /// Record type TRecType recordType; - /** Record length in bytes */ + /// Record length in bytes TRecLen recordLen; - /** Record value (variable size) */ + /// Record value (variable size) uint8_t recordValue[]; }; #pragma pack(pop) @@ -38,69 +34,55 @@ namespace pcpp TLVRawData* m_Data; public: - /** - * A c'tor for this class that gets a pointer to the TLV record raw data (byte array) - * @param[in] recordRawData A pointer to the TLV record raw data - */ + /// A c'tor for this class that gets a pointer to the TLV record raw data (byte array) + /// @param[in] recordRawData A pointer to the TLV record raw data TLVRecord(uint8_t* recordRawData) { assign(recordRawData); } - /** - * A copy c'tor for this class. This copy c'tor doesn't copy the TLV data, but only the pointer to it, - * which means that after calling it both the old and the new instance will point to the same TLV raw data - * @param[in] other The TLVRecord instance to copy from - */ + /// A copy c'tor for this class. This copy c'tor doesn't copy the TLV data, but only the pointer to it, + /// which means that after calling it both the old and the new instance will point to the same TLV raw data + /// @param[in] other The TLVRecord instance to copy from TLVRecord(const TLVRecord& other) { m_Data = other.m_Data; } - /** - * A d'tor for this class, currently does nothing - */ + /// A d'tor for this class, currently does nothing virtual ~TLVRecord() = default; - /** - * Assign a pointer to the TLV record raw data (byte array) - * @param[in] recordRawData A pointer to the TLV record raw data - */ + /// Assign a pointer to the TLV record raw data (byte array) + /// @param[in] recordRawData A pointer to the TLV record raw data void assign(uint8_t* recordRawData) { m_Data = reinterpret_cast(recordRawData); } - /** - * Check if a pointer can be assigned to the TLV record data - * @param[in] recordRawData A pointer to the TLV record raw data - * @param[in] tlvDataLen The size of the TLV record raw data - * @return True if data is valid and can be assigned - */ + /// Check if a pointer can be assigned to the TLV record data + /// @param[in] recordRawData A pointer to the TLV record raw data + /// @param[in] tlvDataLen The size of the TLV record raw data + /// @return True if data is valid and can be assigned static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen) { return recordRawData != nullptr && tlvDataLen >= (sizeof(TLVRawData::recordType) + sizeof(TLVRawData::recordLen)); } - /** - * Overload of the assignment operator. This operator doesn't copy the TLV data, but rather copies the pointer - * to it, which means that after calling it both the old and the new instance will point to the same TLV raw - * data - * @param[in] other The TLVRecord instance to assign - */ + /// Overload of the assignment operator. This operator doesn't copy the TLV data, but rather copies the pointer + /// to it, which means that after calling it both the old and the new instance will point to the same TLV raw + /// data + /// @param[in] other The TLVRecord instance to assign TLVRecord& operator=(const TLVRecord& other) { m_Data = other.m_Data; return *this; } - /** - * Overload of the equality operator. Two record are equal if both of them point to the same data, or if they - * point to different data but their total size is equal and the raw data they both contain is similar. - * @param[in] rhs The object to compare to - * @return True if both objects are equal, false otherwise - */ + /// Overload of the equality operator. Two record are equal if both of them point to the same data, or if they + /// point to different data but their total size is equal and the raw data they both contain is similar. + /// @param[in] rhs The object to compare to + /// @return True if both objects are equal, false otherwise bool operator==(const TLVRecord& rhs) const { if (m_Data == rhs.m_Data) @@ -115,19 +97,15 @@ namespace pcpp return (memcmp(m_Data, rhs.m_Data, getTotalSize()) == 0); } - /** - * Overload of the not equal operator. - * @param[in] rhs The object to compare to - * @return True if objects are not equal, false otherwise - */ + /// Overload of the not equal operator. + /// @param[in] rhs The object to compare to + /// @return True if objects are not equal, false otherwise bool operator!=(const TLVRecord& rhs) const { return !operator==(rhs); } - /** - * @return The type field of the record (the 'T' in __Type__-Length-Value) - */ + /// @return The type field of the record (the 'T' in __Type__-Length-Value) TRecType getType() const { if (m_Data == nullptr) @@ -136,9 +114,7 @@ namespace pcpp return m_Data->recordType; } - /** - * @return A pointer to the value of the record as byte array (the 'V' in Type-Length- __Value__) - */ + /// @return A pointer to the value of the record as byte array (the 'V' in Type-Length- __Value__) uint8_t* getValue() const { if (m_Data == nullptr) @@ -147,33 +123,25 @@ namespace pcpp return m_Data->recordValue; } - /** - * @return True if the TLV record raw data is nullptr, false otherwise - */ + /// @return True if the TLV record raw data is nullptr, false otherwise bool isNull() const { return (m_Data == nullptr); } - /** - * @return True if the TLV record raw data is not nullptr, false otherwise - */ + /// @return True if the TLV record raw data is not nullptr, false otherwise bool isNotNull() const { return (m_Data != nullptr); } - /** - * @return A pointer to the TLV record raw data byte stream - */ + /// @return A pointer to the TLV record raw data byte stream uint8_t* getRecordBasePtr() const { return reinterpret_cast(m_Data); } - /** - * Free the memory of the TLV record raw data - */ + /// Free the memory of the TLV record raw data void purgeRecordData() { if (!isNull()) @@ -183,15 +151,13 @@ namespace pcpp } } - /** - * A templated method to retrieve the record data as a certain type T. For example, if record data is 4B long - * (integer) then this method should be used as getValueAs() and it will return the record data as an - * integer.
Notice this return value is a copy of the data, not a pointer to the actual data - * @param[in] offset The offset in the record data to start reading the value from. Useful for cases when you - * want to read some of the data that doesn't start at offset 0. This is an optional parameter and the default - * value is 0, meaning start reading the value at the beginning of the record data - * @return The record data as type T - */ + /// A templated method to retrieve the record data as a certain type T. For example, if record data is 4B long + /// (integer) then this method should be used as getValueAs() and it will return the record data as an + /// integer.
Notice this return value is a copy of the data, not a pointer to the actual data + /// @param[in] offset The offset in the record data to start reading the value from. Useful for cases when you + /// want to read some of the data that doesn't start at offset 0. This is an optional parameter and the default + /// value is 0, meaning start reading the value at the beginning of the record data + /// @return The record data as type T template T getValueAs(size_t offset = 0) const { if (getDataSize() - offset < sizeof(T)) @@ -202,15 +168,13 @@ namespace pcpp return result; } - /** - * A templated method to copy data of type T into the TLV record data. For example: if record data is 4[Bytes] - * long use this method with \ to set an integer value into the record data: setValue(num) - * @param[in] newValue The value of type T to copy to the record data - * @param[in] valueOffset An optional parameter that specifies where to start setting the record data (default - * set to 0). For example: if record data is 20 bytes long and you only need to set the 4 last bytes as integer - * then use this method like this: setValue(num, 16) - * @return True if value was set successfully or false if the size of T is larger than the record data size - */ + /// A templated method to copy data of type T into the TLV record data. For example: if record data is 4[Bytes] + /// long use this method with \ to set an integer value into the record data: setValue(num) + /// @param[in] newValue The value of type T to copy to the record data + /// @param[in] valueOffset An optional parameter that specifies where to start setting the record data (default + /// set to 0). For example: if record data is 20 bytes long and you only need to set the 4 last bytes as integer + /// then use this method like this: setValue(num, 16) + /// @return True if value was set successfully or false if the size of T is larger than the record data size template bool setValue(T newValue, int valueOffset = 0) { if (getDataSize() < sizeof(T)) @@ -220,14 +184,10 @@ namespace pcpp return true; } - /** - * @return The total size of the TLV record (in bytes) - */ + /// @return The total size of the TLV record (in bytes) virtual size_t getTotalSize() const = 0; - /** - * @return The size of the record value (meaning the size of the 'V' part in TLV) - */ + /// @return The size of the record value (meaning the size of the 'V' part in TLV) virtual size_t getDataSize() const = 0; protected: @@ -237,56 +197,44 @@ namespace pcpp } }; - /** - * @class TLVRecordReader - * A class for reading TLV records data out of a byte stream. This class contains helper methods for retrieving and - * counting TLV records. This is a template class that expects template argument class derived from TLVRecord. - */ + /// @class TLVRecordReader + /// A class for reading TLV records data out of a byte stream. This class contains helper methods for retrieving and + /// counting TLV records. This is a template class that expects template argument class derived from TLVRecord. template class TLVRecordReader { private: mutable size_t m_RecordCount; public: - /** - * A default c'tor for this class - */ + /// A default c'tor for this class TLVRecordReader() { m_RecordCount = static_cast(-1); } - /** - * A default copy c'tor for this class - */ + /// A default copy c'tor for this class TLVRecordReader(const TLVRecordReader& other) { m_RecordCount = other.m_RecordCount; } - /** - * A d'tor for this class which currently does nothing - */ + /// A d'tor for this class which currently does nothing virtual ~TLVRecordReader() = default; - /** - * Overload of the assignment operator for this class - * @param[in] other The TLVRecordReader instance to assign - */ + /// Overload of the assignment operator for this class + /// @param[in] other The TLVRecordReader instance to assign TLVRecordReader& operator=(const TLVRecordReader& other) { m_RecordCount = other.m_RecordCount; return *this; } - /** - * Get the first TLV record out of a byte stream - * @param[in] tlvDataBasePtr A pointer to the TLV data byte stream - * @param[in] tlvDataLen The TLV data byte stream length - * @return An instance of type TLVRecordType that contains the first TLV record. If tlvDataBasePtr is nullptr or - * tlvDataLen is zero the returned TLVRecordType instance will be logically null, meaning - * TLVRecordType.isNull() will return true - */ + /// Get the first TLV record out of a byte stream + /// @param[in] tlvDataBasePtr A pointer to the TLV data byte stream + /// @param[in] tlvDataLen The TLV data byte stream length + /// @return An instance of type TLVRecordType that contains the first TLV record. If tlvDataBasePtr is nullptr + /// or tlvDataLen is zero the returned TLVRecordType instance will be logically null, meaning + /// TLVRecordType.isNull() will return true TLVRecordType getFirstTLVRecord(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const { TLVRecordType resRec(nullptr); // for NRVO optimization @@ -305,15 +253,13 @@ namespace pcpp return resRec; } - /** - * Get a TLV record that follows a given TLV record in a byte stream - * @param[in] record A given TLV record - * @param[in] tlvDataBasePtr A pointer to the TLV data byte stream - * @param[in] tlvDataLen The TLV data byte stream length - * @return An instance of type TLVRecordType that wraps the record following the record given as input. If the - * input record.isNull() is true or if the next record is out of bounds of the byte stream, a logical null - * instance of TLVRecordType will be returned, meaning TLVRecordType.isNull() will return true - */ + /// Get a TLV record that follows a given TLV record in a byte stream + /// @param[in] record A given TLV record + /// @param[in] tlvDataBasePtr A pointer to the TLV data byte stream + /// @param[in] tlvDataLen The TLV data byte stream length + /// @return An instance of type TLVRecordType that wraps the record following the record given as input. If the + /// input record.isNull() is true or if the next record is out of bounds of the byte stream, a logical null + /// instance of TLVRecordType will be returned, meaning TLVRecordType.isNull() will return true TLVRecordType getNextTLVRecord(TLVRecordType& record, const uint8_t* tlvDataBasePtr, size_t tlvDataLen) const { TLVRecordType resRec(nullptr); // for NRVO optimization @@ -342,14 +288,12 @@ namespace pcpp return resRec; } - /** - * Search for the first TLV record that corresponds to a given record type (the 'T' in __Type__-Length-Value) - * @param[in] recordType The record type to search for - * @param[in] tlvDataBasePtr A pointer to the TLV data byte stream - * @param[in] tlvDataLen The TLV data byte stream length - * @return An instance of type TLVRecordType that contains the result record. If record was not found a logical - * null instance of TLVRecordType will be returned, meaning TLVRecordType.isNull() will return true - */ + /// Search for the first TLV record that corresponds to a given record type (the 'T' in __Type__-Length-Value) + /// @param[in] recordType The record type to search for + /// @param[in] tlvDataBasePtr A pointer to the TLV data byte stream + /// @param[in] tlvDataLen The TLV data byte stream length + /// @return An instance of type TLVRecordType that contains the result record. If record was not found a logical + /// null instance of TLVRecordType will be returned, meaning TLVRecordType.isNull() will return true TLVRecordType getTLVRecord(uint32_t recordType, uint8_t* tlvDataBasePtr, size_t tlvDataLen) const { TLVRecordType curRec = getFirstTLVRecord(tlvDataBasePtr, tlvDataLen); @@ -367,15 +311,13 @@ namespace pcpp return curRec; // for NRVO optimization } - /** - * Get the TLV record count in a given TLV data byte stream. For efficiency purposes the count is being cached - * so only the first call to this method will go over all the TLV records, while all consequent calls will - * return the cached number. This implies that if there is a change in the number of records, it's the user's - * responsibility to call changeTLVRecordCount() with the record count change - * @param[in] tlvDataBasePtr A pointer to the TLV data byte stream - * @param[in] tlvDataLen The TLV data byte stream length - * @return The TLV record count - */ + /// Get the TLV record count in a given TLV data byte stream. For efficiency purposes the count is being cached + /// so only the first call to this method will go over all the TLV records, while all consequent calls will + /// return the cached number. This implies that if there is a change in the number of records, it's the user's + /// responsibility to call changeTLVRecordCount() with the record count change + /// @param[in] tlvDataBasePtr A pointer to the TLV data byte stream + /// @param[in] tlvDataLen The TLV data byte stream length + /// @return The TLV record count size_t getTLVRecordCount(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const { if (m_RecordCount != static_cast(-1)) @@ -392,13 +334,11 @@ namespace pcpp return m_RecordCount; } - /** - * As described in getTLVRecordCount(), the TLV record count is being cached for efficiency purposes. So if the - * number of TLV records change, it's the user's responsibility to call this method with the number of TLV - * records being added or removed. If records were added the change should be a positive number, or a negative - * number if records were removed - * @param[in] changedBy Number of records that were added or removed - */ + /// As described in getTLVRecordCount(), the TLV record count is being cached for efficiency purposes. So if the + /// number of TLV records change, it's the user's responsibility to call this method with the number of TLV + /// records being added or removed. If records were added the change should be a positive number, or a negative + /// number if records were removed + /// @param[in] changedBy Number of records that were added or removed void changeTLVRecordCount(int changedBy) { if (m_RecordCount != static_cast(-1)) @@ -406,15 +346,13 @@ namespace pcpp } }; - /** - * @class TLVRecordBuilder - * A base class for building Type-Length-Value (TLV) records. This builder receives the record parameters in its - * c'tor, builds the record raw buffer and provides a method to build a TLVRecord object out of it. Please notice - * this is a base class that lacks the capability of actually building TLVRecord objects and also cannot be - * instantiated. The reason for that is that different protocols build TLV records in different ways, so these - * missing capabilities will be implemented by the derived classes which are specific to each protocol. This class - * only provides the common infrastructure that will be used by them - */ + /// @class TLVRecordBuilder + /// A base class for building Type-Length-Value (TLV) records. This builder receives the record parameters in its + /// c'tor, builds the record raw buffer and provides a method to build a TLVRecord object out of it. Please notice + /// this is a base class that lacks the capability of actually building TLVRecord objects and also cannot be + /// instantiated. The reason for that is that different protocols build TLV records in different ways, so these + /// missing capabilities will be implemented by the derived classes which are specific to each protocol. This class + /// only provides the common infrastructure that will be used by them class TLVRecordBuilder { protected: diff --git a/Packet++/header/TcpLayer.h b/Packet++/header/TcpLayer.h index b042e98b54..43b0adac47 100644 --- a/Packet++/header/TcpLayer.h +++ b/Packet++/header/TcpLayer.h @@ -10,290 +10,269 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct tcphdr - * Represents an TCP protocol header - */ + /// @struct tcphdr + /// Represents an TCP protocol header #pragma pack(push, 1) struct tcphdr { - /** Source TCP port */ + /// Source TCP port uint16_t portSrc; - /** Destination TCP port */ + /// Destination TCP port uint16_t portDst; - /** Sequence number */ + /// Sequence number uint32_t sequenceNumber; - /** Acknowledgment number */ + /// Acknowledgment number uint32_t ackNumber; #if (BYTE_ORDER == LITTLE_ENDIAN) uint16_t reserved : 4; - /** Specifies the size of the TCP header in 32-bit words */ + /// Specifies the size of the TCP header in 32-bit words uint16_t dataOffset : 4; - /** FIN flag */ + /// FIN flag uint16_t finFlag : 1; - /** SYN flag */ + /// SYN flag uint16_t synFlag : 1; - /** RST flag */ + /// RST flag uint16_t rstFlag : 1; - /** PSH flag */ + /// PSH flag uint16_t pshFlag : 1; - /** ACK flag */ + /// ACK flag uint16_t ackFlag : 1; - /** URG flag */ + /// URG flag uint16_t urgFlag : 1; - /** ECE flag */ + /// ECE flag uint16_t eceFlag : 1; - /** CWR flag */ + /// CWR flag uint16_t cwrFlag : 1; #elif (BYTE_ORDER == BIG_ENDIAN) - /** Specifies the size of the TCP header in 32-bit words */ + /// Specifies the size of the TCP header in 32-bit words uint16_t dataOffset : 4; - /** Reserved */ + /// Reserved uint16_t reserved : 4; - /** CWR flag */ + /// CWR flag uint16_t cwrFlag : 1; - /** ECE flag */ + /// ECE flag uint16_t eceFlag : 1; - /** URG flag */ + /// URG flag uint16_t urgFlag : 1; - /** ACK flag */ + /// ACK flag uint16_t ackFlag : 1; - /** PSH flag */ + /// PSH flag uint16_t pshFlag : 1; - /** RST flag */ + /// RST flag uint16_t rstFlag : 1; - /** SYN flag */ + /// SYN flag uint16_t synFlag : 1; - /** FIN flag */ + /// FIN flag uint16_t finFlag : 1; #else # error "Endian is not LE nor BE..." #endif - /** The size of the receive window, which specifies the number of window size units (by default, bytes) */ + /// The size of the receive window, which specifies the number of window size units (by default, bytes) uint16_t windowSize; - /** The 16-bit checksum field is used for error-checking of the header and data */ + /// The 16-bit checksum field is used for error-checking of the header and data uint16_t headerChecksum; - /** If the URG flag (@ref tcphdr#urgFlag) is set, then this 16-bit field is an offset from the sequence number - * indicating the last urgent data byte */ + /// If the URG flag (@ref tcphdr#urgFlag) is set, then this 16-bit field is an offset from the sequence number + /// indicating the last urgent data byte uint16_t urgentPointer; }; #pragma pack(pop) static_assert(sizeof(tcphdr) == 20, "tcphdr size is not 20 bytes"); - /** - * TCP options types - */ + /// TCP options types enum TcpOptionType : uint8_t { - /** Padding */ + /// Padding PCPP_TCPOPT_NOP = 1, - /** End of options */ + /// End of options PCPP_TCPOPT_EOL = 0, - /** Segment size negotiating */ + /// Segment size negotiating TCPOPT_MSS = 2, - /** Window scaling */ + /// Window scaling PCPP_TCPOPT_WINDOW = 3, - /** SACK Permitted */ + /// SACK Permitted TCPOPT_SACK_PERM = 4, - /** SACK Block */ + /// SACK Block PCPP_TCPOPT_SACK = 5, - /** Echo (obsoleted by option TcpOptionType::PCPP_TCPOPT_TIMESTAMP) */ + /// Echo (obsoleted by option TcpOptionType::PCPP_TCPOPT_TIMESTAMP) TCPOPT_ECHO = 6, - /** Echo Reply (obsoleted by option TcpOptionType::PCPP_TCPOPT_TIMESTAMP) */ + /// Echo Reply (obsoleted by option TcpOptionType::PCPP_TCPOPT_TIMESTAMP) TCPOPT_ECHOREPLY = 7, - /** TCP Timestamps */ + /// TCP Timestamps PCPP_TCPOPT_TIMESTAMP = 8, - /** CC (obsolete) */ + /// CC (obsolete) TCPOPT_CC = 11, - /** CC.NEW (obsolete) */ + /// CC.NEW (obsolete) TCPOPT_CCNEW = 12, - /** CC.ECHO(obsolete) */ + /// CC.ECHO(obsolete) TCPOPT_CCECHO = 13, - /** MD5 Signature Option */ + /// MD5 Signature Option TCPOPT_MD5 = 19, - /** Multipath TCP */ + /// Multipath TCP TCPOPT_MPTCP = 0x1e, - /** SCPS Capabilities */ + /// SCPS Capabilities TCPOPT_SCPS = 20, - /** SCPS SNACK */ + /// SCPS SNACK TCPOPT_SNACK = 21, - /** SCPS Record Boundary */ + /// SCPS Record Boundary TCPOPT_RECBOUND = 22, - /** SCPS Corruption Experienced */ + /// SCPS Corruption Experienced TCPOPT_CORREXP = 23, - /** Quick-Start Response */ + /// Quick-Start Response TCPOPT_QS = 27, - /** User Timeout Option (also, other known unauthorized use) */ + /// User Timeout Option (also, other known unauthorized use) TCPOPT_USER_TO = 28, - /** RFC3692-style Experiment 1 (also improperly used for shipping products) */ + /// RFC3692-style Experiment 1 (also improperly used for shipping products) TCPOPT_EXP_FD = 0xfd, - /** RFC3692-style Experiment 2 (also improperly used for shipping products) */ + /// RFC3692-style Experiment 2 (also improperly used for shipping products) TCPOPT_EXP_FE = 0xfe, - /** Riverbed probe option, non IANA registered option number */ + /// Riverbed probe option, non IANA registered option number TCPOPT_RVBD_PROBE = 76, - /** Riverbed transparency option, non IANA registered option number */ + /// Riverbed transparency option, non IANA registered option number TCPOPT_RVBD_TRPY = 78, - /** Unknown option */ + /// Unknown option TCPOPT_Unknown = 255 }; - /** - * TCP options types - */ + /// TCP options types enum class TcpOptionEnumType : uint8_t { - /** Padding */ + /// Padding Nop = 1, - /** End of options */ + /// End of options Eol = 0, - /** Segment size negotiating */ + /// Segment size negotiating Mss = 2, - /** Window scaling */ + /// Window scaling Window = 3, - /** SACK Permitted */ + /// SACK Permitted SackPerm = 4, - /** SACK Block */ + /// SACK Block Sack = 5, - /** Echo (obsoleted by option TcpOptionEnumType::Timestamp) */ + /// Echo (obsoleted by option TcpOptionEnumType::Timestamp) Echo = 6, - /** Echo Reply (obsoleted by option TcpOptionEnumType::Timestamp) */ + /// Echo Reply (obsoleted by option TcpOptionEnumType::Timestamp) EchoReply = 7, - /** TCP Timestamps */ + /// TCP Timestamps Timestamp = 8, - /** CC (obsolete) */ + /// CC (obsolete) Cc = 11, - /** CC.NEW (obsolete) */ + /// CC.NEW (obsolete) CcNew = 12, - /** CC.ECHO(obsolete) */ + /// CC.ECHO(obsolete) CcEcho = 13, - /** MD5 Signature Option */ + /// MD5 Signature Option Md5 = 19, - /** Multipath TCP */ + /// Multipath TCP MpTcp = 0x1e, - /** SCPS Capabilities */ + /// SCPS Capabilities Scps = 20, - /** SCPS SNACK */ + /// SCPS SNACK Snack = 21, - /** SCPS Record Boundary */ + /// SCPS Record Boundary RecBound = 22, - /** SCPS Corruption Experienced */ + /// SCPS Corruption Experienced CorrExp = 23, - /** Quick-Start Response */ + /// Quick-Start Response Qs = 27, - /** User Timeout Option (also, other known unauthorized use) */ + /// User Timeout Option (also, other known unauthorized use) UserTo = 28, - /** RFC3692-style Experiment 1 (also improperly used for shipping products) */ + /// RFC3692-style Experiment 1 (also improperly used for shipping products) ExpFd = 0xfd, - /** RFC3692-style Experiment 2 (also improperly used for shipping products) */ + /// RFC3692-style Experiment 2 (also improperly used for shipping products) ExpFe = 0xfe, - /** Riverbed probe option, non IANA registered option number */ + /// Riverbed probe option, non IANA registered option number RvbdProbe = 76, - /** Riverbed transparency option, non IANA registered option number */ + /// Riverbed transparency option, non IANA registered option number RvbdTrpy = 78, - /** Unknown option */ + /// Unknown option Unknown = 255 }; // TCP option lengths - /** pcpp::TcpOptionEnumType::Nop length */ + /// pcpp::TcpOptionEnumType::Nop length #define PCPP_TCPOLEN_NOP 1 - /** pcpp::TcpOptionEnumType::Eol length */ + /// pcpp::TcpOptionEnumType::Eol length #define PCPP_TCPOLEN_EOL 1 - /** pcpp::TcpOptionEnumType::Mss length */ + /// pcpp::TcpOptionEnumType::Mss length #define PCPP_TCPOLEN_MSS 4 - /** pcpp::TcpOptionEnumType::Window length */ + /// pcpp::TcpOptionEnumType::Window length #define PCPP_TCPOLEN_WINDOW 3 - /** pcpp::TcpOptionEnumType::SackPerm length */ + /// pcpp::TcpOptionEnumType::SackPerm length #define PCPP_TCPOLEN_SACK_PERM 2 - /** pcpp::TcpOptionEnumType::Sack length */ + /// pcpp::TcpOptionEnumType::Sack length #define PCPP_TCPOLEN_SACK_MIN 2 - /** pcpp::TcpOptionEnumType::Echo length */ + /// pcpp::TcpOptionEnumType::Echo length #define PCPP_TCPOLEN_ECHO 6 - /** pcpp::TcpOptionEnumType::EchoReply length */ + /// pcpp::TcpOptionEnumType::EchoReply length #define PCPP_TCPOLEN_ECHOREPLY 6 - /** pcpp::TcpOptionEnumType::Timestamp length */ + /// pcpp::TcpOptionEnumType::Timestamp length #define PCPP_TCPOLEN_TIMESTAMP 10 - /** pcpp::TcpOptionEnumType::Cc length */ + /// pcpp::TcpOptionEnumType::Cc length #define PCPP_TCPOLEN_CC 6 - /** pcpp::TcpOptionEnumType::CcNew length */ + /// pcpp::TcpOptionEnumType::CcNew length #define PCPP_TCPOLEN_CCNEW 6 - /** pcpp::TcpOptionEnumType::CcEcho length */ + /// pcpp::TcpOptionEnumType::CcEcho length #define PCPP_TCPOLEN_CCECHO 6 - /** pcpp::TcpOptionEnumType::Md5 length */ + /// pcpp::TcpOptionEnumType::Md5 length #define PCPP_TCPOLEN_MD5 18 - /** pcpp::TcpOptionEnumType::MpTcp length */ + /// pcpp::TcpOptionEnumType::MpTcp length #define PCPP_TCPOLEN_MPTCP_MIN 8 - /** pcpp::TcpOptionEnumType::Scps length */ + /// pcpp::TcpOptionEnumType::Scps length #define PCPP_TCPOLEN_SCPS 4 - /** pcpp::TcpOptionEnumType::Snack length */ + /// pcpp::TcpOptionEnumType::Snack length #define PCPP_TCPOLEN_SNACK 6 - /** pcpp::TcpOptionEnumType::RecBound length */ + /// pcpp::TcpOptionEnumType::RecBound length #define PCPP_TCPOLEN_RECBOUND 2 - /** pcpp::TcpOptionEnumType::CorrExp length */ + /// pcpp::TcpOptionEnumType::CorrExp length #define PCPP_TCPOLEN_CORREXP 2 - /** pcpp::TcpOptionEnumType::Qs length */ + /// pcpp::TcpOptionEnumType::Qs length #define PCPP_TCPOLEN_QS 8 - /** pcpp::TcpOptionEnumType::UserTo length */ + /// pcpp::TcpOptionEnumType::UserTo length #define PCPP_TCPOLEN_USER_TO 4 - /** pcpp::TcpOptionEnumType::RvbdProbe length */ + /// pcpp::TcpOptionEnumType::RvbdProbe length #define PCPP_TCPOLEN_RVBD_PROBE_MIN 3 - /** pcpp::TcpOptionEnumType::RvbdTrpy length */ + /// pcpp::TcpOptionEnumType::RvbdTrpy length #define PCPP_TCPOLEN_RVBD_TRPY_MIN 16 - /** pcpp::TcpOptionEnumType::ExpFd and pcpp::TcpOptionEnumType::ExpFe length */ + /// pcpp::TcpOptionEnumType::ExpFd and pcpp::TcpOptionEnumType::ExpFe length #define PCPP_TCPOLEN_EXP_MIN 2 - /** - * @class TcpOption - * A wrapper class for TCP options. This class does not create or modify TCP option records, but rather - * serves as a wrapper and provides useful methods for retrieving data from them - */ + /// @class TcpOption + /// A wrapper class for TCP options. This class does not create or modify TCP option records, but rather + /// serves as a wrapper and provides useful methods for retrieving data from them class TcpOption : public TLVRecord { public: - /** - * A c'tor for this class that gets a pointer to the option raw data (byte array) - * @param[in] optionRawData A pointer to the TCP option raw data - */ + /// A c'tor for this class that gets a pointer to the option raw data (byte array) + /// @param[in] optionRawData A pointer to the TCP option raw data explicit TcpOption(uint8_t* optionRawData) : TLVRecord(optionRawData) {} - /** - * A d'tor for this class, currently does nothing - */ + /// A d'tor for this class, currently does nothing ~TcpOption() override = default; - /** - * @deprecated This method is deprecated, please use getTcpOptionEnumType() - */ + /// @deprecated This method is deprecated, please use getTcpOptionEnumType() PCPP_DEPRECATED("Use getTcpOptionEnumType instead") TcpOptionType getTcpOptionType() const { return getTcpOptionType(m_Data); } - /** - * @return TCP option type casted as pcpp::TcpOptionEnumType enum. If the data is null a value - * of TcpOptionEnumType::Unknown is returned - */ + /// @return TCP option type casted as pcpp::TcpOptionEnumType enum. If the data is null a value + /// of TcpOptionEnumType::Unknown is returned TcpOptionEnumType getTcpOptionEnumType() const { return getTcpOptionEnumType(m_Data); } - /** - * Check if a pointer can be assigned to the TLV record data - * @param[in] recordRawData A pointer to the TLV record raw data - * @param[in] tlvDataLen The size of the TLV record raw data - * @return True if data is valid and can be assigned - */ + /// Check if a pointer can be assigned to the TLV record data + /// @param[in] recordRawData A pointer to the TLV record raw data + /// @param[in] tlvDataLen The size of the TLV record raw data + /// @return True if data is valid and can be assigned static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen) { const auto* data = reinterpret_cast(recordRawData); @@ -354,313 +333,236 @@ namespace pcpp } }; - /** - * @class TcpOptionBuilder - * A class for building TCP option records. This builder receives the TCP option parameters in its c'tor, - * builds the TCP option raw buffer and provides a build() method to get a TcpOption object out of it - */ + /// @class TcpOptionBuilder + /// A class for building TCP option records. This builder receives the TCP option parameters in its c'tor, + /// builds the TCP option raw buffer and provides a build() method to get a TcpOption object out of it class TcpOptionBuilder : public TLVRecordBuilder { public: - /** - * An enum to describe NOP and EOL TCP options. Used in one of this class's c'tors - */ + /// An enum to describe NOP and EOL TCP options. Used in one of this class's c'tors enum NopEolOptionTypes : uint8_t { - /** NOP TCP option */ + /// NOP TCP option NOP, - /** EOL TCP option */ + /// EOL TCP option EOL }; - /** - * An enum to describe NOP and EOL TCP options. Used in one of this class's c'tors - */ + /// An enum to describe NOP and EOL TCP options. Used in one of this class's c'tors enum class NopEolOptionEnumType : uint8_t { - /** NOP TCP option */ + /// NOP TCP option Nop, - /** EOL TCP option */ + /// EOL TCP option Eol }; - /** - * @deprecated This method is deprecated, please use constructor with TcpOptionEnumType - */ + /// @deprecated This method is deprecated, please use constructor with TcpOptionEnumType PCPP_DEPRECATED_TCP_OPTION_TYPE TcpOptionBuilder(TcpOptionType optionType, const uint8_t* optionValue, uint8_t optionValueLen) : TLVRecordBuilder(static_cast(optionType), optionValue, optionValueLen) {} - /** - * A c'tor for building TCP options which their value is a byte array. The TcpOption object can be later - * retrieved by calling build() - * @param[in] optionType TCP option type - * @param[in] optionValue A buffer containing the option value. This buffer is read-only and isn't modified in - * any way. - * @param[in] optionValueLen Option value length in bytes - */ + /// A c'tor for building TCP options which their value is a byte array. The TcpOption object can be later + /// retrieved by calling build() + /// @param[in] optionType TCP option type + /// @param[in] optionValue A buffer containing the option value. This buffer is read-only and isn't modified in + /// any way. + /// @param[in] optionValueLen Option value length in bytes TcpOptionBuilder(TcpOptionEnumType optionType, const uint8_t* optionValue, uint8_t optionValueLen) : TLVRecordBuilder(static_cast(optionType), optionValue, optionValueLen) {} - /** - * @deprecated This method is deprecated, please use constructor with TcpOptionEnumType - */ + /// @deprecated This method is deprecated, please use constructor with TcpOptionEnumType PCPP_DEPRECATED_TCP_OPTION_TYPE TcpOptionBuilder(TcpOptionType optionType, uint8_t optionValue) : TLVRecordBuilder(static_cast(optionType), optionValue) {} - /** - * A c'tor for building TCP options which have a 1-byte value. The TcpOption object can be later retrieved - * by calling build() - * @param[in] optionType TCP option type - * @param[in] optionValue A 1-byte option value - */ + /// A c'tor for building TCP options which have a 1-byte value. The TcpOption object can be later retrieved + /// by calling build() + /// @param[in] optionType TCP option type + /// @param[in] optionValue A 1-byte option value TcpOptionBuilder(TcpOptionEnumType optionType, uint8_t optionValue) : TLVRecordBuilder(static_cast(optionType), optionValue) {} - /** - * @deprecated This method is deprecated, please use constructor with TcpOptionEnumType - */ + /// @deprecated This method is deprecated, please use constructor with TcpOptionEnumType PCPP_DEPRECATED_TCP_OPTION_TYPE TcpOptionBuilder(TcpOptionType optionType, uint16_t optionValue) : TLVRecordBuilder(static_cast(optionType), optionValue) {} - /** - * A c'tor for building TCP options which have a 2-byte value. The TcpOption object can be later retrieved - * by calling build() - * @param[in] optionType TCP option type - * @param[in] optionValue A 2-byte option value - */ + /// A c'tor for building TCP options which have a 2-byte value. The TcpOption object can be later retrieved + /// by calling build() + /// @param[in] optionType TCP option type + /// @param[in] optionValue A 2-byte option value TcpOptionBuilder(TcpOptionEnumType optionType, uint16_t optionValue) : TLVRecordBuilder(static_cast(optionType), optionValue) {} - /** - * @deprecated This method is deprecated, please use constructor with TcpOptionEnumType - */ + /// @deprecated This method is deprecated, please use constructor with TcpOptionEnumType PCPP_DEPRECATED_TCP_OPTION_TYPE TcpOptionBuilder(TcpOptionType optionType, uint32_t optionValue) : TLVRecordBuilder(static_cast(optionType), optionValue) {} - /** - * A c'tor for building TCP options which have a 4-byte value. The TcpOption object can be later retrieved - * by calling build() - * @param[in] optionType TCP option type - * @param[in] optionValue A 4-byte option value - */ + /// A c'tor for building TCP options which have a 4-byte value. The TcpOption object can be later retrieved + /// by calling build() + /// @param[in] optionType TCP option type + /// @param[in] optionValue A 4-byte option value TcpOptionBuilder(TcpOptionEnumType optionType, uint32_t optionValue) : TLVRecordBuilder(static_cast(optionType), optionValue) {} - /** - * @deprecated This method is deprecated, please use constructor with NopEolOptionEnumType - */ + /// @deprecated This method is deprecated, please use constructor with NopEolOptionEnumType PCPP_DEPRECATED("enum NopEolOptionTypes is deprecated; Use enum class NopEolOptionEnumType instead") explicit TcpOptionBuilder(NopEolOptionTypes optionType); - /** - * A c'tor for building TCP NOP and EOL options. These option types are special in that they contain only 1 byte - * which is the TCP option type (NOP or EOL). The TcpOption object can be later retrieved - * by calling build() - * @param[in] optionType An enum value indicating which option type to build (NOP or EOL) - */ + /// A c'tor for building TCP NOP and EOL options. These option types are special in that they contain only 1 + /// byte which is the TCP option type (NOP or EOL). The TcpOption object can be later retrieved by calling + /// build() + /// @param[in] optionType An enum value indicating which option type to build (NOP or EOL) explicit TcpOptionBuilder(NopEolOptionEnumType optionType); - /** - * Build the TcpOption object out of the parameters defined in the c'tor - * @return The TcpOption object - */ + /// Build the TcpOption object out of the parameters defined in the c'tor + /// @return The TcpOption object TcpOption build() const; }; - /** - * @class TcpLayer - * Represents a TCP (Transmission Control Protocol) protocol layer - */ + /// @class TcpLayer + /// Represents a TCP (Transmission Control Protocol) protocol layer class TcpLayer : public Layer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to @ref tcphdr) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to @ref tcphdr) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in TcpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * A constructor that allocates a new TCP header with zero TCP options - */ + /// A constructor that allocates a new TCP header with zero TCP options TcpLayer(); - /** - * A constructor that allocates a new TCP header with source port and destination port and zero TCP options - * @param[in] portSrc Source port - * @param[in] portDst Destination port - */ + /// A constructor that allocates a new TCP header with source port and destination port and zero TCP options + /// @param[in] portSrc Source port + /// @param[in] portDst Destination port TcpLayer(uint16_t portSrc, uint16_t portDst); ~TcpLayer() override = default; - /** - * A copy constructor that copy the entire header from the other TcpLayer (including TCP options) - */ + /// A copy constructor that copy the entire header from the other TcpLayer (including TCP options) TcpLayer(const TcpLayer& other); - /** - * An assignment operator that first delete all data from current layer and then copy the entire header from the - * other TcpLayer (including TCP options) - */ + /// An assignment operator that first delete all data from current layer and then copy the entire header from + /// the other TcpLayer (including TCP options) TcpLayer& operator=(const TcpLayer& other); - /** - * Get a pointer to the TCP header. Notice this points directly to the data, so every change will change the - * actual packet data - * @return A pointer to the @ref tcphdr - */ + /// Get a pointer to the TCP header. Notice this points directly to the data, so every change will change the + /// actual packet data + /// @return A pointer to the @ref tcphdr tcphdr* getTcpHeader() const { return reinterpret_cast(m_Data); } - /** - * @return TCP source port - */ + /// @return TCP source port uint16_t getSrcPort() const; - /** - * @return TCP destination port - */ + /// @return TCP destination port uint16_t getDstPort() const; - /** - * @deprecated This method is deprecated, please use getTcpOption(TcpOptionEnumType option) - */ + /// @deprecated This method is deprecated, please use getTcpOption(TcpOptionEnumType option) PCPP_DEPRECATED_TCP_OPTION_TYPE TcpOption getTcpOption(TcpOptionType option) const; - /** - * Get a TCP option by type - * @param[in] option TCP option type to retrieve - * @return An TcpOption object that contains the first option that matches this type, or logical null - * (TcpOption#isNull() == true) if no such option found - */ + /// Get a TCP option by type + /// @param[in] option TCP option type to retrieve + /// @return An TcpOption object that contains the first option that matches this type, or logical null + /// (TcpOption#isNull() == true) if no such option found TcpOption getTcpOption(TcpOptionEnumType option) const; - /** - * @return The first TCP option in the packet. If the current layer contains no options the returned value will - * contain a logical null (TcpOption#isNull() == true) - */ + /// @return The first TCP option in the packet. If the current layer contains no options the returned value will + /// contain a logical null (TcpOption#isNull() == true) TcpOption getFirstTcpOption() const; - /** - * Get the TCP option that comes after a given option. If the given option was the last one, the - * returned value will contain a logical null (TcpOption#isNull() == true) - * @param[in] tcpOption A TCP option object that exists in the current layer - * @return A TcpOption object that contains the TCP option data that comes next, or logical null if the given - * TCP option: (1) was the last one; or (2) contains a logical null; or (3) doesn't belong to this packet - */ + /// Get the TCP option that comes after a given option. If the given option was the last one, the + /// returned value will contain a logical null (TcpOption#isNull() == true) + /// @param[in] tcpOption A TCP option object that exists in the current layer + /// @return A TcpOption object that contains the TCP option data that comes next, or logical null if the given + /// TCP option: (1) was the last one; or (2) contains a logical null; or (3) doesn't belong to this packet TcpOption getNextTcpOption(TcpOption& tcpOption) const; - /** - * @return The number of TCP options in this layer - */ + /// @return The number of TCP options in this layer size_t getTcpOptionCount() const; - /** - * Add a new TCP option at the end of the layer (after the last TCP option) - * @param[in] optionBuilder A TcpOptionBuilder object that contains the TCP option data to be added - * @return A TcpOption object that contains the newly added TCP option data or logical null - * (TcpOption#isNull() == true) if addition failed. In case of a failure a corresponding error message will be - * printed to log - */ + /// Add a new TCP option at the end of the layer (after the last TCP option) + /// @param[in] optionBuilder A TcpOptionBuilder object that contains the TCP option data to be added + /// @return A TcpOption object that contains the newly added TCP option data or logical null + /// (TcpOption#isNull() == true) if addition failed. In case of a failure a corresponding error message will be + /// printed to log TcpOption addTcpOption(const TcpOptionBuilder& optionBuilder); - /** - * @deprecated This method is deprecated, please use insertTcpOptionAfter(const TcpOptionBuilder& optionBuilder, - * TcpOptionEnumType prevOptionType = TcpOptionEnumType::Unknown) - */ + /// @deprecated This method is deprecated, please use insertTcpOptionAfter(const TcpOptionBuilder& + /// optionBuilder, TcpOptionEnumType prevOptionType = TcpOptionEnumType::Unknown) PCPP_DEPRECATED("Use insertTcpOptionAfter instead") TcpOption addTcpOptionAfter(const TcpOptionBuilder& optionBuilder, TcpOptionType prevOptionType = TcpOptionType::TCPOPT_Unknown); - /** - * Insert a new TCP option after an existing one - * @param[in] optionBuilder A TcpOptionBuilder object that contains the requested TCP option data to be inserted - * @param[in] prevOptionType The TCP option which the newly inserted option should come after. This is an - * optional parameter which gets a default value of TcpOptionType::Unknown if omitted, which means the new - * option will be inserted as the first option in the layer - * @return A TcpOption object containing the newly inserted TCP option data or logical null - * (TcpOption#isNull() == true) if insertion failed. In case of a failure a corresponding error message will be - * printed to log - */ + /// Insert a new TCP option after an existing one + /// @param[in] optionBuilder A TcpOptionBuilder object that contains the requested TCP option data to be + /// inserted + /// @param[in] prevOptionType The TCP option which the newly inserted option should come after. This is an + /// optional parameter which gets a default value of TcpOptionType::Unknown if omitted, which means the new + /// option will be inserted as the first option in the layer + /// @return A TcpOption object containing the newly inserted TCP option data or logical null + /// (TcpOption#isNull() == true) if insertion failed. In case of a failure a corresponding error message will be + /// printed to log TcpOption insertTcpOptionAfter(const TcpOptionBuilder& optionBuilder, TcpOptionEnumType prevOptionType = TcpOptionEnumType::Unknown); - /** - * @deprecated This method is deprecated, please use removeTcpOption(TcpOptionEnumType) - */ + /// @deprecated This method is deprecated, please use removeTcpOption(TcpOptionEnumType) PCPP_DEPRECATED_TCP_OPTION_TYPE bool removeTcpOption(TcpOptionType optionType); - /** - * Remove an existing TCP option from the layer. TCP option is found by type - * @param[in] optionType The TCP option type to remove - * @return True if TCP option was removed or false if type wasn't found or if removal failed (in each case a - * proper error will be written to log) - */ + /// Remove an existing TCP option from the layer. TCP option is found by type + /// @param[in] optionType The TCP option type to remove + /// @return True if TCP option was removed or false if type wasn't found or if removal failed (in each case a + /// proper error will be written to log) bool removeTcpOption(TcpOptionEnumType optionType); - /** - * Remove all TCP options in this layer - * @return True if all TCP options were successfully removed or false if removal failed for some reason - * (a proper error will be written to log) - */ + /// Remove all TCP options in this layer + /// @return True if all TCP options were successfully removed or false if removal failed for some reason + /// (a proper error will be written to log) bool removeAllTcpOptions(); - /** - * Calculate the checksum from header and data and possibly write the result to @ref tcphdr#headerChecksum - * @param[in] writeResultToPacket If set to true then checksum result will be written to @ref - * tcphdr#headerChecksum - * @return The checksum result - */ + /// Calculate the checksum from header and data and possibly write the result to @ref tcphdr#headerChecksum + /// @param[in] writeResultToPacket If set to true then checksum result will be written to @ref + /// tcphdr#headerChecksum + /// @return The checksum result uint16_t calculateChecksum(bool writeResultToPacket); - /** - * The static method makes validation of input data - * @param[in] data The pointer to the beginning of byte stream of TCP packet - * @param[in] dataLen The length of byte stream - * @return True if the data is valid and can represent a TCP packet - */ + /// The static method makes validation of input data + /// @param[in] data The pointer to the beginning of byte stream of TCP packet + /// @param[in] dataLen The length of byte stream + /// @return True if the data is valid and can represent a TCP packet static inline bool isDataValid(const uint8_t* data, size_t dataLen); // implement abstract methods - /** - * Currently identifies the following next layers: HttpRequestLayer, HttpResponseLayer. Otherwise sets - * PayloadLayer - */ + /// Currently identifies the following next layers: HttpRequestLayer, HttpResponseLayer. Otherwise sets + /// PayloadLayer void parseNextLayer() override; - /** - * @return Size of @ref tcphdr + all TCP options - */ + /// @return Size of @ref tcphdr + all TCP options size_t getHeaderLen() const override { return getTcpHeader()->dataOffset * 4; } - /** - * Calculate @ref tcphdr#headerChecksum field - */ + /// Calculate @ref tcphdr#headerChecksum field void computeCalculateFields() override; std::string toString() const override; diff --git a/Packet++/header/TcpReassembly.h b/Packet++/header/TcpReassembly.h index 162cfff29a..f0c3497722 100644 --- a/Packet++/header/TcpReassembly.h +++ b/Packet++/header/TcpReassembly.h @@ -9,210 +9,179 @@ #include #include -/** - * @file - * This is an implementation of TCP reassembly logic, which means reassembly of TCP messages spanning multiple TCP - * segments (or packets).
This logic can be useful in analyzing messages for a large number of protocols implemented - * on top of TCP including HTTP, SSL/TLS, FTP and many many more. - * - * __General Features:__ - * - Manage multiple TCP connections under one pcpp#TcpReassembly instance - * - Support TCP retransmission - * - Support out-of-order packets - * - Support missing TCP data - * - TCP connections can end "naturally" (by FIN/RST packets) or manually by the user - * - Support callbacks for new TCP data, connection start and connection end - * - * __Logic Description:__ - * - The user creates an instance of the pcpp#TcpReassembly class - * - Then the user starts feeding it with TCP packets - * - The pcpp#TcpReassembly instance manages all TCP connections from the packets it's being fed. For each connection it - * manages its 2 sides (A->B and B->A). - * - When a packet arrives, it is first classified to a certain TCP connection - * - Then it is classified to a certain side of the TCP connection - * - Then the pcpp#TcpReassembly logic tries to understand if the data in this packet is the expected data - * (sequence-wise) and if it's new (e.g isn't a retransmission). - * - If the packet data matches these criteria a callback is being invoked. This callback is supplied by the user in the - * creation of the pcpp#TcpReassembly instance. This callback contains the new data (of course), but also information - * about the connection (5-tuple, 4-byte hash key describing the connection, etc.) and also a pointer to a "user - * cookie", meaning a pointer to a structure provided by the user during the creation of the pcpp#TcpReassembly - * instance. - * - If the data in this packet isn't new, it's being ignored - * - If the data in this packet isn't expected (meaning this packet came out-of-order), then the data is being queued - * internally and will be sent to the user when its turn arrives (meaning, after the data before arrives). - * - If the missing data doesn't arrive until a new message from the other side of the connection arrives or until the - * connection ends - this will be considered as missing data and the queued data will be sent to the user, but the - * string "[X bytes missing]" will be added to the message sent in the callback. - * - pcpp#TcpReassembly supports 2 more callbacks - one is invoked when a new TCP connection is first seen and the other - * when it's ended (either by a FIN/RST packet or manually by the user). Both of these callbacks contain data about - * the connection (5-tuple, 4-byte hash key describing the connection, etc.) and also a pointer to a "user cookie", - * meaning a pointer to a structure provided by the user during the creation of the pcpp#TcpReassembly instance. The - * end connection callback also provides the reason for closing it ("naturally" or manually). - * - * __Basic Usage and APIs:__ - * - pcpp#TcpReassembly c'tor - Create an instance, provide the callbacks and the user cookie to the instance - * - pcpp#TcpReassembly#reassemblePacket() - Feed pcpp#TcpReassembly instance with packets - * - pcpp#TcpReassembly#closeConnection() - Manually close a connection by a flow key - * - pcpp#TcpReassembly#closeAllConnections() - Manually close all currently opened connections - * - pcpp#TcpReassembly#OnTcpMessageReady callback - Invoked when new data arrives on a certain connection. Contains the - * new data as well as connection data (5-tuple, flow key). - * - pcpp#TcpReassembly#OnTcpConnectionStart callback - Invoked when a new connection is identified - * - pcpp#TcpReassembly#OnTcpConnectionEnd callback - Invoked when a connection ends (either by FIN/RST or manually by - * the user). - * - * __Additional information:__ - * When the connection is closed the information is not being deleted from memory immediately. There is a delay between - * these moments. Existence of this delay is caused by two reasons: - * - pcpp#TcpReassembly#reassemblePacket() should detect the packets that arrive after the FIN packet has been received. - * - The user can use the information about connections managed by pcpp#TcpReassembly instance. Following methods are - * used for this purpose: pcpp#TcpReassembly#getConnectionInformation and pcpp#TcpReassembly#isConnectionOpen. - * Cleaning of memory can be performed automatically (the default behavior) by pcpp#TcpReassembly#reassemblePacket() or - * manually by calling pcpp#TcpReassembly#purgeClosedConnections in the user code. Automatic cleaning is performed once - * per second. - * - * The struct pcpp#TcpReassemblyConfiguration allows to setup the parameters of cleanup. Following parameters are - * supported: - * - pcpp#TcpReassemblyConfiguration#doNotRemoveConnInfo - if this member is set to false the automatic cleanup mode is - * applied. - * - pcpp#TcpReassemblyConfiguration#closedConnectionDelay - the value of delay expressed in seconds. The minimum value - * is 1. - * - pcpp#TcpReassemblyConfiguration#maxNumToClean - to avoid performance overhead when the cleanup is being performed, - * this parameter is used. It defines the maximum number of items to be removed per one call of - * pcpp#TcpReassembly#purgeClosedConnections. - * - pcpp#TcpReassemblyConfiguration#maxOutOfOrderFragments - the maximum number of unmatched fragments to keep per flow - * before missed fragments are considered lost. A value of 0 means unlimited. - * - */ - -/** - * @namespace pcpp - * @brief The main namespace for the PcapPlusPlus lib - */ +/// @file +/// This is an implementation of TCP reassembly logic, which means reassembly of TCP messages spanning multiple TCP +/// segments (or packets).
This logic can be useful in analyzing messages for a large number of protocols +/// implemented on top of TCP including HTTP, SSL/TLS, FTP and many many more. +/// +/// __General Features:__ +/// - Manage multiple TCP connections under one pcpp#TcpReassembly instance +/// - Support TCP retransmission +/// - Support out-of-order packets +/// - Support missing TCP data +/// - TCP connections can end "naturally" (by FIN/RST packets) or manually by the user +/// - Support callbacks for new TCP data, connection start and connection end +/// +/// __Logic Description:__ +/// - The user creates an instance of the pcpp#TcpReassembly class +/// - Then the user starts feeding it with TCP packets +/// - The pcpp#TcpReassembly instance manages all TCP connections from the packets it's being fed. For each connection +/// it manages its 2 sides (A->B and B->A). +/// - When a packet arrives, it is first classified to a certain TCP connection +/// - Then it is classified to a certain side of the TCP connection +/// - Then the pcpp#TcpReassembly logic tries to understand if the data in this packet is the expected data +/// (sequence-wise) and if it's new (e.g isn't a retransmission). +/// - If the packet data matches these criteria a callback is being invoked. This callback is supplied by the user in +/// the creation of the pcpp#TcpReassembly instance. This callback contains the new data (of course), but also +/// information about the connection (5-tuple, 4-byte hash key describing the connection, etc.) and also a pointer to +/// a "user cookie", meaning a pointer to a structure provided by the user during the creation of the +/// pcpp#TcpReassembly instance. +/// - If the data in this packet isn't new, it's being ignored +/// - If the data in this packet isn't expected (meaning this packet came out-of-order), then the data is being queued +/// internally and will be sent to the user when its turn arrives (meaning, after the data before arrives). +/// - If the missing data doesn't arrive until a new message from the other side of the connection arrives or until the +/// connection ends - this will be considered as missing data and the queued data will be sent to the user, but the +/// string "[X bytes missing]" will be added to the message sent in the callback. +/// - pcpp#TcpReassembly supports 2 more callbacks - one is invoked when a new TCP connection is first seen and the +/// other when it's ended (either by a FIN/RST packet or manually by the user). Both of these callbacks contain data +/// about the connection (5-tuple, 4-byte hash key describing the connection, etc.) and also a pointer to a "user +/// cookie", meaning a pointer to a structure provided by the user during the creation of the pcpp#TcpReassembly +/// instance. The end connection callback also provides the reason for closing it ("naturally" or manually). +/// +/// __Basic Usage and APIs:__ +/// - pcpp#TcpReassembly c'tor - Create an instance, provide the callbacks and the user cookie to the instance +/// - pcpp#TcpReassembly#reassemblePacket() - Feed pcpp#TcpReassembly instance with packets +/// - pcpp#TcpReassembly#closeConnection() - Manually close a connection by a flow key +/// - pcpp#TcpReassembly#closeAllConnections() - Manually close all currently opened connections +/// - pcpp#TcpReassembly#OnTcpMessageReady callback - Invoked when new data arrives on a certain connection. Contains +/// the new data as well as connection data (5-tuple, flow key). +/// - pcpp#TcpReassembly#OnTcpConnectionStart callback - Invoked when a new connection is identified +/// - pcpp#TcpReassembly#OnTcpConnectionEnd callback - Invoked when a connection ends (either by FIN/RST or manually by +/// the user). +/// +/// __Additional information:__ +/// When the connection is closed the information is not being deleted from memory immediately. There is a delay between +/// these moments. Existence of this delay is caused by two reasons: +/// - pcpp#TcpReassembly#reassemblePacket() should detect the packets that arrive after the FIN packet has been +/// received. +/// - The user can use the information about connections managed by pcpp#TcpReassembly instance. Following methods are +/// used for this purpose: pcpp#TcpReassembly#getConnectionInformation and pcpp#TcpReassembly#isConnectionOpen. +/// Cleaning of memory can be performed automatically (the default behavior) by pcpp#TcpReassembly#reassemblePacket() or +/// manually by calling pcpp#TcpReassembly#purgeClosedConnections in the user code. Automatic cleaning is performed once +/// per second. +/// +/// The struct pcpp#TcpReassemblyConfiguration allows to setup the parameters of cleanup. Following parameters are +/// supported: +/// - pcpp#TcpReassemblyConfiguration#doNotRemoveConnInfo - if this member is set to false the automatic cleanup mode is +/// applied. +/// - pcpp#TcpReassemblyConfiguration#closedConnectionDelay - the value of delay expressed in seconds. The minimum value +/// is 1. +/// - pcpp#TcpReassemblyConfiguration#maxNumToClean - to avoid performance overhead when the cleanup is being performed, +/// this parameter is used. It defines the maximum number of items to be removed per one call of +/// pcpp#TcpReassembly#purgeClosedConnections. +/// - pcpp#TcpReassemblyConfiguration#maxOutOfOrderFragments - the maximum number of unmatched fragments to keep per +/// flow before missed fragments are considered lost. A value of 0 means unlimited. + +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct ConnectionData - * Represents basic TCP/UDP + IP connection data - */ + /// @struct ConnectionData + /// Represents basic TCP/UDP + IP connection data struct ConnectionData { - /** Source IP address */ + /// Source IP address IPAddress srcIP; - /** Destination IP address */ + /// Destination IP address IPAddress dstIP; - /** Source TCP/UDP port */ + /// Source TCP/UDP port uint16_t srcPort; - /** Destination TCP/UDP port */ + /// Destination TCP/UDP port uint16_t dstPort; - /** A 4-byte hash key representing the connection */ + /// A 4-byte hash key representing the connection uint32_t flowKey; - /** Start timestamp of the connection with microsecond precision */ + /// Start timestamp of the connection with microsecond precision timeval startTime; - /** End timestamp of the connection with microsecond precision */ + /// End timestamp of the connection with microsecond precision timeval endTime; - /** Start timestamp of the connection with nanosecond precision */ + /// Start timestamp of the connection with nanosecond precision std::chrono::time_point startTimePrecise; - /** End timestamp of the connection with nanosecond precision */ + /// End timestamp of the connection with nanosecond precision std::chrono::time_point endTimePrecise; - /** - * A c'tor for this struct that basically zeros all members - */ + /// A c'tor for this struct that basically zeros all members ConnectionData() : srcPort(0), dstPort(0), flowKey(0), startTime(), endTime() {} - /** - * Set the start time of the connection - * @param[in] startTimeValue timestamp value - */ + /// Set the start time of the connection + /// @param[in] startTimeValue timestamp value void setStartTime(const std::chrono::time_point& startTimeValue); - /** - * Set the end time of the connection - * @param[in] endTimeValue timestamp value - */ + /// Set the end time of the connection + /// @param[in] endTimeValue timestamp value void setEndTime(const std::chrono::time_point& endTimeValue); }; class TcpReassembly; - /** - * @class TcpStreamData - * When following a TCP connection each packet may contain a piece of the data transferred between the client and - * the server. This class represents these pieces: each instance of it contains a piece of data, usually extracted - * from a single packet, as well as information about the connection - */ + /// @class TcpStreamData + /// When following a TCP connection each packet may contain a piece of the data transferred between the client and + /// the server. This class represents these pieces: each instance of it contains a piece of data, usually extracted + /// from a single packet, as well as information about the connection class TcpStreamData { public: - /** - * A c'tor for this class that get data from outside and set the internal members - * @param[in] tcpData A pointer to buffer containing the TCP data piece - * @param[in] tcpDataLength The length of the buffer - * @param[in] missingBytes The number of missing bytes due to packet loss. - * @param[in] connData TCP connection information for this TCP data - * @param[in] timestamp when this packet was received - */ + /// A c'tor for this class that get data from outside and set the internal members + /// @param[in] tcpData A pointer to buffer containing the TCP data piece + /// @param[in] tcpDataLength The length of the buffer + /// @param[in] missingBytes The number of missing bytes due to packet loss. + /// @param[in] connData TCP connection information for this TCP data + /// @param[in] timestamp when this packet was received TcpStreamData(const uint8_t* tcpData, size_t tcpDataLength, size_t missingBytes, const ConnectionData& connData, std::chrono::time_point timestamp) : m_Data(tcpData), m_DataLen(tcpDataLength), m_MissingBytes(missingBytes), m_Connection(connData), m_Timestamp(timestamp) {} - /** - * A getter for the data buffer - * @return A pointer to the buffer - */ + /// A getter for the data buffer + /// @return A pointer to the buffer const uint8_t* getData() const { return m_Data; } - /** - * A getter for buffer length - * @return Buffer length - */ + /// A getter for buffer length + /// @return Buffer length size_t getDataLength() const { return m_DataLen; } - /** - * A getter for missing byte count due to packet loss. - * @return Missing byte count - */ + /// A getter for missing byte count due to packet loss. + /// @return Missing byte count size_t getMissingByteCount() const { return m_MissingBytes; } - /** - * Determine if bytes are missing. getMissingByteCount can be called to determine the number of missing bytes. - * @return true if bytes are missing. - */ + /// Determine if bytes are missing. getMissingByteCount can be called to determine the number of missing bytes. + /// @return true if bytes are missing. bool isBytesMissing() const { return getMissingByteCount() > 0; } - /** - * A getter for the connection data - * @return The const reference to connection data - */ + /// A getter for the connection data + /// @return The const reference to connection data const ConnectionData& getConnectionData() const { return m_Connection; } - /** - * @return A microsecond precision of the packet timestamp - */ + /// @return A microsecond precision of the packet timestamp timeval getTimeStamp() const; - /** - * @return A nanosecond precision of the packet timestamp - */ + /// @return A nanosecond precision of the packet timestamp std::chrono::time_point getTimeStampPrecise() const { return m_Timestamp; @@ -226,50 +195,42 @@ namespace pcpp std::chrono::time_point m_Timestamp; }; - /** - * @struct TcpReassemblyConfiguration - * A structure for configuring the TcpReassembly class - */ + /// @struct TcpReassemblyConfiguration + /// A structure for configuring the TcpReassembly class struct TcpReassemblyConfiguration { - /** The flag indicating whether to remove the connection data after a connection is closed */ + /// The flag indicating whether to remove the connection data after a connection is closed bool removeConnInfo; - /** How long the closed connections will not be cleaned up. The value is expressed in seconds. If the value is - * set to 0 then TcpReassembly should use the default value. This parameter is only relevant if removeConnInfo - * is equal to true. - */ + /// How long the closed connections will not be cleaned up. The value is expressed in seconds. If the value is + /// set to 0 then TcpReassembly should use the default value. This parameter is only relevant if removeConnInfo + /// is equal to true. uint32_t closedConnectionDelay; - /** The maximum number of items to be cleaned up per one call of purgeClosedConnections. If the value is set to - * 0 then TcpReassembly should use the default value. This parameter is only relevant if removeConnInfo is equal - * to true. - */ + /// The maximum number of items to be cleaned up per one call of purgeClosedConnections. If the value is set to + /// 0 then TcpReassembly should use the default value. This parameter is only relevant if removeConnInfo is + /// equal to true. uint32_t maxNumToClean; - /** The maximum number of fragments with a non-matching sequence-number to store per connection flow before - packets are assumed permanently missed. If the value is 0, TcpReassembly should keep out of order fragments - indefinitely, or until a message from the paired side is seen. - */ + /// The maximum number of fragments with a non-matching sequence-number to store per connection flow before + /// packets are assumed permanently missed. If the value is 0, TcpReassembly should keep out of order fragments + /// indefinitely, or until a message from the paired side is seen. uint32_t maxOutOfOrderFragments; - /** To enable to clear buffer once packet contains data from a different side than the side seen before - */ + /// To enable to clear buffer once packet contains data from a different side than the side seen before bool enableBaseBufferClearCondition; - /** - * A c'tor for this struct - * @param[in] removeConnInfo The flag indicating whether to remove the connection data after a connection is - * closed. The default is true - * @param[in] closedConnectionDelay How long the closed connections will not be cleaned up. The value is - * expressed in seconds. If it's set to 0 the default value will be used. The default is 5. - * @param[in] maxNumToClean The maximum number of items to be cleaned up per one call of purgeClosedConnections. - * If it's set to 0 the default value will be used. The default is 30. - * @param[in] maxOutOfOrderFragments The maximum number of unmatched fragments to keep per flow before missed - * fragments are considered lost. The default is unlimited. - * @param[in] enableBaseBufferClearCondition To enable to clear buffer once packet contains data from a - * different side than the side seen before - */ + /// A c'tor for this struct + /// @param[in] removeConnInfo The flag indicating whether to remove the connection data after a connection is + /// closed. The default is true + /// @param[in] closedConnectionDelay How long the closed connections will not be cleaned up. The value is + /// expressed in seconds. If it's set to 0 the default value will be used. The default is 5. + /// @param[in] maxNumToClean The maximum number of items to be cleaned up per one call of + /// purgeClosedConnections. If it's set to 0 the default value will be used. The default is 30. + /// @param[in] maxOutOfOrderFragments The maximum number of unmatched fragments to keep per flow before missed + /// fragments are considered lost. The default is unlimited. + /// @param[in] enableBaseBufferClearCondition To enable to clear buffer once packet contains data from a + /// different side than the side seen before explicit TcpReassemblyConfiguration(bool removeConnInfo = true, uint32_t closedConnectionDelay = 5, uint32_t maxNumToClean = 30, uint32_t maxOutOfOrderFragments = 0, bool enableBaseBufferClearCondition = true) @@ -279,205 +240,161 @@ namespace pcpp {} }; - /** - * @class TcpReassembly - * A class containing the TCP reassembly logic. Please refer to the documentation at the top of TcpReassembly.h for - * understanding how to use this class - */ + /// @class TcpReassembly + /// A class containing the TCP reassembly logic. Please refer to the documentation at the top of TcpReassembly.h for + /// understanding how to use this class class TcpReassembly { public: - /** - * An enum for connection end reasons - */ + /// An enum for connection end reasons enum ConnectionEndReason { - /** Connection ended because of FIN or RST packet */ + /// Connection ended because of FIN or RST packet TcpReassemblyConnectionClosedByFIN_RST, - /** Connection ended manually by the user */ + /// Connection ended manually by the user TcpReassemblyConnectionClosedManually }; - /** - * An enum for providing reassembly status for each processed packet - */ + /// An enum for providing reassembly status for each processed packet enum ReassemblyStatus { - /** - * The processed packet contains valid TCP payload, and its payload is processed by `OnMessageReadyCallback` - * callback function. The packet may be: - * 1. An in-order TCP packet, meaning `packet_sequence == sequence_expected`. - * Note if there's any buffered out-of-order packet waiting for this packet, their associated callbacks - * are called in this `reassemblePacket` call. - * 2. An out-of-order TCP packet which satisfy `packet_sequence < sequence_expected && packet_sequence + - * packet_payload_length > sequence_expected`. Note only the new data (the `[sequence_expected, - * packet_sequence + packet_payload_length]` part ) is processed by `OnMessageReadyCallback` callback - * function. - */ + /// The processed packet contains valid TCP payload, and its payload is processed by + /// `OnMessageReadyCallback` callback function. The packet may be: + /// 1. An in-order TCP packet, meaning `packet_sequence == sequence_expected`. + /// Note if there's any buffered out-of-order packet waiting for this packet, their associated callbacks + /// are called in this `reassemblePacket` call. + /// 2. An out-of-order TCP packet which satisfy `packet_sequence < sequence_expected && packet_sequence + + /// packet_payload_length > sequence_expected`. Note only the new data (the `[sequence_expected, + /// packet_sequence + packet_payload_length]` part ) is processed by `OnMessageReadyCallback` callback + /// function. TcpMessageHandled, - /** - * The processed packet is an out-of-order TCP packet, meaning `packet_sequence > sequence_expected`. It's - * buffered so no `OnMessageReadyCallback` callback function is called. The callback function for this - * packet maybe called LATER, under different circumstances: - * 1. When an in-order packet which is right before this packet arrives(case 1 and case 2 described in - * `TcpMessageHandled` section above). - * 2. When a FIN or RST packet arrives, which will clear the buffered out-of-order packets of this side. - * If this packet contains "new data", meaning `(packet_sequence <= sequence_expected) && - * (packet_sequence + packet_payload_length > sequence_expected)`, the new data is processed by - * `OnMessageReadyCallback` callback. - */ + /// The processed packet is an out-of-order TCP packet, meaning `packet_sequence > sequence_expected`. It's + /// buffered so no `OnMessageReadyCallback` callback function is called. The callback function for this + /// packet maybe called LATER, under different circumstances: + /// 1. When an in-order packet which is right before this packet arrives(case 1 and case 2 described in + /// `TcpMessageHandled` section above). + /// 2. When a FIN or RST packet arrives, which will clear the buffered out-of-order packets of this side. + /// If this packet contains "new data", meaning `(packet_sequence <= sequence_expected) && + /// (packet_sequence + packet_payload_length > sequence_expected)`, the new data is processed by + /// `OnMessageReadyCallback` callback. OutOfOrderTcpMessageBuffered, - /** - * The processed packet is a FIN or RST packet with no payload. - * Buffered out-of-order packets will be cleared. - * If they contain "new data", the new data is processed by `OnMessageReadyCallback` callback. - */ + /// The processed packet is a FIN or RST packet with no payload. + /// Buffered out-of-order packets will be cleared. + /// If they contain "new data", the new data is processed by `OnMessageReadyCallback` callback. FIN_RSTWithNoData, - /** - * The processed packet is not a SYN/SYNACK/FIN/RST packet and has no payload. - * Normally it's just a bare ACK packet. - * It's ignored and no callback function is called. - */ + /// The processed packet is not a SYN/SYNACK/FIN/RST packet and has no payload. + /// Normally it's just a bare ACK packet. + /// It's ignored and no callback function is called. Ignore_PacketWithNoData, - /** - * The processed packet comes from a closed flow(an in-order FIN or RST is seen). - * It's ignored and no callback function is called. - */ + + /// The processed packet comes from a closed flow(an in-order FIN or RST is seen). + /// It's ignored and no callback function is called. + Ignore_PacketOfClosedFlow, - /** - * The processed packet is a restransmission packet with no new data, meaning the `packet_sequence + - * packet_payload_length < sequence_expected`. It's ignored and no callback function is called. - */ + /// The processed packet is a restransmission packet with no new data, meaning the `packet_sequence + + /// packet_payload_length < sequence_expected`. It's ignored and no callback function is called. Ignore_Retransimission, - /** - * The processed packet is not an IP packet. - * It's ignored and no callback function is called. - */ + /// The processed packet is not an IP packet. + /// It's ignored and no callback function is called. NonIpPacket, - /** - * The processed packet is not a TCP packet. - * It's ignored and no callback function is called. - */ + /// The processed packet is not a TCP packet. + /// It's ignored and no callback function is called. NonTcpPacket, - /** - * The processed packet does not belong to any known TCP connection. - * It's ignored and no callback function is called. - * Normally this will be happen. - */ + /// The processed packet does not belong to any known TCP connection. + /// It's ignored and no callback function is called. + /// Normally this will be happen. Error_PacketDoesNotMatchFlow, }; - /** - * The type for storing the connection information - */ + /// The type for storing the connection information typedef std::unordered_map ConnectionInfoList; - /** - * @typedef OnTcpMessageReady - * A callback invoked when new data arrives on a connection - * @param[in] side The side this data belongs to (MachineA->MachineB or vice versa). The value is 0 or 1 where 0 - * is the first side seen in the connection and 1 is the second side seen - * @param[in] tcpData The TCP data itself + connection information - * @param[in] userCookie A pointer to the cookie provided by the user in TcpReassembly c'tor (or nullptr if no - * cookie provided) - */ + /// @typedef OnTcpMessageReady + /// A callback invoked when new data arrives on a connection + /// @param[in] side The side this data belongs to (MachineA->MachineB or vice versa). The value is 0 or 1 where + /// 0 is the first side seen in the connection and 1 is the second side seen + /// @param[in] tcpData The TCP data itself + connection information + /// @param[in] userCookie A pointer to the cookie provided by the user in TcpReassembly c'tor (or nullptr if no + /// cookie provided) typedef void (*OnTcpMessageReady)(int8_t side, const TcpStreamData& tcpData, void* userCookie); - /** - * @typedef OnTcpConnectionStart - * A callback invoked when a new TCP connection is identified (whether it begins with a SYN packet or not) - * @param[in] connectionData Connection information - * @param[in] userCookie A pointer to the cookie provided by the user in TcpReassembly c'tor (or nullptr if no - * cookie provided) - */ + /// @typedef OnTcpConnectionStart + /// A callback invoked when a new TCP connection is identified (whether it begins with a SYN packet or not) + /// @param[in] connectionData Connection information + /// @param[in] userCookie A pointer to the cookie provided by the user in TcpReassembly c'tor (or nullptr if no + /// cookie provided) typedef void (*OnTcpConnectionStart)(const ConnectionData& connectionData, void* userCookie); - /** - * @typedef OnTcpConnectionEnd - * A callback invoked when a TCP connection is terminated, either by a FIN or RST packet or manually by the user - * @param[in] connectionData Connection information - * @param[in] reason The reason for connection termination: FIN/RST packet or manually by the user - * @param[in] userCookie A pointer to the cookie provided by the user in TcpReassembly c'tor (or nullptr if no - * cookie provided) - */ + /// @typedef OnTcpConnectionEnd + /// A callback invoked when a TCP connection is terminated, either by a FIN or RST packet or manually by the + /// user + /// @param[in] connectionData Connection information + /// @param[in] reason The reason for connection termination: FIN/RST packet or manually by the user + /// @param[in] userCookie A pointer to the cookie provided by the user in TcpReassembly c'tor (or nullptr if no + /// cookie provided) typedef void (*OnTcpConnectionEnd)(const ConnectionData& connectionData, ConnectionEndReason reason, void* userCookie); - /** - * A c'tor for this class - * @param[in] onMessageReadyCallback The callback to be invoked when new data arrives - * @param[in] userCookie A pointer to an object provided by the user. This pointer will be returned when - * invoking the various callbacks. This parameter is optional, default cookie is nullptr - * @param[in] onConnectionStartCallback The callback to be invoked when a new connection is identified. This - * parameter is optional - * @param[in] onConnectionEndCallback The callback to be invoked when a new connection is terminated (either by - * a FIN/RST packet or manually by the user). This parameter is optional - * @param[in] config Optional parameter for defining special configuration parameters. If not set the default - * parameters will be set - */ + /// A c'tor for this class + /// @param[in] onMessageReadyCallback The callback to be invoked when new data arrives + /// @param[in] userCookie A pointer to an object provided by the user. This pointer will be returned when + /// invoking the various callbacks. This parameter is optional, default cookie is nullptr + /// @param[in] onConnectionStartCallback The callback to be invoked when a new connection is identified. This + /// parameter is optional + /// @param[in] onConnectionEndCallback The callback to be invoked when a new connection is terminated (either by + /// a FIN/RST packet or manually by the user). This parameter is optional + /// @param[in] config Optional parameter for defining special configuration parameters. If not set the default + /// parameters will be set explicit TcpReassembly(OnTcpMessageReady onMessageReadyCallback, void* userCookie = nullptr, OnTcpConnectionStart onConnectionStartCallback = nullptr, OnTcpConnectionEnd onConnectionEndCallback = nullptr, const TcpReassemblyConfiguration& config = TcpReassemblyConfiguration()); - /** - * The most important method of this class which gets a packet from the user and processes it. If this packet - * opens a new connection, ends a connection or contains new data on an existing connection, the relevant - * callback will be called (TcpReassembly#OnTcpMessageReady, TcpReassembly#OnTcpConnectionStart, - * TcpReassembly#OnTcpConnectionEnd) - * @param[in] tcpData A reference to the packet to process - * @return A enum of `TcpReassembly::ReassemblyStatus`, indicating status of TCP reassembly - */ + /// The most important method of this class which gets a packet from the user and processes it. If this packet + /// opens a new connection, ends a connection or contains new data on an existing connection, the relevant + /// callback will be called (TcpReassembly#OnTcpMessageReady, TcpReassembly#OnTcpConnectionStart, + /// TcpReassembly#OnTcpConnectionEnd) + /// @param[in] tcpData A reference to the packet to process + /// @return A enum of `TcpReassembly::ReassemblyStatus`, indicating status of TCP reassembly ReassemblyStatus reassemblePacket(Packet& tcpData); - /** - * The most important method of this class which gets a raw packet from the user and processes it. If this - * packet opens a new connection, ends a connection or contains new data on an existing connection, the relevant - * callback will be invoked (TcpReassembly#OnTcpMessageReady, TcpReassembly#OnTcpConnectionStart, - * TcpReassembly#OnTcpConnectionEnd) - * @param[in] tcpRawData A reference to the raw packet to process - * @return A enum of `TcpReassembly::ReassemblyStatus`, indicating status of TCP reassembly - */ + /// The most important method of this class which gets a raw packet from the user and processes it. If this + /// packet opens a new connection, ends a connection or contains new data on an existing connection, the + /// relevant callback will be invoked (TcpReassembly#OnTcpMessageReady, TcpReassembly#OnTcpConnectionStart, + /// TcpReassembly#OnTcpConnectionEnd) + /// @param[in] tcpRawData A reference to the raw packet to process + /// @return A enum of `TcpReassembly::ReassemblyStatus`, indicating status of TCP reassembly ReassemblyStatus reassemblePacket(RawPacket* tcpRawData); - /** - * Close a connection manually. If the connection doesn't exist or already closed an error log is printed. This - * method will cause the TcpReassembly#OnTcpConnectionEnd to be invoked with a reason of - * TcpReassembly#TcpReassemblyConnectionClosedManually - * @param[in] flowKey A 4-byte hash key representing the connection. Can be taken from a ConnectionData instance - */ + /// Close a connection manually. If the connection doesn't exist or already closed an error log is printed. This + /// method will cause the TcpReassembly#OnTcpConnectionEnd to be invoked with a reason of + /// TcpReassembly#TcpReassemblyConnectionClosedManually + /// @param[in] flowKey A 4-byte hash key representing the connection. Can be taken from a ConnectionData + /// instance void closeConnection(uint32_t flowKey); - /** - * Close all open connections manually. This method will cause the TcpReassembly#OnTcpConnectionEnd to be - * invoked for each connection with a reason of TcpReassembly#TcpReassemblyConnectionClosedManually - */ + /// Close all open connections manually. This method will cause the TcpReassembly#OnTcpConnectionEnd to be + /// invoked for each connection with a reason of TcpReassembly#TcpReassemblyConnectionClosedManually void closeAllConnections(); - /** - * Get a map of all connections managed by this TcpReassembly instance (both connections that are open and those - * that are already closed) - * @return A map of all connections managed. Notice this map is constant and cannot be changed by the user - */ + /// Get a map of all connections managed by this TcpReassembly instance (both connections that are open and + /// those that are already closed) + /// @return A map of all connections managed. Notice this map is constant and cannot be changed by the user const ConnectionInfoList& getConnectionInformation() const { return m_ConnectionInfo; } - /** - * Check if a certain connection managed by this TcpReassembly instance is currently opened or closed - * @param[in] connection The connection to check - * @return A positive number (> 0) if connection is opened, zero (0) if connection is closed, and a negative - * number (< 0) if this connection isn't managed by this TcpReassembly instance - */ + /// Check if a certain connection managed by this TcpReassembly instance is currently opened or closed + /// @param[in] connection The connection to check + /// @return A positive number (> 0) if connection is opened, zero (0) if connection is closed, and a negative + /// number (< 0) if this connection isn't managed by this TcpReassembly instance int isConnectionOpen(const ConnectionData& connection) const; - /** - * Clean up the closed connections from the memory - * @param[in] maxNumToClean The maximum number of items to be cleaned up per one call. This parameter, when its - * value is not zero, overrides the value that was set by the constructor. - * @return The number of cleared items - */ + /// Clean up the closed connections from the memory + /// @param[in] maxNumToClean The maximum number of items to be cleaned up per one call. This parameter, when its + /// value is not zero, overrides the value that was set by the constructor. + /// @return The number of cleared items uint32_t purgeClosedConnections(uint32_t maxNumToClean = 0); private: diff --git a/Packet++/header/TelnetLayer.h b/Packet++/header/TelnetLayer.h index 0689ee6468..6b56529b5c 100644 --- a/Packet++/header/TelnetLayer.h +++ b/Packet++/header/TelnetLayer.h @@ -4,16 +4,11 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * Class for representing the Telnet Layer - */ + /// Class for representing the Telnet Layer class TelnetLayer : public Layer { private: @@ -38,9 +33,7 @@ namespace pcpp uint8_t* getCommandData(uint8_t* pos, size_t& slen); public: - /** - * Telnet Command Indicator - */ + /// Telnet Command Indicator enum class TelnetCommand : int { /// Indicator to parser reached end of packet @@ -99,9 +92,7 @@ namespace pcpp InterpretAsCommand }; - /** - * Telnet Options - */ + /// Telnet Options enum class TelnetOption : int { /// Internal return for no option detected @@ -219,110 +210,82 @@ namespace pcpp ExtendedOptions = 255 }; - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in TelnetLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, Telnet) { lastPositionOffset = SIZE_MAX; }; - /** - * Get the Telnet data as readable string - * @param[in] removeEscapeCharacters Whether non-alphanumerical characters should be removed or not - * @return Full payload as readable string, empty if Telnet packet contains control commands/options. - */ + /// Get the Telnet data as readable string + /// @param[in] removeEscapeCharacters Whether non-alphanumerical characters should be removed or not + /// @return Full payload as readable string, empty if Telnet packet contains control commands/options. std::string getDataAsString(bool removeEscapeCharacters = true); - /** - * Get the total number of detected Telnet commands - * @return size_t The number of Telnet commands - */ + /// Get the total number of detected Telnet commands + /// @return size_t The number of Telnet commands size_t getTotalNumberOfCommands(); - /** - * Returns the number of occurrences of provided command - * @param[in] command Telnet command to count - * @return size_t Number of occurrences of command - */ + /// Returns the number of occurrences of provided command + /// @param[in] command Telnet command to count + /// @return size_t Number of occurrences of command size_t getNumberOfCommands(TelnetCommand command); - /** - * Returns the first command of packet - * @return TelnetCommand First detected command value, TelnetCommandEndOfPacket if there is no command field - */ + /// Returns the first command of packet + /// @return TelnetCommand First detected command value, TelnetCommandEndOfPacket if there is no command field TelnetCommand getFirstCommand(); - /** - * Returns the next command of packet. Uses an internal iterator. The iterator resets when reached end of - * packet. - * @return TelnetCommand Detected command value, TelnetCommandEndOfPacket if reached the end of packet. - */ + /// Returns the next command of packet. Uses an internal iterator. The iterator resets when reached end of + /// packet. + /// @return TelnetCommand Detected command value, TelnetCommandEndOfPacket if reached the end of packet. TelnetCommand getNextCommand(); - /** - * Returns the option of current command. Uses an internal iterator. Iterator can be moved with getNextCommand - * @return TelnetOption Option of current command - */ + /// Returns the option of current command. Uses an internal iterator. Iterator can be moved with getNextCommand + /// @return TelnetOption Option of current command TelnetOption getOption(); - /** - * Returns the option of provided command. It will return option of first occurrence of the command - * @param[in] command Telnet command to search - * @return TelnetOption Option of the command. Returns TelnetOptionNoOption if the provided command not found. - */ + /// Returns the option of provided command. It will return option of first occurrence of the command + /// @param[in] command Telnet command to search + /// @return TelnetOption Option of the command. Returns TelnetOptionNoOption if the provided command not found. TelnetOption getOption(TelnetCommand command); - /** - * Returns the data of current command. Uses an internal iterator. Iterator can be moved with getNextCommand - * @param[out] length Length of the data of current command - * @return uint8_t* Pointer to the data of current command. nullptr if there is no data for this command. - */ + /// Returns the data of current command. Uses an internal iterator. Iterator can be moved with getNextCommand + /// @param[out] length Length of the data of current command + /// @return uint8_t* Pointer to the data of current command. nullptr if there is no data for this command. uint8_t* getOptionData(size_t& length); - /** - * Returns the data of provided command. It will return data of first occurrence of the command - * @param[in] command Telnet command to search - * @param[out] length Length of the data of current command - * @return uint8_t* Pointer to the data of current command. nullptr if there is no data for this command or if - * can't find the command. - */ + /// Returns the data of provided command. It will return data of first occurrence of the command + /// @param[in] command Telnet command to search + /// @param[out] length Length of the data of current command + /// @return uint8_t* Pointer to the data of current command. nullptr if there is no data for this command or if + /// can't find the command. uint8_t* getOptionData(TelnetCommand command, size_t& length); - /** - * Convert the Telnet Command to readable string - * @param[in] val Value of the command - * @return The Telnet Command as readable string - */ + /// Convert the Telnet Command to readable string + /// @param[in] val Value of the command + /// @return The Telnet Command as readable string static std::string getTelnetCommandAsString(TelnetCommand val); - /** - * Convert the Telnet option to readable string - * @param[in] val Value of the option - * @return The Telnet Option as readable string - */ + /// Convert the Telnet option to readable string + /// @param[in] val Value of the option + /// @return The Telnet Option as readable string static std::string getTelnetOptionAsString(TelnetOption val); - /** - * A static method that checks whether the port is considered as Telnet - * @param[in] port The port number to be checked - */ + /// A static method that checks whether the port is considered as Telnet + /// @param[in] port The port number to be checked static bool isTelnetPort(uint16_t port) { return port == 23; } - /** - * A static method that takes a byte array and detects whether it is a Telnet message - * @param[in] data A byte array - * @param[in] dataSize The byte array size (in bytes) - * @return True if the data is identified as Telnet message - */ + /// A static method that takes a byte array and detects whether it is a Telnet message + /// @param[in] data A byte array + /// @param[in] dataSize The byte array size (in bytes) + /// @return True if the data is identified as Telnet message static bool isDataValid(const uint8_t* data, size_t dataSize) { return data && dataSize; @@ -334,9 +297,7 @@ namespace pcpp void parseNextLayer() override {} - /** - * @return Get the size of the layer - */ + /// @return Get the size of the layer size_t getHeaderLen() const override { return m_DataLen; @@ -346,17 +307,13 @@ namespace pcpp void computeCalculateFields() override {} - /** - * @return The OSI layer level of Telnet (Application Layer). - */ + /// @return The OSI layer level of Telnet (Application Layer). OsiModelLayer getOsiModelLayer() const override { return OsiModelApplicationLayer; } - /** - * @return Returns the protocol info as readable string - */ + /// @return Returns the protocol info as readable string std::string toString() const override; }; diff --git a/Packet++/header/TextBasedProtocol.h b/Packet++/header/TextBasedProtocol.h index 0e57db5174..67e109ca7f 100644 --- a/Packet++/header/TextBasedProtocol.h +++ b/Packet++/header/TextBasedProtocol.h @@ -8,24 +8,22 @@ namespace pcpp { -/** End of header */ +/// End of header #define PCPP_END_OF_TEXT_BASED_PROTOCOL_HEADER "" class TextBasedProtocolMessage; // -------- Class HeaderField ----------------- - /** - * @class HeaderField - * A wrapper class for each text-based-protocol header field, e.g "Host", "Cookie", "Content-Length", "Via", - * "Call-ID", etc. Each field contains a name (e.g "Host") and a value (e.g "www.wikipedia.org"). The user can get - * and set both of them through dedicated methods. The separator between header fields is either CRLF ("\r\n\") or - * LF ("\n") in more rare cases, which means every HeaderField instance is responsible for wrapping and parsing a - * header field from the previous CRLF (not inclusive) until the next CRLF/LF (inclusive) A special case is with the - * end of a header, meaning 2 consecutive CRLFs ("\r\n\r\n") or consecutive LFs ("\n\n"). PcapPlusPlus treats the - * first CRLF/LF as part of the last field in the header, and the second CRLF is an HeaderField instance of its own - * which name and values are an empty string ("") or pcpp::PCPP_END_OF_TEXT_BASED_PROTOCOL_HEADER - */ + /// @class HeaderField + /// A wrapper class for each text-based-protocol header field, e.g "Host", "Cookie", "Content-Length", "Via", + /// "Call-ID", etc. Each field contains a name (e.g "Host") and a value (e.g "www.wikipedia.org"). The user can get + /// and set both of them through dedicated methods. The separator between header fields is either CRLF ("\r\n\") or + /// LF ("\n") in more rare cases, which means every HeaderField instance is responsible for wrapping and parsing a + /// header field from the previous CRLF (not inclusive) until the next CRLF/LF (inclusive) A special case is with + /// the end of a header, meaning 2 consecutive CRLFs ("\r\n\r\n") or consecutive LFs ("\n\n"). PcapPlusPlus treats + /// the first CRLF/LF as part of the last field in the header, and the second CRLF is an HeaderField instance of its + /// own which name and values are an empty string ("") or pcpp::PCPP_END_OF_TEXT_BASED_PROTOCOL_HEADER class HeaderField { friend class TextBasedProtocolMessage; @@ -33,55 +31,41 @@ namespace pcpp public: ~HeaderField(); - /** - * A copy constructor that creates a new instance out of an existing HeaderField instance. The copied instance - * will not have shared resources with the original instance, meaning all members and properties are copied - * @param[in] other The original instance to copy from - */ + /// A copy constructor that creates a new instance out of an existing HeaderField instance. The copied instance + /// will not have shared resources with the original instance, meaning all members and properties are copied + /// @param[in] other The original instance to copy from HeaderField(const HeaderField& other); - /** - * Assignment operator for this class. This method copies the data from the other instance and will not share - * any resources with it. Also, if the instance already contains data it will be deleted or zeroed - * @param[in] other The instance to assign from - * @return A reference to the assignee - */ + /// Assignment operator for this class. This method copies the data from the other instance and will not share + /// any resources with it. Also, if the instance already contains data it will be deleted or zeroed + /// @param[in] other The instance to assign from + /// @return A reference to the assignee HeaderField& operator=(const HeaderField& other); - /** - * @return The field length in bytes, meaning count of all characters from the previous CRLF (not inclusive) - * until the next CRLF (inclusive) For example: the field "Host: www.wikipedia.org\r\n" will have the length of - * 25 - */ + /// @return The field length in bytes, meaning count of all characters from the previous CRLF (not inclusive) + /// until the next CRLF (inclusive) For example: the field "Host: www.wikipedia.org\r\n" will have the length of + /// 25 size_t getFieldSize() const { return m_FieldSize; } - /** - * @return The field name as string. Notice the return data is copied data, so changing it won't change the - * packet data - */ + /// @return The field name as string. Notice the return data is copied data, so changing it won't change the + /// packet data std::string getFieldName() const; - /** - * @return The field value as string. Notice the return data is copied data, so changing it won't change the - * packet data - */ + /// @return The field value as string. Notice the return data is copied data, so changing it won't change the + /// packet data std::string getFieldValue() const; - /** - * A setter for field value - * @param[in] newValue The new value to set to the field. Old value will be deleted - * @return True if setting the value was completed successfully, false otherwise - */ + /// A setter for field value + /// @param[in] newValue The new value to set to the field. Old value will be deleted + /// @return True if setting the value was completed successfully, false otherwise bool setFieldValue(const std::string& newValue); - /** - * Get an indication whether the field is a field that ends the header (meaning contain only CRLF - see class - * explanation) - * @return True if this is a end-of-header field, false otherwise - */ + /// Get an indication whether the field is a field that ends the header (meaning contain only CRLF - see class + /// explanation) + /// @return True if this is a end-of-header field, false otherwise bool isEndOfHeader() const { return m_IsEndOfHeaderField; @@ -114,11 +98,9 @@ namespace pcpp // -------- Class TextBasedProtocolMessage ----------------- - /** - * @class TextBasedProtocolMessage - * An abstract base class that wraps text-based-protocol header layers (both requests and responses). It is the base - * class for all those layers. This class is not meant to be instantiated, hence the protected c'tor - */ + /// @class TextBasedProtocolMessage + /// An abstract base class that wraps text-based-protocol header layers (both requests and responses). It is the + /// base class for all those layers. This class is not meant to be instantiated, hence the protected c'tor class TextBasedProtocolMessage : public Layer { friend class HeaderField; @@ -126,32 +108,26 @@ namespace pcpp public: ~TextBasedProtocolMessage() override; - /** - * Get a pointer to a header field by name. The search is case insensitive, meaning if a field with name "Host" - * exists and the fieldName parameter is "host" (all letter are lower case), this method will return a pointer - * to "Host" field - * @param[in] fieldName The field name - * @param[in] index Optional parameter. If the field name appears more than once, this parameter will indicate - * which field to get. The default value is 0 (get the first appearance of the field name as appears on the - * packet) - * @return A pointer to an HeaderField instance, or nullptr if field doesn't exist - */ + /// Get a pointer to a header field by name. The search is case insensitive, meaning if a field with name "Host" + /// exists and the fieldName parameter is "host" (all letter are lower case), this method will return a pointer + /// to "Host" field + /// @param[in] fieldName The field name + /// @param[in] index Optional parameter. If the field name appears more than once, this parameter will indicate + /// which field to get. The default value is 0 (get the first appearance of the field name as appears on the + /// packet) + /// @return A pointer to an HeaderField instance, or nullptr if field doesn't exist HeaderField* getFieldByName(std::string fieldName, int index = 0) const; - /** - * @return A pointer to the first header field exists in this message, or nullptr if no such field exists - */ + /// @return A pointer to the first header field exists in this message, or nullptr if no such field exists HeaderField* getFirstField() const { return m_FieldList; } - /** - * Get the field which appears after a certain field - * @param[in] prevField A pointer to the field - * @return The field after prevField or nullptr if prevField is the last field. If prevField is nullptr, this - * method will return nullptr - */ + /// Get the field which appears after a certain field + /// @param[in] prevField A pointer to the field + /// @return The field after prevField or nullptr if prevField is the last field. If prevField is nullptr, this + /// method will return nullptr HeaderField* getNextField(HeaderField* prevField) const { if (prevField != nullptr) @@ -160,103 +136,77 @@ namespace pcpp return nullptr; } - /** - * @return The number of header fields currently in the layer (not including CRLF at the end of the header) - */ + /// @return The number of header fields currently in the layer (not including CRLF at the end of the header) int getFieldCount() const; - /** - * Add a new header field to this message. This field will be added last (before the end-of-header field) - * @param[in] fieldName The field name - * @param[in] fieldValue The field value - * @return A pointer to the newly created header field, or nullptr if the field could not be created - */ + /// Add a new header field to this message. This field will be added last (before the end-of-header field) + /// @param[in] fieldName The field name + /// @param[in] fieldValue The field value + /// @return A pointer to the newly created header field, or nullptr if the field could not be created virtual HeaderField* addField(const std::string& fieldName, const std::string& fieldValue); - /** - * Add a new header field to this message. This field will be added last (before the end-of-header field) - * @param[in] newField The header field to add - * @return A pointer to the newly created header field, or nullptr if the field could not be created - */ + /// Add a new header field to this message. This field will be added last (before the end-of-header field) + /// @param[in] newField The header field to add + /// @return A pointer to the newly created header field, or nullptr if the field could not be created virtual HeaderField* addField(const HeaderField& newField); - /** - * Add the special end-of-header field (see the explanation in HeaderField) - * @return A pointer to the newly created header field, or nullptr if the field could not be created - */ + /// Add the special end-of-header field (see the explanation in HeaderField) + /// @return A pointer to the newly created header field, or nullptr if the field could not be created HeaderField* addEndOfHeader(); - /** - * Insert a new field after an existing field - * @param[in] prevField A pointer to the existing field. If it's nullptr the new field will be added as first - * field - * @param[in] fieldName The field name - * @param[in] fieldValue The field value - * @return A pointer to the newly created header field, or nullptr if the field could not be created - */ + /// Insert a new field after an existing field + /// @param[in] prevField A pointer to the existing field. If it's nullptr the new field will be added as first + /// field + /// @param[in] fieldName The field name + /// @param[in] fieldValue The field value + /// @return A pointer to the newly created header field, or nullptr if the field could not be created virtual HeaderField* insertField(HeaderField* prevField, const std::string& fieldName, const std::string& fieldValue); - /** - * Insert a new field after an existing field - * @param[in] prevFieldName A name of an existing field. If the field doesn't exist nullptr will be returned. - * If field name is empty ('') the new field will be added as first field - * @param[in] fieldName The field name - * @param[in] fieldValue The field value - * @return A pointer to the newly created header field, or nullptr if the field could not be created - */ + /// Insert a new field after an existing field + /// @param[in] prevFieldName A name of an existing field. If the field doesn't exist nullptr will be returned. + /// If field name is empty ('') the new field will be added as first field + /// @param[in] fieldName The field name + /// @param[in] fieldValue The field value + /// @return A pointer to the newly created header field, or nullptr if the field could not be created virtual HeaderField* insertField(std::string prevFieldName, const std::string& fieldName, const std::string& fieldValue); - /** - * Insert a new field after an existing field - * @param[in] prevField A pointer to the existing field - * @param[in] newField The header field to add - * @return A pointer to the newly created header field, or nullptr if the field could not be created - */ + /// Insert a new field after an existing field + /// @param[in] prevField A pointer to the existing field + /// @param[in] newField The header field to add + /// @return A pointer to the newly created header field, or nullptr if the field could not be created virtual HeaderField* insertField(HeaderField* prevField, const HeaderField& newField); - /** - * Remove a field from the message - * @param[in] fieldToRemove A pointer to the field that should be removed - * @return True if the field was removed successfully, or false otherwise (for example: if fieldToRemove is - * nullptr, if it doesn't exist in the message, or if the removal failed) - */ + /// Remove a field from the message + /// @param[in] fieldToRemove A pointer to the field that should be removed + /// @return True if the field was removed successfully, or false otherwise (for example: if fieldToRemove is + /// nullptr, if it doesn't exist in the message, or if the removal failed) bool removeField(HeaderField* fieldToRemove); - /** - * Remove a field from the message - * @param[in] fieldName The name of the field that should be removed - * @param[in] index Optional parameter. If the field name appears more than once, this parameter will indicate - * which field to remove. The default value is 0 (remove the first appearance of the field name as appears on - * the packet) - * @return True if the field was removed successfully, or false otherwise (for example: if fieldName doesn't - * exist in the message, or if the removal failed) - */ + /// Remove a field from the message + /// @param[in] fieldName The name of the field that should be removed + /// @param[in] index Optional parameter. If the field name appears more than once, this parameter will indicate + /// which field to remove. The default value is 0 (remove the first appearance of the field name as appears on + /// the packet) + /// @return True if the field was removed successfully, or false otherwise (for example: if fieldName doesn't + /// exist in the message, or if the removal failed) bool removeField(std::string fieldName, int index = 0); - /** - * Indicate whether the header is complete (ending with end-of-header "\r\n\r\n" or "\n\n") or spread over more - * packets - * @return True if the header is complete or false if not - */ + /// Indicate whether the header is complete (ending with end-of-header "\r\n\r\n" or "\n\n") or spread over more + /// packets + /// @return True if the header is complete or false if not bool isHeaderComplete() const; // implement Layer's abstract methods - /** - * Currently set only PayloadLayer for the rest of the data - */ + /// Currently set only PayloadLayer for the rest of the data void parseNextLayer() override; - /** - * @return The message length - */ + /// @return The message length size_t getHeaderLen() const override; - /** - * Does nothing for this class - */ + /// Does nothing for this class void computeCalculateFields() override; protected: @@ -283,5 +233,4 @@ namespace pcpp int m_FieldsOffset; std::multimap m_FieldNameToFieldMap; }; - } // namespace pcpp diff --git a/Packet++/header/TpktLayer.h b/Packet++/header/TpktLayer.h index e0b8130bee..8122e6bd1c 100644 --- a/Packet++/header/TpktLayer.h +++ b/Packet++/header/TpktLayer.h @@ -5,120 +5,89 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct tpkthdr - * Represents a TPKT protocol header - */ + /// @struct tpkthdr + /// Represents a TPKT protocol header #pragma pack(push, 1) struct tpkthdr { - /** message version */ + /// message version uint8_t version; - /** message reserved */ + /// message reserved uint8_t reserved; - /** message length */ + /// message length uint16_t length; }; #pragma pack(pop) static_assert(sizeof(tpkthdr) == 4, "tpkthdr size is not 4 bytes"); - /** - * @class TpktLayer - * Represents a TPKT (Transport Service on top of the TCP) protocol layer - */ + /// @class TpktLayer + /// Represents a TPKT (Transport Service on top of the TCP) protocol layer class TpktLayer : public Layer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to @ref tpkthdr) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to @ref tpkthdr) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in TpktLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, TPKT) {} - /** - * A constructor that allocates a new TPKT header - * @param[in] version Protocol version number - * @param[in] length Packet length - */ + /// A constructor that allocates a new TPKT header + /// @param[in] version Protocol version number + /// @param[in] length Packet length TpktLayer(uint8_t version, uint16_t length); ~TpktLayer() override = default; - /** - * @return TPKT reserved - */ + /// @return TPKT reserved uint8_t getReserved() const; - /** - * @return TPKT version - */ + /// @return TPKT version uint8_t getVersion() const; - /** - * @return TPKT length - */ + /// @return TPKT length uint16_t getLength() const; - /** - * Set the value of the version - * @param[in] version The value of the version - */ + /// Set the value of the version + /// @param[in] version The value of the version void setVersion(uint8_t version) const; - /** - * Set the value of the length - * @param[in] length The value of the length - */ + /// Set the value of the length + /// @param[in] length The value of the length void setLength(uint16_t length) const; - /** - * @return Size of @ref tpkthdr - */ + /// @return Size of @ref tpkthdr size_t getHeaderLen() const override { return sizeof(tpkthdr); } - /** - * Does nothing for this layer - */ + /// Does nothing for this layer void computeCalculateFields() override {} - /** - * Currently parses the rest of the packet as a COTP protocol or generic payload (PayloadLayer) - */ + /// Currently parses the rest of the packet as a COTP protocol or generic payload (PayloadLayer) void parseNextLayer() override; - /** - * A static method that checks whether a source or dest port match those associated with the TPKT protocol - * @param[in] portSrc Source port number to check - * @param[in] portDst Dest port number to check - * @return True if the source or dest port match those associated with the TPKT protocol - */ + /// A static method that checks whether a source or dest port match those associated with the TPKT protocol + /// @param[in] portSrc Source port number to check + /// @param[in] portDst Dest port number to check + /// @return True if the source or dest port match those associated with the TPKT protocol static bool isTpktPort(uint16_t portSrc, uint16_t portDst) { return portSrc == 102 || portDst == 102; } - /** - * A static method that takes a byte array and detects whether it is a TPKT message - * @param[in] data A byte array - * @param[in] dataSize The byte array size (in bytes) - * @return True if the data size is greater or equal than the size of tpkthdr - */ + /// A static method that takes a byte array and detects whether it is a TPKT message + /// @param[in] data A byte array + /// @param[in] dataSize The byte array size (in bytes) + /// @return True if the data size is greater or equal than the size of tpkthdr static bool isDataValid(const uint8_t* data, size_t dataSize) { return data && dataSize >= sizeof(tpkthdr); @@ -132,12 +101,10 @@ namespace pcpp } private: - /** - * Get a pointer to the TPKT header. Data can be retrieved through the - * other methods of this layer. Notice the return value points directly to the data, so every change will change - * the actual packet data - * @return A pointer to the @ref tpkthdr - */ + /// Get a pointer to the TPKT header. Data can be retrieved through the + /// other methods of this layer. Notice the return value points directly to the data, so every change will + /// change the actual packet data + /// @return A pointer to the @ref tpkthdr tpkthdr* getTpktHeader() const { return reinterpret_cast(m_Data); diff --git a/Packet++/header/UdpLayer.h b/Packet++/header/UdpLayer.h index 53f12f07b9..83cbc555f4 100644 --- a/Packet++/header/UdpLayer.h +++ b/Packet++/header/UdpLayer.h @@ -4,104 +4,79 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct udphdr - * Represents an UDP protocol header - */ + /// @struct udphdr + /// Represents an UDP protocol header #pragma pack(push, 1) struct udphdr { - /** Source port */ + /// Source port uint16_t portSrc; - /** Destination port */ + /// Destination port uint16_t portDst; - /** Length of header and payload in bytes */ + /// Length of header and payload in bytes uint16_t length; - /** Error-checking of the header and data */ + /// Error-checking of the header and data uint16_t headerChecksum; }; #pragma pack(pop) static_assert(sizeof(udphdr) == 8, "udphdr size is not 8 bytes"); - /** - * @class UdpLayer - * Represents an UDP (User Datagram Protocol) protocol layer - */ + /// @class UdpLayer + /// Represents an UDP (User Datagram Protocol) protocol layer class UdpLayer : public Layer { public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data (will be casted to @ref udphdr) - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data (will be casted to @ref udphdr) + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in UdpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, UDP) {} - /** - * A constructor that allocates a new UDP header with source and destination ports - * @param[in] portSrc Source UDP port address - * @param[in] portDst Destination UDP port - */ + /// A constructor that allocates a new UDP header with source and destination ports + /// @param[in] portSrc Source UDP port address + /// @param[in] portDst Destination UDP port UdpLayer(uint16_t portSrc, uint16_t portDst); - /** - * Get a pointer to the UDP header. Notice this points directly to the data, so every change will change the - * actual packet data - * @return A pointer to the @ref udphdr - */ + /// Get a pointer to the UDP header. Notice this points directly to the data, so every change will change the + /// actual packet data + /// @return A pointer to the @ref udphdr udphdr* getUdpHeader() const { return reinterpret_cast(m_Data); } - /** - * @return UDP source port - */ + /// @return UDP source port uint16_t getSrcPort() const; - /** - * @return UDP destination port - */ + /// @return UDP destination port uint16_t getDstPort() const; - /** - * Calculate the checksum from header and data and possibly write the result to @ref udphdr#headerChecksum - * @param[in] writeResultToPacket If set to true then checksum result will be written to @ref - * udphdr#headerChecksum - * @return The checksum result - */ + /// Calculate the checksum from header and data and possibly write the result to @ref udphdr#headerChecksum + /// @param[in] writeResultToPacket If set to true then checksum result will be written to @ref + /// udphdr#headerChecksum + /// @return The checksum result uint16_t calculateChecksum(bool writeResultToPacket); // implement abstract methods - /** - * Currently identifies the following next layers: DnsLayer, DhcpLayer, VxlanLayer, SipRequestLayer, - * SipResponseLayer, RadiusLayer. Otherwise sets PayloadLayer - */ + /// Currently identifies the following next layers: DnsLayer, DhcpLayer, VxlanLayer, SipRequestLayer, + /// SipResponseLayer, RadiusLayer. Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * @return Size of @ref udphdr - */ + /// @return Size of @ref udphdr size_t getHeaderLen() const override { return sizeof(udphdr); } - /** - * Calculate @ref udphdr#headerChecksum field - */ + /// Calculate @ref udphdr#headerChecksum field void computeCalculateFields() override; std::string toString() const override; @@ -111,5 +86,4 @@ namespace pcpp return OsiModelTransportLayer; } }; - } // namespace pcpp diff --git a/Packet++/header/VlanLayer.h b/Packet++/header/VlanLayer.h index d4463bc44d..4dc169cbc1 100644 --- a/Packet++/header/VlanLayer.h +++ b/Packet++/header/VlanLayer.h @@ -5,136 +5,104 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct vlan_header - * Represents a VLAN header - */ + /// @struct vlan_header + /// Represents a VLAN header #pragma pack(push, 1) struct vlan_header { - /** - @verbatim - 0 1 2 - 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |Prio |C| VLAN ID | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - @endverbatim - */ + /// @code{.unparsed} + /// 0 1 2 + /// 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// |Prio |C| VLAN ID | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// @endcode uint16_t vlan; - /** Ethernet type for next layer */ + /// Ethernet type for next layer uint16_t etherType; }; #pragma pack(pop) static_assert(sizeof(vlan_header) == 4, "vlan_header size is not 4 bytes"); - /** - * @class VlanLayer - * Represents a VLAN tunnel layer - */ + /// @class VlanLayer + /// Represents a VLAN tunnel layer class VlanLayer : public Layer { public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in VlanLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, VLAN) {} - /** - * A constructor that allocates a new VLAN header - * @param[in] vlanID VLAN ID - * @param[in] cfi CFI value - * @param[in] priority Priority value - * @param[in] etherType Protocol EtherType of the next layer. It's an optional parameter, a value of 0 will be - * set if not provided - */ + /// A constructor that allocates a new VLAN header + /// @param[in] vlanID VLAN ID + /// @param[in] cfi CFI value + /// @param[in] priority Priority value + /// @param[in] etherType Protocol EtherType of the next layer. It's an optional parameter, a value of 0 will be + /// set if not provided VlanLayer(const uint16_t vlanID, bool cfi, uint8_t priority, uint16_t etherType = 0); ~VlanLayer() override = default; - /** - * Get a pointer to the VLAN header. Notice this points directly to the data, so every change will change the - * actual packet data - * @return A pointer to the vlan_header - */ + /// Get a pointer to the VLAN header. Notice this points directly to the data, so every change will change the + /// actual packet data + /// @return A pointer to the vlan_header vlan_header* getVlanHeader() const { return reinterpret_cast(m_Data); } - /** - * Get the VLAN ID value. This method differs from vlan_header#vlanID because vlan_header#vlanID is 12 bits long - * in a 16 bit field. This methods extracts only the 12 bit relevant for the VLAN ID - * @return VLAN ID value - * @todo Verify it works in big endian machines as well - */ + /// Get the VLAN ID value. This method differs from vlan_header#vlanID because vlan_header#vlanID is 12 bits + /// long in a 16 bit field. This methods extracts only the 12 bit relevant for the VLAN ID + /// @return VLAN ID value + /// @todo Verify it works in big endian machines as well uint16_t getVlanID() const; - /** - * @return The CFI bit value - * @todo Verify it works in big endian machines as well - */ + /// @return The CFI bit value + /// @todo Verify it works in big endian machines as well uint8_t getCFI() const; - /** - * @return The priority value - * @todo Verify it works in big endian machines as well - */ + /// @return The priority value + /// @todo Verify it works in big endian machines as well uint8_t getPriority() const; - /** - * Set VLAN ID. This method differs from setting vlan_header#vlanID because vlan_header#vlanID is 12 bits long - * in a 16 bit field. This methods sets only the 12 bit relevant for the VLAN ID - * @param[in] id The VLAN ID to set - * @todo Verify it works in big endian machines as well - */ + /// Set VLAN ID. This method differs from setting vlan_header#vlanID because vlan_header#vlanID is 12 bits long + /// in a 16 bit field. This methods sets only the 12 bit relevant for the VLAN ID + /// @param[in] id The VLAN ID to set + /// @todo Verify it works in big endian machines as well void setVlanID(uint16_t id); - /** - * Set CFI bit - * @param[in] cfi The CFI bit to set - * @todo Verify it works in big endian machines as well - */ + /// Set CFI bit + /// @param[in] cfi The CFI bit to set + /// @todo Verify it works in big endian machines as well void setCFI(bool cfi); - /** - * Set priority value - * @param[in] priority The priority value to set - * @todo Verify it works in big endian machines as well - */ + /// Set priority value + /// @param[in] priority The priority value to set + /// @todo Verify it works in big endian machines as well void setPriority(uint8_t priority); // implement abstract methods - /** - * Currently identifies the following next layers: IPv4Layer, IPv6Layer, ArpLayer, VlanLayer, MplsLayer. - * Otherwise sets PayloadLayer - */ + /// Currently identifies the following next layers: IPv4Layer, IPv6Layer, ArpLayer, VlanLayer, MplsLayer. + /// Otherwise sets PayloadLayer void parseNextLayer() override; - /** - * @return Size of vlan_header - */ + /// @return Size of vlan_header size_t getHeaderLen() const override { return sizeof(vlan_header); } - /** - * Calculate the EtherType for known protocols: IPv4, IPv6, ARP, VLAN - */ + /// Calculate the EtherType for known protocols: IPv4, IPv6, ARP, VLAN void computeCalculateFields() override; std::string toString() const override; @@ -144,5 +112,4 @@ namespace pcpp return OsiModelDataLinkLayer; } }; - } // namespace pcpp diff --git a/Packet++/header/VrrpLayer.h b/Packet++/header/VrrpLayer.h index 4875116d0e..ea33189a08 100644 --- a/Packet++/header/VrrpLayer.h +++ b/Packet++/header/VrrpLayer.h @@ -6,114 +6,104 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - For more info see: - https://datatracker.ietf.org/doc/html/rfc2338 - https://datatracker.ietf.org/doc/html/rfc3768 - https://datatracker.ietf.org/doc/html/rfc5798 - */ - - /* VRRPv2 Packet Format - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |Version| Type | Virtual Rtr ID| Priority | Count IP Addrs| - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Auth Type | Adver Int | Checksum | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | IP Address (1) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | . | - | . | - | . | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | IP Address (n) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Authentication Data (1) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Authentication Data (2) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - - /* VRRPv3 Packet Format - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | IPv4 Fields or IPv6 Fields | - ... ... - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |Version| Type | Virtual Rtr ID| Priority |Count IPvX Addr| - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |(rsvd) | Max Adver Int | Checksum | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - + + - | IPvX Address(es) | - + + - + + - + + - + + - | | - + + - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - - /** - * @struct vrrp_header - * VRRP generic header - */ + /// For more info see: + /// https://datatracker.ietf.org/doc/html/rfc2338 + /// https://datatracker.ietf.org/doc/html/rfc3768 + /// https://datatracker.ietf.org/doc/html/rfc5798 + + /// VRRPv2 Packet Format + /// 0 1 2 3 + /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// |Version| Type | Virtual Rtr ID| Priority | Count IP Addrs| + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | Auth Type | Adver Int | Checksum | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | IP Address (1) | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | . | + /// | . | + /// | . | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | IP Address (n) | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | Authentication Data (1) | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | Authentication Data (2) | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + /// VRRPv3 Packet Format + /// 0 1 2 3 + /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | IPv4 Fields or IPv6 Fields | + /// ... ... + /// | | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// |Version| Type | Virtual Rtr ID| Priority |Count IPvX Addr| + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// |(rsvd) | Max Adver Int | Checksum | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + /// | | + /// + + + /// | IPvX Address(es) | + /// + + + /// + + + /// + + + /// + + + /// | | + /// + + + /// | | + /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + /// @struct vrrp_header + /// VRRP generic header struct vrrp_header { #if (BYTE_ORDER == LITTLE_ENDIAN) - /** Type */ + /// Type uint8_t type : 4; - /** Version bits */ + /// Version bits uint8_t version : 4; #else - /** Version bits */ + /// Version bits uint8_t version : 4; - /** Type */ + /// Type uint8_t type : 4; #endif - /** The Virtual Router Identifier (VRID) field identifies the virtual router this packet is reporting status - * for*/ + /// The Virtual Router Identifier (VRID) field identifies the virtual router this packet is reporting status + /// for uint8_t vrId; - /** This specifies the sending VRRP router's priority for the virtual router */ + /// This specifies the sending VRRP router's priority for the virtual router uint8_t priority; - /** Specifies how many IPvX addresses are present in this Packet */ + /// Specifies how many IPvX addresses are present in this Packet uint8_t ipAddrCount; - /** This specifies authentication type(v2) or (Max) Advertisement interval (in seconds(v2) or - * centi-seconds(v3)). */ + /// This specifies authentication type(v2) or (Max) Advertisement interval (in seconds(v2) or + /// centi-seconds(v3)). uint16_t authTypeAdvInt; - /** This specifies checksum field that is used to detect data corruption in the VRRP message. - * VRRPv2 uses normal checksum algorithm, while VRRPv3 uses "pseudo-header" checksum algorithm. */ + /// This specifies checksum field that is used to detect data corruption in the VRRP message. + /// VRRPv2 uses normal checksum algorithm, while VRRPv3 uses "pseudo-header" checksum algorithm. uint16_t checksum; - /** This specifies one or more IPvX addresses that are associated with the virtual router. */ + /// This specifies one or more IPvX addresses that are associated with the virtual router. uint8_t* ipAddresses[]; }; static_assert(sizeof(vrrp_header) == 8, "vrrp_header size is not 8 bytes"); - /** - * @class VrrpLayer - * A base class for all VRRP (Virtual Router Redundancy Protocol) protocol classes. This is an abstract class and - * cannot be instantiated, only its child classes can be instantiated. The inherited classes represent the different - * versions of the protocol: VRRPv2 and VRRPv3 - */ + /// @class VrrpLayer + /// A base class for all VRRP (Virtual Router Redundancy Protocol) protocol classes. This is an abstract class and + /// cannot be instantiated, only its child classes can be instantiated. The inherited classes represent the + /// different versions of the protocol: VRRPv2 and VRRPv3 class VrrpLayer : public Layer { private: @@ -149,165 +139,119 @@ namespace pcpp void setAddressType(IPAddress::AddressType addressType); public: - /** - * VRRP message types - */ + /// VRRP message types enum VrrpType { - /** Unknown VRRP message */ + /// Unknown VRRP message VrrpType_Unknown = 0, - /** VRRP advertisement message */ + /// VRRP advertisement message VrrpType_Advertisement = 1 }; - /** - * An enum describing VRRP special priority values - */ + /// An enum describing VRRP special priority values enum VrrpPriority { - /** Default priority for a backup VRRP router (value of 100) */ + /// Default priority for a backup VRRP router (value of 100) Default, - /** Current Master has stopped participating in VRRP (value of 0) */ + /// Current Master has stopped participating in VRRP (value of 0) Stop, - /** This VRRP router owns the virtual router's IP address(es) (value of 255) */ + /// This VRRP router owns the virtual router's IP address(es) (value of 255) Owner, - /** Other priority */ + /// Other priority Other }; ~VrrpLayer() override = default; - /** - * @return The VRRP IP Address type - */ + /// @return The VRRP IP Address type IPAddress::AddressType getAddressType() const; - /** - * A static method that validates the input data - * @param[in] data VRRP raw data (byte stream) - * @param[in] dataLen The length of the byte stream - * @return One of the values ::VRRPv2, ::VRRPv3 according to detected VRRP version or ::UnknownProtocol if - * couldn't detect VRRP version - */ + /// A static method that validates the input data + /// @param[in] data VRRP raw data (byte stream) + /// @param[in] dataLen The length of the byte stream + /// @return One of the values ::VRRPv2, ::VRRPv3 according to detected VRRP version or ::UnknownProtocol if + /// couldn't detect VRRP version static ProtocolType getVersionFromData(uint8_t* data, size_t dataLen); - /** - * @return VRRP version of this message - */ + /// @return VRRP version of this message uint8_t getVersion() const; - /** - * @return VRRP type set in vrrp_header#type as VrrpLayer::VrrpType enum. - */ + /// @return VRRP type set in vrrp_header#type as VrrpLayer::VrrpType enum. VrrpType getType() const; - /** - * @return The virtual router id (vrId) in this message - */ + /// @return The virtual router id (vrId) in this message uint8_t getVirtualRouterID() const; - /** - * Set the virtual router ID - * @param virtualRouterID new ID to set - */ + /// Set the virtual router ID + /// @param virtualRouterID new ID to set void setVirtualRouterID(uint8_t virtualRouterID); - /** - * @return The priority in this message - */ + /// @return The priority in this message + uint8_t getPriority() const; - /** - * @return An enum describing VRRP priority - */ + /// @return An enum describing VRRP priority VrrpPriority getPriorityAsEnum() const; - /** - * Set the priority - * @param priority new priority to set - */ + /// Set the priority + /// @param priority new priority to set void setPriority(uint8_t priority); - /** - * @return VRRP checksum of this message - */ + /// @return VRRP checksum of this message uint16_t getChecksum() const; - /** - * Fill the checksum from header and data and write the result to @ref vrrp_header#checksum - */ + /// Fill the checksum from header and data and write the result to @ref vrrp_header#checksum void calculateAndSetChecksum(); - /** - * Calculate the checksum from header and data and write the result to @ref vrrp_header#checksum - * @return The checksum result - */ + /// Calculate the checksum from header and data and write the result to @ref vrrp_header#checksum + /// @return The checksum result virtual uint16_t calculateChecksum() const = 0; - /** - * @return True if VRRP checksum is correct - */ + /// @return True if VRRP checksum is correct bool isChecksumCorrect() const; - /** - * @return The count of VRRP virtual IP addresses in this message - */ + /// @return The count of VRRP virtual IP addresses in this message uint8_t getIPAddressesCount() const; - /** - * @return A list of the virtual IP addresses in this message - */ + /// @return A list of the virtual IP addresses in this message std::vector getIPAddresses() const; - /** - * Add a list of virtual IP addresses at a the end of the virtual IP address list. The - * vrrp_header#ipAddressCount field will be incremented accordingly - * @param[in] ipAddresses A vector containing all the virtual IP address - * @return true if added successfully, false otherwise - */ + /// Add a list of virtual IP addresses at a the end of the virtual IP address list. The + /// vrrp_header#ipAddressCount field will be incremented accordingly + /// @param[in] ipAddresses A vector containing all the virtual IP address + /// @return true if added successfully, false otherwise bool addIPAddresses(const std::vector& ipAddresses); - /** - * Add a virtual IP address at a the end of the virtual IP address list. The vrrp_header#ipAddressCount field - * will be incremented accordingly - * @param[in] ipAddress Virtual IP address to add - * @return true if add successfully, false otherwise - */ + /// Add a virtual IP address at a the end of the virtual IP address list. The vrrp_header#ipAddressCount field + /// will be incremented accordingly + /// @param[in] ipAddress Virtual IP address to add + /// @return true if add successfully, false otherwise bool addIPAddress(const IPAddress& ipAddress); - /** - * Remove a virtual IP address at a certain index. The vrrp_header#ipAddressCount field will be decremented - * accordingly - * @param[in] index The index of the virtual IP address to be removed - * @return True if virtual IP address was removed successfully or false otherwise. If false is returned an - * appropriate error message will be printed to log - */ + /// Remove a virtual IP address at a certain index. The vrrp_header#ipAddressCount field will be decremented + /// accordingly + /// @param[in] index The index of the virtual IP address to be removed + /// @return True if virtual IP address was removed successfully or false otherwise. If false is returned an + /// appropriate error message will be printed to log bool removeIPAddressAtIndex(int index); - /** - * Remove all virtual IP addresses in the message. The vrrp_header#ipAddressCount field will be set to 0 - * @return True if virtual IP addresses were cleared successfully or false otherwise. If false is returned an - * appropriate error message will be printed to log - */ + /// Remove all virtual IP addresses in the message. The vrrp_header#ipAddressCount field will be set to 0 + /// @return True if virtual IP addresses were cleared successfully or false otherwise. If false is returned an + /// appropriate error message will be printed to log bool removeAllIPAddresses(); // implement abstract methods - /** - * Does nothing for this layer (VRRP layer is always last) - */ + /// Does nothing for this layer (VRRP layer is always last) void parseNextLayer() override {} - /** - * Calculate the VRRP checksum - */ + /// Calculate the VRRP checksum void computeCalculateFields() override; - /** - * @return The message size in bytes which include the size of the basic header + the size of the IP address(es) - */ + /// @return The message size in bytes which include the size of the basic header + the size of the IP + /// address(es) size_t getHeaderLen() const override { return m_DataLen; @@ -321,11 +265,9 @@ namespace pcpp } }; - /** - * @class VrrpV2Layer - * Represents VRRPv2 (Virtual Router Redundancy Protocol ver 2) layer. This class represents all the different - * messages of VRRPv2 - */ + /// @class VrrpV2Layer + /// Represents VRRPv2 (Virtual Router Redundancy Protocol ver 2) layer. This class represents all the different + /// messages of VRRPv2 class VrrpV2Layer : public VrrpLayer { private: @@ -336,88 +278,67 @@ namespace pcpp }; public: - /** - * VRRP v2 authentication types - */ + /// VRRP v2 authentication types enum class VrrpAuthType : uint8_t { - /** No Authentication */ + /// No Authentication NoAuthentication = 0, - /** Simple Text Password */ + /// Simple Text Password SimpleTextPassword = 1, - /** IP Authentication Header */ + /// IP Authentication Header IPAuthenticationHeader = 2, - /** Cisco VRRP MD5 Authentication */ + /// Cisco VRRP MD5 Authentication MD5 = 3, - /** Other/Unknown Authentication Type */ + /// Other/Unknown Authentication Type Other = 4 }; - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in VrrpV2Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : VrrpLayer(data, dataLen, prevLayer, packet, VRRPv2, IPAddress::IPv4AddressType) {} - /** - * A constructor that allocates a new VRRP v2 layer - * @param virtualRouterId Virtual router ID - * @param priority Priority - * @param advInt Advertisement interval - * @param authType Authentication type (default value is 0) - */ + /// A constructor that allocates a new VRRP v2 layer + /// @param virtualRouterId Virtual router ID + /// @param priority Priority + /// @param advInt Advertisement interval + /// @param authType Authentication type (default value is 0) explicit VrrpV2Layer(uint8_t virtualRouterId, uint8_t priority, uint8_t advInt, uint8_t authType = 0); - /** - * A destructor for this layer (does nothing) - */ + /// A destructor for this layer (does nothing) ~VrrpV2Layer() override = default; - /** - * @return The VRRP advertisement interval in this message - */ + /// @return The VRRP advertisement interval in this message uint8_t getAdvInt() const; - /** - * Set advertisement interval value in this message - * @param advInt value to set - */ + /// Set advertisement interval value in this message + /// @param advInt value to set void setAdvInt(uint8_t advInt); - /** - * @return The authentication type in this message - */ + /// @return The authentication type in this message uint8_t getAuthType() const; - /** - * @return The VRRP authentication type as enum - */ + /// @return The VRRP authentication type as enum VrrpAuthType getAuthTypeAsEnum() const; - /** - * Set VRRP authentication type - * @param authType value to set - */ + /// Set VRRP authentication type + /// @param authType value to set void setAuthType(uint8_t authType); // implement abstract methods - /** - * Calculate the checksum from header and data and write the result to @ref vrrp_header#checksum - * @return The checksum result - */ + /// Calculate the checksum from header and data and write the result to @ref vrrp_header#checksum + /// @return The checksum result uint16_t calculateChecksum() const override; }; - /** - * @class VrrpV3Layer - * Represents VRRPv3 (Virtual Router Redundancy Protocol ver 3) layer. This class represents all the different - * messages of VRRP - */ + /// @class VrrpV3Layer + /// Represents VRRPv3 (Virtual Router Redundancy Protocol ver 3) layer. This class represents all the different + /// messages of VRRP class VrrpV3Layer : public VrrpLayer { private: @@ -427,49 +348,38 @@ namespace pcpp }; public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - * @param[in] addressType The IP address type to set for this layer - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in + /// @param[in] addressType The IP address type to set for this layer VrrpV3Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, IPAddress::AddressType addressType) : VrrpLayer(data, dataLen, prevLayer, packet, VRRPv3, addressType) {} - /** - * A constructor that allocates a new VRRPv3 - * @param addressType The IP address type to set for this layer - * @param virtualRouterId Virtual router ID - * @param priority Priority - * @param maxAdvInt Max advertisement interval - */ + /// A constructor that allocates a new VRRPv3 + /// @param addressType The IP address type to set for this layer + /// @param virtualRouterId Virtual router ID + /// @param priority Priority + /// @param maxAdvInt Max advertisement interval explicit VrrpV3Layer(IPAddress::AddressType addressType, uint8_t virtualRouterId, uint8_t priority, uint16_t maxAdvInt); - /** - * A destructor for this layer (does nothing) - */ + /// A destructor for this layer (does nothing) ~VrrpV3Layer() override = default; - /** - * @return The maximum advertisement interval in this message - */ + /// @return The maximum advertisement interval in this message uint16_t getMaxAdvInt() const; - /** - * Set the maximum advertisement interval value - * @param maxAdvInt Value to set - */ + /// Set the maximum advertisement interval value + /// @param maxAdvInt Value to set void setMaxAdvInt(uint16_t maxAdvInt); // implement abstract methods - /** - * Calculate the checksum from header and data and write the result to @ref vrrp_header#checksum - * @return The checksum result - */ + /// Calculate the checksum from header and data and write the result to @ref vrrp_header#checksum + /// @return The checksum result uint16_t calculateChecksum() const override; }; } // namespace pcpp diff --git a/Packet++/header/VxlanLayer.h b/Packet++/header/VxlanLayer.h index 12e099ea32..0924dc5b3e 100644 --- a/Packet++/header/VxlanLayer.h +++ b/Packet++/header/VxlanLayer.h @@ -4,123 +4,109 @@ /// @file +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct vxlan_header - * Represents a VXLAN protocol header - */ + /// @struct vxlan_header + /// Represents a VXLAN protocol header #pragma pack(push, 1) struct vxlan_header { #if (BYTE_ORDER == LITTLE_ENDIAN) - /** Reserved bits */ + /// Reserved bits uint16_t reserved6_8 : 3; - /** VNI present flag */ + /// VNI present flag uint16_t vniPresentFlag : 1; - /** Reserved bits */ + /// Reserved bits uint16_t reserved2_4 : 3; - /** GBP flag */ + /// GBP flag uint16_t gbpFlag : 1; - /** Reserved bits */ + /// Reserved bits uint16_t reserved14_16 : 3; - /** Policy applied flag */ + /// Policy applied flag uint16_t policyAppliedFlag : 1; - /** Reserved bits */ + /// Reserved bits uint16_t reserved11_12 : 2; - /** Don't learn flag */ + /// Don't learn flag uint16_t dontLearnFlag : 1; - /** Reserved bits */ + /// Reserved bits uint16_t reserved9 : 1; #else - /** Reserved bits */ + /// Reserved bits uint16_t reserved9 : 1; - /** Don't learn flag */ + /// Don't learn flag uint16_t dontLearnFlag : 1; - /** Reserved bits */ + /// Reserved bits uint16_t reserved11_12 : 2; - /** Policy applied flag */ + /// Policy applied flag uint16_t policyAppliedFlag : 1; - /** Reserved bits */ + /// Reserved bits uint16_t reserved14_16 : 3; - /** GBP flag */ + /// GBP flag uint16_t gbpFlag : 1; - /** Reserved bits */ + /// Reserved bits uint16_t reserved2_4 : 3; - /** VNI present flag */ + /// VNI present flag uint16_t vniPresentFlag : 1; - /** Reserved bits */ + /// Reserved bits uint16_t reserved6_8 : 3; #endif - /** Group Policy ID */ + /// Group Policy ID uint16_t groupPolicyID; - /** VXLAN Network ID (VNI) */ + /// VXLAN Network ID (VNI) uint32_t vni : 24; - /** Reserved bits */ + /// Reserved bits uint32_t pad : 8; }; #pragma pack(pop) static_assert(sizeof(vxlan_header) == 8, "vxlan_header size is not 8 bytes"); - /** - * @class VxlanLayer - * Represents a VXLAN (Virtual eXtensible Local Area Network) protocol layer - */ + /// @class VxlanLayer + /// Represents a VXLAN (Virtual eXtensible Local Area Network) protocol layer class VxlanLayer : public Layer { public: - /** A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in VxlanLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, VXLAN) {} - /** - * A constructor that creates a new VXLAN header and allocates the data. Note: the VNI present flag is set - * automatically - * @param[in] vni VNI (VXLAN Network ID) to set. Optional parameter (default is 0) - * @param[in] groupPolicyID Group Policy ID to set. Optional parameter (default is 0) - * @param[in] setGbpFlag Set GBP flag. Optional parameter (default is false) - * @param[in] setPolicyAppliedFlag Set Policy Applied flag. Optional parameter (default is false) - * @param[in] setDontLearnFlag Set Don't Learn flag. Optional parameter (default is false) - */ + /// A constructor that creates a new VXLAN header and allocates the data. Note: the VNI present flag is set + /// automatically + /// @param[in] vni VNI (VXLAN Network ID) to set. Optional parameter (default is 0) + /// @param[in] groupPolicyID Group Policy ID to set. Optional parameter (default is 0) + /// @param[in] setGbpFlag Set GBP flag. Optional parameter (default is false) + /// @param[in] setPolicyAppliedFlag Set Policy Applied flag. Optional parameter (default is false) + /// @param[in] setDontLearnFlag Set Don't Learn flag. Optional parameter (default is false) explicit VxlanLayer(uint32_t vni = 0, uint16_t groupPolicyID = 0, bool setGbpFlag = false, bool setPolicyAppliedFlag = false, bool setDontLearnFlag = false); ~VxlanLayer() override = default; - /** - * Get a pointer to the VXLAN header. Notice this points directly to the data, so every change will change the - * actual packet data - * @return A pointer to the vxlan_header - */ + /// Get a pointer to the VXLAN header. Notice this points directly to the data, so every change will change the + /// actual packet data + /// @return A pointer to the vxlan_header vxlan_header* getVxlanHeader() const { return reinterpret_cast(m_Data); } - /** - * @return The VXLAN Network ID (VNI) value - */ + /// @return The VXLAN Network ID (VNI) value uint32_t getVNI() const; - /** - * Set VXLAN Network ID (VNI) value - * @param[in] vni VNI value to set - */ + /// Set VXLAN Network ID (VNI) value + /// @param[in] vni VNI value to set void setVNI(uint32_t vni); - /** - * A static method that checks whether the port is considered as VxLAN - * @param[in] port The port number to be checked - */ + /// A static method that checks whether the port is considered as VxLAN + /// @param[in] port The port number to be checked static bool isVxlanPort(uint16_t port) { return port == 4789; @@ -128,22 +114,16 @@ namespace pcpp // implement abstract methods - /** - * Next layer for VXLAN is always Ethernet - */ + /// Next layer for VXLAN is always Ethernet void parseNextLayer() override; - /** - * @return Size of vxlan_header - */ + /// @return Size of vxlan_header size_t getHeaderLen() const override { return sizeof(vxlan_header); } - /** - * Does nothing for this layer - */ + /// Does nothing for this layer void computeCalculateFields() override {} @@ -154,5 +134,4 @@ namespace pcpp return OsiModelDataLinkLayer; } }; - } // namespace pcpp diff --git a/Packet++/header/WakeOnLanLayer.h b/Packet++/header/WakeOnLanLayer.h index 1e9eec506f..3e98acc46a 100644 --- a/Packet++/header/WakeOnLanLayer.h +++ b/Packet++/header/WakeOnLanLayer.h @@ -6,25 +6,19 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * Class for representing the Wake on LAN Layer - */ + /// Class for representing the Wake on LAN Layer class WakeOnLanLayer : public Layer { private: void init(uint16_t len); public: - /** - * @struct wol_header - * Wake On LAN protocol header - */ + /// @struct wol_header + /// Wake On LAN protocol header #pragma pack(push, 1) struct wol_header { @@ -36,117 +30,87 @@ namespace pcpp #pragma pack(pop) static_assert(sizeof(wol_header) == 102, "wol_header size is not 102 bytes"); - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in WakeOnLanLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, WakeOnLan) {} - /** - * Construct a new Wake On Lan Layer with provided values - * @param[in] targetAddr Target MAC address - */ + /// Construct a new Wake On Lan Layer with provided values + /// @param[in] targetAddr Target MAC address explicit WakeOnLanLayer(const pcpp::MacAddress& targetAddr); - /** - * Construct a new Wake On Lan Layer with provided values - * @param[in] targetAddr Target MAC address - * @param[in] password Password as array - * @param[in] len Length of the password array, length of the password should be less than 6 bytes - */ + /// Construct a new Wake On Lan Layer with provided values + /// @param[in] targetAddr Target MAC address + /// @param[in] password Password as array + /// @param[in] len Length of the password array, length of the password should be less than 6 bytes WakeOnLanLayer(const pcpp::MacAddress& targetAddr, uint8_t* password, uint8_t len); - /** - * Construct a new Wake On Lan Layer with provided values - * @param[in] targetAddr Target MAC address - * @param[in] password Password as MAC address - */ + /// Construct a new Wake On Lan Layer with provided values + /// @param[in] targetAddr Target MAC address + /// @param[in] password Password as MAC address WakeOnLanLayer(const pcpp::MacAddress& targetAddr, const pcpp::MacAddress& password); - /** - * Construct a new Wake On Lan Layer with provided values - * @param[in] targetAddr Target MAC address - * @param[in] password Password as IPv4 address - */ + /// Construct a new Wake On Lan Layer with provided values + /// @param[in] targetAddr Target MAC address + /// @param[in] password Password as IPv4 address WakeOnLanLayer(const pcpp::MacAddress& targetAddr, const IPv4Address& password); - /** - * Get a pointer to the Wake On LAN header. Notice this points directly to the data, so every change will change - * the actual packet data - * @return A pointer to the wol_header - */ + /// Get a pointer to the Wake On LAN header. Notice this points directly to the data, so every change will + /// change the actual packet data + /// @return A pointer to the wol_header inline wol_header* getWakeOnLanHeader() const { return reinterpret_cast(m_Data); } - /** - * Get the target MAC address of the command - * @return MAC address of the target - */ + /// Get the target MAC address of the command + /// @return MAC address of the target pcpp::MacAddress getTargetAddr() const; - /** - * Set the target MAC address - * @param[in] targetAddr MAC address of the target - */ + /// Set the target MAC address + /// @param[in] targetAddr MAC address of the target void setTargetAddr(const pcpp::MacAddress& targetAddr); - /** - * Get the password of the command - * @return Returns the password if exists, empty string otherwise - */ + /// Get the password of the command + /// @return Returns the password if exists, empty string otherwise std::string getPassword() const; - /** - * Set the password of the command - * @param[in] password Password as array - * @param[in] len Length of the password array, length of the password should be less than 6 bytes - * @return True if operation successful, false otherwise - */ + /// Set the password of the command + /// @param[in] password Password as array + /// @param[in] len Length of the password array, length of the password should be less than 6 bytes + /// @return True if operation successful, false otherwise bool setPassword(const uint8_t* password, uint8_t len); - /** - * Set the password of the command - * @param[in] password Password as string. Length of the password should be less than 6 bytes - * @return True if operation successful, false otherwise - */ + /// Set the password of the command + /// @param[in] password Password as string. Length of the password should be less than 6 bytes + /// @return True if operation successful, false otherwise bool setPassword(const std::string& password); - /** - * Set the password of the command - * @param[in] addr Password as MAC address - * @return True if operation successful, false otherwise - */ + /// Set the password of the command + /// @param[in] addr Password as MAC address + /// @return True if operation successful, false otherwise bool setPassword(const MacAddress& addr); - /** - * Set the password of the command - * @param addr Password as IPv4 address - * @return True if operation successful, false otherwise - */ + /// Set the password of the command + /// @param addr Password as IPv4 address + /// @return True if operation successful, false otherwise bool setPassword(const IPv4Address& addr); - /** - * A static method that checks whether the port is considered as Wake on LAN - * @param[in] port The port number to be checked - */ + /// A static method that checks whether the port is considered as Wake on LAN + /// @param[in] port The port number to be checked static bool isWakeOnLanPort(uint16_t port) { return (port == 0) || (port == 7) || (port == 9); } - /** - * A static method that takes a byte array and detects whether it is a Wake on LAN message - * @param[in] data A byte array - * @param[in] dataSize The byte array size (in bytes) - * @return True if the data is identified as Wake on LAN message - */ + /// A static method that takes a byte array and detects whether it is a Wake on LAN message + /// @param[in] data A byte array + /// @param[in] dataSize The byte array size (in bytes) + /// @return True if the data is identified as Wake on LAN message static bool isDataValid(const uint8_t* data, size_t dataSize); // overridden methods @@ -155,9 +119,7 @@ namespace pcpp void parseNextLayer() override {} - /** - * @return Get the size of the layer - */ + /// @return Get the size of the layer size_t getHeaderLen() const override { return m_DataLen; @@ -167,17 +129,13 @@ namespace pcpp void computeCalculateFields() override {} - /** - * @return The OSI layer level of Wake on LAN (Data Link Layer) - */ + /// @return The OSI layer level of Wake on LAN (Data Link Layer) OsiModelLayer getOsiModelLayer() const override { return OsiModelDataLinkLayer; } - /** - * @return Returns the protocol info as readable string - */ + /// @return Returns the protocol info as readable string std::string toString() const override; }; } // namespace pcpp diff --git a/Packet++/header/WireGuardLayer.h b/Packet++/header/WireGuardLayer.h index 99be143f22..0d59287e93 100644 --- a/Packet++/header/WireGuardLayer.h +++ b/Packet++/header/WireGuardLayer.h @@ -6,30 +6,23 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @class WireGuardLayer - * Represents a WireGuard protocol layer - */ + /// @class WireGuardLayer + /// Represents a WireGuard protocol layer class WireGuardLayer : public Layer { protected: #pragma pack(push, 1) - /** - * @struct wg_common_header - * Represents the common header for all WireGuard message types - */ + /// @struct wg_common_header + /// Represents the common header for all WireGuard message types struct wg_common_header { - /** Message type field */ + /// Message type field uint8_t messageType; - /** Reserved field (3 bytes) */ + /// Reserved field (3 bytes) uint8_t reserved[3]; }; #pragma pack(pop) @@ -43,153 +36,114 @@ namespace pcpp WireGuardLayer() = default; public: - /** - * WireGuard message types - */ + /// WireGuard message types enum class WireGuardMessageType { - /** Unknown Initiation message */ + /// Unknown Initiation message Unknown = 0, - /** Handshake Initiation message */ + /// Handshake Initiation message HandshakeInitiation = 1, - /** Handshake Response message */ + /// Handshake Response message HandshakeResponse = 2, - /** Cookie Reply message */ + /// Cookie Reply message CookieReply = 3, - /** Transport Data message */ + /// Transport Data message TransportData = 4 }; - /** - * Constructs a WireGuardLayer object. - * - * @param data Pointer to the raw data representing the WireGuard layer - * @param dataLen Length of the data - * @param prevLayer Pointer to the previous layer in the packet (if any) - * @param packet Pointer to the packet this layer belongs to - */ + /// Constructs a WireGuardLayer object. + /// @param data Pointer to the raw data representing the WireGuard layer + /// @param dataLen Length of the data + /// @param prevLayer Pointer to the previous layer in the packet (if any) + /// @param packet Pointer to the packet this layer belongs to WireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet, WireGuard) {} - /** - * Checks if the given port numbers are WireGuard ports. - * - * @param portSrc The source port number to check - * @param portDst The destination port number to check - * @return True if either port matches the WireGuard port (51820), false otherwise - */ + /// Checks if the given port numbers are WireGuard ports. + /// @param portSrc The source port number to check + /// @param portDst The destination port number to check + /// @return True if either port matches the WireGuard port (51820), false otherwise static bool isWireGuardPorts(uint16_t portSrc, uint16_t portDst) { return (portSrc == 51820 || portDst == 51820); } - /** - * Checks if the given data represents a WireGuard message. - * - * @param data Pointer to the raw data - * @param dataLen Length of the data - * @return True if the data starts with a valid WireGuard message type, false otherwise - */ + /// Checks if the given data represents a WireGuard message. + /// @param data Pointer to the raw data + /// @param dataLen Length of the data + /// @return True if the data starts with a valid WireGuard message type, false otherwise static bool isDataValid(const uint8_t* data, size_t dataLen); - /** - * Parses the raw data into a WireGuard layer. - * - * @param data Pointer to the raw data - * @param dataLen Length of the data - * @param prevLayer Pointer to the previous layer - * @param packet Pointer to the packet - * @return A pointer to the parsed WireGuardLayer, or nullptr if parsing fails - */ + /// Parses the raw data into a WireGuard layer. + /// @param data Pointer to the raw data + /// @param dataLen Length of the data + /// @param prevLayer Pointer to the previous layer + /// @param packet Pointer to the packet + /// @return A pointer to the parsed WireGuardLayer, or nullptr if parsing fails static WireGuardLayer* parseWireGuardLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); - /** - * @return String representation of the message type. - */ + /// @return String representation of the message type. std::string getMessageTypeAsString() const; - /** - * @return The message type as an unsigned 32-bit integer. - */ + /// @return The message type as an unsigned 32-bit integer. uint8_t getMessageType() const; - /** - * @return The reserved field as a 32-bit integer. - */ + /// @return The reserved field as a 32-bit integer. uint32_t getReserved() const; - /** - * @param reserved The reserved field to set as a An array containing the 3-byte. - */ + /// @param reserved The reserved field to set as a An array containing the 3-byte. void setReserved(const std::array& reserved); - /** - * Does nothing for this layer (WireGuard layer is always last) - */ + /// Does nothing for this layer (WireGuard layer is always last) void parseNextLayer() override {} - /** - * @return Size of the header in bytes. - */ + /// @return Size of the header in bytes. size_t getHeaderLen() const override; - /** - * No fields to compute or update, so this method is left empty. - */ + /// No fields to compute or update, so this method is left empty. void computeCalculateFields() override {} - /** - * Converts the WireGuard layer to a string representation. - * - * @return String representation of the WireGuard layer - */ + /// Converts the WireGuard layer to a string representation. + /// @return String representation of the WireGuard layer std::string toString() const override; - /** - * @return OSI model layer corresponding to the Network layer - */ + /// @return OSI model layer corresponding to the Network layer OsiModelLayer getOsiModelLayer() const override { return OsiModelNetworkLayer; } - /** - * @return The message type as a WireGuardMessageType enum value. - */ + /// @return The message type as a WireGuardMessageType enum value. virtual WireGuardMessageType getWireGuardMessageType() const { return WireGuardMessageType::Unknown; } }; - /** - * @class WireGuardHandshakeInitiationLayer - * Represents the Handshake Initiation message layer - */ + /// @class WireGuardHandshakeInitiationLayer + /// Represents the Handshake Initiation message layer class WireGuardHandshakeInitiationLayer : public WireGuardLayer { private: #pragma pack(push, 1) - /** - * @struct wg_handshake_initiation - * Represents the Handshake Initiation message structure - */ + /// @struct wg_handshake_initiation + /// Represents the Handshake Initiation message structure typedef struct wg_handshake_initiation : wg_common_header { - /** Sender index */ + /// Sender index uint32_t senderIndex; - /** Initiator's ephemeral public key */ + /// Initiator's ephemeral public key uint8_t initiatorEphemeral[32]; - /** Encrypted initiator's static key */ + /// Encrypted initiator's static key uint8_t encryptedInitiatorStatic[48]; - /** Encrypted timestamp */ + /// Encrypted timestamp uint8_t encryptedTimestamp[28]; - /** MAC1 field */ + /// MAC1 field uint8_t mac1[16]; - /** MAC2 field */ + /// MAC2 field uint8_t mac2[16]; } wg_handshake_initiation; #pragma pack(pop) @@ -199,127 +153,93 @@ namespace pcpp } public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in WireGuardHandshakeInitiationLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : WireGuardLayer(data, dataLen, prevLayer, packet) {} - /** - * A constructor that creates a new Handshake Initiation message - * @param[in] senderIndex The sender's index - * @param[in] initiatorEphemeral The initiator's ephemeral public key - * @param[in] encryptedInitiatorStatic The encrypted initiator's static key - * @param[in] encryptedTimestamp The encrypted timestamp - * @param[in] mac1 The MAC1 field - * @param[in] mac2 The MAC2 field - */ + /// A constructor that creates a new Handshake Initiation message + /// @param[in] senderIndex The sender's index + /// @param[in] initiatorEphemeral The initiator's ephemeral public key + /// @param[in] encryptedInitiatorStatic The encrypted initiator's static key + /// @param[in] encryptedTimestamp The encrypted timestamp + /// @param[in] mac1 The MAC1 field + /// @param[in] mac2 The MAC2 field WireGuardHandshakeInitiationLayer(uint32_t senderIndex, const uint8_t initiatorEphemeral[32], const uint8_t encryptedInitiatorStatic[48], const uint8_t encryptedTimestamp[28], const uint8_t mac1[16], const uint8_t mac2[16]); - /** - * @return The sender index as a 32-bit integer. - */ + /// @return The sender index as a 32-bit integer. uint32_t getSenderIndex() const; - /** - * @return An array containing the initiator's ephemeral public key. - */ + /// @return An array containing the initiator's ephemeral public key. std::array getInitiatorEphemeral() const; - /** - * @return An array containing the encrypted initiator's static key. - */ + /// @return An array containing the encrypted initiator's static key. std::array getEncryptedInitiatorStatic() const; - /** - * @return An array containing the encrypted timestamp. - */ + /// @return An array containing the encrypted timestamp. std::array getEncryptedTimestamp() const; - /** - * @return An array containing the MAC1 field. - */ + /// @return An array containing the MAC1 field. std::array getMac1() const; - /** - * @return An array containing the MAC2 field. - */ + /// @return An array containing the MAC2 field. std::array getMac2() const; - /** - * @param senderIndex A 32-bit integer representing the sender index. - */ + /// @param senderIndex A 32-bit integer representing the sender index. void setSenderIndex(uint32_t senderIndex); - /** - * @param initiatorEphemeral An array containing the 32-byte initiator ephemeral public key. - */ + /// @param initiatorEphemeral An array containing the 32-byte initiator ephemeral public key. void setInitiatorEphemeral(const std::array& initiatorEphemeral); - /** - * @param encryptedInitiatorStatic An array containing the 48-byte encrypted initiator's static key. - */ + /// @param encryptedInitiatorStatic An array containing the 48-byte encrypted initiator's static key. void setEncryptedInitiatorStatic(const std::array& encryptedInitiatorStatic); - /** - * @param encryptedTimestamp An array containing the 28-byte encrypted timestamp. - */ + /// @param encryptedTimestamp An array containing the 28-byte encrypted timestamp. void setEncryptedTimestamp(const std::array& encryptedTimestamp); - /** - * @param mac1 An array containing the 16-byte MAC1 field. - */ + /// @param mac1 An array containing the 16-byte MAC1 field. void setMac1(const std::array& mac1); - /** - * @param mac2 An array containing the 16-byte MAC2 field. - */ + /// @param mac2 An array containing the 16-byte MAC2 field. void setMac2(const std::array& mac2); // implement abstract methods - /** - * @return WireGuardMessageType enum value indicating HandshakeInitiation. - */ + /// @return WireGuardMessageType enum value indicating HandshakeInitiation. WireGuardMessageType getWireGuardMessageType() const override { return WireGuardMessageType::HandshakeInitiation; } }; - /** - * @class WireGuardHandshakeResponseLayer - * Represents a Handshake Response message - */ + /// @class WireGuardHandshakeResponseLayer + /// Represents a Handshake Response message class WireGuardHandshakeResponseLayer : public WireGuardLayer { private: #pragma pack(push, 1) - /** - * @struct wg_handshake_response - * Represents the Handshake Response message structure - */ + /// @struct wg_handshake_response + /// Represents the Handshake Response message structure typedef struct wg_handshake_response : wg_common_header { - /** Sender index */ + /// Sender index uint32_t senderIndex; - /** Receiver index */ + /// Receiver index uint32_t receiverIndex; - /** Responder's ephemeral public key */ + /// Responder's ephemeral public key uint8_t responderEphemeral[32]; - /** Encrypted empty field */ + /// Encrypted empty field uint8_t encryptedEmpty[16]; - /** MAC1 field */ + /// MAC1 field uint8_t mac1[16]; - /** MAC2 field */ + /// MAC2 field uint8_t mac2[16]; } wg_handshake_response; #pragma pack(pop) @@ -330,120 +250,86 @@ namespace pcpp } public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in WireGuardHandshakeResponseLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : WireGuardLayer(data, dataLen, prevLayer, packet) {} - /** - * A constructor that creates a new Handshake Response message - * @param[in] senderIndex The sender index - * @param[in] receiverIndex The receiver index - * @param[in] responderEphemeral The responder's ephemeral public key - * @param[in] encryptedEmpty The encrypted empty field - * @param[in] mac1 The MAC1 field - * @param[in] mac2 The MAC2 field - */ + /// A constructor that creates a new Handshake Response message + /// @param[in] senderIndex The sender index + /// @param[in] receiverIndex The receiver index + /// @param[in] responderEphemeral The responder's ephemeral public key + /// @param[in] encryptedEmpty The encrypted empty field + /// @param[in] mac1 The MAC1 field + /// @param[in] mac2 The MAC2 field WireGuardHandshakeResponseLayer(uint32_t senderIndex, uint32_t receiverIndex, const uint8_t responderEphemeral[32], const uint8_t encryptedEmpty[16], const uint8_t mac1[16], const uint8_t mac2[16]); - /** - * @return The sender index as a 32-bit unsigned integer. - */ + /// @return The sender index as a 32-bit unsigned integer. uint32_t getSenderIndex() const; - /** - * @return The receiver index as a 32-bit unsigned integer. - */ + /// @return The receiver index as a 32-bit unsigned integer. uint32_t getReceiverIndex() const; - /** - * @return The responder's ephemeral public key as an array of 32 bytes. - */ + /// @return The responder's ephemeral public key as an array of 32 bytes. std::array getResponderEphemeral() const; - /** - * @return The encrypted empty field as an array of 16 bytes. - */ + /// @return The encrypted empty field as an array of 16 bytes. std::array getEncryptedEmpty() const; - /** - * @return The MAC1 field as an array of 16 bytes. - */ + /// @return The MAC1 field as an array of 16 bytes. std::array getMac1() const; - /** - * @return The MAC2 field as an array of 16 bytes. - */ + /// @return The MAC2 field as an array of 16 bytes. std::array getMac2() const; - /** - * @param senderIndex A 32-bit unsigned integer representing the sender index. - */ + /// @param senderIndex A 32-bit unsigned integer representing the sender index. void setSenderIndex(uint32_t senderIndex); - /** - * @param receiverIndex A 32-bit unsigned integer representing the receiver index. - */ + /// @param receiverIndex A 32-bit unsigned integer representing the receiver index. void setReceiverIndex(uint32_t receiverIndex); - /** - * @param responderEphemeral An array containing the 32-byte responder ephemeral public key. - */ + /// @param responderEphemeral An array containing the 32-byte responder ephemeral public key. void setResponderEphemeral(const std::array& responderEphemeral); - /** - * @param encryptedEmpty An array containing the 16-byte encrypted empty field. - */ + /// @param encryptedEmpty An array containing the 16-byte encrypted empty field. void setEncryptedEmpty(const std::array& encryptedEmpty); - /** - * @param mac1 An array containing the 16-byte MAC1 field. - */ + /// @param mac1 An array containing the 16-byte MAC1 field. void setMac1(const std::array& mac1); - /** - * @param mac2 An array containing the 16-byte MAC2 field. - */ + /// @param mac2 An array containing the 16-byte MAC2 field. void setMac2(const std::array& mac2); // implement abstract methods - /** - * @return The message type as a WireGuardMessageType enum value. - */ + /// @return The message type as a WireGuardMessageType enum value. WireGuardMessageType getWireGuardMessageType() const override { return WireGuardMessageType::HandshakeResponse; } }; - /** - * @class WireGuardCookieReplyLayer - * Represents a Cookie Reply message - */ + /// @class WireGuardCookieReplyLayer + /// Represents a Cookie Reply message class WireGuardCookieReplyLayer : public WireGuardLayer { private: #pragma pack(push, 1) - /** - * @struct wg_cookie_reply - * Represents the Cookie Reply message structure - */ + /// @struct wg_cookie_reply + /// Represents the Cookie Reply message structure typedef struct wg_cookie_reply : wg_common_header { - /** Receiver index */ + /// Receiver index uint32_t receiverIndex; - /** Nonce field */ + /// Nonce field uint8_t nonce[24]; - /** Encrypted cookie */ + /// Encrypted cookie uint8_t encryptedCookie[32]; } wg_cookie_reply; #pragma pack(pop) @@ -454,85 +340,63 @@ namespace pcpp } public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in WireGuardCookieReplyLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : WireGuardLayer(data, dataLen, prevLayer, packet) {} - /** - * A constructor that creates a new Cookie Reply message - * @param[in] receiverIndex The receiver index - * @param[in] nonce The nonce field - * @param[in] encryptedCookie The encrypted cookie - */ + /// A constructor that creates a new Cookie Reply message + /// @param[in] receiverIndex The receiver index + /// @param[in] nonce The nonce field + /// @param[in] encryptedCookie The encrypted cookie WireGuardCookieReplyLayer(uint32_t receiverIndex, const uint8_t nonce[24], const uint8_t encryptedCookie[32]); - /** - * @return The receiver index as a 32-bit unsigned integer. - */ + /// @return The receiver index as a 32-bit unsigned integer. uint32_t getReceiverIndex() const; - /** - * @return The nonce field as an array of 24 bytes. - */ + /// @return The nonce field as an array of 24 bytes. std::array getNonce() const; - /** - * @return The encrypted cookie as an array of 32 bytes. - */ + /// @return The encrypted cookie as an array of 32 bytes. std::array getEncryptedCookie() const; - /** - * @param receiverIndex A 32-bit unsigned integer representing the receiver index. - */ + /// @param receiverIndex A 32-bit unsigned integer representing the receiver index. void setReceiverIndex(uint32_t receiverIndex); - /** - * @param nonce An array containing the 24-byte nonce field. - */ + /// @param nonce An array containing the 24-byte nonce field. void setNonce(const std::array& nonce); - /** - * @param encryptedCookie An array containing the 32-byte encrypted cookie. - */ + /// @param encryptedCookie An array containing the 32-byte encrypted cookie. void setEncryptedCookie(const std::array& encryptedCookie); // implement abstract methods - /** - * @return The message type as a WireGuardMessageType enum value. - */ + /// @return The message type as a WireGuardMessageType enum value. WireGuardMessageType getWireGuardMessageType() const override { return WireGuardMessageType::CookieReply; } }; - /** - * @class WireGuardTransportDataLayer - * Represents a Transport Data message - */ + /// @class WireGuardTransportDataLayer + /// Represents a Transport Data message class WireGuardTransportDataLayer : public WireGuardLayer { private: #pragma pack(push, 1) - /** - * @struct wg_transport_data - * Represents the Transport Data message structure - */ + /// @struct wg_transport_data + /// Represents the Transport Data message structure typedef struct wg_transport_data : wg_common_header { - /** Receiver index */ + /// Receiver index uint32_t receiverIndex; - /** Counter field */ + /// Counter field uint64_t counter; - /** Flexible array member for encrypted data */ + /// Flexible array member for encrypted data uint8_t encryptedData[0]; } wg_transport_data; #pragma pack(pop) @@ -543,63 +407,45 @@ namespace pcpp } public: - /** - * A constructor that creates the layer from an existing packet raw data - * @param[in] data A pointer to the raw data - * @param[in] dataLen Size of the data in bytes - * @param[in] prevLayer A pointer to the previous layer - * @param[in] packet A pointer to the Packet instance where layer will be stored in - */ + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] prevLayer A pointer to the previous layer + /// @param[in] packet A pointer to the Packet instance where layer will be stored in WireGuardTransportDataLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : WireGuardLayer(data, dataLen, prevLayer, packet) {} - /** - * A constructor that creates a new Transport Data message - * @param[in] receiverIndex The receiver index - * @param[in] counter The counter field - * @param[in] encryptedData The encrypted data - * @param[in] encryptedDataLen The length of the encrypted data - */ + /// A constructor that creates a new Transport Data message + /// @param[in] receiverIndex The receiver index + /// @param[in] counter The counter field + /// @param[in] encryptedData The encrypted data + /// @param[in] encryptedDataLen The length of the encrypted data WireGuardTransportDataLayer(uint32_t receiverIndex, uint64_t counter, const uint8_t* encryptedData, size_t encryptedDataLen); - /** - * @return The receiver index as a 32-bit unsigned integer. - */ + /// @return The receiver index as a 32-bit unsigned integer. uint32_t getReceiverIndex() const; - /** - * @return The counter field as a 64-bit unsigned integer. - */ + /// @return The counter field as a 64-bit unsigned integer. uint64_t getCounter() const; - /** - * @return A pointer to the encrypted data field. - */ + /// @return A pointer to the encrypted data field. const uint8_t* getEncryptedData() const; - /** - * @param receiverIndex A 32-bit unsigned integer representing the receiver index. - */ + /// @param receiverIndex A 32-bit unsigned integer representing the receiver index. void setReceiverIndex(uint32_t receiverIndex); - /** - * @param counter A 64-bit unsigned integer representing the counter field. - */ + /// @param counter A 64-bit unsigned integer representing the counter field. void setCounter(uint64_t counter); - /** - * @param encryptedData A pointer to the encrypted data. - * @param encryptedDataLen The length of the encrypted data. - */ + /// @param encryptedData A pointer to the encrypted data. + /// @param encryptedDataLen The length of the encrypted data. void setEncryptedData(const uint8_t* encryptedData, size_t encryptedDataLen); // implement abstract methods - /** - * @return The message type as a WireGuardMessageType enum value. - */ + /// @return The message type as a WireGuardMessageType enum value. WireGuardMessageType getWireGuardMessageType() const override { return WireGuardMessageType::TransportData; diff --git a/Packet++/src/EthDot3Layer.cpp b/Packet++/src/EthDot3Layer.cpp index 7091cd2eba..35d6d48b14 100644 --- a/Packet++/src/EthDot3Layer.cpp +++ b/Packet++/src/EthDot3Layer.cpp @@ -7,7 +7,6 @@ namespace pcpp { - EthDot3Layer::EthDot3Layer(const MacAddress& sourceMac, const MacAddress& destMac, uint16_t length) : Layer() { const size_t headerLen = sizeof(ether_dot3_header); @@ -45,14 +44,12 @@ namespace pcpp { if (dataLen >= sizeof(ether_dot3_header)) { - /** - * LSAPs: ... Such a length must, when considered as an - * unsigned integer, be less than 0x5DC or it could be mistaken as - * an Ethertype... - * - * From: https://tools.ietf.org/html/rfc5342#section-2.3.2.1 - * More: IEEE Std 802.3 Clause 3.2.6 - */ + // LSAPs: ... Such a length must, when considered as an + // unsigned integer, be less than 0x5DC or it could be mistaken as + // an Ethertype... + // + // From: https://tools.ietf.org/html/rfc5342#section-2.3.2.1 + // More: IEEE Std 802.3 Clause 3.2.6 return be16toh(*reinterpret_cast(data + 12)) <= static_cast(0x05DC); } else @@ -60,5 +57,4 @@ namespace pcpp return false; } } - } // namespace pcpp diff --git a/Packet++/src/EthLayer.cpp b/Packet++/src/EthLayer.cpp index 611bc10138..564e804196 100644 --- a/Packet++/src/EthLayer.cpp +++ b/Packet++/src/EthLayer.cpp @@ -13,7 +13,6 @@ namespace pcpp { - EthLayer::EthLayer(const MacAddress& sourceMac, const MacAddress& destMac, uint16_t etherType) : Layer() { const size_t headerLen = sizeof(ether_header); @@ -112,15 +111,13 @@ namespace pcpp { if (dataLen >= sizeof(ether_header)) { - /** - * Ethertypes: These are 16-bit identifiers appearing as the initial - * two octets after the MAC destination and source (or after a - * tag) which, when considered as an unsigned integer, are equal - * to or larger than 0x0600. - * - * From: https://tools.ietf.org/html/rfc5342#section-2.3.2.1 - * More: IEEE Std 802.3 Clause 3.2.6 - */ + // Ethertypes: These are 16-bit identifiers appearing as the initial + // two octets after the MAC destination and source (or after a + // tag) which, when considered as an unsigned integer, are equal + // to or larger than 0x0600. + // + // From: https://tools.ietf.org/html/rfc5342#section-2.3.2.1 + // More: IEEE Std 802.3 Clause 3.2.6 return be16toh(*reinterpret_cast(data + 12)) >= static_cast(0x0600); } else @@ -128,5 +125,4 @@ namespace pcpp return false; } } - } // namespace pcpp diff --git a/Packet++/src/HttpLayer.cpp b/Packet++/src/HttpLayer.cpp index ddb7a1181f..d3452b3aff 100644 --- a/Packet++/src/HttpLayer.cpp +++ b/Packet++/src/HttpLayer.cpp @@ -10,7 +10,6 @@ namespace pcpp { - // -------- Class HttpMessage ----------------- HeaderField* HttpMessage::addField(const std::string& fieldName, const std::string& fieldValue) @@ -542,10 +541,8 @@ namespace pcpp } } - /** - * @struct HttpResponseStatusCodeHash - * @brief The helper structure for hash HttpResponseStatusCode while using std::unordered_map - */ + /// @struct HttpResponseStatusCodeHash + /// @brief The helper structure for hash HttpResponseStatusCode while using std::unordered_map struct HttpResponseStatusCodeHash { size_t operator()(const HttpResponseStatusCode& status) const @@ -984,5 +981,4 @@ namespace pcpp } return versionAsEnum->second; } - } // namespace pcpp diff --git a/Packet++/src/IcmpV6Layer.cpp b/Packet++/src/IcmpV6Layer.cpp index 247eee2cca..000031845c 100644 --- a/Packet++/src/IcmpV6Layer.cpp +++ b/Packet++/src/IcmpV6Layer.cpp @@ -75,12 +75,11 @@ namespace pcpp void IcmpV6Layer::calculateChecksum() { - /* Pseudo header of 40 bytes which is composed as follows(in order): - - 16 bytes for the source address - - 16 bytes for the destination address - - 4 bytes big endian payload length(the same value as in the IPv6 header) - - 3 bytes zero + 1 byte nextheader( 58 decimal) big endian - */ + // Pseudo header of 40 bytes which is composed as follows(in order): + // - 16 bytes for the source address + // - 16 bytes for the destination address + // - 4 bytes big endian payload length(the same value as in the IPv6 header) + // - 3 bytes zero + 1 byte nextheader( 58 decimal) big endian getIcmpv6Header()->checksum = 0; @@ -103,7 +102,7 @@ namespace pcpp vec[1].buffer = pseudoHeader; vec[1].len = pseudoHeaderLen; - /* Calculate and write checksum */ + // Calculate and write checksum getIcmpv6Header()->checksum = htobe16(computeChecksum(vec, 2)); } } diff --git a/Packet++/src/IgmpLayer.cpp b/Packet++/src/IgmpLayer.cpp index fd23c97072..141b7351f5 100644 --- a/Packet++/src/IgmpLayer.cpp +++ b/Packet++/src/IgmpLayer.cpp @@ -7,10 +7,7 @@ namespace pcpp { - - /************* - * IgmpLayer - *************/ + // -------- Class IgmpLayer ----------------- IgmpLayer::IgmpLayer(IgmpType type, const IPv4Address& groupAddr, uint8_t maxResponseTime, ProtocolType igmpVer) { @@ -179,9 +176,7 @@ namespace pcpp return result; } - /************* - * IgmpV1Layer - *************/ + // -------- Class IgmpV1Layer ----------------- void IgmpV1Layer::computeCalculateFields() { @@ -191,9 +186,7 @@ namespace pcpp hdr->maxResponseTime = 0; } - /************* - * IgmpV2Layer - *************/ + // -------- Class IgmpV2Layer ----------------- void IgmpV2Layer::computeCalculateFields() { @@ -202,9 +195,7 @@ namespace pcpp hdr->checksum = htobe16(calculateChecksum()); } - /****************** - * IgmpV3QueryLayer - ******************/ + // -------- Class IgmpV3QueryLayer ----------------- IgmpV3QueryLayer::IgmpV3QueryLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : IgmpLayer(data, dataLen, prevLayer, packet, IGMPv3) @@ -335,9 +326,7 @@ namespace pcpp return true; } - /******************* - * IgmpV3ReportLayer - *******************/ + // -------- Class IgmpV3ReportLayer ----------------- uint16_t IgmpV3ReportLayer::getGroupRecordCount() const { @@ -505,9 +494,7 @@ namespace pcpp return true; } - /********************* - * igmpv3_group_record - *********************/ + // -------- Struct igmpv3_group_record ----------------- uint16_t igmpv3_group_record::getSourceAddressCount() const { @@ -532,5 +519,4 @@ namespace pcpp int headerLen = numOfRecords * sizeof(uint32_t) + sizeof(igmpv3_group_record); return (size_t)headerLen; } - } // namespace pcpp diff --git a/Packet++/src/NdpLayer.cpp b/Packet++/src/NdpLayer.cpp index c0448938a5..38da82ec9e 100644 --- a/Packet++/src/NdpLayer.cpp +++ b/Packet++/src/NdpLayer.cpp @@ -6,9 +6,7 @@ namespace pcpp { - /* - * NdpOptionBuilder - */ + // -------- Class NdpOptionBuilder ----------------- NdpOption NdpOptionBuilder::build() const { @@ -26,9 +24,7 @@ namespace pcpp return NdpOption(recordBuffer); } - /* - * NDPLayerBase - */ + // -------- Class NDPLayerBase ----------------- size_t NDPLayerBase::getNdpOptionCount() const { @@ -95,9 +91,7 @@ namespace pcpp return true; } - /* - * NDPNeighborSolicitationLayer - */ + // -------- Class NDPNeighborSolicitationLayer ----------------- NDPNeighborSolicitationLayer::NDPNeighborSolicitationLayer(uint8_t code, const IPv6Address& targetIP) { @@ -153,9 +147,7 @@ namespace pcpp return typeStream.str(); } - /* - * NDPNeighborAdvertisementLayer - */ + // -------- Class NDPNeighborAdvertisementLayer ----------------- NDPNeighborAdvertisementLayer::NDPNeighborAdvertisementLayer(uint8_t code, const IPv6Address& targetIP, const MacAddress& targetMac, bool routerFlag, diff --git a/Packet++/src/NflogLayer.cpp b/Packet++/src/NflogLayer.cpp index 2533a8d660..3dc6f94480 100644 --- a/Packet++/src/NflogLayer.cpp +++ b/Packet++/src/NflogLayer.cpp @@ -9,9 +9,9 @@ namespace pcpp { -/** IPv4 protocol */ +/// IPv4 protocol #define PCPP_WS_NFPROTO_IPV4 2 -/** IPv6 protocol */ +/// IPv6 protocol #define PCPP_WS_NFPROTO_IPV6 10 uint8_t NflogLayer::getFamily() diff --git a/Packet++/src/SSLHandshake.cpp b/Packet++/src/SSLHandshake.cpp index 0517c60b35..d7a0328517 100644 --- a/Packet++/src/SSLHandshake.cpp +++ b/Packet++/src/SSLHandshake.cpp @@ -685,10 +685,10 @@ namespace pcpp return result; } -#define A 54059 /* a prime */ -#define B 76963 /* another prime */ -#define C 86969 /* yet another prime */ -#define FIRST_HASH 37 /* also prime */ +#define A 54059 ///< a prime +#define B 76963 ///< another prime +#define C 86969 ///< yet another prime +#define FIRST_HASH 37 ///< also prime static uint32_t hashString(std::string str) { diff --git a/Packet++/src/SomeIpLayer.cpp b/Packet++/src/SomeIpLayer.cpp index 8149043e18..1c7bdec1c3 100644 --- a/Packet++/src/SomeIpLayer.cpp +++ b/Packet++/src/SomeIpLayer.cpp @@ -45,7 +45,7 @@ namespace pcpp Layer* SomeIpLayer::parseSomeIpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) { - /* Ideas taken from wireshark some ip dissector */ + // Ideas taken from wireshark some ip dissector const size_t headerLen = sizeof(someiphdr); if (dataLen < headerLen) return new PayloadLayer(data, dataLen, prevLayer, packet); diff --git a/Packet++/src/SomeIpSdLayer.cpp b/Packet++/src/SomeIpSdLayer.cpp index d7f2c9de76..33aa48e819 100644 --- a/Packet++/src/SomeIpSdLayer.cpp +++ b/Packet++/src/SomeIpSdLayer.cpp @@ -8,10 +8,8 @@ namespace pcpp { + // -------- Class SomeIpSdOption ----------------- - /* - * SomeIpSdOption - */ SomeIpSdOption::~SomeIpSdOption() { if (m_ShadowData != nullptr) @@ -41,13 +39,12 @@ namespace pcpp someipsdhdroptionsbase* optionHdr = getSomeIpSdOptionHeader(); optionHdr->type = static_cast(type); - /* Length field is excluding length field itself and uint8_t type field */ + // Length field is excluding length field itself and uint8_t type field optionHdr->length = htobe16((uint16_t)(m_DataLen - sizeof(optionHdr->length) - sizeof(optionHdr->type))); } - /* - * SomeIpSdIPv4Option - */ + // -------- Class SomeIpSdIPv4Option ----------------- + SomeIpSdIPv4Option::SomeIpSdIPv4Option(IPv4OptionType type, IPv4Address ipAddress, uint16_t port, SomeIpSdProtocolType l4Protocol) { @@ -100,9 +97,8 @@ namespace pcpp return hdr->l4Protocol; } - /* - * SomeIpSdIPv6Option - */ + // -------- Class SomeIpSdIPv6Option ----------------- + SomeIpSdIPv6Option::SomeIpSdIPv6Option(IPv6OptionType type, IPv6Address ipAddress, uint16_t port, SomeIpSdProtocolType l4Protocol) { @@ -155,9 +151,8 @@ namespace pcpp return hdr->l4Protocol; } - /* - * SomeIpSdConfigurationOption - */ + // -------- Class SomeIpSdConfigurationOption ----------------- + SomeIpSdConfigurationOption::SomeIpSdConfigurationOption(const std::string& configurationString) { m_DataLen = configurationString.length() + sizeof(someipsdhdroptionsbase); @@ -181,9 +176,8 @@ namespace pcpp be16toh(getSomeIpSdOptionHeader()->length) - 1); } - /* - * SomeIpSdLoadBalancingOption - */ + // -------- Class SomeIpSdLoadBalancingOption ----------------- + SomeIpSdLoadBalancingOption::SomeIpSdLoadBalancingOption(uint16_t priority, uint16_t weight) { m_DataLen = sizeof(someipsdhdroptionsload); @@ -215,9 +209,7 @@ namespace pcpp return be16toh(hdr->weight); } - /* - * SomeIpSdEntry - */ + // -------- Class SomeIpSdEntry ----------------- SomeIpSdEntry::SomeIpSdEntry(EntryType type, uint16_t serviceID, uint16_t instanceID, uint8_t majorVersion, uint32_t TTL, uint32_t minorVersion) @@ -435,9 +427,8 @@ namespace pcpp } } - /* - * SomeIpSdLayer - */ + // -------- Class SomeIpSdLayer ----------------- + SomeIpSdLayer::SomeIpSdLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : SomeIpLayer(data, dataLen, prevLayer, packet) { @@ -711,17 +702,15 @@ namespace pcpp bool SomeIpSdLayer::addOptionIndex(uint32_t indexEntry, uint32_t indexOffset) { - /* - The SOME/IP-SD protocol supports two option runs. Runs meaning that two different starting indices with - differing length can be provided. Of course, this only works if the indices in both runs are consecutive. - - So, indices like this would work: - 1 2 3 ; 7 8 - - What wouldn't work is this: - 1 2 3 ; 7 9 - 1 3 ; 7 8 - */ + // The SOME/IP-SD protocol supports two option runs. Runs meaning that two different starting indices with + // differing length can be provided. Of course, this only works if the indices in both runs are consecutive. + // + // So, indices like this would work: + // 1 2 3 ; 7 8 + // + // What wouldn't work is this: + // 1 2 3 ; 7 9 + // 1 3 ; 7 8 const size_t someipsdhdrentrySize = sizeof(SomeIpSdEntry::someipsdhdrentry); size_t offsetToAddAt = sizeof(someipsdhdr) + sizeof(uint32_t) + indexEntry * someipsdhdrentrySize; @@ -821,5 +810,4 @@ namespace pcpp { *((uint32_t*)(m_Data + sizeof(someipsdhdr) + sizeof(uint32_t) + getLenEntries())) = htobe32(length); } - } // namespace pcpp diff --git a/Packet++/src/VrrpLayer.cpp b/Packet++/src/VrrpLayer.cpp index 8f391155a7..d40ab6770d 100644 --- a/Packet++/src/VrrpLayer.cpp +++ b/Packet++/src/VrrpLayer.cpp @@ -11,9 +11,9 @@ namespace pcpp { -#define VRRP_PRIO_STOP 0 /* priority to stop */ -#define VRRP_PRIO_DEF 100 /* default priority */ -#define VRRP_PRIO_OWNER 255 /* priority of the ip owner */ +#define VRRP_PRIO_STOP 0 ///< priority to stop +#define VRRP_PRIO_DEF 100 ///< default priority +#define VRRP_PRIO_OWNER 255 ///< priority of the ip owner #define VRRP_PACKET_FIX_LEN 8 #define VRRP_PACKET_MAX_IP_ADDRESS_NUM 255 @@ -21,9 +21,7 @@ namespace pcpp #define VRRP_V2_VERSION 2 #define VRRP_V3_VERSION 3 - /************* - * VrrpLayer - *************/ + // -------- Class VrrpLayer ----------------- VrrpLayer::VrrpLayer(ProtocolType subProtocol, uint8_t virtualRouterId, uint8_t priority) { @@ -383,9 +381,7 @@ namespace pcpp m_AddressType = addressType; } - /************* - * Vrrpv2Layer - *************/ + // -------- Class Vrrpv2Layer ----------------- VrrpV2Layer::VrrpV2Layer(uint8_t virtualRouterId, uint8_t priority, uint8_t advInt, uint8_t authType) : VrrpLayer(VRRPv2, virtualRouterId, priority) @@ -451,9 +447,7 @@ namespace pcpp return checksum; } - /************* - * Vrrpv3Layer - *************/ + // -------- Class Vrrpv3Layer ----------------- VrrpV3Layer::VrrpV3Layer(IPAddress::AddressType addressType, uint8_t virtualRouterId, uint8_t priority, uint16_t maxAdvInt) From a9e823951efa2aca929f09b0f842f902ce28249d Mon Sep 17 00:00:00 2001 From: aled-ua Date: Sun, 2 Feb 2025 18:48:15 -0600 Subject: [PATCH 12/36] Fix Heap-buffer-overflow in __parse_options (#1678) * Fix vuln crash-7d18f37e1f05e0ff4aa4dfa2f67dd738340ad9cf * Move the heap overflow check before the allocation * Terminating immediately when overflow is found * Fix typo err --------- Co-authored-by: dataisland --- .../LightPcapNg/src/light_pcapng.c | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/3rdParty/LightPcapNg/LightPcapNg/src/light_pcapng.c b/3rdParty/LightPcapNg/LightPcapNg/src/light_pcapng.c index 1db448de7f..26423426f6 100644 --- a/3rdParty/LightPcapNg/LightPcapNg/src/light_pcapng.c +++ b/3rdParty/LightPcapNg/LightPcapNg/src/light_pcapng.c @@ -49,15 +49,28 @@ static struct _light_option *__parse_options(uint32_t **memory, const int32_t ma opt->custom_option_code = *local_memory++; opt->option_length = *local_memory++; + // PCPP patch + // Validate option_length + if (opt->option_length > max_len - 2 * sizeof(*local_memory)) { + free(opt); + return NULL; + } + // PCPP patch end + actual_length = (opt->option_length % alignment) == 0 ? opt->option_length : (opt->option_length / alignment + 1) * alignment; - if (actual_length > 0) { - opt->data = calloc(1, actual_length); - memcpy(opt->data, local_memory, actual_length); - local_memory += (sizeof(**memory) / sizeof(*local_memory)) * (actual_length / alignment); + // PCPP patch + // Validate actual_length + if (actual_length <= 0 || actual_length > max_len - 2 * sizeof(*local_memory)) { + free(opt); + return NULL; } + opt->data = calloc(1, actual_length); + memcpy(opt->data, local_memory, actual_length); + local_memory += (sizeof(**memory) / sizeof(*local_memory)) * (actual_length / alignment); + // PCPP patch end *memory = (uint32_t*)local_memory; remaining_size = max_len - actual_length - 2 * sizeof(*local_memory); From 80277e1bb7b0a48c5f3cf60f39208fa628e76d50 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 2 Feb 2025 18:54:45 -0800 Subject: [PATCH 13/36] Bump the pip-dependencies group across 1 directory with 2 updates (#1704) * Bump the pip-dependencies group across 1 directory with 2 updates Bumps the pip-dependencies group with 2 updates in the /Tests/ExamplesTest directory: [attrs](https://github.com/sponsors/hynek) and [pyparsing](https://github.com/pyparsing/pyparsing). Updates `attrs` from 24.3.0 to 25.1.0 - [Commits](https://github.com/sponsors/hynek/commits) Updates `pyparsing` from 3.1.4 to 3.2.1 - [Release notes](https://github.com/pyparsing/pyparsing/releases) - [Changelog](https://github.com/pyparsing/pyparsing/blob/master/CHANGES) - [Commits](https://github.com/pyparsing/pyparsing/compare/3.1.4...3.2.1) --- updated-dependencies: - dependency-name: attrs dependency-type: direct:production update-type: version-update:semver-major dependency-group: pip-dependencies - dependency-name: pyparsing dependency-type: direct:production update-type: version-update:semver-minor dependency-group: pip-dependencies ... Signed-off-by: dependabot[bot] * Update Tests/ExamplesTest/requirements.txt --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Liu, An-Chi --- Tests/ExamplesTest/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/ExamplesTest/requirements.txt b/Tests/ExamplesTest/requirements.txt index 1665e3e6ff..13ca7b596f 100644 --- a/Tests/ExamplesTest/requirements.txt +++ b/Tests/ExamplesTest/requirements.txt @@ -1,4 +1,4 @@ -attrs==24.3.0 +attrs==25.1.0 iniconfig==2.0.0 py==1.11.0 pyparsing==3.1.4 From 3292f14659fc3b7b8ac24bca8510f2bb5220b38c Mon Sep 17 00:00:00 2001 From: seladb Date: Mon, 3 Feb 2025 08:29:43 -0800 Subject: [PATCH 14/36] Auto OUI Database Update (#1700) Co-authored-by: GitHub --- 3rdParty/OUIDataset/PCPP_OUIDataset.json | 622 ++++++++++++++++++++++- 1 file changed, 606 insertions(+), 16 deletions(-) diff --git a/3rdParty/OUIDataset/PCPP_OUIDataset.json b/3rdParty/OUIDataset/PCPP_OUIDataset.json index 64cf364ca6..91b057420d 100644 --- a/3rdParty/OUIDataset/PCPP_OUIDataset.json +++ b/3rdParty/OUIDataset/PCPP_OUIDataset.json @@ -2514,7 +2514,7 @@ "vendor": "Routrek Networks Corporation" }, "838": { - "vendor": "Hitachi Kokusai Electric, Inc." + "vendor": "KOKUSAI DENKI Electric Inc." }, "839": { "vendor": "Intel Corporation" @@ -7596,7 +7596,7 @@ "vendor": "X.net 2000 GmbH" }, "2560": { - "vendor": "Mediatek Corp." + "vendor": "MediaTek Inc" }, "2561": { "vendor": "SOHOware, Inc." @@ -9333,7 +9333,7 @@ "vendor": "Routerboard.com" }, "3139": { - "vendor": "Ralink Technology, Corp." + "vendor": "MediaTek Inc" }, "3140": { "vendor": "Automated Interfaces, Inc." @@ -9825,7 +9825,7 @@ "vendor": "Fortinet, Inc." }, "3303": { - "vendor": "MediaTek Inc." + "vendor": "MediaTek Inc" }, "3304": { "vendor": "GuangZhou AnJuBao Co., Ltd" @@ -18075,7 +18075,7 @@ "vendor": "Hewlett Packard" }, "6053": { - "vendor": "Ralink Technology Corp" + "vendor": "MediaTek Inc" }, "6054": { "vendor": "Yosin Electronics Co., Ltd." @@ -31041,7 +31041,7 @@ "vendor": "Gk Computer" }, "16433": { - "vendor": "Hitachi Kokusai Electric, Inc." + "vendor": "KOKUSAI DENKI Electric Inc." }, "16434": { "vendor": "Digital Communications" @@ -35144,6 +35144,9 @@ "39634": { "vendor": "Cisco Systems, Inc" }, + "39688": { + "vendor": "Quectel Wireless Solutions Co.,Ltd." + }, "39938": { "vendor": "Hewlett Packard" }, @@ -35987,6 +35990,9 @@ "42431": { "vendor": "Cisco Systems, Inc" }, + "42539": { + "vendor": "Shanghai High-Flying Electronics Technology Co.,Ltd" + }, "42698": { "vendor": "Cisco Systems, Inc" }, @@ -36414,7 +36420,7 @@ "vendor": "Jasco Corporation" }, "49193": { - "vendor": "Nexans Deutschland GmbH - ANS" + "vendor": "Aginode Germany GmbH" }, "49194": { "vendor": "Ohkura Electric Co., Ltd." @@ -39032,6 +39038,9 @@ "262247": { "vendor": "Stanley Black & Decker" }, + "262254": { + "vendor": "Google, Inc." + }, "262561": { "vendor": "Fortinet, Inc." }, @@ -39716,6 +39725,9 @@ "305194": { "vendor": "Nokia Corporation" }, + "305242": { + "vendor": "Sz Dji Technology Co.,Ltd" + }, "305497": { "vendor": "New H3C Technologies Co., Ltd" }, @@ -41006,6 +41018,9 @@ "549269": { "vendor": "Rockwell Automation" }, + "549378": { + "vendor": "Apple, Inc." + }, "549478": { "vendor": "ASUSTek COMPUTER INC." }, @@ -41348,6 +41363,9 @@ "570911": { "vendor": "Espressif Inc." }, + "570967": { + "vendor": "AVM Audiovisuelles Marketing und Computersysteme GmbH" + }, "571192": { "vendor": "Lite-On Technogy Corp." }, @@ -42422,6 +42440,9 @@ "833417": { "vendor": "Honor Device Co., Ltd." }, + "833422": { + "vendor": "Huawei Device Co., Ltd." + }, "833557": { "vendor": "Espressif Inc." }, @@ -42692,6 +42713,9 @@ "847897": { "vendor": "Malgn Technology Co., Ltd." }, + "847995": { + "vendor": "Shenzhen Skyworth Digital Technology CO., Ltd" + }, "848052": { "vendor": "Globalsat International Technology Ltd" }, @@ -42827,6 +42851,9 @@ "1052031": { "vendor": "Netgear" }, + "1052044": { + "vendor": "Huawei Device Co., Ltd." + }, "1052203": { "vendor": "NEC CASIO Mobile Communications" }, @@ -43139,6 +43166,9 @@ "1069426": { "vendor": "Huawei Technologies Co.,Ltd" }, + "1069531": { + "vendor": "Espressif Inc." + }, "1069596": { "vendor": "Espressif Inc." }, @@ -44156,6 +44186,9 @@ "1323729": { "vendor": "Samsung Electronics Co.,Ltd" }, + "1323868": { + "vendor": "Espressif Inc." + }, "1323877": { "vendor": "TEM Mobile Limited" }, @@ -44411,6 +44444,9 @@ "1338890": { "vendor": "Private" }, + "1339479": { + "vendor": "Shennan Circuits Co.,Ltd" + }, "1340275": { "vendor": "Tubitak Uekae" }, @@ -44462,6 +44498,9 @@ "1343438": { "vendor": "Apple, Inc." }, + "1343519": { + "vendor": "Sunnovo International Limited" + }, "1343692": { "vendor": "Quectel Wireless Solutions Co.,Ltd." }, @@ -45233,6 +45272,9 @@ "1589412": { "vendor": "Shenzhen Trylong Smart Science and Technology Co., Ltd." }, + "1589699": { + "vendor": "GD Midea Air-Conditioning Equipment Co.,Ltd." + }, "1589758": { "vendor": "Digital 14" }, @@ -46523,6 +46565,9 @@ "1860020": { "vendor": "TP-Link Corporation Limited" }, + "1860031": { + "vendor": "Apple, Inc." + }, "1860222": { "vendor": "Huawei Technologies Co.,Ltd" }, @@ -46649,6 +46694,9 @@ "1865806": { "vendor": "China Mobile Iot Limited company" }, + "1866029": { + "vendor": "China Dragon Technology Limited" + }, "1866307": { "vendor": "vivo Mobile Communication Co., Ltd." }, @@ -46793,6 +46841,9 @@ "1874263": { "vendor": "Intel Corporate" }, + "1874395": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "1874982": { "vendor": "Zoovel Technologies" }, @@ -47210,6 +47261,9 @@ "2101104": { "vendor": "Foxtech" }, + "2101138": { + "vendor": "STK Technology Co., Ltd." + }, "2101370": { "vendor": "Gemtek Technology Co., Ltd." }, @@ -47366,6 +47420,9 @@ "2110150": { "vendor": "Apple, Inc." }, + "2110562": { + "vendor": "Xiaomi Communications Co Ltd" + }, "2110715": { "vendor": "Xiaomi Communications Co Ltd" }, @@ -48491,6 +48548,9 @@ "2376380": { "vendor": "Alinco,incorporated" }, + "2376419": { + "vendor": "Shenzhen Ai-Thinker Technology Co.,Ltd" + }, "2376674": { "vendor": "DASAN Network Solutions" }, @@ -48638,6 +48698,9 @@ "2385169": { "vendor": "AVM GmbH" }, + "2385377": { + "vendor": "Ciena Corporation" + }, "2385968": { "vendor": "Shenzhen Shokzhear Co., Ltd" }, @@ -48704,6 +48767,9 @@ "2389306": { "vendor": "Guangdong Oppo Mobile Telecommunications Corp.,Ltd" }, + "2389427": { + "vendor": "Guangdong Oppo Mobile Telecommunications Corp.,Ltd" + }, "2389500": { "vendor": "zte corporation" }, @@ -49019,6 +49085,9 @@ "2411211": { "vendor": "Fiberhome Telecommunication Technologies Co.,LTD" }, + "2411489": { + "vendor": "Ericsson AB" + }, "2411495": { "vendor": "MYK, Inc." }, @@ -49334,6 +49403,9 @@ "2624557": { "vendor": "Qualvision Technology Co.,Ltd" }, + "2624592": { + "vendor": "Intel Corporate" + }, "2624696": { "vendor": "Mikrosay Yazilim ve Elektronik A.S." }, @@ -49868,6 +49940,9 @@ "2658768": { "vendor": "Stage Tec Entwicklungsgesellschaft für professionelle Audiotechnik mbH" }, + "2658816": { + "vendor": "Intel Corporate" + }, "2658890": { "vendor": "Hewlett Packard" }, @@ -49886,6 +49961,9 @@ "2659503": { "vendor": "Samhwa Telecom" }, + "2659625": { + "vendor": "Intel Corporate" + }, "2660280": { "vendor": "myenergi Ltd" }, @@ -50414,6 +50492,9 @@ "2755512": { "vendor": "xFusion Digital Technologies Co., Limited" }, + "2758039": { + "vendor": "Cotsworks" + }, "2793451": { "vendor": "AVnu Alliance" }, @@ -50619,7 +50700,7 @@ "vendor": "LG Innotek" }, "2895176": { - "vendor": "bct electronic GesmbH" + "vendor": "Commend International GmbH" }, "2895898": { "vendor": "Technicolor CH USA Inc for Telus" @@ -51269,6 +51350,9 @@ "2932459": { "vendor": "Nothing Technology Limited" }, + "2932462": { + "vendor": "Nothing Technology Limited" + }, "2933331": { "vendor": "Apple, Inc." }, @@ -51368,6 +51452,9 @@ "2938879": { "vendor": "LANCOM Systems GmbH" }, + "2939054": { + "vendor": "Shenzhen SEI Robotics Co.,Ltd" + }, "2939102": { "vendor": "AltoBeam Inc." }, @@ -51491,6 +51578,9 @@ "2947746": { "vendor": "Alcatel-Lucent Enterprise" }, + "2947855": { + "vendor": "Sagemcom Broadband SAS" + }, "2948235": { "vendor": "Guangdong Oppo Mobile Telecommunications Corp.,Ltd" }, @@ -51557,6 +51647,9 @@ "3148224": { "vendor": "Motorola Mobility LLC, a Lenovo Company" }, + "3148445": { + "vendor": "Axino Solutions AG" + }, "3148485": { "vendor": "Ruio telecommunication technologies Co., Limited" }, @@ -51932,6 +52025,9 @@ "3171185": { "vendor": "Shenzhenshi Xinzhongxin Technology Co.Ltd" }, + "3171279": { + "vendor": "Zhejiang Cainiao Supply Chain Management Co., Ltd" + }, "3171306": { "vendor": "Juniper Networks" }, @@ -52280,6 +52376,9 @@ "3193264": { "vendor": "Intracom Asia Co., Ltd" }, + "3193667": { + "vendor": "Sixi Networks Co., Ltd" + }, "3193725": { "vendor": "OnePlus Technology (Shenzhen) Co., Ltd" }, @@ -52586,6 +52685,9 @@ "3408862": { "vendor": "Texas Instruments" }, + "3409239": { + "vendor": "vivo Mobile Communication Co., Ltd." + }, "3409743": { "vendor": "AccelStor, Inc." }, @@ -52862,6 +52964,9 @@ "3426541": { "vendor": "Dell Inc." }, + "3426641": { + "vendor": "Eliyan Corp." + }, "3426651": { "vendor": "Sagemcom Broadband SAS" }, @@ -53960,6 +54065,9 @@ "3679595": { "vendor": "Microsoft Mobile Oy" }, + "3679731": { + "vendor": "Mellanox Technologies, Inc." + }, "3679787": { "vendor": "UTran Technology" }, @@ -54264,7 +54372,7 @@ "vendor": "Euronda SpA" }, "3700685": { - "vendor": "KOKUSAI DENKI Electric Inc." + "vendor": "Kokusai Electric Corporation" }, "3700834": { "vendor": "Sony Corporation" @@ -54287,6 +54395,9 @@ "3701878": { "vendor": "Universal Global Scientific Industrial Co., Ltd." }, + "3702667": { + "vendor": "Apple, Inc." + }, "3703007": { "vendor": "Motorola Mobility LLC, a Lenovo Company" }, @@ -55298,6 +55409,9 @@ "3954139": { "vendor": "Shenzhen Skyworth Digital Technology CO., Ltd" }, + "3954286": { + "vendor": "Infinix mobility limited" + }, "3954481": { "vendor": "Cisco Systems, Inc" }, @@ -56216,6 +56330,9 @@ "4206193": { "vendor": "Texas Instruments" }, + "4206417": { + "vendor": "Maxtek Optoelectronics Ltd" + }, "4206470": { "vendor": "LG Innotek" }, @@ -56486,6 +56603,9 @@ "4223092": { "vendor": "Life Technology (China) Co., Ltd" }, + "4223141": { + "vendor": "Sichuan Tianyi Comheart Telecom Co.,LTD" + }, "4223221": { "vendor": "Apple, Inc." }, @@ -56519,6 +56639,9 @@ "4225141": { "vendor": "IMBEL - Industria de Material Belico do Brasil" }, + "4225297": { + "vendor": "Apple, Inc." + }, "4225298": { "vendor": "Texas Instruments" }, @@ -56783,6 +56906,9 @@ "4240333": { "vendor": "Chiyoda Electronics Co.,Ltd." }, + "4240378": { + "vendor": "Apple, Inc." + }, "4240380": { "vendor": "Logital Co. Limited" }, @@ -56894,6 +57020,9 @@ "4245289": { "vendor": "Sagemcom Broadband SAS" }, + "4245308": { + "vendor": "Intel Corporate" + }, "4245449": { "vendor": "Naviit Inc." }, @@ -57830,6 +57959,9 @@ "4499407": { "vendor": "Murata Manufacturing Co., Ltd." }, + "4499444": { + "vendor": "Apple, Inc." + }, "4499522": { "vendor": "Dell Inc." }, @@ -57884,6 +58016,9 @@ "4502402": { "vendor": "Kuang-chi Institute of Advanced Technology" }, + "4502469": { + "vendor": "Huawei Device Co., Ltd." + }, "4502546": { "vendor": "Sius Ag" }, @@ -58211,6 +58346,9 @@ "4521531": { "vendor": "Arcadyan Corporation" }, + "4521711": { + "vendor": "Guangdong Oppo Mobile Telecommunications Corp.,Ltd" + }, "4521914": { "vendor": "zte corporation" }, @@ -59318,6 +59456,9 @@ "4782460": { "vendor": "Fiberhome Telecommunication Technologies Co.,LTD" }, + "4782463": { + "vendor": "shenzhen Huaxufeng Technology Development Co.,Ltd" + }, "4783286": { "vendor": "Lava International(H.K) Limited" }, @@ -59435,6 +59576,9 @@ "4984302": { "vendor": "Jabil Circuit (Shanghai) Ltd." }, + "4984638": { + "vendor": "Intel Corporate" + }, "4984686": { "vendor": "Hon Hai Precision Ind. Co.,Ltd." }, @@ -59507,6 +59651,9 @@ "4988310": { "vendor": "Intel Corporate" }, + "4988806": { + "vendor": "Hangzhou Hikvision Digital Technology Co.,Ltd." + }, "4988876": { "vendor": "Huawei Technologies Co.,Ltd" }, @@ -59603,6 +59750,9 @@ "4994638": { "vendor": "Panasonic Connect Co., Ltd." }, + "4995038": { + "vendor": "AltoBeam Inc." + }, "4995285": { "vendor": "Mitac Computing Technology Corporation" }, @@ -60005,6 +60155,9 @@ "5020050": { "vendor": "vivo Mobile Communication Co., Ltd." }, + "5020136": { + "vendor": "Zhejiang Dahua Technologyco.,Ltd" + }, "5020515": { "vendor": "LG Innotek" }, @@ -60023,6 +60176,9 @@ "5021439": { "vendor": "Zyxel Communications Corporation" }, + "5021681": { + "vendor": "Apple, Inc." + }, "5021699": { "vendor": "Vitec" }, @@ -60230,6 +60386,9 @@ "5032531": { "vendor": "Skyera, Inc." }, + "5032597": { + "vendor": "Huawei Device Co., Ltd." + }, "5032949": { "vendor": "zte corporation" }, @@ -60239,6 +60398,9 @@ "5033066": { "vendor": "Micro-Star INTL CO., LTD." }, + "5033398": { + "vendor": "Apple, Inc." + }, "5033517": { "vendor": "Danlaw Inc" }, @@ -62375,6 +62537,9 @@ "5550595": { "vendor": "Pegatron Corporation" }, + "5550749": { + "vendor": "Shenzhen YOUHUA Technology Co., Ltd" + }, "5551468": { "vendor": "Xi'an NovaStar Tech Co., Ltd" }, @@ -62510,6 +62675,9 @@ "5561373": { "vendor": "Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd" }, + "5561577": { + "vendor": "Silicon Laboratories" + }, "5561679": { "vendor": "Samsung Electronics Co.,Ltd" }, @@ -62774,6 +62942,9 @@ "5773068": { "vendor": "Sony Corporation" }, + "5773410": { + "vendor": "Sony Corporation" + }, "5773816": { "vendor": "Commscope" }, @@ -63248,6 +63419,9 @@ "5805438": { "vendor": "Huawei Device Co., Ltd." }, + "5805578": { + "vendor": "LG Electronics" + }, "5805597": { "vendor": "Intel Corporate" }, @@ -63770,6 +63944,9 @@ "6033811": { "vendor": "Seal One AG" }, + "6034380": { + "vendor": "Apple, Inc." + }, "6034487": { "vendor": "Thyssenkrupp Aufzugswerke GmbH" }, @@ -64283,6 +64460,9 @@ "6064596": { "vendor": "Beijing Banner Electric Co.,Ltd" }, + "6064614": { + "vendor": "Richard Wolf GmbH" + }, "6064696": { "vendor": "Hewlett Packard" }, @@ -65135,6 +65315,9 @@ "6309325": { "vendor": "Sagemcom Broadband SAS" }, + "6309352": { + "vendor": "Arcadyan Corporation" + }, "6309398": { "vendor": "Xiamen Vann Intelligent Co., Ltd" }, @@ -65459,6 +65642,9 @@ "6328855": { "vendor": "Apple, Inc." }, + "6329032": { + "vendor": "Roku, Inc" + }, "6329077": { "vendor": "Commscope" }, @@ -66176,6 +66362,9 @@ "6565831": { "vendor": "New H3C Technologies Co., Ltd" }, + "6566197": { + "vendor": "Apple, Inc." + }, "6566224": { "vendor": "Hewlett Packard" }, @@ -66191,6 +66380,9 @@ "6566568": { "vendor": "Intel Corporate" }, + "6566826": { + "vendor": "Mellanox Technologies, Inc." + }, "6566875": { "vendor": "Texas Instruments" }, @@ -66767,6 +66959,9 @@ "6602603": { "vendor": "Huawei Technologies Co.,Ltd" }, + "6602778": { + "vendor": "Sichuan Tianyi Comheart Telecom Co.,LTD" + }, "6603134": { "vendor": "cheilelectric" }, @@ -67193,6 +67388,9 @@ "6824948": { "vendor": "Shenzhen Jinlangxin Technology Co., Ltd" }, + "6825437": { + "vendor": "Espressif Inc." + }, "6825508": { "vendor": "Ergatta" }, @@ -67361,6 +67559,9 @@ "6835080": { "vendor": "Galtronics Telemetry Inc." }, + "6835237": { + "vendor": "Huawei Device Co., Ltd." + }, "6835368": { "vendor": "Shenzhen Herotel Tech. Co., Ltd." }, @@ -67940,6 +68141,9 @@ "6871356": { "vendor": "Apple, Inc." }, + "6871414": { + "vendor": "EM Microelectronic" + }, "6871892": { "vendor": "Phicomm (Shanghai) Co., Ltd." }, @@ -68054,6 +68258,9 @@ "6877117": { "vendor": "Cisco Systems, Inc" }, + "6877148": { + "vendor": "Apple, Inc." + }, "6877293": { "vendor": "Along Industrial Co., Limited" }, @@ -68456,6 +68663,9 @@ "7094634": { "vendor": "Cisco Systems, Inc" }, + "7094750": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "7094955": { "vendor": "Subscriber Networks, Inc." }, @@ -68696,6 +68906,9 @@ "7108192": { "vendor": "Kyocera Corporation" }, + "7108801": { + "vendor": "Juniper Networks" + }, "7109048": { "vendor": "Texas Instruments" }, @@ -70517,6 +70730,9 @@ "7608586": { "vendor": "Samsung Electronics Co.,Ltd" }, + "7609145": { + "vendor": "Convey India Private Limited" + }, "7609266": { "vendor": "Apple, Inc." }, @@ -71519,6 +71735,9 @@ "7662015": { "vendor": "Huawei Technologies Co.,Ltd" }, + "7662040": { + "vendor": "Shanghai High-Flying Electronics Technology Co.,Ltd" + }, "7662138": { "vendor": "Tp-Link Technologies Co.,Ltd." }, @@ -71603,6 +71822,9 @@ "7666455": { "vendor": "Qingdao Goertek Horizons Tecnology Co.,LTD" }, + "7666757": { + "vendor": "Siemens Ag" + }, "7667104": { "vendor": "Compupal (Group) Corporation" }, @@ -71810,6 +72032,9 @@ "7873914": { "vendor": "LEO Innovation Lab" }, + "7873945": { + "vendor": "Huawei Device Co., Ltd." + }, "7873965": { "vendor": "Samsung Electronics Co.,Ltd" }, @@ -72098,6 +72323,9 @@ "7888546": { "vendor": "Sunitec Enterprise Co.,Ltd" }, + "7888588": { + "vendor": "Apple, Inc." + }, "7888680": { "vendor": "EM Microelectronic" }, @@ -72107,6 +72335,9 @@ "7888716": { "vendor": "Argox Information Co., Ltd." }, + "7888748": { + "vendor": "Arista Networks" + }, "7888987": { "vendor": "Tp-Link Technologies Co.,Ltd." }, @@ -72374,6 +72605,9 @@ "7905100": { "vendor": "HOERBIGER Elektronik GmbH" }, + "7905130": { + "vendor": "Ruckus Wireless" + }, "7905136": { "vendor": "Apple, Inc." }, @@ -72803,6 +73037,9 @@ "7927293": { "vendor": "Huawei Technologies Co.,Ltd" }, + "7927715": { + "vendor": "Opentext" + }, "7927742": { "vendor": "Samsung Electronics Co.,Ltd" }, @@ -73689,7 +73926,7 @@ "vendor": "Private" }, "8175479": { - "vendor": "Speedtech Corp. Jio" + "vendor": "Speedtech Corp." }, "8175496": { "vendor": "Mobilicom LTD" @@ -74066,6 +74303,9 @@ "8389912": { "vendor": "Huawei Technologies Co.,Ltd" }, + "8389919": { + "vendor": "Vizio, Inc" + }, "8389946": { "vendor": "CHeKT Inc." }, @@ -74108,6 +74348,9 @@ "8392228": { "vendor": "ForgetBox" }, + "8392361": { + "vendor": "TCL Yuxin Zhixing Technology (Huizhou) Co.,Ltd" + }, "8393439": { "vendor": "Shenzhen SuperElectron Technology Co.,Ltd." }, @@ -74618,6 +74861,9 @@ "8422390": { "vendor": "Apple, Inc." }, + "8422537": { + "vendor": "Intel Corporate" + }, "8422569": { "vendor": "oshkosh Corporation" }, @@ -74711,6 +74957,9 @@ "8428320": { "vendor": "Intel Corporate" }, + "8428901": { + "vendor": "FN-LINK TECHNOLOGY Ltd." + }, "8429467": { "vendor": "Sichuan AI-Link Technology Co., Ltd." }, @@ -75446,6 +75695,9 @@ "8671617": { "vendor": "Samsung Electronics Co.,Ltd" }, + "8671796": { + "vendor": "Juniper Networks" + }, "8672479": { "vendor": "Huawei Device Co., Ltd." }, @@ -76076,6 +76328,9 @@ "8709337": { "vendor": "Shenzhen NEED technology Ltd." }, + "8709509": { + "vendor": "EM Microelectronic" + }, "8709592": { "vendor": "Guangdong UNIPOE IoT Technology Co.,Ltd." }, @@ -76223,6 +76478,9 @@ "8913401": { "vendor": "Texas Instruments" }, + "8913508": { + "vendor": "Pascal Audio" + }, "8913740": { "vendor": "Weifang Goertek Electronics Co.,Ltd" }, @@ -76610,6 +76868,9 @@ "8937590": { "vendor": "Sparnex n.v." }, + "8937592": { + "vendor": "Sparnex n.v." + }, "8937818": { "vendor": "Siano Mobile Silicon Ltd." }, @@ -77180,6 +77441,9 @@ "8969593": { "vendor": "Voltaire" }, + "8969656": { + "vendor": "Huawei Device Co., Ltd." + }, "8969852": { "vendor": "Askey Computer Corp" }, @@ -77273,6 +77537,9 @@ "8976092": { "vendor": "Huawei Device Co., Ltd." }, + "8976149": { + "vendor": "Arista Networks" + }, "8976319": { "vendor": "vivo Mobile Communication Co., Ltd." }, @@ -78062,6 +78329,9 @@ "9217441": { "vendor": "Oregano Systems - Design & Consulting GmbH" }, + "9217487": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "9217759": { "vendor": "Tp-Link Technologies Co.,Ltd." }, @@ -78122,9 +78392,15 @@ "9222693": { "vendor": "Union Man Technology Co.,Ltd" }, + "9223479": { + "vendor": "Shenzhen Phaten Tech. LTD" + }, "9223716": { "vendor": "Tashang Semiconductor(Shanghai) Co., Ltd." }, + "9223791": { + "vendor": "Tianyi Telecom Terminals Company Limited" + }, "9223870": { "vendor": "Xiaomi Communications Co Ltd" }, @@ -78332,6 +78608,9 @@ "9236221": { "vendor": "zte corporation" }, + "9236703": { + "vendor": "Beijing Zhongyuan Yishang Technology Co.,LTD" + }, "9236754": { "vendor": "Motorola Mobility LLC, a Lenovo Company" }, @@ -78497,6 +78776,9 @@ "9441036": { "vendor": "Cloud Network Technology Singapore Pte. Ltd." }, + "9441367": { + "vendor": "Intel Corporate" + }, "9441685": { "vendor": "Amazon Technologies Inc." }, @@ -79442,6 +79724,9 @@ "9495728": { "vendor": "SHARP Corporation" }, + "9496131": { + "vendor": "Tesla,Inc." + }, "9496250": { "vendor": "ASUSTek COMPUTER INC." }, @@ -80408,6 +80693,9 @@ "9750251": { "vendor": "NOVA electronics, Inc." }, + "9750440": { + "vendor": "Jiangsu Huitong Group Co.,Ltd." + }, "9750447": { "vendor": "Raylios Technology" }, @@ -80591,6 +80879,9 @@ "9758698": { "vendor": "Huawei Technologies Co.,Ltd" }, + "9758707": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "9758792": { "vendor": "Fylde Micro Ltd" }, @@ -80981,6 +81272,9 @@ "9976719": { "vendor": "Intel Corporate" }, + "9976972": { + "vendor": "Apple, Inc." + }, "9977262": { "vendor": "Espressif Inc." }, @@ -81209,6 +81503,9 @@ "9992139": { "vendor": "Vorteks ED" }, + "9992149": { + "vendor": "WiZ" + }, "9992167": { "vendor": "Kaon Group Co., Ltd." }, @@ -81269,6 +81566,9 @@ "9996140": { "vendor": "Huawei Device Co., Ltd." }, + "9996512": { + "vendor": "Espressif Inc." + }, "9996580": { "vendor": "Texas Instruments" }, @@ -81341,6 +81641,9 @@ "10001495": { "vendor": "Huawei Technologies Co.,Ltd" }, + "10001721": { + "vendor": "China Mobile Group Device Co.,Ltd." + }, "10001757": { "vendor": "Vantiva USA LLC" }, @@ -82181,6 +82484,9 @@ "10246785": { "vendor": "Xiaomi Communications Co Ltd" }, + "10246794": { + "vendor": "Dji Baiwang Technology Co Ltd" + }, "10247062": { "vendor": "NMR Corporation" }, @@ -82736,6 +83042,9 @@ "10279371": { "vendor": "Lesira Manufacturing Pty Ltd" }, + "10279478": { + "vendor": "Tecno Mobile Limited" + }, "10279486": { "vendor": "Intel Corporate" }, @@ -83231,6 +83540,9 @@ "10504220": { "vendor": "Hewlett Packard" }, + "10504249": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "10504798": { "vendor": "Microsoft Corporation" }, @@ -83597,6 +83909,9 @@ "10525629": { "vendor": "Total Aviation Solutions Pty Ltd" }, + "10525986": { + "vendor": "Apple, Inc." + }, "10526086": { "vendor": "Alcatel-Lucent Shanghai Bell Co., Ltd" }, @@ -83678,6 +83993,9 @@ "10530146": { "vendor": "Huawei Technologies Co.,Ltd" }, + "10530207": { + "vendor": "ASUSTek COMPUTER INC." + }, "10530209": { "vendor": "JMR Electronics, Inc" }, @@ -83963,6 +84281,9 @@ "10546714": { "vendor": "Apple, Inc." }, + "10546926": { + "vendor": "Cig Shanghai Co Ltd" + }, "10547076": { "vendor": "Seine Image Int'l Co., Ltd" }, @@ -84080,6 +84401,9 @@ "10750197": { "vendor": "Sagemcom Broadband SAS" }, + "10750343": { + "vendor": "Apple, Inc." + }, "10750387": { "vendor": "Huawei Technologies Co.,Ltd" }, @@ -84332,6 +84656,9 @@ "10764859": { "vendor": "Intel Corporate" }, + "10765123": { + "vendor": "Huawei Device Co., Ltd." + }, "10765184": { "vendor": "Huawei Device Co., Ltd." }, @@ -84686,6 +85013,9 @@ "10787201": { "vendor": "FuJian Elite Power Tech CO.,LTD." }, + "10787240": { + "vendor": "eero inc." + }, "10787416": { "vendor": "Samsung Electronics Co.,Ltd" }, @@ -85076,6 +85406,9 @@ "10807715": { "vendor": "Honest Technology Co., Ltd" }, + "10807887": { + "vendor": "VusionGroup" + }, "10807950": { "vendor": "Extreme Networks Headquarters" }, @@ -85181,6 +85514,9 @@ "11011584": { "vendor": "Samsung Electronics Co.,Ltd" }, + "11012303": { + "vendor": "Vestel Elektronik San ve Tic. A.S." + }, "11012529": { "vendor": "Huawei Device Co., Ltd." }, @@ -85283,6 +85619,9 @@ "11020232": { "vendor": "Edgecore Americas Networking Corporation" }, + "11020616": { + "vendor": "TP-Link Systems Inc." + }, "11020620": { "vendor": "Precision Optical Transceivers, Inc." }, @@ -85298,6 +85637,9 @@ "11021261": { "vendor": "Huawei Technologies Co.,Ltd" }, + "11021269": { + "vendor": "Xiaomi Communications Co Ltd" + }, "11021270": { "vendor": "Shina System Co., Ltd" }, @@ -86519,6 +86861,9 @@ "11290058": { "vendor": "Guangdong Oppo Mobile Telecommunications Corp.,Ltd" }, + "11290095": { + "vendor": "Intel Corporate" + }, "11290395": { "vendor": "Huawei Device Co., Ltd." }, @@ -87689,6 +88034,9 @@ "11554579": { "vendor": "Dell Inc." }, + "11554620": { + "vendor": "Genuine Optics" + }, "11554726": { "vendor": "DongGuan Ramaxel Memory Technology" }, @@ -87728,6 +88076,9 @@ "11557444": { "vendor": "Fibocom Wireless Inc." }, + "11557499": { + "vendor": "Huawei Device Co., Ltd." + }, "11557594": { "vendor": "Hewlett Packard" }, @@ -88523,6 +88874,9 @@ "11800699": { "vendor": "Texas Instruments" }, + "11801380": { + "vendor": "Google, Inc." + }, "11801737": { "vendor": "Cisco Systems, Inc" }, @@ -88796,6 +89150,9 @@ "11819105": { "vendor": "CRemote, LLC" }, + "11819382": { + "vendor": "Apple, Inc." + }, "11820196": { "vendor": "Thing-talk Wireless Communication Technologies Corporation Limited" }, @@ -88916,6 +89273,9 @@ "11827953": { "vendor": "Hewlett Packard Enterprise" }, + "11827994": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "11828265": { "vendor": "Shenzhen Guzidi Technology Co.,Ltd" }, @@ -89762,6 +90122,9 @@ "12076249": { "vendor": "Apple, Inc." }, + "12076523": { + "vendor": "Apple, Inc." + }, "12076532": { "vendor": "New H3C Technologies Co., Ltd" }, @@ -90299,6 +90662,9 @@ "12107783": { "vendor": "tickIoT Inc." }, + "12107857": { + "vendor": "VusionGroup" + }, "12107877": { "vendor": "Universal Electronics, Inc." }, @@ -90356,6 +90722,9 @@ "12110633": { "vendor": "Dell Inc." }, + "12110739": { + "vendor": "Ic Boss.Com Tech Inc" + }, "12110943": { "vendor": "Shenzhen iComm Semiconductor CO.,LTD" }, @@ -90542,6 +90911,9 @@ "12121972": { "vendor": "Fiberhome Telecommunication Technologies Co.,LTD" }, + "12121973": { + "vendor": "Intel Corporate" + }, "12122152": { "vendor": "Changshu Gaoshida Optoelectronic Technology Co. Ltd." }, @@ -91229,6 +91601,9 @@ "12355024": { "vendor": "Sky Uk Limited" }, + "12355237": { + "vendor": "Cambridge Mobile Telematics, Inc." + }, "12355578": { "vendor": "Bose Corporation" }, @@ -91259,6 +91634,9 @@ "12356895": { "vendor": "Cisco Systems, Inc" }, + "12356990": { + "vendor": "Silicon Laboratories" + }, "12357690": { "vendor": "Robert Bosch GmbH" }, @@ -91289,6 +91667,9 @@ "12359649": { "vendor": "Broadcom Limited" }, + "12359721": { + "vendor": "vivo Mobile Communication Co., Ltd." + }, "12359817": { "vendor": "Fiberhome Telecommunication Technologies Co.,LTD" }, @@ -91517,6 +91898,9 @@ "12373375": { "vendor": "Huawei Device Co., Ltd." }, + "12373401": { + "vendor": "Intel Corporate" + }, "12373541": { "vendor": "Nintendo Co.,Ltd" }, @@ -91553,6 +91937,9 @@ "12375478": { "vendor": "d2d technologies" }, + "12375533": { + "vendor": "Sagemcom Broadband SAS" + }, "12375827": { "vendor": "Owl Labs" }, @@ -92516,12 +92903,18 @@ "12633866": { "vendor": "Ruckus Wireless" }, + "12634075": { + "vendor": "Apple, Inc." + }, "12634438": { "vendor": "Mitsuya Laboratories Inc." }, "12634486": { "vendor": "Shenzhen TINNO Mobile Technology Corp." }, + "12634505": { + "vendor": "Edgecore Americas Networking Corporation" + }, "12634595": { "vendor": "Tp-Link Technologies Co.,Ltd." }, @@ -92606,6 +92999,9 @@ "12639338": { "vendor": "Qingdao Eastsoft Communication Technology Co.,LTD" }, + "12639403": { + "vendor": "LG Innotek" + }, "12639447": { "vendor": "Huawei Device Co., Ltd." }, @@ -92741,6 +93137,9 @@ "12845229": { "vendor": "Advantech Technology (CHINA) Co., Ltd." }, + "12845237": { + "vendor": "HongKong Tenry Technology Co., Ltd." + }, "12845378": { "vendor": "MaxMedia Technology Limited" }, @@ -92813,6 +93212,9 @@ "12848709": { "vendor": "ACK Networks,Inc." }, + "12848904": { + "vendor": "Intel Corporate" + }, "12848905": { "vendor": "Hermes electronic GmbH" }, @@ -92897,6 +93299,9 @@ "12853704": { "vendor": "Kyocera Corporation" }, + "12853838": { + "vendor": "Telink Micro LLC" + }, "12854112": { "vendor": "Intel Corporate" }, @@ -93569,6 +93974,9 @@ "12891793": { "vendor": "Angel Robotics" }, + "12891991": { + "vendor": "Alpsalpine Co,.Ltd" + }, "12892340": { "vendor": "Huawei Technologies Co.,Ltd" }, @@ -93695,9 +94103,15 @@ "12899942": { "vendor": "Cisco Meraki" }, + "12900051": { + "vendor": "Dell Inc." + }, "12900152": { "vendor": "Huawei Device Co., Ltd." }, + "12900316": { + "vendor": "Zhejiang Weilai Jingling Artificial Intelligence Technology Co., Ltd." + }, "12900349": { "vendor": "Bouffalo Lab (Nanjing) Co., Ltd." }, @@ -93902,6 +94316,9 @@ "12910370": { "vendor": "Huawei Device Co., Ltd." }, + "12910489": { + "vendor": "Intel Corporate" + }, "13107332": { "vendor": "Cisco Systems, Inc" }, @@ -94817,6 +95234,9 @@ "13162628": { "vendor": "Universal Electronics, Inc." }, + "13162841": { + "vendor": "Motorola Mobility LLC, a Lenovo Company" + }, "13162962": { "vendor": "Hewlett Packard" }, @@ -96950,6 +97370,9 @@ "13681077": { "vendor": "Dell Inc." }, + "13681087": { + "vendor": "Xiaomi Communications Co Ltd" + }, "13681230": { "vendor": "Samsung Electronics Co.,Ltd" }, @@ -97286,6 +97709,9 @@ "13899617": { "vendor": "Xiaomi Communications Co Ltd" }, + "13900146": { + "vendor": "Hewlett Packard Enterprise" + }, "13900278": { "vendor": "NXP Semiconductor (Tianjin) LTD." }, @@ -97472,6 +97898,9 @@ "13910798": { "vendor": "Zhejiang Dahua Technology Co., Ltd." }, + "13910922": { + "vendor": "Beijing Xiaomi Mobile Software Co., Ltd" + }, "13910952": { "vendor": "Changzhou Haojie Electric Co., Ltd." }, @@ -97583,6 +98012,9 @@ "13916850": { "vendor": "Galleon Systems" }, + "13917009": { + "vendor": "Motorola Mobility LLC, a Lenovo Company" + }, "13917296": { "vendor": "Wi-Fi Alliance" }, @@ -97904,6 +98336,9 @@ "13931869": { "vendor": "zte corporation" }, + "13931918": { + "vendor": "Universal Electronics, Inc." + }, "13932255": { "vendor": "Sungjin C&T Co.,Ltd" }, @@ -97997,6 +98432,9 @@ "13937407": { "vendor": "Micro World" }, + "13937505": { + "vendor": "Intel Corporate" + }, "13937538": { "vendor": "Commscope" }, @@ -98480,6 +98918,9 @@ "14162131": { "vendor": "Juniper Networks" }, + "14162185": { + "vendor": "Wiwynn Technology Service Malaysia" + }, "14162298": { "vendor": "Nuheara Ltd" }, @@ -98526,7 +98967,7 @@ "vendor": "Avnet Silica" }, "14164960": { - "vendor": "Speedtech Corp. Jio" + "vendor": "Speedtech Corp." }, "14165111": { "vendor": "Universal Electric Corporation" @@ -100130,6 +100571,9 @@ "14455410": { "vendor": "Sagemcom Broadband SAS" }, + "14456166": { + "vendor": "Apple, Inc." + }, "14456364": { "vendor": "NST Audio Ltd" }, @@ -100175,6 +100619,9 @@ "14457938": { "vendor": "Sapphire Technology Limited." }, + "14458009": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "14458015": { "vendor": "Shenzhen YOUHUA Technology Co., Ltd" }, @@ -100889,6 +101336,9 @@ "14695515": { "vendor": "Shenzhen Jiaxinjie Electron Co.,Ltd" }, + "14695846": { + "vendor": "Taicang T&W Electronics" + }, "14696004": { "vendor": "Broadcom" }, @@ -101291,6 +101741,9 @@ "14721964": { "vendor": "Huawei Technologies Co.,Ltd" }, + "14722200": { + "vendor": "Shenzhen Orfa Tech Co.,Ltd" + }, "14722313": { "vendor": "Bitmain Technologies Inc" }, @@ -101408,6 +101861,9 @@ "14728707": { "vendor": "Lite-On Network Communication (Dongguan) Limited" }, + "14729138": { + "vendor": "Apple, Inc." + }, "14729425": { "vendor": "CK Telecom (Shenzhen) Limited" }, @@ -101519,6 +101975,9 @@ "14734106": { "vendor": "EQUES Technology Co., Limited" }, + "14734178": { + "vendor": "TP-Link Systems Inc." + }, "14734260": { "vendor": "Cisco Meraki" }, @@ -102119,6 +102578,9 @@ "14968491": { "vendor": "zte corporation" }, + "14968549": { + "vendor": "Nanjing Qinheng Microelectronics Co., Ltd." + }, "14968606": { "vendor": "SHEN ZHEN NUO XIN CHENG TECHNOLOGY co., Ltd." }, @@ -102230,6 +102692,9 @@ "14975692": { "vendor": "Jumptronic GmbH" }, + "14975743": { + "vendor": "Ecliptic Enterprises Corp" + }, "14975782": { "vendor": "Huawei Technologies Co.,Ltd" }, @@ -102596,6 +103061,9 @@ "15000172": { "vendor": "Guangdong Oppo Mobile Telecommunications Corp.,Ltd" }, + "15000381": { + "vendor": "Qingdao Intelligent&Precise Electronics Co.,Ltd." + }, "15000585": { "vendor": "Leifheit Ag" }, @@ -103004,6 +103472,9 @@ "15222155": { "vendor": "MitraStar Technology Corp." }, + "15222251": { + "vendor": "Kohler Ventures, Inc." + }, "15222567": { "vendor": "Quectel Wireless Solutions Co.,Ltd." }, @@ -104126,6 +104597,9 @@ "15479149": { "vendor": "Hansgrohe" }, + "15480114": { + "vendor": "Tactrix Inc." + }, "15480141": { "vendor": "Wingtech Mobile Communications Co.,Ltd" }, @@ -105302,6 +105776,9 @@ "15752059": { "vendor": "Samsung Electronics Co.,Ltd" }, + "15752206": { + "vendor": "Huawei Device Co., Ltd." + }, "15752217": { "vendor": "Hewlett Packard Enterprise" }, @@ -105929,6 +106406,9 @@ "15790082": { "vendor": "Hon Hai Precision Ind. Co.,Ltd." }, + "15790185": { + "vendor": "Private" + }, "15790223": { "vendor": "Nextek Solutions Pte Ltd" }, @@ -106469,6 +106949,9 @@ "16017197": { "vendor": "ShenZhen Topstar Technology Company" }, + "16017410": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "16017730": { "vendor": "Askey Computer Corp" }, @@ -106598,6 +107081,9 @@ "16025541": { "vendor": "Huawei Device Co., Ltd." }, + "16025880": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "16026418": { "vendor": "Xiaomi Communications Co Ltd" }, @@ -107201,6 +107687,9 @@ "16257171": { "vendor": "Apple, Inc." }, + "16257184": { + "vendor": "Xtreme Testek Inc." + }, "16257800": { "vendor": "Nokia" }, @@ -107414,6 +107903,9 @@ "16268622": { "vendor": "Softlink Automation System Co., Ltd" }, + "16268742": { + "vendor": "AzureWave Technology Inc." + }, "16268799": { "vendor": "Huawei Technologies Co.,Ltd" }, @@ -108572,6 +109064,9 @@ "16524069": { "vendor": "EosTek (Shenzhen) Co., Ltd." }, + "16524237": { + "vendor": "Shenzhen Bilian Electronic Co.,Ltd" + }, "16524607": { "vendor": "Apple, Inc." }, @@ -108818,6 +109313,9 @@ "16538141": { "vendor": "Hitron Technologies. Inc" }, + "16538332": { + "vendor": "Keenetic Limited" + }, "16538404": { "vendor": "Weibel Scientific A/S" }, @@ -109028,6 +109526,9 @@ "16552535": { "vendor": "Renesas Electronics (Penang) Sdn. Bhd." }, + "16552733": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "16552811": { "vendor": "Samsung Electronics Co.,Ltd" }, @@ -109196,6 +109697,9 @@ "16561031": { "vendor": "Leapmotor (Jinhua) New Energy Vehicle Parts Technology Co., Ltd." }, + "16561066": { + "vendor": "Intel Corporate" + }, "16561084": { "vendor": "Intel Corporate" }, @@ -110219,6 +110723,31 @@ } ] }, + "1599126": { + "vendor": "", + "maskedFilters": [ + { + "mask": 28, + "vendors": { + "26828882313216": "Annapurna labs", + "26828883361792": "Turtle AV", + "26828884410368": "Nanjin KW technology Co.,Ltd.", + "26828885458944": "Cheersu(Shenzhen) Technology Co., Ltd", + "26828886507520": "Akteena Inc", + "26828887556096": "Wuhan Precise Electronics Co.,Ltd.", + "26828888604672": "Shenzhen Safecuit Photonic Technology Co., Ltd", + "26828889653248": "Shandong Hummingbird Internet of Things Technology Co., Ltd", + "26828890701824": "Xunmu Information Technology(Shanghai) Co.,Ltd.", + "26828891750400": "Coocaa Network Technology Co.,Ltd.", + "26828892798976": "Bipai Electronic Technology(Dongguan)Co.,Ltd", + "26828893847552": "Hunan Songben Information Co., Ltd", + "26828894896128": "Kee Tat Innovative Technology Holdings Limited", + "26828895944704": "Viva Co.,Ltd.", + "26828896993280": "Indusenz AS" + } + } + ] + }, "1602786": { "vendor": "", "maskedFilters": [ @@ -111183,7 +111712,7 @@ "48829970776064": "Katek Se", "48829971824640": "Abode Systems Inc", "48829972873216": "Sunsa, Inc", - "48829973921792": "Speedtech Corp. Jio", + "48829973921792": "Speedtech Corp.", "48829974970368": "LG Electronics Inc.", "48829976018944": "Carnegie Robotics", "48829977067520": "Shenzhen Gigalight Technology Co., Ltd", @@ -111232,7 +111761,7 @@ "vendors": { "49221650612224": "Shenzhen Syeconmax Technology Co. Ltd", "49221651660800": "Joyoful", - "49221652709376": "Falcon V Systems S. A.", + "49221652709376": "Vecima Networks Inc.", "49221653757952": "somon", "49221654806528": "Beijing Siling Robot Technology Co.,Ltd", "49221655855104": "Mohan Electronics And Systems (Optivision)", @@ -112856,8 +113385,12 @@ { "mask": 28, "vendors": { + "96910501216256": "Shenzhen Huasifei Technology Co., Ltd", + "96910502264832": "Lens Technology (Xiangtan) Co.,Ltd", "96910503313408": "Great Wall Power Supply Technology Co., Ltd.", "96910504361984": "SHSYSTEM.Co.,LTD", + "96910505410560": "Shenzhen C & D Electronics Co., Ltd.", + "96910506459136": "Shenzhen Zhixuan Network Technology Co., Ltd.", "96910507507712": "Next Vision", "96910508556288": "Shenzhen MinDe Electronics Technology Ltd.", "96910509604864": "Wuhan Rayoptek Co.,Ltd", @@ -112865,7 +113398,8 @@ "96910511702016": "Hangzhou Xindatong Communication Technology Co.,Ltd.", "96910512750592": "Annapurna labs", "96910513799168": "Yuyao Sunny Optical Intelligence Technology Co., Ltd", - "96910514847744": "New Energy Technology Co.,Ltd" + "96910514847744": "New Energy Technology Co.,Ltd", + "96910515896320": "Broadradio International Pte.Ltd." } } ] @@ -116503,6 +117037,31 @@ } ] }, + "12378081": { + "vendor": "", + "maskedFilters": [ + { + "mask": 28, + "vendors": { + "207669738602496": "Shenzhen Galaxy Century Information Technology Co.,Ltd", + "207669739651072": "Shenzhen Valley Ventures Co.,Ltd.", + "207669740699648": "Shanghai Zhuoyu Communication Technology Co., Ltd", + "207669741748224": "System Industrie Electronic GmbH", + "207669742796800": "Ochno AB", + "207669743845376": "Enli Inc.", + "207669744893952": "D3 Technical Partners, LLC", + "207669745942528": "Databridge Dynamic", + "207669746991104": "Cortex Systems", + "207669748039680": "Annapurna labs", + "207669749088256": "Building Automation Products Inc.", + "207669750136832": "Hi-Target Surveying Instrument Co.,Ltd", + "207669751185408": "XY Sense, Inc.", + "207669752233984": "Ugpa Llc", + "207669753282560": "Clairvoyant Technology Inc." + } + } + ] + }, "12591857": { "vendor": "", "maskedFilters": [ @@ -116592,7 +117151,7 @@ "211670371663872": "Viper Design, LLC", "211670372712448": "Beijing Cloud Fly Technology Development Co.Ltd", "211670373761024": "Fuzhou Fdlinker Technology Co.,LTD", - "211670374809600": "ista International GmbH", + "211670374809600": "Ista SE", "211670375858176": "Shenzhen Pay Device Technology Co., Ltd.", "211670376906752": "Shanghai Charmhope Information Technology Co.,Ltd.", "211670377955328": "Suzhou Siheng Science and Technology Ltd.", @@ -127868,6 +128427,7 @@ "154066450345984": "Tiama", "154066450350080": "Signatrol Ltd", "154066450362368": "InfraChen Technology Co., Ltd.", + "154066450370560": "Solace Systems Inc.", "154066450374656": "Bnb", "154066450378752": "Aurora Communication Technologies Corp.", "154066450382848": "Active Research Limited", @@ -128041,6 +128601,7 @@ "154066451881984": "Jide Car Rastreamento e Monitoramento LTDA", "154066451898368": "Monnit Corporation", "154066451910656": "Marson Technology Co., Ltd.", + "154066451927040": "Shekel Scales 2008 Ltd", "154066451943424": "Mokila Networks Pvt Ltd", "154066451955712": "HuiTong intelligence Company", "154066451963904": "Giordano Controls Spa", @@ -128076,10 +128637,12 @@ "154066452217856": "Heitec Ag", "154066452221952": "Nvp Teco Ltd", "154066452242432": "i2s", + "154066452250624": "Vision Systems Safety Tech", "154066452254720": "Craft4 Digital GmbH", "154066452258816": "Arcopie", "154066452267008": "Sakura Seiki Co.,Ltd.", "154066452271104": "AVA Monitoring AB", + "154066452287488": "Jiangsu Ruidong Electric Power Technology Co.,Ltd", "154066452291584": "Gogo Business Aviation", "154066452295680": "Landis+Gyr Equipamentos de Medição Ltda", "154066452299776": "nanoTRONIX Computing Inc.", @@ -128099,6 +128662,7 @@ "154066452385792": "Elbit Systems of America, LLC", "154066452398080": "Dco Systems Ltd", "154066452418560": "U -Mei-Dah Int'L Enterprise Co.,Ltd.", + "154066452430848": "Sonel S.A.", "154066452439040": "Stercom Power Solutions GmbH", "154066452447232": "Veinland GmbH", "154066452459520": "Chakra Technology Ltd", @@ -128148,6 +128712,7 @@ "154066452795392": "Flextronics International Kft", "154066452799488": "Tangent Design Engineering", "154066452803584": "East Photonics", + "154066452819968": "Sb-Group Ltd", "154066452824064": "Cedel BV", "154066452832256": "Potter Electric Signal Company", "154066452836352": "Bacancy Systems LLP", @@ -128268,6 +128833,7 @@ "154066453692416": "Ruichuangte", "154066453700608": "Chipscape Security Systems", "154066453716992": "BnB Information Technology", + "154066453737472": "Cambrian Works, Inc.", "154066453741568": "Actelser S.L.", "154066453753856": "Mitsubishi Electric India Pvt. Ltd.", "154066453762048": "Yu Yan System Technology Co., Ltd.", @@ -128324,6 +128890,7 @@ "154066454204416": "Ixorigue Technologies Sl", "154066454208512": "Intamsys Technology Co.Ltd", "154066454224896": "Pharsighted LLC", + "154066454249472": "Canfield Scientific Inc", "154066454257664": "Surge Networks, Inc.", "154066454265856": "Audiobyte S.R.L.", "154066454269952": "Alpine Quantum Technologies GmbH", @@ -128366,6 +128933,7 @@ "154066454573056": "Smart Monitoring Innovations Private Limited", "154066454581248": "Clock-O-Matic", "154066454585344": "Laser Imagineering Vertriebs GmbH", + "154066454593536": "Innovative Industries", "154066454605824": "SBS SpA", "154066454614016": "Apantac LLC", "154066454618112": "North Building Technologies Limited", @@ -128487,6 +129055,7 @@ "154066455560192": "Sonel S.A.", "154066455572480": "eumig industrie-TV GmbH.", "154066455576576": "Axion Lighting", + "154066455580672": "Hubris Technologies Private Limited", "154066455588864": "Vortex Sp. z o.o.", "154066455597056": "ViewSonic Corp", "154066455601152": "Connectcom System Co., Ltd", @@ -128537,6 +129106,7 @@ "154066455945216": "ICT International", "154066455953408": "Beijing Zhongzhi Huida Technology Co., Ltd", "154066455957504": "Siemens Industry Software Inc.", + "154066455986176": "Foshan YiFeng Electric Industrial Co., ltd", "154066455990272": "Labtrino AB", "154066456002560": "Automata GmbH & Co. KG", "154066456014848": "Lightworks GmbH", @@ -128606,6 +129176,7 @@ "154066456510464": "Arcus-EDS GmbH", "154066456514560": "FIDICA GmbH & Co. KG", "154066456535040": "AT-Automation Technology GmbH", + "154066456539136": "Insightec", "154066456543232": "Avionica", "154066456555520": "Becton Dickinson", "154066456559616": "Automata Spa", @@ -128668,6 +129239,7 @@ "154066457071616": "M/S Milind Ramachandra Rajwade", "154066457075712": "Artome Oy", "154066457079808": "Celestica Inc.", + "154066457083904": "Heitec Ag", "154066457092096": "Dave Srl", "154066457108480": "Dorlet Sau", "154066457112576": "Abbott Diagnostics Technologies AS", @@ -128709,6 +129281,7 @@ "154066457366528": "Vonamic GmbH", "154066457370624": "Dorlet Sau", "154066457378816": "Guan Show Technologe Co., Ltd.", + "154066457391104": "INVENTIA Sp. z o.o.", "154066457411584": "navXperience GmbH", "154066457415680": "Becton Dickinson", "154066457419776": "Visiosoft Pty Ltd", @@ -128778,6 +129351,7 @@ "154066457915392": "SAXOGY POWER ELECTRONICS GmbH", "154066457923584": "AEM Singapore Pte Ltd", "154066457927680": "AT-Automation Technology GmbH", + "154066457931776": "Videosys Broadcast Ltd", "154066457935872": "G.M. International srl", "154066457952256": "FleetSafe India Private Limited", "154066457968640": "Mitsubishi Electric Klimat Transportation Systems S.p.A.", @@ -128852,6 +129426,7 @@ "154066458562560": "Pantherun Technologies Pvt Ltd", "154066458566656": "CubeWorks, Inc.", "154066458574848": "WonATech Co., Ltd.", + "154066458578944": "Brocere electronics corp. ltd.", "154066458583040": "MDI Industrial", "154066458595328": "Dacom West GmbH", "154066458607616": "Copper Connections Ltd", @@ -128954,6 +129529,7 @@ "154066459402240": "Shenzhen Longyun Lighting Electric Appliances Co., Ltd", "154066459406336": "Qualitel Corporation", "154066459410432": "Fasetto, Inc.", + "154066459418624": "Landis+Gyr Equipamentos de Medição Ltda", "154066459435008": "Umano Medical Inc.", "154066459439104": "Gogo Business Aviation", "154066459443200": "Power Electronics Espana, S.L.", @@ -128967,6 +129543,7 @@ "154066459529216": "Arktis Radiation Detectors", "154066459541504": "MB connect line GmbH Fernwartungssysteme", "154066459545600": "KSE GmbH", + "154066459549696": "Sona Networks Private Limited", "154066459553792": "Talleres de Escoriaza SA", "154066459574272": "Abacus Peripherals Pvt Ltd", "154066459586560": "Peter Huber Kaeltemaschinenbau SE", @@ -128993,6 +129570,7 @@ "154066459762688": "Emerson Rosemount Analytical", "154066459766784": "Böckelt GmbH", "154066459779072": "GS Elektromedizinsiche Geräte G. Stemple GmbH", + "154066459783168": "Stercom Power Soltions GmbH", "154066459787264": "Makel Elektrik Malzemeleri A.Ş.", "154066459791360": "Quercus Technologies, S.L.", "154066459795456": "Wintus System", @@ -129086,6 +129664,7 @@ "154066460532736": "shenzhen beswave co.,ltd", "154066460536832": "Cardinal Scales Manufacturing Co", "154066460540928": "V-teknik Elektronik AB", + "154066460561408": "Procon Electronics Pty Ltd", "154066460565504": "DEUTA-WERKE GmbH", "154066460569600": "Rax-Tech International", "154066460585984": "CPAT Flex Inc.", @@ -129107,6 +129686,7 @@ "154066460721152": "Upstart Power", "154066460729344": "Optimum Instruments Inc.", "154066460737536": "Flextronics International Kft", + "154066460741632": "Tech Fass s.r.o.", "154066460749824": "Peter Huber Kaeltemaschinenbau SE", "154066460753920": "HEINEN ELEKTRONIK GmbH", "154066460762112": "Data Conversion Systems Ltd", @@ -129137,6 +129717,7 @@ "154066460966912": "Novanta IMS", "154066460979200": "Hebei Weiji Electric Co.,Ltd", "154066461003776": "YUYAMA MFG Co.,Ltd", + "154066461007872": "Jiangsu Yi Rong Mstar Technology Ltd.", "154066461011968": "Private", "154066461020160": "Ltec Co.,Ltd", "154066461032448": "Adetec Sas", @@ -129187,6 +129768,7 @@ "154066461372416": "Sicon srl", "154066461376512": "Safepro AI Video Research Labs Pvt Ltd", "154066461380608": "RealD, Inc.", + "154066461388800": "Fell Technology AS", "154066461417472": "Phygitall Soluções Em Internet Das Coisas", "154066461421568": "Lineage Power Pvt Ltd.,", "154066461442048": "Picocom Technology Ltd", @@ -129206,6 +129788,7 @@ "154066461573120": "Laser Mechanisms, Inc.", "154066461577216": "Andy-L Ltd", "154066461581312": "Loop Technologies", + "154066461593600": "Sichuan Youke Communication Technology Co., Ltd", "154066461601792": "Comm-ence, Inc.", "154066461618176": "Carestream Dental LLC", "154066461626368": "AddSecure Smart Grids", @@ -129255,7 +129838,7 @@ "154066461929472": "FoxIoT OÜ", "154066461933568": "EasyNet Industry (Shenzhen) Co., Ltd", "154066461941760": "Chengdu ZiChen Time&Frequency Technology Co.,Ltd", - "154066461945856": "UGARD NETWORKS TECHNOLOGY Co.,LTD", + "154066461945856": "UGUARD NETWORKS TECHNOLOGY Co.,LTD", "154066461954048": "Gl Tech Co.,Ltd", "154066461958144": "OPTOKON, a.s.", "154066461962240": "A&T Corporation", @@ -129413,6 +129996,7 @@ "154066463199232": "VeoTech", "154066463203328": "YUYAMA MFG Co.,Ltd", "154066463207424": "YUYAMA MFG Co.,Ltd", + "154066463211520": "Abbott Diagnostics Technologies AS", "154066463215616": "Smart-VOD Pty Ltd", "154066463236096": "Flextronics International Kft", "154066463256576": "Talleres de Escoriaza SAU", @@ -129423,7 +130007,9 @@ "154066463289344": "Mecco LLC", "154066463297536": "Benetel", "154066463305728": "EYatsko Individual", + "154066463313920": "MB connect line GmbH", "154066463322112": "I.S.A. - Altanova group srl", + "154066463334400": "Monnit Corporation", "154066463338496": "Audiodo International AB", "154066463342592": "Vesper Technologies", "154066463354880": "Free Talk Engineering Co., Ltd", @@ -129462,6 +130048,7 @@ "154066463625216": "Advent Diamond", "154066463629312": "Alpes recherche et développement", "154066463633408": "Mobileye", + "154066463637504": "Potter Electric Signal Company", "154066463657984": "ADiCo Corporation", "154066463670272": "Packetalk LLC", "154066463698944": "BRS Sistemas Eletrônicos", @@ -129608,7 +130195,9 @@ "154066464882688": "Zin Technologies", "154066464899072": "Luxshare Electronic Technology (Kunshan) LTD", "154066464903168": "Pantherun Technologies Pvt Ltd", + "154066464907264": "SiFive Inc", "154066464927744": "Lumiplan Duhamel", + "154066464956416": "Dial Plan Limited", "154066464964608": "Zumbach Electronic AG", "154066464972800": "\"KB \"Modul\", LLC", "154066464980992": "Miracle Healthcare, Inc.", @@ -129681,6 +130270,7 @@ "154066465607680": "Jbf", "154066465611776": "Broadcast Tools, Inc.", "154066465624064": "CenterClick LLC", + "154066465632256": "Jorex Lorex India Private Limited", "154066465636352": "inomatic GmbH", "154066465644544": "ADAMCZEWSKI elektronische Messtechnik GmbH", "154066465648640": "Leonardo Germany GmbH", From 0fdcb1f640ad5abc24a3dd982c463da4dce2688a Mon Sep 17 00:00:00 2001 From: seladb Date: Fri, 28 Feb 2025 23:55:48 -0800 Subject: [PATCH 15/36] Auto OUI Database Update (#1723) Co-authored-by: GitHub --- 3rdParty/OUIDataset/PCPP_OUIDataset.json | 410 +++++++++++++++++++++-- 1 file changed, 389 insertions(+), 21 deletions(-) diff --git a/3rdParty/OUIDataset/PCPP_OUIDataset.json b/3rdParty/OUIDataset/PCPP_OUIDataset.json index 91b057420d..a7b13b9de0 100644 --- a/3rdParty/OUIDataset/PCPP_OUIDataset.json +++ b/3rdParty/OUIDataset/PCPP_OUIDataset.json @@ -324,7 +324,7 @@ "vendor": "Silicon Graphics" }, "108": { - "vendor": "Private" + "vendor": "Schneider Electric" }, "109": { "vendor": "Cray Communications, Ltd." @@ -1380,7 +1380,7 @@ "vendor": "Evr" }, "460": { - "vendor": "Japan Total Design Communication Co., Ltd." + "vendor": "Brand Maker Enabler Inc." }, "461": { "vendor": "ARtem" @@ -3450,7 +3450,7 @@ "vendor": "Motorola Solutions Inc." }, "1150": { - "vendor": "Siqura B.V." + "vendor": "TKH Security B.V." }, "1151": { "vendor": "Chr. Mayr GmbH & Co. KG" @@ -21546,7 +21546,7 @@ "vendor": "Envisacor Technologies Inc." }, "7211": { - "vendor": "Alertme.com Limited" + "vendor": "Hive" }, "7212": { "vendor": "Synapse" @@ -28983,7 +28983,7 @@ "vendor": "Probits Co., LTD." }, "9695": { - "vendor": "Taser International Inc." + "vendor": "Axon Enterprise, Inc." }, "9696": { "vendor": "CeedTec Sdn Bhd" @@ -31703,6 +31703,9 @@ "19063": { "vendor": "zte corporation" }, + "19218": { + "vendor": "Espressif Inc." + }, "19443": { "vendor": "Shenzhen Mercury Communication Technologies Co.,Ltd." }, @@ -32492,6 +32495,9 @@ "22791": { "vendor": "LenovoEMC Products USA, LLC" }, + "22892": { + "vendor": "Cisco Systems, Inc" + }, "22905": { "vendor": "Networked Energy Services" }, @@ -37773,7 +37779,7 @@ "vendor": "Atan Technology Inc." }, "53454": { - "vendor": "iSystem Labs" + "vendor": "TASKING Labs" }, "53455": { "vendor": "Moreton Bay" @@ -39872,6 +39878,9 @@ "313351": { "vendor": "Xiaomi Communications Co Ltd" }, + "313413": { + "vendor": "TP-Link Systems Inc." + }, "313472": { "vendor": "Samtec Inc" }, @@ -40664,6 +40673,9 @@ "528040": { "vendor": "Velex s.r.l." }, + "528357": { + "vendor": "Cisco Systems, Inc" + }, "528378": { "vendor": "Ksp Inc." }, @@ -40931,6 +40943,9 @@ "543439": { "vendor": "Guangdong Oppo Mobile Telecommunications Corp.,Ltd" }, + "543556": { + "vendor": "Robert Bosch Elektronika Kft." + }, "544284": { "vendor": "H2A Systems, LLC" }, @@ -41735,6 +41750,9 @@ "788447": { "vendor": "Xiaomi Communications Co Ltd" }, + "788467": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "788660": { "vendor": "HUMAX Co., Ltd." }, @@ -42179,6 +42197,9 @@ "819760": { "vendor": "Shenzhen Magnus Technologies Co.,Ltd" }, + "819783": { + "vendor": "Cig Shanghai Co Ltd" + }, "819816": { "vendor": "Tp-Link Technologies Co.,Ltd." }, @@ -43610,6 +43631,9 @@ "1095262": { "vendor": "New H3C Technologies Co., Ltd" }, + "1095286": { + "vendor": "HP Inc." + }, "1095443": { "vendor": "Private" }, @@ -44222,6 +44246,9 @@ "1324859": { "vendor": "PROCOM Systems" }, + "1325359": { + "vendor": "Lear" + }, "1325722": { "vendor": "Hon Hai Precision Industry Co.,LTD" }, @@ -44504,6 +44531,9 @@ "1343692": { "vendor": "Quectel Wireless Solutions Co.,Ltd." }, + "1343777": { + "vendor": "TOP WING Corporation" + }, "1344091": { "vendor": "Hefei Radio Communication Technology Co., Ltd" }, @@ -44516,6 +44546,9 @@ "1344631": { "vendor": "New H3C Technologies Co., Ltd" }, + "1344769": { + "vendor": "Rivos Inc." + }, "1344777": { "vendor": "Apple, Inc." }, @@ -46658,6 +46691,9 @@ "1863973": { "vendor": "Apple, Inc." }, + "1863974": { + "vendor": "snom technology GmbH" + }, "1864221": { "vendor": "Dell Inc." }, @@ -47156,6 +47192,9 @@ "1897515": { "vendor": "Huawei Device Co., Ltd." }, + "1897535": { + "vendor": "Arcadyan Corporation" + }, "1897674": { "vendor": "Private" }, @@ -47315,6 +47354,9 @@ "2103387": { "vendor": "Shenzhen Jingxun Technology Co., Ltd." }, + "2103795": { + "vendor": "WavTek Technologies, Inc" + }, "2103814": { "vendor": "Compal Information (Kunshan) Co., Ltd." }, @@ -47333,6 +47375,9 @@ "2104579": { "vendor": "Elatec GmbH" }, + "2104861": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "2104968": { "vendor": "Intel Corporate" }, @@ -48803,6 +48848,9 @@ "2390520": { "vendor": "KUPSON spol. s r.o." }, + "2390948": { + "vendor": "China Mobile Group Device Co.,Ltd." + }, "2391110": { "vendor": "Flextronics Technologies Mexico S De Rl De Cv" }, @@ -48842,6 +48890,9 @@ "2393240": { "vendor": "Beijing Jiaoda Microunion Tech.Co.,Ltd." }, + "2393602": { + "vendor": "Bouffalo Lab (Nanjing) Co., Ltd." + }, "2393844": { "vendor": "Ctek, Inc." }, @@ -48995,6 +49046,9 @@ "2405177": { "vendor": "Apple, Inc." }, + "2405874": { + "vendor": "Shanghai Ingeek Technology Co., Ltd" + }, "2405975": { "vendor": "Cisco Systems, Inc" }, @@ -49661,6 +49715,9 @@ "2638316": { "vendor": "Huawei Technologies Co.,Ltd" }, + "2638812": { + "vendor": "United Memory Technology (Jiangsu) Limited" + }, "2638896": { "vendor": "Arcade Communications Ltd." }, @@ -49871,6 +49928,9 @@ "2652937": { "vendor": "zte corporation" }, + "2652945": { + "vendor": "Hui Zhou Gaoshengda Technology Co.,LTD" + }, "2653403": { "vendor": "Hefei Toycloud Technology Co.,ltd" }, @@ -51461,6 +51521,9 @@ "2939252": { "vendor": "Hui Zhou Gaoshengda Technology Co.,LTD" }, + "2939455": { + "vendor": "DongGuan Ramaxel Memory Technology Limited" + }, "2939655": { "vendor": "Intel Corporate" }, @@ -52586,6 +52649,9 @@ "3207121": { "vendor": "Alstom Strongwish (Shenzhen) Co., Ltd." }, + "3207208": { + "vendor": "Bosch Sicherheitssysteme GmbH" + }, "3207740": { "vendor": "Tecno Mobile Limited" }, @@ -52913,6 +52979,9 @@ "3422100": { "vendor": "Hamee Corp." }, + "3422265": { + "vendor": "NEC Platforms, Ltd." + }, "3422383": { "vendor": "Inlab Networks GmbH" }, @@ -52922,6 +52991,9 @@ "3422752": { "vendor": "Hewlett Packard Enterprise" }, + "3423280": { + "vendor": "NXP Semiconductor (Tianjin) LTD." + }, "3423615": { "vendor": "Klipsch Group, Inc." }, @@ -53345,6 +53417,9 @@ "3446639": { "vendor": "Rootech, Inc." }, + "3446743": { + "vendor": "Yealink(Xiamen) Network Technology Co.,Ltd." + }, "3446774": { "vendor": "ASUSTek COMPUTER INC." }, @@ -53972,6 +54047,9 @@ "3675214": { "vendor": "Fiberhome Telecommunication Technologies Co.,LTD" }, + "3675738": { + "vendor": "zte corporation" + }, "3675762": { "vendor": "Shenzhen SuperElectron Technology Co.,Ltd." }, @@ -54371,6 +54449,9 @@ "3700433": { "vendor": "Euronda SpA" }, + "3700487": { + "vendor": "AltoBeam Inc." + }, "3700685": { "vendor": "Kokusai Electric Corporation" }, @@ -56297,6 +56378,9 @@ "4203698": { "vendor": "Sichuan AI-Link Technology Co., Ltd." }, + "4203784": { + "vendor": "Highway 9 Networks, Inc." + }, "4203970": { "vendor": "Intel Corporate" }, @@ -56519,6 +56603,9 @@ "4218242": { "vendor": "Netgear" }, + "4218575": { + "vendor": "Esconet Technologies Limited" + }, "4218593": { "vendor": "Shenzhen H&T Intelligent Control Co.,Ltd." }, @@ -57572,6 +57659,9 @@ "4475272": { "vendor": "Intel Corporate" }, + "4475447": { + "vendor": "Xiaomi Communications Co Ltd" + }, "4475493": { "vendor": "Silverflare Ltd." }, @@ -57767,6 +57857,9 @@ "4486252": { "vendor": "Sony Corporation" }, + "4486665": { + "vendor": "New H3C Technologies Co., Ltd" + }, "4486740": { "vendor": "Huawei Technologies Co.,Ltd" }, @@ -58055,6 +58148,9 @@ "4505054": { "vendor": "BHTC GmbH" }, + "4505099": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "4505571": { "vendor": "Shenzhen Longtech Electronics Co.,Ltd" }, @@ -59456,9 +59552,6 @@ "4782460": { "vendor": "Fiberhome Telecommunication Technologies Co.,LTD" }, - "4782463": { - "vendor": "shenzhen Huaxufeng Technology Development Co.,Ltd" - }, "4783286": { "vendor": "Lava International(H.K) Limited" }, @@ -59717,6 +59810,9 @@ "4992766": { "vendor": "Shenzhen Comnect Technology Co.,LTD" }, + "4992891": { + "vendor": "AltoBeam Inc." + }, "4992925": { "vendor": "ICM Controls" }, @@ -61208,6 +61304,9 @@ "5273349": { "vendor": "Samsung Electronics Co.,Ltd" }, + "5273725": { + "vendor": "Espressif Inc." + }, "5273776": { "vendor": "Huawei Device Co., Ltd." }, @@ -62786,6 +62885,9 @@ "5566276": { "vendor": "Lumi United Technology Co., Ltd" }, + "5566299": { + "vendor": "Science Corporation" + }, "5566354": { "vendor": "Shenzhen Elink Technology Co., LTD" }, @@ -63323,6 +63425,9 @@ "5800616": { "vendor": "Microsoft" }, + "5800758": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "5801188": { "vendor": "IP500 Alliance e.V." }, @@ -64277,6 +64382,9 @@ "6053547": { "vendor": "Juniper Networks" }, + "6053563": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "6053735": { "vendor": "Intel Corporate" }, @@ -64481,6 +64589,9 @@ "6065486": { "vendor": "Apple, Inc." }, + "6065637": { + "vendor": "Delta Electronics, Inc." + }, "6065680": { "vendor": "TimeWatch Infocom Pvt. Ltd." }, @@ -65342,6 +65453,9 @@ "6310428": { "vendor": "SUYIN Corporation" }, + "6310519": { + "vendor": "Finder SpA" + }, "6310826": { "vendor": "Magic Leap, Inc." }, @@ -65492,6 +65606,9 @@ "6319681": { "vendor": "Barrot Technology Co.,LTD" }, + "6319699": { + "vendor": "Beijing Wisdomstar Technology Co., Ltd" + }, "6319824": { "vendor": "Seal Ag" }, @@ -65951,6 +66068,9 @@ "6346908": { "vendor": "HMD Global Oy" }, + "6346916": { + "vendor": "Vantiva Connected Home - Technologies Telco" + }, "6347168": { "vendor": "Lenovo Mobile Communication Technology Ltd." }, @@ -66188,6 +66308,9 @@ "6555638": { "vendor": "Samsung Electronics Co.,Ltd" }, + "6555748": { + "vendor": "Cisco Systems, Inc" + }, "6555980": { "vendor": "Beijing Superbee Wireless Technology Co.,Ltd" }, @@ -67115,6 +67238,9 @@ "6610142": { "vendor": "ZheJiang FuChunJiang Information Technology Co.,Ltd" }, + "6610280": { + "vendor": "Zyxel Communications Corporation" + }, "6610409": { "vendor": "Xiaomi Communications Co Ltd" }, @@ -67782,7 +67908,7 @@ "vendor": "Huawei Technologies Co.,Ltd" }, "6849266": { - "vendor": "grandcentrix GmbH" + "vendor": "FIXME GmbH" }, "6849306": { "vendor": "Pandora Mobility Corporation" @@ -68012,6 +68138,9 @@ "6860948": { "vendor": "Inesa Electron Co.,Ltd" }, + "6861257": { + "vendor": "IYO, Inc" + }, "6861662": { "vendor": "Shenzhen Neostra Technology Co.Ltd" }, @@ -68282,6 +68411,9 @@ "6878531": { "vendor": "Huawei Technologies Co.,Ltd" }, + "6878763": { + "vendor": "Itel Mobile Limited" + }, "6878779": { "vendor": "Amazon Technologies Inc." }, @@ -69140,6 +69272,9 @@ "7122709": { "vendor": "Webasto SE" }, + "7123063": { + "vendor": "ALL Winner (Hong Kong) Limited" + }, "7123150": { "vendor": "Netgear" }, @@ -69255,7 +69390,7 @@ "vendor": "1More" }, "7130937": { - "vendor": "Guangdong Starfive Technology Co., Ltd." + "vendor": "Shanghai StarFive Semiconductor Co., Ltd." }, "7131144": { "vendor": "zte corporation" @@ -70151,6 +70286,9 @@ "7375736": { "vendor": "citygrow technology co., ltd" }, + "7375767": { + "vendor": "INSYS icom GmbH" + }, "7375821": { "vendor": "ASUSTek COMPUTER INC." }, @@ -72371,6 +72509,9 @@ "7890606": { "vendor": "ZTEC Instruments, Inc." }, + "7890647": { + "vendor": "Genstoraige Technology Co.Ltd." + }, "7890675": { "vendor": "shenzhen worldelite electronics co., LTD" }, @@ -72479,6 +72620,9 @@ "7898612": { "vendor": "Huawei Device Co., Ltd." }, + "7898670": { + "vendor": "Microsoft Corporation" + }, "7898806": { "vendor": "Shenzhen YOUHUA Technology Co., Ltd" }, @@ -72998,6 +73142,9 @@ "7924852": { "vendor": "Kyland-USA" }, + "7925029": { + "vendor": "New H3C Technologies Co., Ltd" + }, "7925180": { "vendor": "OnePlus Technology (Shenzhen) Co., Ltd" }, @@ -73772,6 +73919,9 @@ "8165678": { "vendor": "Shanghai Notion lnformatio Technology Co.,Ltd." }, + "8165702": { + "vendor": "Sector Alarm Tech S.L." + }, "8165917": { "vendor": "Apple, Inc." }, @@ -74879,6 +75029,9 @@ "8423154": { "vendor": "Intel Corporate" }, + "8423424": { + "vendor": "zte corporation" + }, "8423703": { "vendor": "Tp-Link Technologies Co.,Ltd." }, @@ -75788,6 +75941,9 @@ "8679089": { "vendor": "Park Assist LLC" }, + "8679100": { + "vendor": "Nokia solutions and networks Pvt Ltd" + }, "8679374": { "vendor": "Guangdong Oppo Mobile Telecommunications Corp.,Ltd" }, @@ -76104,7 +76260,7 @@ "vendor": "Apple, Inc." }, "8695583": { - "vendor": "Beat System Service Co,. Ltd." + "vendor": "GopherTec Inc." }, "8695788": { "vendor": "Buffalo.Inc" @@ -76652,6 +76808,9 @@ "8923742": { "vendor": "New H3C Technologies Co., Ltd" }, + "8923873": { + "vendor": "Mrc Inc." + }, "8924052": { "vendor": "MADOKA SYSTEM Co.,Ltd." }, @@ -77174,6 +77333,9 @@ "8954462": { "vendor": "Juniper Networks" }, + "8954526": { + "vendor": "Raspberry Pi (Trading) Ltd" + }, "8954583": { "vendor": "Huawei Technologies Co.,Ltd" }, @@ -77849,6 +78011,9 @@ "9190833": { "vendor": "Beijing H-IoT Technology Co., Ltd." }, + "9191236": { + "vendor": "GD Midea Air-Conditioning Equipment Co.,Ltd." + }, "9191922": { "vendor": "RDA Technologies Ltd." }, @@ -78416,6 +78581,9 @@ "9224481": { "vendor": "Panasonic Corporation AVC Networks Company" }, + "9225587": { + "vendor": "Xsight Labs LTD." + }, "9225612": { "vendor": "ShenZhen Elsky Technology Co.,LTD" }, @@ -79571,6 +79739,9 @@ "9484593": { "vendor": "Apple, Inc." }, + "9484610": { + "vendor": "zte corporation" + }, "9484669": { "vendor": "Johnson Outdoors Marine Electronics d/b/a Minnkota" }, @@ -79826,6 +79997,9 @@ "9500817": { "vendor": "Kaon Group Co., Ltd." }, + "9501028": { + "vendor": "Rawasi Co" + }, "9501040": { "vendor": "Huawei Technologies Co.,Ltd" }, @@ -81104,6 +81278,9 @@ "9966115": { "vendor": "Tarmoc Network LTD" }, + "9966304": { + "vendor": "Xiaomi Communications Co Ltd" + }, "9966387": { "vendor": "zte corporation" }, @@ -81173,6 +81350,9 @@ "9970510": { "vendor": "Micromedia AG" }, + "9970811": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "9971018": { "vendor": "Tp-Link Corporation Pte. Ltd." }, @@ -81380,6 +81560,9 @@ "9982115": { "vendor": "Signaltek Jsc" }, + "9982471": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "9982525": { "vendor": "Sunitec Enterprise Co.,Ltd" }, @@ -82130,6 +82313,9 @@ "10225262": { "vendor": "Hytera Communications Corporation Limited" }, + "10225359": { + "vendor": "PLAUD Inc." + }, "10226033": { "vendor": "New H3C Technologies Co., Ltd" }, @@ -82427,6 +82613,9 @@ "10244898": { "vendor": "TP-Link Corporation Limited" }, + "10244997": { + "vendor": "PT. Hartono Istana Teknologi" + }, "10245069": { "vendor": "ENGICAM s.r.l." }, @@ -82577,6 +82766,9 @@ "10250705": { "vendor": "Huawei Technologies Co.,Ltd" }, + "10250707": { + "vendor": "ASIX Electronics Corporation" + }, "10250733": { "vendor": "Arista Networks" }, @@ -83051,6 +83243,9 @@ "10279592": { "vendor": "Apple, Inc." }, + "10279607": { + "vendor": "Hewlett Packard Enterprise" + }, "10279687": { "vendor": "Yellowtec GmbH" }, @@ -83078,6 +83273,9 @@ "10280881": { "vendor": "Shenzhen Crave Communication Co., LTD" }, + "10280883": { + "vendor": "NXP Semiconductor (Tianjin) LTD." + }, "10281025": { "vendor": "Nokia" }, @@ -83894,6 +84092,9 @@ "10525083": { "vendor": "Apple, Inc." }, + "10525266": { + "vendor": "Shenzhen MoreSense Technology Co., Ltd." + }, "10525274": { "vendor": "Time Domain" }, @@ -85064,6 +85265,9 @@ "10789450": { "vendor": "Cisco SPVTG" }, + "10789892": { + "vendor": "Bubendorff SAS" + }, "10789977": { "vendor": "Hangzhou Hikvision Digital Technology Co.,Ltd." }, @@ -85157,6 +85361,9 @@ "10795392": { "vendor": "Parking BOXX Inc." }, + "10795632": { + "vendor": "Beijing Xiaomi Mobile Software Co., Ltd" + }, "10795638": { "vendor": "Huawei Technologies Co.,Ltd" }, @@ -85520,6 +85727,9 @@ "11012529": { "vendor": "Huawei Device Co., Ltd." }, + "11012971": { + "vendor": "Chipsea Technologies (Shenzhen) Corp." + }, "11013115": { "vendor": "Ruckus Wireless" }, @@ -85535,6 +85745,9 @@ "11013322": { "vendor": "Shenzhen Sundray Technologies Company Limited" }, + "11013601": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "11014279": { "vendor": "Texas Instruments" }, @@ -88547,6 +88760,9 @@ "11584857": { "vendor": "Samsung Electronics Co.,Ltd" }, + "11585052": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "11585178": { "vendor": "Juniper Networks" }, @@ -88991,6 +89207,9 @@ "11808504": { "vendor": "Eline Technology co.Ltd" }, + "11808515": { + "vendor": "Quectel Wireless Solutions Co.,Ltd." + }, "11808850": { "vendor": "Huawei Technologies Co.,Ltd" }, @@ -89759,6 +89978,9 @@ "11856304": { "vendor": "Cisco Systems, Inc" }, + "11856312": { + "vendor": "Dell Inc." + }, "11856898": { "vendor": "Alpsalpine Co,.Ltd" }, @@ -91757,6 +91979,9 @@ "12363177": { "vendor": "Apple, Inc." }, + "12363405": { + "vendor": "Continetal Automotive Systems Sibiu" + }, "12363942": { "vendor": "Intel Corporate" }, @@ -93680,6 +93905,9 @@ "12873917": { "vendor": "Mellanox Technologies, Inc." }, + "12873999": { + "vendor": "Xiaomi Communications Co Ltd" + }, "12874032": { "vendor": "Fon Technology S.L." }, @@ -93725,6 +93953,9 @@ "12876037": { "vendor": "Zhejiang Uniview Technologies Co.,Ltd." }, + "12876161": { + "vendor": "Ehya LTD" + }, "12876191": { "vendor": "Haiguang Smart Device Co.,Ltd." }, @@ -95423,6 +95654,9 @@ "13239386": { "vendor": "Ossia Inc" }, + "13240380": { + "vendor": "Western Digital Technologies, Inc." + }, "13242972": { "vendor": "Microsoft Corporation" }, @@ -97202,6 +97436,9 @@ "13668864": { "vendor": "FiRa Consortium" }, + "13669000": { + "vendor": "Powertek Limited" + }, "13669022": { "vendor": "Microsoft Corporation" }, @@ -97622,6 +97859,9 @@ "13893736": { "vendor": "Fiberhome Telecommunication Technologies Co.,LTD" }, + "13893834": { + "vendor": "Continental Automotive Systems S.R.L" + }, "13893929": { "vendor": "Broadcom" }, @@ -98126,6 +98366,9 @@ "13921190": { "vendor": "Huawei Technologies Co.,Ltd" }, + "13921378": { + "vendor": "MultiTracks.com, LLC" + }, "13921389": { "vendor": "Commscope" }, @@ -101249,6 +101492,9 @@ "14690156": { "vendor": "Guangzhou Shiyuan Electronic Technology Company Limited" }, + "14690314": { + "vendor": "TP-Link Systems Inc." + }, "14690401": { "vendor": "Huawei Technologies Co.,Ltd" }, @@ -102110,6 +102356,9 @@ "14741285": { "vendor": "Lintes Technology Co., Ltd." }, + "14741439": { + "vendor": "Nintendo Co.,Ltd" + }, "14742033": { "vendor": "Digitalwatt" }, @@ -104492,6 +104741,9 @@ "15473597": { "vendor": "Silicon Laboratories" }, + "15473615": { + "vendor": "Brain Technologies, Inc." + }, "15473757": { "vendor": "Siemens AG" }, @@ -107693,6 +107945,9 @@ "16257800": { "vendor": "Nokia" }, + "16258269": { + "vendor": "Cisco Systems, Inc" + }, "16258302": { "vendor": "Union Man Technology Co.,Ltd" }, @@ -108614,6 +108869,9 @@ "16306365": { "vendor": "Samsung Electronics Co.,Ltd" }, + "16306373": { + "vendor": "Sector Alarm Tech S.L." + }, "16306449": { "vendor": "Tp-Link Technologies Co.,Ltd." }, @@ -109868,6 +110126,9 @@ "16572818": { "vendor": "Sichuan Jinwangtong Electronic Science&Technology Co,.Ltd" }, + "16572838": { + "vendor": "Huawei Technologies Co.,Ltd" + }, "16572889": { "vendor": "Stable Imaging Solutions LLC" }, @@ -110096,6 +110357,31 @@ } ] }, + "303471": { + "vendor": "", + "maskedFilters": [ + { + "mask": 28, + "vendors": { + "5091398516736": "Shenzhen C & D Electronics Co., Ltd.", + "5091399565312": "iENSO Inc.", + "5091400613888": "Suzhou Lianshichuangzhi Technology Co.,Ltd", + "5091401662464": "Crypto4A Technologies", + "5091402711040": "Xiamen Akubela Innovation Technology CO., Ltd.", + "5091403759616": "DOM Security", + "5091404808192": "Gy-Fx Sas", + "5091405856768": "NDW Rollers B.V.", + "5091406905344": "Annapurna labs", + "5091407953920": "Chongqing Jinmei Automotive Electronics co.,Ltd.", + "5091409002496": "Uyar Group", + "5091410051072": "Chroma-Q", + "5091411099648": "Broadband International", + "5091412148224": "Zettlab Innovation Technology CO.,LTD", + "5091413196800": "GajShield Infotech India Pvt. Ltd." + } + } + ] + }, "312294": { "vendor": "", "maskedFilters": [ @@ -115701,6 +115987,17 @@ } ] }, + "9715453": { + "vendor": "", + "maskedFilters": [ + { + "mask": 28, + "vendors": { + "162998254567424": "ShenZhen chino-e communication co.Ltd." + } + } + ] + }, "9750967": { "vendor": "", "maskedFilters": [ @@ -116077,6 +116374,31 @@ } ] }, + "10282313": { + "vendor": "", + "maskedFilters": [ + { + "mask": 28, + "vendors": { + "172508586180608": "Speedtech Corp.", + "172508587229184": "Lightmatter, Inc.", + "172508588277760": "Volumatic Limited", + "172508589326336": "Shenzhen Jooan Technology Co., Ltd", + "172508590374912": "Beijing Lingji Innovations technology Co,LTD.", + "172508591423488": "Wetek Electronics Limited", + "172508592472064": "shenzhen Huaxufeng Technology Development Co.,Ltd", + "172508593520640": "ecodata solutions GmbH", + "172508594569216": "Hemla Group AB", + "172508595617792": "Hangzhou Xieneng Technology Co., Ltd.", + "172508596666368": "Arcteq Relays Ltd.", + "172508597714944": "Shenzhen Lingdu Auto Electronics Co.,Ltd", + "172508598763520": "Innodep Inc.", + "172508599812096": "Annapurna labs", + "172508600860672": "Amoi Mobile Co.,Ltd." + } + } + ] + }, "10286813": { "vendor": "", "maskedFilters": [ @@ -125212,7 +125534,7 @@ "123917679017984": "Sanmina Israel", "123917679022080": "oxynet Solutions", "123917679026176": "Ariston Thermo s.p.a.", - "123917679030272": "Remote Sensing Solutions, Inc.", + "123917679030272": "Tomorrow Companies Inc", "123917679034368": "Abitsoftware, Ltd.", "123917679038464": "Aplex Technology Inc.", "123917679042560": "Loop Labs, Inc.", @@ -128332,6 +128654,7 @@ "mask": 36, "vendors": { "154066449596416": "Suzhou Xingxiangyi Precision Manufacturing Co.,Ltd.", + "154066449600512": "HYFIX Spatial Intelligence", "154066449608704": "Brighten Controls LLP", "154066449633280": "Converging Systems Inc.", "154066449637376": "TaskUnite Inc. (dba AMPAworks)", @@ -128365,12 +128688,14 @@ "154066449883136": "American Fullway Corp.", "154066449891328": "FieldLine Medical", "154066449895424": "Nuances Org", + "154066449899520": "GS Elektromedizinsiche Geräte G. Stemple GmbH", "154066449915904": "Auditdata", "154066449920000": "ISILINE srl", "154066449928192": "CP contech electronic GmbH", "154066449936384": "HS.com Kft", "154066449944576": "Intercreate", "154066449948672": "Dong Guan Yung Fu Electronics Ltd.", + "154066449956864": "Mect Srl", "154066449960960": "MB connect line GmbH Fernwartungssysteme", "154066449973248": "tickIoT Inc.", "154066449985536": "ESCAD AUTOMATION GmbH", @@ -128381,6 +128706,7 @@ "154066450018304": "Genius Vision Digital Private Limited", "154066450030592": "Intellisense Systems Inc.", "154066450034688": "Sanwa Supply Inc.", + "154066450038784": "COBES GmbH", "154066450042880": "Monnit Corporation", "154066450059264": "Dorlet Sau", "154066450067456": "Potter Electric Signal Company", @@ -128402,6 +128728,7 @@ "154066450178048": "qiio AG", "154066450182144": "AixControl GmbH", "154066450186240": "kousyuhaneturen", + "154066450190336": "Limitless Electromechanical Works LLC", "154066450194432": "Gogo BA", "154066450198528": "MAG Audio LLC", "154066450202624": "El.En. Spa", @@ -128432,7 +128759,7 @@ "154066450378752": "Aurora Communication Technologies Corp.", "154066450382848": "Active Research Limited", "154066450403328": "TechnipFMC", - "154066450415616": "EA Elektro-Automatik", + "154066450415616": "EA Elektro-Automatik GmbH", "154066450423808": "CLOUD TELECOM Inc.", "154066450436096": "DEUTA Werke GmbH", "154066450456576": "biosilver.co.,ltd", @@ -128573,6 +128900,7 @@ "154066451587072": "Radian Research, Inc.", "154066451591168": "Canon Electron Tubes & Devices Co., Ltd.", "154066451595264": "Haptech Defense Systems", + "154066451615744": "Lichtwart GmbH", "154066451623936": "Tantronic AG", "154066451628032": "AVCOMM Technologies Inc", "154066451644416": "Eiffage Energie Electronique", @@ -128767,6 +129095,7 @@ "154066453217280": "Accord Communications Ltd", "154066453221376": "Duevi Srl", "154066453225472": "DIAS Infrared GmbH", + "154066453229568": "Solotech", "154066453233664": "spar Power Technologies Inc.", "154066453258240": "SIDUS Solutions, LLC", "154066453262336": "Scarlet Tech Co., Ltd.", @@ -128831,6 +129160,7 @@ "154066453680128": "Systems Mechanics", "154066453684224": "elbe informatik GmbH", "154066453692416": "Ruichuangte", + "154066453696512": "Heitec Ag", "154066453700608": "Chipscape Security Systems", "154066453716992": "BnB Information Technology", "154066453737472": "Cambrian Works, Inc.", @@ -128842,6 +129172,7 @@ "154066453786624": "Uisee(Shanghai) Automotive Technologies Ltd.", "154066453798912": "Integer.pl S.A.", "154066453815296": "Anda Telecom Pvt Ltd", + "154066453819392": "broadtek", "154066453823488": "techone system", "154066453831680": "Enki Multimedia", "154066453839872": "Sichuan Aiyijan Technology Company Ltd.", @@ -128898,8 +129229,10 @@ "154066454278144": "Blaucomm Ltd", "154066454286336": "AKSE srl", "154066454290432": "Missing Link Electronics, Inc.", + "154066454294528": "Fluid Components Intl", "154066454302720": "Eb Neuro Spa", "154066454306816": "Novanta IMS", + "154066454315008": "Soca Technology Co., Ltd.", "154066454319104": "VirtualV Trading Limited", "154066454323200": "Vismes sarl", "154066454339584": "Longhorn lntelligent Tech Co.,Ltd.", @@ -128970,6 +129303,7 @@ "154066454880256": "Bellco Trading Company (Pvt) Ltd", "154066454884352": "Beijing Entian Technology Development Co., Ltd", "154066454888448": "Automata GmbH & Co. KG", + "154066454892544": "Shenzhen Guanxin Information Technology Co.,Ltd", "154066454896640": "Panoramic Power", "154066454904832": "Novanta IMS", "154066454908928": "Control Aut Tecnologia em Automação LTDA", @@ -129019,6 +129353,7 @@ "154066455232512": "Dexter Laundry Inc.", "154066455236608": "Deep Detection / ESB01736990", "154066455257088": "Ultiroam", + "154066455265280": "Integer.pl S.A.", "154066455277568": "Avida, Inc.", "154066455281664": "ELTEK SpA", "154066455285760": "Acod", @@ -129026,6 +129361,7 @@ "154066455293952": "Adetec Sas", "154066455306240": "Zmbizi App Llc", "154066455310336": "Ingenious Technology LLC", + "154066455314432": "Flock Audio Inc.", "154066455318528": "Yu-Heng Electric Co., LTD", "154066455339008": "NPO ECO-INTECH Ltd.", "154066455343104": "Potter Electric Signal Company", @@ -129042,6 +129378,7 @@ "154066455453696": "RF Code", "154066455461888": "Tirasoft Technology", "154066455470080": "Primalucelab isrl", + "154066455478272": "Private", "154066455490560": "Delta Computers LLC.", "154066455494656": "Seongwon Eng Co.,Ltd", "154066455511040": "Dave Srl", @@ -129062,6 +129399,7 @@ "154066455609344": "Heitec Ag", "154066455613440": "MPT-Service project", "154066455617536": "Benchmark Electronics BV", + "154066455621632": "SUS Corporation", "154066455638016": "R3Vox Ltd", "154066455642112": "Cooltera Limited", "154066455646208": "Active Research Limited", @@ -129212,6 +129550,7 @@ "154066456821760": "RAB Microfluidics R&D Company Ltd", "154066456834048": "WiTricity Corporation", "154066456846336": "KMtronic ltd", + "154066456850432": "Enless Wireless", "154066456854528": "Bit Trade One, Ltd.", "154066456862720": "Cortical Labs Pte Ltd", "154066456887296": "Elsist Srl", @@ -129241,6 +129580,7 @@ "154066457079808": "Celestica Inc.", "154066457083904": "Heitec Ag", "154066457092096": "Dave Srl", + "154066457104384": "ZER01CHI Corporation", "154066457108480": "Dorlet Sau", "154066457112576": "Abbott Diagnostics Technologies AS", "154066457116672": "Antai technology Co.,Ltd", @@ -129266,6 +129606,7 @@ "154066457243648": "AR Modular RF", "154066457255936": "OpenPark Technologies Kft", "154066457268224": "CITSA Technologies Private Limited", + "154066457280512": "DevRay IT Solutions Private Limited", "154066457284608": "Flextronics International Kft", "154066457288704": "Star Systems International Limited", "154066457300992": "Systel Inc", @@ -129282,6 +129623,7 @@ "154066457370624": "Dorlet Sau", "154066457378816": "Guan Show Technologe Co., Ltd.", "154066457391104": "INVENTIA Sp. z o.o.", + "154066457399296": "Automatizacion Y Conectividad", "154066457411584": "navXperience GmbH", "154066457415680": "Becton Dickinson", "154066457419776": "Visiosoft Pty Ltd", @@ -129314,7 +129656,7 @@ "154066457649152": "D-E-K GmbH & Co.KG", "154066457653248": "E Vision India Pvt Ltd", "154066457657344": "Axid System", - "154066457661440": "EA Elektro-Automatik", + "154066457661440": "EA Elektro-Automatik GmbH", "154066457677824": "Guan Show Technologe Co., Ltd.", "154066457681920": "Keyline S.P.A.", "154066457686016": "James G. Biddle dba Megger", @@ -129345,6 +129687,7 @@ "154066457862144": "Aaronn Electronic GmbH", "154066457866240": "Une Srl", "154066457882624": "robert juliat", + "154066457886720": "EA Elektro-Automatik GmbH", "154066457903104": "Methods2Business B.V.", "154066457907200": "Eding CNC bv", "154066457911296": "Orange Precision Measurement LLC", @@ -129359,7 +129702,7 @@ "154066457989120": "Zhejiang Laolan Information Technology Co., Ltd", "154066457993216": "Daiichi Electric Industry Co., Ltd", "154066457997312": "MOSCA Elektronik und Antriebstechnik GmbH", - "154066458001408": "EA Elektro-Automatik", + "154066458001408": "EA Elektro-Automatik GmbH", "154066458009600": "Matrixspace", "154066458013696": "Giordano Controls Spa", "154066458034176": "Thermify Holdings Ltd", @@ -129377,6 +129720,7 @@ "154066458112000": "ViewSonic Corp", "154066458116096": "Tiama", "154066458124288": "IP Devices", + "154066458132480": "Logicube Inc", "154066458136576": "MTU Aero Engines AG", "154066458161152": "Flow Power", "154066458165248": "Power Electronics Espana, S.L.", @@ -129449,6 +129793,7 @@ "154066458734592": "DA-Design Oy", "154066458738688": "Wien Energie GmbH", "154066458742784": "Zynex Monitoring Solutions", + "154066458763264": "YUYAMA MFG Co.,Ltd", "154066458779648": "Cirrus Systems, Inc.", "154066458787840": "Hermes Network Inc", "154066458791936": "NextT Microwave Inc", @@ -129494,6 +129839,7 @@ "154066459095040": "BELIMO Automation AG", "154066459099136": "Vortex IoT Ltd", "154066459103232": "Eolane", + "154066459107328": "MARIAN GmbH", "154066459111424": "Zeus Product Design Ltd", "154066459131904": "Abbott Diagnostics Technologies AS", "154066459140096": "Profcon AB", @@ -129533,9 +129879,10 @@ "154066459435008": "Umano Medical Inc.", "154066459439104": "Gogo Business Aviation", "154066459443200": "Power Electronics Espana, S.L.", + "154066459447296": "Potter Electric Signal Company", "154066459455488": "Dave Srl", "154066459459584": "Iav Engineering Sarl", - "154066459467776": "EA Elektro-Automatik", + "154066459467776": "EA Elektro-Automatik GmbH", "154066459492352": "Potter Electric Signal Co. LLC", "154066459496448": "Infrasafe/ Advantor Systems", "154066459504640": "Dorsett Technologies Inc", @@ -129548,6 +129895,7 @@ "154066459574272": "Abacus Peripherals Pvt Ltd", "154066459586560": "Peter Huber Kaeltemaschinenbau SE", "154066459594752": "Phe-nX B.V.", + "154066459598848": "Ligpt", "154066459602944": "Syscom Instruments SA", "154066459607040": "PAN Business & Consulting (ANYOS]", "154066459611136": "Aksel sp. z o.o.", @@ -129569,6 +129917,7 @@ "154066459738112": "Hangzhou Jingtang Communication Technology Co.,Ltd.", "154066459762688": "Emerson Rosemount Analytical", "154066459766784": "Böckelt GmbH", + "154066459774976": "Berkeley Nucleonics Corp", "154066459779072": "GS Elektromedizinsiche Geräte G. Stemple GmbH", "154066459783168": "Stercom Power Soltions GmbH", "154066459787264": "Makel Elektrik Malzemeleri A.Ş.", @@ -129586,7 +129935,7 @@ "154066459877376": "Exi Flow Measurement Ltd", "154066459881472": "ASAP Electronics GmbH", "154066459885568": "Saline Lectronics, Inc.", - "154066459897856": "EA Elektro-Automatik", + "154066459897856": "EA Elektro-Automatik GmbH", "154066459901952": "Wolfspyre Labs", "154066459918336": "Integer.pl S.A.", "154066459930624": "HD Renewable Energy Co.,Ltd", @@ -129645,10 +129994,12 @@ "154066460352512": "Rodgers Instruments US LLC", "154066460360704": "Rapidev Pvt Ltd", "154066460372992": "Saarni Cloud Oy", + "154066460377088": "Wallenius Water Innovation AB", "154066460381184": "Integer.pl S.A.", "154066460385280": "YUYAMA MFG Co.,Ltd", "154066460393472": "Flextronics International Kft", "154066460401664": "Syscom Instruments SA", + "154066460405760": "Ascon Tecnologic S.r.l.", "154066460413952": "Babtel", "154066460434432": "Flextronics International Kft", "154066460438528": "EkspertStroyProekt", @@ -129668,6 +130019,7 @@ "154066460565504": "DEUTA-WERKE GmbH", "154066460569600": "Rax-Tech International", "154066460585984": "CPAT Flex Inc.", + "154066460590080": "Proprietary Controls Systems Corporation", "154066460610560": "3D perception AS", "154066460618752": "EkspertStroyProekt", "154066460622848": "Beijing Wenrise Technology Co., Ltd.", @@ -129751,6 +130103,7 @@ "154066461229056": "Grossenbacher Systeme AG", "154066461233152": "DITRON S.r.l.", "154066461241344": "Nov'in", + "154066461249536": "Tocho Marking Systems America, Inc", "154066461261824": "Lechpol Electronics Spółka z o.o. Sp.k.", "154066461270016": "Blighter Surveillance Systems Ltd", "154066461278208": "Abb", @@ -129779,6 +130132,7 @@ "154066461495296": "Vision Systems Safety Tech", "154066461499392": "YUYAMA MFG Co.,Ltd", "154066461503488": "Tri-light Wuhan Electronics Technology Co.,Ltd", + "154066461519872": "Code Blue Corporation", "154066461540352": "Televic Rail GmbH", "154066461544448": "HomyHub SL", "154066461552640": "M2M craft Co., Ltd.", @@ -129805,6 +130159,7 @@ "154066461708288": "Tongye lnnovation Science and Technology (Shenzhen) Co.,Ltd", "154066461724672": "Clealink Technology", "154066461728768": "Neurable", + "154066461732864": "Modern Server Solutions LLP", "154066461749248": "Gemini Electronics B.V.", "154066461753344": "Calamity, Inc.", "154066461757440": "iLifeX", @@ -129812,6 +130167,8 @@ "154066461765632": "Kromek Limited", "154066461777920": "Power Electronics Espana, S.L.", "154066461782016": "Lithion Battery Inc", + "154066461786112": "Jmv Lps Ltd", + "154066461794304": "BESO sp. z o.o.", "154066461798400": "DEUTA-WERKE GmbH", "154066461810688": "FMC Technologies Measurement Solutions Inc", "154066461814784": "iLensys Technologies PVT LTD", @@ -129929,9 +130286,10 @@ "154066462605312": "Fiberme Communications Llc", "154066462613504": "Red Phase Technologies Limited", "154066462617600": "Mediana", - "154066462625792": "EA Elektro-Automatik", + "154066462625792": "EA Elektro-Automatik GmbH", "154066462629888": "Safe Instruments", "154066462642176": "Yaviar LLC", + "154066462674944": "P3Lab", "154066462683136": "Freedom Atlantic", "154066462687232": "MERKLE Schweissanlagen-Technik GmbH", "154066462691328": "Glasson Electronics Ltd", @@ -130009,6 +130367,8 @@ "154066463305728": "EYatsko Individual", "154066463313920": "MB connect line GmbH", "154066463322112": "I.S.A. - Altanova group srl", + "154066463326208": "Wuxi Tongxin Hengtong Technology Co., Ltd.", + "154066463330304": "Ynm Systems Inc.", "154066463334400": "Monnit Corporation", "154066463338496": "Audiodo International AB", "154066463342592": "Vesper Technologies", @@ -130066,6 +130426,7 @@ "154066463809536": "Potter Electric Signal Co. LLC", "154066463813632": "DEUTA-WERKE GmbH", "154066463817728": "SMITEC S.p.A.", + "154066463821824": "Zhejiang Healnoc Technology Co., Ltd.", "154066463825920": "Mitsubishi Electric India Pvt. Ltd.", "154066463830016": "Algodue Elettronica Srl", "154066463842304": "Smart Cabling & Transmission Corp.", @@ -130109,6 +130470,7 @@ "154066464149504": "Franke Aquarotter GmbH", "154066464153600": "Softgent sp. z o.o.", "154066464165888": "Gogo Business Aviation", + "154066464169984": "IHI Inspection & Instrumentation Co.,Ltd.", "154066464182272": "EON Technology, Corp", "154066464186368": "Natron Energy", "154066464190464": "PXM Marek Zupnik spolka komandytowa", @@ -130122,6 +130484,7 @@ "154066464276480": "Dvb-Tech S.R.L.", "154066464284672": "ITS Teknik A/S", "154066464292864": "新川センサテクノロジ株式会社", + "154066464309248": "Imagenet Co.,Ltd", "154066464313344": "Enless Wireless", "154066464321536": "Laurel Electronics LLC", "154066464325632": "Telestrider Sa", @@ -130131,6 +130494,7 @@ "154066464358400": "Proserv", "154066464362496": "Panascais ehf.", "154066464382976": "DAccess Security Systems P Ltd", + "154066464395264": "Xworks NZ Limited", "154066464399360": "Flextronics International Kft", "154066464411648": "LG-LHT Aircraft Solutions GmbH", "154066464419840": "Chemito Infotech PVT LTD", @@ -130145,6 +130509,7 @@ "154066464514048": "AITEC Corporation", "154066464522240": "Finotex Electronic Solutions PVT LTD", "154066464534528": "Teletech Services", + "154066464538624": "ThermoG Limited", "154066464542720": "Grossenbacher Systeme AG", "154066464546816": "Shenzhen Forddok Technology Co., Ltd", "154066464550912": "Daedalean AG", @@ -130182,6 +130547,7 @@ "154066464772096": "Shenzhen Guangwen Industrial Co.,Ltd", "154066464780288": "Dongguan Pengchen Earth Instrument CO. LT", "154066464784384": "Ashinne Technology Co., Ltd", + "154066464788480": "Audio Visual Digital Systems", "154066464800768": "Power Electronics Espana, S.L.", "154066464825344": "ComVetia AG", "154066464833536": "SiFive Inc", @@ -130191,7 +130557,7 @@ "154066464854016": "Plura", "154066464862208": "JieChuang HeYi(Beijing) Technology Co., Ltd.", "154066464866304": "MHE Electronics", - "154066464874496": "EA Elektro-Automatik", + "154066464874496": "EA Elektro-Automatik GmbH", "154066464882688": "Zin Technologies", "154066464899072": "Luxshare Electronic Technology (Kunshan) LTD", "154066464903168": "Pantherun Technologies Pvt Ltd", @@ -130203,6 +130569,7 @@ "154066464980992": "Miracle Healthcare, Inc.", "154066464985088": "Messung Systems Pvt Ltd", "154066464989184": "Traffic Polska sp. z o. o.", + "154066464997376": "Exyte Technology GmbH", "154066465005568": "Aqua Broadcast Ltd", "154066465017856": "Meiryo Denshi Corp.", "154066465026048": "Delta Solutions LLC", @@ -130278,7 +130645,7 @@ "154066465660928": "AMF Medical SA", "154066465665024": "Beckman Coulter Inc", "154066465677312": "KC5 International Sdn Bhd", - "154066465681408": "EA Elektro-Automatik", + "154066465681408": "EA Elektro-Automatik GmbH", "154066465689600": "Inovonics Inc.", "154066465693696": "Telco Antennas Pty Ltd", "154066465697792": "SemaConnect, Inc", @@ -130335,6 +130702,7 @@ "154066466115584": "Nidec asi spa", "154066466119680": "I/O Controls", "154066466123776": "Cyclops Technology Group", + "154066466127872": "Dorlet Sau", "154066466131968": "Sumico", "154066466160640": "Gredmann Taiwan Ltd.", "154066466164736": "elbit systems - EW and sigint - Elisra", From 631245d08f87147d97e82e4ff0e2bbe0dfdbe866 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Tue, 18 Mar 2025 10:37:31 +0200 Subject: [PATCH 16/36] Marked Logger copy ctors as deleted. (#1714) --- Common++/header/Logger.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Common++/header/Logger.h b/Common++/header/Logger.h index df9ce372ee..fc36013cb9 100644 --- a/Common++/header/Logger.h +++ b/Common++/header/Logger.h @@ -223,6 +223,9 @@ namespace pcpp class Logger { public: + Logger(const Logger&) = delete; + Logger& operator=(const Logger&) = delete; + // Deprecated, Use the LogLevel in the pcpp namespace instead. using LogLevel = pcpp::LogLevel; PCPP_DEPRECATED("Use the LogLevel in the pcpp namespace instead.") From 49ac8ef78c4d0f6455e16e57d1fe71349fca16c5 Mon Sep 17 00:00:00 2001 From: seladb Date: Tue, 18 Mar 2025 02:29:56 -0700 Subject: [PATCH 17/36] Update GitHub Actions Cache to 4.2.2 (#1729) --- .github/workflows/build_and_test.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index bc9eeef8ba..6f18b0df45 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -91,7 +91,7 @@ jobs: - name: Restore Ccache id: ccache-restore - uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2 with: path: | ${{ env.CCACHE_DIR }} @@ -156,7 +156,7 @@ jobs: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - name: Save Ccache - uses: actions/cache/save@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2 with: path: ${{ env.CCACHE_DIR }} key: ${{ steps.ccache-restore.outputs.cache-primary-key }} @@ -179,7 +179,7 @@ jobs: - name: Restore Ccache id: ccache-restore - uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2 with: path: ${{ env.CCACHE_DIR }} key: ${{ matrix.image }}-ccache-${{ github.run_id }} @@ -220,7 +220,7 @@ jobs: run: cd build_examples/tutorials_bin && ./Tutorial-HelloWorld - name: Save Ccache - uses: actions/cache/save@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2 with: path: ${{ env.CCACHE_DIR }} key: ${{ steps.ccache-restore.outputs.cache-primary-key }} @@ -239,7 +239,7 @@ jobs: - name: Restore Ccache id: ccache-restore - uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2 with: path: ${{ env.CCACHE_DIR }} key: ${{ matrix.image }}-ccache-${{ github.run_id }} @@ -277,7 +277,7 @@ jobs: run: cd build_examples/tutorials_bin && ./Tutorial-HelloWorld - name: Save Ccache - uses: actions/cache/save@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2 with: path: ${{ env.CCACHE_DIR }} key: ${{ steps.ccache-restore.outputs.cache-primary-key }} @@ -331,7 +331,7 @@ jobs: - name: Restore Ccache id: ccache-restore - uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2 with: path: ${{ env.CCACHE_DIR }} key: ${{ matrix.os-version }}-${{ matrix.arch }}-ccache-${{ github.run_id }} @@ -405,7 +405,7 @@ jobs: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - name: Save Ccache - uses: actions/cache/save@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2 with: path: ${{ env.CCACHE_DIR }} key: ${{ steps.ccache-restore.outputs.cache-primary-key }} @@ -713,7 +713,7 @@ jobs: - name: Restore Ccache id: ccache-restore - uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2 with: path: ${{ env.CCACHE_DIR }} key: ${{ matrix.image }}-ccache-${{ github.run_id }} @@ -753,7 +753,7 @@ jobs: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - name: Save Ccache - uses: actions/cache/save@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2 with: path: ${{ env.CCACHE_DIR }} key: ${{ steps.ccache-restore.outputs.cache-primary-key }} @@ -782,7 +782,7 @@ jobs: - name: Restore Ccache id: ccache-restore - uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2 with: path: ${{ env.CCACHE_DIR }} key: ${{ matrix.engine }}-${{ matrix.sanitizer }}-ccache-${{ github.run_id }} @@ -804,7 +804,7 @@ jobs: Tests/Fuzzers/RegressionTests/run_tests.sh - name: Save Ccache - uses: actions/cache/save@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2 with: path: ${{ env.CCACHE_DIR }} key: ${{ steps.ccache-restore.outputs.cache-primary-key }} From 62e4f351f79db1198827eef6d81ed4c95f465d01 Mon Sep 17 00:00:00 2001 From: Ivan Morozko Date: Tue, 18 Mar 2025 13:13:47 +0300 Subject: [PATCH 18/36] Fix memory management in RawPacket (#1709) Ensure that the destructor and assignment operator correctly handle the deletion of raw data based on the m_DeleteRawDataAtDestructor flag by using the updated clear() method. Update comments to reflect these changes. Co-authored-by: seladb --- Packet++/header/RawPacket.h | 8 +++----- Packet++/src/RawPacket.cpp | 21 +++++---------------- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/Packet++/header/RawPacket.h b/Packet++/header/RawPacket.h index 0cdf34efe0..32b337faea 100644 --- a/Packet++/header/RawPacket.h +++ b/Packet++/header/RawPacket.h @@ -311,9 +311,8 @@ namespace pcpp RawPacket(const RawPacket& other); /// Assignment operator overload for this class. When using this operator on an already initialized RawPacket - /// instance, the original raw data is freed first. Then the other instance is copied to this instance, the same - /// way the copy constructor works - /// @todo free raw data only if deleteRawDataAtDestructor was set to 'true' + /// instance, the original raw data is freed first if deleteRawDataAtDestructor was set to 'true'. + /// Then the other instance is copied to this instance, the same way the copy constructor works /// @param[in] other The instance to copy from RawPacket& operator=(const RawPacket& other); @@ -423,8 +422,7 @@ namespace pcpp } /// Clears all members of this instance, meaning setting raw data to nullptr, raw data length to 0, etc. - /// Currently raw data is always freed, even if deleteRawDataAtDestructor was set to 'false' - /// @todo deleteRawDataAtDestructor was set to 'true', don't free the raw data + /// Frees the raw data if deleteRawDataAtDestructor was set to 'true' /// @todo set timestamp to a default value as well virtual void clear(); diff --git a/Packet++/src/RawPacket.cpp b/Packet++/src/RawPacket.cpp index a68385bb94..4eb36b31a6 100644 --- a/Packet++/src/RawPacket.cpp +++ b/Packet++/src/RawPacket.cpp @@ -41,10 +41,7 @@ namespace pcpp RawPacket::~RawPacket() { - if (m_DeleteRawDataAtDestructor) - { - delete[] m_RawData; - } + clear(); } RawPacket::RawPacket(const RawPacket& other) @@ -57,10 +54,7 @@ namespace pcpp { if (this != &other) { - if (m_RawData != nullptr) - delete[] m_RawData; - - m_RawPacketSet = false; + clear(); copyDataFrom(other, true); } @@ -104,14 +98,9 @@ namespace pcpp bool RawPacket::setRawData(const uint8_t* pRawData, int rawDataLen, timespec timestamp, LinkLayerType layerType, int frameLength) { - if (frameLength == -1) - frameLength = rawDataLen; - m_FrameLength = frameLength; - if (m_RawData != nullptr && m_DeleteRawDataAtDestructor) - { - delete[] m_RawData; - } + clear(); + m_FrameLength = (frameLength == -1) ? rawDataLen : frameLength; m_RawData = (uint8_t*)pRawData; m_RawDataLen = rawDataLen; m_TimeStamp = timestamp; @@ -129,7 +118,7 @@ namespace pcpp void RawPacket::clear() { - if (m_RawData != nullptr) + if (m_RawData != nullptr && m_DeleteRawDataAtDestructor) delete[] m_RawData; m_RawData = nullptr; From 4f650ff46a29ab39f1e78a405369f32f6ae60d8f Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Tue, 18 Mar 2025 12:25:52 +0200 Subject: [PATCH 19/36] Use lowercase for Windows headers (#1716) These are all in _MSC_VER which is Windows-only, but let them be lower for consistency. Co-authored-by: seladb --- 3rdParty/LightPcapNg/LightPcapNg/include/light_pcapng_ext.h | 2 +- Packet++/header/IcmpLayer.h | 2 +- Packet++/header/RawPacket.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/3rdParty/LightPcapNg/LightPcapNg/include/light_pcapng_ext.h b/3rdParty/LightPcapNg/LightPcapNg/include/light_pcapng_ext.h index 624d937411..c604a7e27c 100644 --- a/3rdParty/LightPcapNg/LightPcapNg/include/light_pcapng_ext.h +++ b/3rdParty/LightPcapNg/LightPcapNg/include/light_pcapng_ext.h @@ -33,7 +33,7 @@ extern "C" { #include #include #ifdef _MSC_VER -#include +#include #include #else #include diff --git a/Packet++/header/IcmpLayer.h b/Packet++/header/IcmpLayer.h index 0f629ef3b6..940aa8ce3d 100644 --- a/Packet++/header/IcmpLayer.h +++ b/Packet++/header/IcmpLayer.h @@ -3,7 +3,7 @@ #include "Layer.h" #include "IPv4Layer.h" #ifdef _MSC_VER -# include +# include #else # include #endif diff --git a/Packet++/header/RawPacket.h b/Packet++/header/RawPacket.h index 32b337faea..8fc7483984 100644 --- a/Packet++/header/RawPacket.h +++ b/Packet++/header/RawPacket.h @@ -2,7 +2,7 @@ #include #ifdef _MSC_VER -# include +# include # include #else # include From 231cba2dfeeb28bc596d2d15f6aa153ab0514d63 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Wed, 19 Mar 2025 07:51:32 +0200 Subject: [PATCH 20/36] Allow gratuitous ARP requests. (#1684) --- Common++/header/MacAddress.h | 2 + Common++/src/MacAddress.cpp | 2 + Examples/ArpSpoofing/main.cpp | 7 +- Packet++/header/ArpLayer.h | 133 +++++++++++++++- Packet++/src/ArpLayer.cpp | 86 +++++++++-- Pcap++/src/NetworkUtils.cpp | 6 +- Tests/Packet++Test/Tests/EthAndArpTests.cpp | 161 +++++++++++++++++--- Tests/Packet++Test/Tests/VlanMplsTests.cpp | 4 +- Tests/Packet++Test/Utils/TestUtils.cpp | 38 +++++ Tests/Packet++Test/Utils/TestUtils.h | 2 + 10 files changed, 390 insertions(+), 51 deletions(-) diff --git a/Common++/header/MacAddress.h b/Common++/header/MacAddress.h index 1cf5852e6b..2f172c332d 100644 --- a/Common++/header/MacAddress.h +++ b/Common++/header/MacAddress.h @@ -143,6 +143,8 @@ namespace pcpp /// A static value representing a zero value of MAC address, meaning address of value "00:00:00:00:00:00" static MacAddress Zero; + /// A static value representing a broadcast MAC address, meaning address of value "ff:ff:ff:ff:ff:ff" + static MacAddress Broadcast; private: std::array m_Address{}; diff --git a/Common++/src/MacAddress.cpp b/Common++/src/MacAddress.cpp index 18886faaea..29d2449c7d 100644 --- a/Common++/src/MacAddress.cpp +++ b/Common++/src/MacAddress.cpp @@ -5,6 +5,8 @@ namespace pcpp MacAddress MacAddress::Zero(0, 0, 0, 0, 0, 0); + MacAddress MacAddress::Broadcast(0xff, 0xff, 0xff, 0xff, 0xff, 0xff); + std::string MacAddress::toString() const { char str[19]; diff --git a/Examples/ArpSpoofing/main.cpp b/Examples/ArpSpoofing/main.cpp index 538dd4c7b8..0db3a604ca 100644 --- a/Examples/ArpSpoofing/main.cpp +++ b/Examples/ArpSpoofing/main.cpp @@ -66,8 +66,7 @@ pcpp::MacAddress getMacAddress(const pcpp::IPv4Address& ipAddr, pcpp::PcapLiveDe pcpp::MacAddress macSrc = pDevice->getMacAddress(); pcpp::MacAddress macDst(0xff, 0xff, 0xff, 0xff, 0xff, 0xff); pcpp::EthLayer ethLayer(macSrc, macDst, static_cast(PCPP_ETHERTYPE_ARP)); - pcpp::ArpLayer arpLayer(pcpp::ARP_REQUEST, pDevice->getMacAddress(), pDevice->getMacAddress(), - pDevice->getIPv4Address(), ipAddr); + pcpp::ArpLayer arpLayer(pcpp::ArpRequest(pDevice->getMacAddress(), pDevice->getIPv4Address(), ipAddr)); arpRequest.addLayer(ðLayer); arpRequest.addLayer(&arpLayer); @@ -137,7 +136,7 @@ void doArpSpoofing(pcpp::PcapLiveDevice* pDevice, const pcpp::IPv4Address& gatew // Create ARP reply for the gateway pcpp::Packet gwArpReply(500); pcpp::EthLayer gwEthLayer(deviceMacAddress, gatewayMacAddr, static_cast(PCPP_ETHERTYPE_ARP)); - pcpp::ArpLayer gwArpLayer(pcpp::ARP_REPLY, pDevice->getMacAddress(), gatewayMacAddr, victimAddr, gatewayAddr); + pcpp::ArpLayer gwArpLayer(pcpp::ArpReply(pDevice->getMacAddress(), victimAddr, gatewayMacAddr, gatewayAddr)); gwArpReply.addLayer(&gwEthLayer); gwArpReply.addLayer(&gwArpLayer); gwArpReply.computeCalculateFields(); @@ -145,7 +144,7 @@ void doArpSpoofing(pcpp::PcapLiveDevice* pDevice, const pcpp::IPv4Address& gatew // Create ARP reply for the victim pcpp::Packet victimArpReply(500); pcpp::EthLayer victimEthLayer(deviceMacAddress, victimMacAddr, static_cast(PCPP_ETHERTYPE_ARP)); - pcpp::ArpLayer victimArpLayer(pcpp::ARP_REPLY, pDevice->getMacAddress(), victimMacAddr, gatewayAddr, victimAddr); + pcpp::ArpLayer victimArpLayer(pcpp::ArpReply(pDevice->getMacAddress(), gatewayAddr, victimMacAddr, victimAddr)); victimArpReply.addLayer(&victimEthLayer); victimArpReply.addLayer(&victimArpLayer); victimArpReply.computeCalculateFields(); diff --git a/Packet++/header/ArpLayer.h b/Packet++/header/ArpLayer.h index 0b1a3278e6..02251c4207 100644 --- a/Packet++/header/ArpLayer.h +++ b/Packet++/header/ArpLayer.h @@ -3,6 +3,7 @@ #include "Layer.h" #include "IpAddress.h" #include "MacAddress.h" +#include "DeprecationUtils.h" /// @file @@ -37,6 +38,7 @@ namespace pcpp uint32_t targetIpAddr; }; #pragma pack(pop) + static_assert(sizeof(arphdr) == 28, "arphdr size is not 28 bytes"); /// An enum for ARP message type enum ArpOpcode @@ -45,6 +47,97 @@ namespace pcpp ARP_REPLY = 0x0002 ///< ARP reply (response) }; + /// @brief An enum representing the ARP message type + enum class ArpMessageType + { + Unknown, ///< Unknown ARP message type + Request, ///< ARP request + Reply, ///< ARP reply + GratuitousRequest, ///< Gratuitous ARP request + GratuitousReply, ///< Gratuitous ARP reply + }; + + /// @brief A struct representing the build data for an ARP request + /// + /// An ARP request is a message sent by a machine to request the MAC address of another machine on the network. + struct ArpRequest + { + MacAddress senderMacAddr; + IPv4Address senderIpAddr; + IPv4Address targetIpAddr; + + /// @brief Construct a new Arp Request object + /// @param senderMacAddress The MAC address of the machine sending the query. + /// @param senderIPAddress The IP address of the machine sending the query. + /// @param targetIPAddress The IP address of the target machine being queried. + ArpRequest(MacAddress const& senderMacAddress, IPv4Address const& senderIPAddress, + IPv4Address const& targetIPAddress) + : senderMacAddr(senderMacAddress), senderIpAddr(senderIPAddress), targetIpAddr(targetIPAddress) {}; + }; + + /// @brief A struct representing the build data for an ARP reply + /// + /// An ARP reply is a message sent by a machine in response to an ARP request. It contains the MAC address of the + /// answering machine, and is sent to the IP/MAC address of the machine that sent the original ARP request. + struct ArpReply + { + MacAddress senderMacAddr; + IPv4Address senderIpAddr; + MacAddress targetMacAddr; + IPv4Address targetIpAddr; + + /// @brief Construct a new Arp Reply object + /// @param senderMacAddress The MAC address of the machine sending the reply. + /// @param senderIPAddress The IP address of the machine sending the reply. + /// @param targetMacAddress The MAC address of the target machine being replied to. + /// @param targetIPAddress The IP address of the target machine being replied to. + /// @remarks The target machine is considered the machine that sent the original ARP request. + ArpReply(MacAddress const& senderMacAddress, IPv4Address const& senderIPAddress, + MacAddress const& targetMacAddress, IPv4Address const& targetIPAddress) + : senderMacAddr(senderMacAddress), senderIpAddr(senderIPAddress), targetMacAddr(targetMacAddress), + targetIpAddr(targetIPAddress) {}; + }; + + /// @brief A struct representing the build data for a gratuitous ARP request + /// + /// A gratuitous ARP request is an ARP request that is sent by a machine to announce its presence on the network. + /// It is an ARP request that has both the sender and target IP addresses set to the IP address of the machine + /// and the target MAC address set to the broadcast address. Normally such a request will not receive a reply. + /// + /// These requests can be used to update ARP caches on other machines on the network, or to help in detecting IP + /// address conflicts. + struct GratuitousArpRequest + { + MacAddress senderMacAddr; + IPv4Address senderIpAddr; + + /// @brief Construct a new Gratuitous Arp Request object + /// @param senderMacAddress The MAC address of the machine sending the gratuitous ARP request. + /// @param senderIPAddress The IP address of the machine sending the gratuitous ARP request. + /// @remarks The target MAC address is set to the broadcast address and the target IP address is set to the + /// sender's. + GratuitousArpRequest(MacAddress const& senderMacAddress, IPv4Address const& senderIPAddress) + : senderMacAddr(senderMacAddress), senderIpAddr(senderIPAddress) {}; + }; + + /// @brief A struct representing the build data a gratuitous ARP reply + /// + /// A gratuitous ARP reply is an ARP reply that is sent by a machine to announce its presence on the network. + /// It is gratuitous in the sense that it is not in response to an ARP request, but sent unsolicited to the network. + struct GratuitousArpReply + { + MacAddress senderMacAddr; + IPv4Address senderIpAddr; + + /// @brief Construct a new Gratuitous Arp Reply object + /// @param senderMacAddress The MAC address of the machine sending the gratuitous ARP reply. + /// @param senderIPAddress The IP address of the machine sending the gratuitous ARP reply. + /// @remarks The target MAC address is set to the broadcast address and the target IP address is set to the + /// sender's. + GratuitousArpReply(MacAddress const& senderMacAddress, IPv4Address const& senderIPAddress) + : senderMacAddr(senderMacAddress), senderIpAddr(senderIPAddress) {}; + }; + /// @class ArpLayer /// Represents an ARP protocol layer. Currently only IPv4 ARP messages are supported class ArpLayer : public Layer @@ -61,15 +154,45 @@ namespace pcpp m_DataLen = sizeof(arphdr); } + /// @brief A constructor that creates an ARP header + /// @param[in] opCode ARP message type (ARP request or ARP reply) + /// @param[in] senderMacAddr The sender MAC address (will be put in arphdr#senderMacAddr) + /// @param[in] senderIpAddr The sender IP address (will be put in arphdr#senderIpAddr) + /// @param[in] targetMacAddr The target MAC address (will be put in arphdr#targetMacAddr) + /// @param[in] targetIpAddr The target IP address (will be put in arphdr#targetIpAddr) + /// @remarks No validation is done on the input parameters. The caller must ensure that the input creates a + /// valid header. + ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const IPv4Address& senderIpAddr, + const MacAddress& targetMacAddr, const IPv4Address& targetIpAddr); + /// A constructor that allocates a new ARP header /// @param[in] opCode ARP message type (ARP request or ARP reply) /// @param[in] senderMacAddr The sender MAC address (will be put in arphdr#senderMacAddr) /// @param[in] targetMacAddr The target MAC address (will be put in arphdr#targetMacAddr) /// @param[in] senderIpAddr The sender IP address (will be put in arphdr#senderIpAddr) /// @param[in] targetIpAddr The target IP address (will be put in arphdr#targetIpAddr) + /// @deprecated This constructor has been deprecated. Please use one of the other overloads. + /// @remarks This constructor zeroes the target MAC address for ARP requests to keep backward compatibility. + PCPP_DEPRECATED("This constructor has been deprecated. Please use one of the other overloads.") ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const MacAddress& targetMacAddr, const IPv4Address& senderIpAddr, const IPv4Address& targetIpAddr); + /// @brief A constructor that creates an ARP request header. + /// @param arpRequest The ARP request data + explicit ArpLayer(ArpRequest const& arpRequest); + + /// @brief A constructor that creates an ARP reply header. + /// @param arpReply The ARP reply data + explicit ArpLayer(ArpReply const& arpReply); + + /// @brief A constructor that creates a gratuitous ARP request header. + /// @param gratuitousArpRequest The gratuitous ARP request data + explicit ArpLayer(GratuitousArpRequest const& gratuitousArpRequest); + + /// @brief A constructor that creates a gratuitous ARP reply header. + /// @param gratuitousArpReply The gratuitous ARP reply data + explicit ArpLayer(GratuitousArpReply const& gratuitousArpReply); + ~ArpLayer() override = default; /// Get a pointer to the ARP header. Notice this points directly to the data, so every change will change the @@ -80,6 +203,11 @@ namespace pcpp return reinterpret_cast(m_Data); } + /// Get the ARP opcode + /// @return The ARP opcode + /// @remarks The opcode may not be one of the values in @ref ArpOpcode + ArpOpcode getOpcode() const; + /// Get the sender hardware address (SHA) in the form of MacAddress /// @return A MacAddress containing the sender hardware address (SHA) inline MacAddress getSenderMacAddress() const @@ -125,9 +253,12 @@ namespace pcpp /// - @ref arphdr#hardwareSize = 6 /// - @ref arphdr#protocolType = ETHERTYPE_IP (assume IPv4 over ARP) /// - @ref arphdr#protocolSize = 4 (assume IPv4 over ARP) - /// - if it's an ARP request: @ref arphdr#targetMacAddr = MacAddress("00:00:00:00:00:00") void computeCalculateFields() override; + /// @brief Attempts to determine the ARP message type based on the header signature. + /// @return An @ref ArpMessageType representing the ARP message type. + ArpMessageType getMessageType() const; + /// Is this packet an ARP request? bool isRequest() const; diff --git a/Packet++/src/ArpLayer.cpp b/Packet++/src/ArpLayer.cpp index 4971addd37..0ae415d27f 100644 --- a/Packet++/src/ArpLayer.cpp +++ b/Packet++/src/ArpLayer.cpp @@ -6,22 +6,52 @@ namespace pcpp { - - ArpLayer::ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const MacAddress& targetMacAddr, - const IPv4Address& senderIpAddr, const IPv4Address& targetIpAddr) + ArpLayer::ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const IPv4Address& senderIpAddr, + const MacAddress& targetMacAddr, const IPv4Address& targetIpAddr) { - const size_t headerLen = sizeof(arphdr); + constexpr size_t headerLen = sizeof(arphdr); m_DataLen = headerLen; - m_Data = new uint8_t[headerLen]; - memset(m_Data, 0, sizeof(headerLen)); + m_Data = new uint8_t[headerLen]{}; // zero-initialized m_Protocol = ARP; arphdr* arpHeader = getArpHeader(); arpHeader->opcode = htobe16(static_cast(opCode)); - targetMacAddr.copyTo(arpHeader->targetMacAddr); senderMacAddr.copyTo(arpHeader->senderMacAddr); - arpHeader->targetIpAddr = targetIpAddr.toInt(); + targetMacAddr.copyTo(arpHeader->targetMacAddr); arpHeader->senderIpAddr = senderIpAddr.toInt(); + arpHeader->targetIpAddr = targetIpAddr.toInt(); + } + + // This constructor zeroes the target MAC address for ARP requests to keep backward compatibility. + ArpLayer::ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const MacAddress& targetMacAddr, + const IPv4Address& senderIpAddr, const IPv4Address& targetIpAddr) + : ArpLayer(opCode, senderMacAddr, senderIpAddr, opCode == ARP_REQUEST ? MacAddress::Zero : targetMacAddr, + targetIpAddr) + {} + + ArpLayer::ArpLayer(ArpRequest const& arpRequest) + : ArpLayer(ARP_REQUEST, arpRequest.senderMacAddr, arpRequest.senderIpAddr, MacAddress::Zero, + arpRequest.targetIpAddr) + {} + + ArpLayer::ArpLayer(ArpReply const& arpReply) + : ArpLayer(ARP_REPLY, arpReply.senderMacAddr, arpReply.senderIpAddr, arpReply.targetMacAddr, + arpReply.targetIpAddr) + {} + + ArpLayer::ArpLayer(GratuitousArpRequest const& gratuitousArpRequest) + : ArpLayer(ARP_REQUEST, gratuitousArpRequest.senderMacAddr, gratuitousArpRequest.senderIpAddr, + MacAddress::Broadcast, gratuitousArpRequest.senderIpAddr) + {} + + ArpLayer::ArpLayer(GratuitousArpReply const& gratuitousArpReply) + : ArpLayer(ARP_REPLY, gratuitousArpReply.senderMacAddr, gratuitousArpReply.senderIpAddr, MacAddress::Broadcast, + gratuitousArpReply.senderIpAddr) + {} + + ArpOpcode ArpLayer::getOpcode() const + { + return static_cast(be16toh(getArpHeader()->opcode)); } void ArpLayer::computeCalculateFields() @@ -31,31 +61,55 @@ namespace pcpp arpHeader->hardwareSize = 6; arpHeader->protocolType = htobe16(PCPP_ETHERTYPE_IP); // assume IPv4 over ARP arpHeader->protocolSize = 4; // assume IPv4 over ARP - if (arpHeader->opcode == htobe16(ARP_REQUEST)) - MacAddress::Zero.copyTo(arpHeader->targetMacAddr); + } + + ArpMessageType ArpLayer::getMessageType() const + { + switch (getOpcode()) + { + case ArpOpcode::ARP_REQUEST: + { + if (getTargetMacAddress() == MacAddress::Broadcast && getSenderIpAddr() == getTargetIpAddr()) + { + return ArpMessageType::GratuitousRequest; + } + return ArpMessageType::Request; + } + case ArpOpcode::ARP_REPLY: + { + if (getTargetMacAddress() == MacAddress::Broadcast && getSenderIpAddr() == getTargetIpAddr()) + { + return ArpMessageType::GratuitousReply; + } + return ArpMessageType::Reply; + } + default: + return ArpMessageType::Unknown; + } } bool ArpLayer::isRequest() const { - return be16toh(getArpHeader()->opcode) == pcpp::ArpOpcode::ARP_REQUEST; + return getOpcode() == pcpp::ArpOpcode::ARP_REQUEST; } bool ArpLayer::isReply() const { - return be16toh(getArpHeader()->opcode) == pcpp::ArpOpcode::ARP_REPLY; + return getOpcode() == pcpp::ArpOpcode::ARP_REPLY; } std::string ArpLayer::toString() const { - if (be16toh(getArpHeader()->opcode) == ARP_REQUEST) + switch (getOpcode()) { + case ArpOpcode::ARP_REQUEST: return "ARP Layer, ARP request, who has " + getTargetIpAddr().toString() + " ? Tell " + getSenderIpAddr().toString(); - } - else - { + case ArpOpcode::ARP_REPLY: return "ARP Layer, ARP reply, " + getSenderIpAddr().toString() + " is at " + getSenderMacAddress().toString(); + default: + return "ARP Layer, unknown opcode (" + std::to_string(getOpcode()) + ")"; } } diff --git a/Pcap++/src/NetworkUtils.cpp b/Pcap++/src/NetworkUtils.cpp index 75a19e5de8..c6eff7b82c 100644 --- a/Pcap++/src/NetworkUtils.cpp +++ b/Pcap++/src/NetworkUtils.cpp @@ -106,10 +106,8 @@ namespace pcpp Packet arpRequest(100); - MacAddress destMac(0xff, 0xff, 0xff, 0xff, 0xff, 0xff); - EthLayer ethLayer(sourceMac, destMac); - - ArpLayer arpLayer(ARP_REQUEST, sourceMac, destMac, sourceIP, ipAddr); + EthLayer ethLayer(sourceMac, MacAddress::Broadcast); + ArpLayer arpLayer(ArpRequest(sourceMac, sourceIP, ipAddr)); if (!arpRequest.addLayer(ðLayer)) { diff --git a/Tests/Packet++Test/Tests/EthAndArpTests.cpp b/Tests/Packet++Test/Tests/EthAndArpTests.cpp index b8faea90aa..5628c63692 100644 --- a/Tests/Packet++Test/Tests/EthAndArpTests.cpp +++ b/Tests/Packet++Test/Tests/EthAndArpTests.cpp @@ -120,32 +120,145 @@ PTF_TEST_CASE(EthAndArpPacketParsing) PTF_TEST_CASE(ArpPacketCreation) { - pcpp::MacAddress srcMac("6c:f0:49:b2:de:6e"); - pcpp::MacAddress dstMac("ff:ff:ff:ff:ff:ff"); - pcpp::EthLayer ethLayer(srcMac, dstMac, PCPP_ETHERTYPE_ARP); + { + auto const buffer = pcpp_tests::readFileIntoBuffer("PacketExamples/ArpRequestPacket.dat"); - pcpp::ArpLayer arpLayer(pcpp::ARP_REQUEST, srcMac, srcMac, pcpp::IPv4Address("10.0.0.1"), - pcpp::IPv4Address("10.0.0.138")); + { + pcpp::MacAddress srcMac("6c:f0:49:b2:de:6e"); + pcpp::MacAddress dstMac("ff:ff:ff:ff:ff:ff"); + pcpp::EthLayer ethLayer(srcMac, dstMac, PCPP_ETHERTYPE_ARP); + pcpp::ArpLayer arpLayer(pcpp::ARP_REQUEST, srcMac, srcMac, pcpp::IPv4Address("10.0.0.1"), + pcpp::IPv4Address("10.0.0.138")); - pcpp::Packet arpRequestPacket(1); - PTF_ASSERT_TRUE(arpRequestPacket.addLayer(ðLayer)); - PTF_ASSERT_TRUE(arpRequestPacket.addLayer(&arpLayer)); - arpRequestPacket.computeCalculateFields(); - PTF_ASSERT_EQUAL(arpRequestPacket.getRawPacket()->getRawDataLen(), 42); - - pcpp::ArpLayer* pArpLayer = arpRequestPacket.getLayerOfType(); - PTF_ASSERT_NOT_NULL(pArpLayer); - - pcpp::arphdr* arpHeader = pArpLayer->getArpHeader(); - PTF_ASSERT_EQUAL(arpHeader->hardwareSize, 6); - PTF_ASSERT_EQUAL(arpHeader->protocolType, htobe16(PCPP_ETHERTYPE_IP)); - - READ_FILE_INTO_BUFFER(1, "PacketExamples/ArpRequestPacket.dat"); - - PTF_ASSERT_EQUAL(bufferLength1, arpRequestPacket.getRawPacket()->getRawDataLen()); - PTF_ASSERT_BUF_COMPARE(arpRequestPacket.getRawPacket()->getRawData(), buffer1, bufferLength1); - - delete[] buffer1; + PTF_ASSERT_TRUE(arpLayer.getMessageType() == pcpp::ArpMessageType::Request); + + pcpp::Packet arpRequestPacket(1); + + PTF_ASSERT_TRUE(arpRequestPacket.addLayer(ðLayer)); + PTF_ASSERT_TRUE(arpRequestPacket.addLayer(&arpLayer)); + arpRequestPacket.computeCalculateFields(); + PTF_ASSERT_EQUAL(arpRequestPacket.getRawPacket()->getRawDataLen(), 42); + + pcpp::ArpLayer* pArpLayer = arpRequestPacket.getLayerOfType(); + PTF_ASSERT_NOT_NULL(pArpLayer); + + pcpp::arphdr* arpHeader = pArpLayer->getArpHeader(); + PTF_ASSERT_EQUAL(arpHeader->hardwareSize, 6); + PTF_ASSERT_EQUAL(arpHeader->protocolType, htobe16(PCPP_ETHERTYPE_IP)); + + PTF_ASSERT_EQUAL(arpRequestPacket.getRawPacket()->getRawDataLen(), buffer.size()); + PTF_ASSERT_BUF_COMPARE(arpRequestPacket.getRawPacket()->getRawData(), buffer.data(), buffer.size()); + } + + { + pcpp::MacAddress srcMac("6c:f0:49:b2:de:6e"); + pcpp::IPv4Address srcIp("10.0.0.1"); + pcpp::IPv4Address dstIp("10.0.0.138"); + + pcpp::EthLayer ethLayer(srcMac, pcpp::MacAddress::Broadcast, PCPP_ETHERTYPE_ARP); + pcpp::ArpLayer arpLayer(pcpp::ArpRequest(srcMac, srcIp, dstIp)); + + PTF_ASSERT_TRUE(arpLayer.getMessageType() == pcpp::ArpMessageType::Request); + + pcpp::Packet argRequestPacket(1); + PTF_ASSERT_TRUE(argRequestPacket.addLayer(ðLayer)); + PTF_ASSERT_TRUE(argRequestPacket.addLayer(&arpLayer)); + + argRequestPacket.computeCalculateFields(); + PTF_ASSERT_EQUAL(argRequestPacket.getRawPacket()->getRawDataLen(), 42); + + pcpp::ArpLayer* pArpLayer = argRequestPacket.getLayerOfType(); + PTF_ASSERT_NOT_NULL(pArpLayer); + + pcpp::arphdr* arpHeader = pArpLayer->getArpHeader(); + PTF_ASSERT_EQUAL(arpHeader->hardwareSize, 6); + PTF_ASSERT_EQUAL(arpHeader->protocolType, htobe16(PCPP_ETHERTYPE_IP)); + + PTF_ASSERT_EQUAL(argRequestPacket.getRawPacket()->getRawDataLen(), buffer.size()); + PTF_ASSERT_BUF_COMPARE(argRequestPacket.getRawPacket()->getRawData(), buffer.data(), buffer.size()); + } + } + + { + auto buffer = pcpp_tests::readFileIntoBuffer("PacketExamples/ArpResponsePacket.dat"); + + pcpp::MacAddress srcMac("30:46:9a:23:fb:fa"); + pcpp::IPv4Address srcIp("10.0.0.138"); + pcpp::MacAddress dstMac("6c:f0:49:b2:de:6e"); + pcpp::IPv4Address dstIp("10.0.0.1"); + + pcpp::EthLayer ethLayer(pcpp::EthLayer(srcMac, dstMac, PCPP_ETHERTYPE_ARP)); + pcpp::ArpLayer arpLayer(pcpp::ArpReply(srcMac, srcIp, dstMac, dstIp)); + + pcpp::Packet packet(1); + PTF_ASSERT_TRUE(packet.addLayer(ðLayer)); + PTF_ASSERT_TRUE(packet.addLayer(&arpLayer)); + + packet.computeCalculateFields(); + + PTF_ASSERT_EQUAL(arpLayer.getHeaderLen(), 28); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->hardwareSize, 6); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->protocolSize, 4); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->hardwareType, htobe16(1)); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->protocolType, htobe16(PCPP_ETHERTYPE_IP)); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->opcode, htobe16(pcpp::ARP_REPLY)); + PTF_ASSERT_TRUE(arpLayer.getMessageType() == pcpp::ArpMessageType::Reply); + PTF_ASSERT_EQUAL(arpLayer.getSenderMacAddress(), srcMac); + PTF_ASSERT_EQUAL(arpLayer.getSenderIpAddr(), srcIp); + PTF_ASSERT_EQUAL(arpLayer.getTargetMacAddress(), dstMac); + PTF_ASSERT_EQUAL(arpLayer.getTargetIpAddr(), dstIp); + + PTF_ASSERT_EQUAL(packet.getRawPacket()->getRawDataLen(), 42); + + pcpp::ArpLayer* pArpLayer = packet.getLayerOfType(); + PTF_ASSERT_NOT_NULL(pArpLayer); + + PTF_ASSERT_EQUAL(buffer.size(), packet.getRawPacket()->getRawDataLen() + 18 /* ethernet trailer */); + PTF_ASSERT_BUF_COMPARE(packet.getRawPacket()->getRawData(), buffer.data(), + packet.getRawPacket()->getRawDataLen()); + } + + { + // TODO: Add an actual packet to test against. + pcpp::MacAddress srcMac("02:00:00:00:00:01"); + pcpp::IPv4Address srcIp("10.0.0.1"); + + pcpp::ArpLayer arpLayer(pcpp::GratuitousArpRequest(srcMac, srcIp)); + arpLayer.computeCalculateFields(); + + PTF_ASSERT_EQUAL(arpLayer.getHeaderLen(), 28); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->hardwareSize, 6); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->protocolSize, 4); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->hardwareType, htobe16(1)); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->protocolType, htobe16(PCPP_ETHERTYPE_IP)); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->opcode, htobe16(pcpp::ARP_REQUEST)); + PTF_ASSERT_TRUE(arpLayer.getMessageType() == pcpp::ArpMessageType::GratuitousRequest); + PTF_ASSERT_EQUAL(arpLayer.getSenderMacAddress(), srcMac); + PTF_ASSERT_EQUAL(arpLayer.getSenderIpAddr(), srcIp); + PTF_ASSERT_EQUAL(arpLayer.getTargetMacAddress(), pcpp::MacAddress::Broadcast); + PTF_ASSERT_EQUAL(arpLayer.getTargetIpAddr(), srcIp); + } + + { + // TODO: Add an actual packet to test against. + pcpp::MacAddress srcMac("02:00:00:00:00:01"); + pcpp::IPv4Address srcIp("10.0.0.1"); + + pcpp::ArpLayer arpLayer(pcpp::GratuitousArpReply(srcMac, srcIp)); + arpLayer.computeCalculateFields(); + + PTF_ASSERT_EQUAL(arpLayer.getHeaderLen(), 28); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->hardwareSize, 6); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->protocolSize, 4); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->hardwareType, htobe16(1)); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->protocolType, htobe16(PCPP_ETHERTYPE_IP)); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->opcode, htobe16(pcpp::ARP_REPLY)); + PTF_ASSERT_TRUE(arpLayer.getMessageType() == pcpp::ArpMessageType::GratuitousReply); + PTF_ASSERT_EQUAL(arpLayer.getSenderMacAddress(), srcMac); + PTF_ASSERT_EQUAL(arpLayer.getSenderIpAddr(), srcIp); + PTF_ASSERT_EQUAL(arpLayer.getTargetMacAddress(), pcpp::MacAddress::Broadcast); + PTF_ASSERT_EQUAL(arpLayer.getTargetIpAddr(), srcIp); + } } // ArpPacketCreation PTF_TEST_CASE(EthDot3LayerParsingTest) diff --git a/Tests/Packet++Test/Tests/VlanMplsTests.cpp b/Tests/Packet++Test/Tests/VlanMplsTests.cpp index 44ab437489..4a1bcc141a 100644 --- a/Tests/Packet++Test/Tests/VlanMplsTests.cpp +++ b/Tests/Packet++Test/Tests/VlanMplsTests.cpp @@ -52,8 +52,8 @@ PTF_TEST_CASE(VlanParseAndCreation) pcpp::EthLayer ethLayer(macSrc, macDest); pcpp::VlanLayer firstVlanLayer(666, 1, 5); pcpp::VlanLayer secondVlanLayer(200, 0, 2, PCPP_ETHERTYPE_ARP); - pcpp::ArpLayer arpLayer(pcpp::ARP_REQUEST, macSrc, pcpp::MacAddress("00:00:00:00:00:00"), - pcpp::IPv4Address("192.168.2.200"), pcpp::IPv4Address("192.168.2.254")); + pcpp::ArpLayer arpLayer( + pcpp::ArpRequest(macSrc, pcpp::IPv4Address("192.168.2.200"), pcpp::IPv4Address("192.168.2.254"))); pcpp::Packet arpWithVlanNew(1); PTF_ASSERT_TRUE(arpWithVlanNew.addLayer(ðLayer)); PTF_ASSERT_TRUE(arpWithVlanNew.addLayer(&firstVlanLayer)); diff --git a/Tests/Packet++Test/Utils/TestUtils.cpp b/Tests/Packet++Test/Utils/TestUtils.cpp index ed30c46c0b..6d7d3b2230 100644 --- a/Tests/Packet++Test/Utils/TestUtils.cpp +++ b/Tests/Packet++Test/Utils/TestUtils.cpp @@ -19,6 +19,44 @@ namespace pcpp_tests return length; } + namespace + { + std::uint8_t hexCharToDigit(char c) + { + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + throw std::invalid_argument("Invalid hex character"); + } + + std::uint8_t hexPairToByte(const char* pair) + { + return (hexCharToDigit(pair[0]) << 4) | hexCharToDigit(pair[1]); + } + } // namespace + + std::vector readFileIntoBuffer(const char* filename) + { + int fileLength = getFileLength(filename); + if (fileLength == -1) + throw std::runtime_error(std::string("Failed to open file: ") + filename); + + std::ifstream infile(filename); + if (!infile) + throw std::runtime_error(std::string("Failed to open file: ") + filename); + + std::vector buffer; + char hexPair[2]; // 0 - high, 1 - low + while (infile.read(hexPair, 2)) + { + buffer.push_back(hexPairToByte(hexPair)); + } + return buffer; + } + uint8_t* readFileIntoBuffer(const char* filename, int& bufferLength) { int fileLength = getFileLength(filename); diff --git a/Tests/Packet++Test/Utils/TestUtils.h b/Tests/Packet++Test/Utils/TestUtils.h index 7a452e2616..89c2691110 100644 --- a/Tests/Packet++Test/Utils/TestUtils.h +++ b/Tests/Packet++Test/Utils/TestUtils.h @@ -7,12 +7,14 @@ // clang-format on #include #include +#include namespace pcpp_tests { int getFileLength(const char* filename); + std::vector readFileIntoBuffer(const char* filename); uint8_t* readFileIntoBuffer(const char* filename, int& bufferLength); void printBufferDifferences(const uint8_t* buffer1, size_t buffer1Len, const uint8_t* buffer2, size_t buffer2Len); From 208946825b02bb272a29374bf6b22bfe10f30142 Mon Sep 17 00:00:00 2001 From: Daniel Roethlisberger Date: Wed, 19 Mar 2025 07:27:16 +0100 Subject: [PATCH 21/36] Remove non-functional SSL 2 version code point (#1694) As per discussion in #1694, remove SSL 2 for now. SSL 2 is not actually implemented, and the version code point is wrong anyway. SSL 2 uses a version field of 0x0002, not 0x0200. This is confirmed not only in the original Netscape spec [1] and RFC draft of the time [2], but also in major implementations such as OpenSSL [3] and Wireshark [4]. More importantly, SSL 2 has a different record format, without version field, that is used for both SSL 2 proper, and SSL 2 compatible SSL 3 / TLS. For Packet++ to see a SSL 2 version field on the wire, it would first have to support the SSL 2 record format, and at least one of SSL 2 handshake messages, or SSL 2 compatible SSL 3 or later handshakes. [1] https://www-archive.mozilla.org/projects/security/pki/nss/ssl/draft02.html [2] https://datatracker.ietf.org/doc/html/draft-hickman-netscape-ssl-00 [3] https://github.com/openssl/openssl/blob/OpenSSL_0_9_6m/ssl/ssl2.h#L66-L71 [4] https://github.com/wireshark/wireshark/blob/release-4.4/epan/dissectors/packet-tls-utils.h#L266-L277 Co-authored-by: seladb --- Packet++/header/SSLCommon.h | 2 -- Packet++/src/SSLCommon.cpp | 5 ----- 2 files changed, 7 deletions(-) diff --git a/Packet++/header/SSLCommon.h b/Packet++/header/SSLCommon.h index 4a54d1506e..575dc19716 100644 --- a/Packet++/header/SSLCommon.h +++ b/Packet++/header/SSLCommon.h @@ -100,8 +100,6 @@ namespace pcpp /// SSL/TLS versions enum enum SSLVersionEnum { - /// SSL 2.0 - SSL2 = 0x0200, /// SSL 3.0 SSL3 = 0x0300, /// TLS 1.0 diff --git a/Packet++/src/SSLCommon.cpp b/Packet++/src/SSLCommon.cpp index 31207d8866..1ddd0bea97 100644 --- a/Packet++/src/SSLCommon.cpp +++ b/Packet++/src/SSLCommon.cpp @@ -23,9 +23,6 @@ namespace pcpp return static_cast(m_SSLVersionValue); } - if (m_SSLVersionValue == 0x200) - return SSLVersion::SSL2; - return SSLVersion::Unknown; } @@ -81,8 +78,6 @@ namespace pcpp return "TLS 1.3 (Facebook draft 26)"; case SSLVersion::Unknown: return "Unknown"; - case SSLVersion::SSL2: - return "SSL 2.0"; default: return "Unknown"; } From 5a86e05289671177addccdb6b3a2a743e1227cd9 Mon Sep 17 00:00:00 2001 From: seladb Date: Wed, 19 Mar 2025 00:17:54 -0700 Subject: [PATCH 22/36] Auto precommit update (#1724) --- .pre-commit-config.yaml | 6 +++--- cmake/setup_dpdk.py | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c59e90eeef..980ed721d8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,7 +22,7 @@ repos: args: ['--fix=lf'] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.8.4 + rev: v0.9.9 hooks: - id: ruff # Run the linter. types_or: [ python ] @@ -38,7 +38,7 @@ repos: - id: cppcheck args: ["--std=c++11", "--language=c++", "--suppressions-list=cppcheckSuppressions.txt", "--inline-suppr", "--force"] - repo: https://github.com/BlankSpruce/gersemi - rev: 0.18.2 + rev: 0.19.1 hooks: - id: gersemi args: ["-c"] @@ -48,7 +48,7 @@ repos: - id: codespell pass_filenames: false - repo: https://github.com/crate-ci/typos - rev: typos-dict-v0.12.4 + rev: typos-dict-v0.12.6 hooks: - id: typos args: ['--config=typos-config.toml'] diff --git a/cmake/setup_dpdk.py b/cmake/setup_dpdk.py index 0d7a2937bf..05e17d26d2 100755 --- a/cmake/setup_dpdk.py +++ b/cmake/setup_dpdk.py @@ -406,8 +406,7 @@ def dev_id_from_dev_name(dev_name): # if nothing else matches - error raise ValueError( - "Unknown device: %s. " - 'Please specify device in "bus:slot.func" format' % dev_name + 'Unknown device: %s. Please specify device in "bus:slot.func" format' % dev_name ) @@ -643,7 +642,7 @@ def show_device_status(devices_type, device_name): display_devices( "%s devices using kernel driver" % device_name, kernel_drv, - "if=%(Interface)s drv=%(Driver_str)s " "unused=%(Module_str)s %(Active)s", + "if=%(Interface)s drv=%(Driver_str)s unused=%(Module_str)s %(Active)s", ) if len(no_drv) != 0: display_devices( From 7b96fc8d154a5604821a24cde84fcadf19d023ed Mon Sep 17 00:00:00 2001 From: enomis101 <66433073+enomis101@users.noreply.github.com> Date: Wed, 19 Mar 2025 09:07:06 +0100 Subject: [PATCH 23/36] Fix CMake config file to use PcapPlusPlus_INCLUDE_DIR consistently (#1728) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Changed PcapPlusPlus_INCLUDE_DIRS to PcapPlusPlus_INCLUDE_DIR in comments to match actual variable name - Removed PcapPlusPlus_LIBRARIES reference from comments to align with target-based CMake practices Co-authored-by: Ege Çetin <64282645+egecetin@users.noreply.github.com> --- cmake/PcapPlusPlusConfig.cmake.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmake/PcapPlusPlusConfig.cmake.in b/cmake/PcapPlusPlusConfig.cmake.in index ea904cbdd0..b5c03a9472 100644 --- a/cmake/PcapPlusPlusConfig.cmake.in +++ b/cmake/PcapPlusPlusConfig.cmake.in @@ -1,8 +1,7 @@ # ~~~ # - Config file for the PcapPlusPlus package # It defines the following variables -# PcapPlusPlus_INCLUDE_DIRS - include directories for PcapPlusPlus -# PcapPlusPlus_LIBRARIES - libraries to link against +# PcapPlusPlus_INCLUDE_DIR - include directories for PcapPlusPlus # ~~~ @PACKAGE_INIT@ From 5db5cad87f4f3116d5f7a46ef3496800f5b5de6d Mon Sep 17 00:00:00 2001 From: s-genereux Date: Wed, 19 Mar 2025 04:40:30 -0400 Subject: [PATCH 24/36] Fix getCommandOption for command-only packets (#1718) --- Packet++/src/SingleCommandTextProtocol.cpp | 6 ++++-- .../PacketExamples/ftpIpv4CmdOnlyReq.dat | 1 + Tests/Packet++Test/Tests/FtpTests.cpp | 13 +++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 Tests/Packet++Test/PacketExamples/ftpIpv4CmdOnlyReq.dat diff --git a/Packet++/src/SingleCommandTextProtocol.cpp b/Packet++/src/SingleCommandTextProtocol.cpp index 04b0841b7b..ebb3b3cd81 100644 --- a/Packet++/src/SingleCommandTextProtocol.cpp +++ b/Packet++/src/SingleCommandTextProtocol.cpp @@ -135,10 +135,12 @@ namespace pcpp size_t offset = getArgumentFieldOffset(); // We don't want to get delimiter so add 1 for start unless there is no command, - // and we don't want to trailing newline characters so remove 2 and remove addition from start point int addition = offset ? 1 : 0; - if (offset != (m_DataLen - 1)) + + // Check if command-only packet (-2 to account for len/position comparison and size of CRLF) + if (offset != (m_DataLen - 2)) { + // We don't want to trailing newline characters so remove 2 and remove addition from start point auto option = std::string((char*)&m_Data[offset + addition], m_DataLen - (offset + 2 + addition)); // Remove XXX- and XXX since they are delimiters of the protocol where XXX is the usually status code diff --git a/Tests/Packet++Test/PacketExamples/ftpIpv4CmdOnlyReq.dat b/Tests/Packet++Test/PacketExamples/ftpIpv4CmdOnlyReq.dat new file mode 100644 index 0000000000..c3b7fd274e --- /dev/null +++ b/Tests/Packet++Test/PacketExamples/ftpIpv4CmdOnlyReq.dat @@ -0,0 +1 @@ +00000000000000000000000008004510003a7efb40004006bdb07f0000017f000001991a0015a11240363cc091be80187fe6fe2e00000101080aaefa0886aef8fc96535953540d0a diff --git a/Tests/Packet++Test/Tests/FtpTests.cpp b/Tests/Packet++Test/Tests/FtpTests.cpp index 9f243ae836..d9047dce24 100644 --- a/Tests/Packet++Test/Tests/FtpTests.cpp +++ b/Tests/Packet++Test/Tests/FtpTests.cpp @@ -88,6 +88,19 @@ PTF_TEST_CASE(FtpParsingTests) PTF_ASSERT_EQUAL(ftpDataLayer->getDataLen(), 1452); PTF_ASSERT_EQUAL(ftpDataLayer->toString(), "FTP Data"); + // Test IPv4 Command Only Request Packet + READ_FILE_AND_CREATE_PACKET(7, "PacketExamples/ftpIpv4CmdOnlyReq.dat"); + + pcpp::Packet ftpPacket7(&rawPacket7); + pcpp::FtpRequestLayer* ftpLayer7 = ftpPacket7.getLayerOfType(); + + PTF_ASSERT_NOT_NULL(ftpLayer7); + PTF_ASSERT_EQUAL(int(ftpLayer7->getCommand()), int(pcpp::FtpRequestLayer::FtpCommand::SYST)); + PTF_ASSERT_EQUAL(ftpLayer7->getCommandString(), "SYST"); + PTF_ASSERT_EQUAL(ftpLayer7->getCommandOption(), ""); + PTF_ASSERT_EQUAL(ftpLayer7->toString(), "FTP Request: SYST"); + PTF_ASSERT_FALSE(ftpLayer7->isMultiLine()); + // Command codes // clang-format off std::vector> possibleCommandCodes = { From a78cdc6f2fbf28da05f82045e4f7b6f5d95f3c77 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Sat, 22 Mar 2025 10:37:37 +0200 Subject: [PATCH 25/36] Exported set thread affinity code to a helper function. (#1734) * Exported set thread affinity code to a helper function. * Error logs fixup. * Reordered exception handling order so an exception in the logging infrastructure does not prevent shutdown of the initializing threads. --- Pcap++/src/PfRingDevice.cpp | 48 +++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/Pcap++/src/PfRingDevice.cpp b/Pcap++/src/PfRingDevice.cpp index 55134abbe1..29e57cbc37 100644 --- a/Pcap++/src/PfRingDevice.cpp +++ b/Pcap++/src/PfRingDevice.cpp @@ -15,6 +15,26 @@ namespace pcpp { + namespace + { + void setThreadCoreAffinity(std::thread& thread, int coreId) + { + if (thread.get_id() == std::thread::id{}) + { + throw std::invalid_argument("Can't set core affinity for a non-joinable thread"); + } + + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(coreId, &cpuset); + int err = pthread_setaffinity_np(thread.native_handle(), sizeof(cpu_set_t), &cpuset); + if (err != 0) + { + throw std::runtime_error("Error while binding thread to core " + std::to_string(coreId) + + ": errno=" + std::to_string(err)); + } + } + } // namespace PfRingDevice::PfRingDevice(const char* deviceName) : m_MacAddress(MacAddress::Zero) { @@ -468,21 +488,19 @@ namespace pcpp m_CoreConfiguration[coreId].RxThread = std::thread(&pcpp::PfRingDevice::captureThreadMain, this, startupBlock); - // set affinity to cores - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - CPU_SET(coreId, &cpuset); - int err = pthread_setaffinity_np(m_CoreConfiguration[coreId].RxThread.native_handle(), sizeof(cpu_set_t), - &cpuset); - if (err != 0) + try + { + setThreadCoreAffinity(m_CoreConfiguration[coreId].RxThread, coreId); + } + catch (const std::exception& e) { - PCPP_LOG_ERROR("Error while binding thread to core " << coreId << ": errno=" << err); { std::unique_lock lock(startupBlock->Mutex); startupBlock->State = 1; } startupBlock->Cond.notify_all(); clearCoreConfiguration(); + PCPP_LOG_ERROR(e.what()); return false; } } @@ -524,15 +542,16 @@ namespace pcpp std::shared_ptr startupBlock = std::make_shared(); - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - CPU_SET(0, &cpuset); m_CoreConfiguration[0].IsInUse = true; m_CoreConfiguration[0].Channel = m_PfRingDescriptors[0]; m_CoreConfiguration[0].RxThread = std::thread(&pcpp::PfRingDevice::captureThreadMain, this, startupBlock); m_CoreConfiguration[0].IsAffinitySet = false; - int err = pthread_setaffinity_np(m_CoreConfiguration[0].RxThread.native_handle(), sizeof(cpu_set_t), &cpuset); - if (err != 0) + + try + { + setThreadCoreAffinity(m_CoreConfiguration[0].RxThread, 0); + } + catch (const std::exception& e) { { std::unique_lock lock(startupBlock->Mutex); @@ -540,9 +559,8 @@ namespace pcpp } startupBlock->Cond.notify_all(); m_CoreConfiguration[0].RxThread.join(); - - PCPP_LOG_ERROR("Error while binding thread to core 0: errno=" << err); clearCoreConfiguration(); + PCPP_LOG_ERROR(e.what()); return false; } From 63620c880de92096b612cc5d567fd164bc44139f Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Sat, 22 Mar 2025 10:38:24 +0200 Subject: [PATCH 26/36] Adds CMake variable to configure compile time log levels. (#1733) * Adds cmake variable PCAPPP_LOG_LEVEL to determine compile time log level through cmake. * Added checks for log level input. * Lint? --- CMakeLists.txt | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78e03653ca..44990a89af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,31 @@ if(PCAPPP_USE_SANITIZER) endif() endif() +# Build options (Compile time log level) +set( + PCAPP_ALLOWED_LOG_LEVELS + "" + "0" + "1" + "2" + "3" +) +set( + PCAPPP_LOG_LEVEL + "" + CACHE STRING + "Compile time log level (0 - Off, 1 - Error, 2 - Info, 3 - Debug) Default(empty): Debug" +) +set_property(CACHE PCAPPP_LOG_LEVEL PROPERTY STRINGS ${PCAPP_ALLOWED_LOG_LEVELS}) + +if(NOT PCAPPP_LOG_LEVEL IN_LIST PCAPP_ALLOWED_LOG_LEVELS) + message(FATAL_ERROR "PCAPPP_LOG_LEVEL must be one of ${PCAPP_ALLOWED_LOG_LEVELS}") +endif() + +if(PCAPPP_LOG_LEVEL) + add_compile_definitions("PCPP_ACTIVE_LOG_LEVEL=${PCAPPP_LOG_LEVEL}") +endif() + # Build options (Turn on Examples and Tests if it's the main project) option(PCAPPP_BUILD_EXAMPLES "Build Examples" ${PCAPPP_MAIN_PROJECT}) cmake_dependent_option( From bb6875139cfb6cc432b27853f8901bf7f8fa7aa7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 22 Mar 2025 02:29:13 -0700 Subject: [PATCH 27/36] Bump the actions-dependencies group across 1 directory with 11 updates (#1730) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Bump the actions-dependencies group across 1 directory with 11 updates Bumps the actions-dependencies group with 11 updates in the / directory: | Package | From | To | | --- | --- | --- | | [actions/setup-python](https://github.com/actions/setup-python) | `5.3.0` | `5.4.0` | | [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) | `7.0.5` | `7.0.8` | | [codecov/codecov-action](https://github.com/codecov/codecov-action) | `5.0.7` | `5.4.0` | | [msys2/setup-msys2](https://github.com/msys2/setup-msys2) | `2.25.0` | `2.27.0` | | [vmactions/freebsd-vm](https://github.com/vmactions/freebsd-vm) | `1.1.5` | `1.1.9` | | [actions/upload-artifact](https://github.com/actions/upload-artifact) | `4.4.3` | `4.6.1` | | [github/codeql-action](https://github.com/github/codeql-action) | `3.27.5` | `3.28.11` | | [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) | `1.4.4` | `2.2.3` | | [ncipollo/release-action](https://github.com/ncipollo/release-action) | `1.14.0` | `1.16.0` | | [actions/download-artifact](https://github.com/actions/download-artifact) | `4.1.8` | `4.1.9` | | [ossf/scorecard-action](https://github.com/ossf/scorecard-action) | `2.4.0` | `2.4.1` | Updates `actions/setup-python` from 5.3.0 to 5.4.0 - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/0b93645e9fea7318ecaed2b359559ac225c90a2b...42375524e23c412d93fb67b49958b491fce71c38) Updates `peter-evans/create-pull-request` from 7.0.5 to 7.0.8 - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/5e914681df9dc83aa4e4905692ca88beb2f9e91f...271a8d0340265f705b14b6d32b9829c1cb33d45e) Updates `codecov/codecov-action` from 5.0.7 to 5.4.0 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/015f24e6818733317a2da2edd6290ab26238649a...0565863a31f2c772f9f0395002a31e3f06189574) Updates `msys2/setup-msys2` from 2.25.0 to 2.27.0 - [Release notes](https://github.com/msys2/setup-msys2/releases) - [Changelog](https://github.com/msys2/setup-msys2/blob/main/CHANGELOG.md) - [Commits](https://github.com/msys2/setup-msys2/compare/c52d1fa9c7492275e60fe763540fb601f5f232a1...61f9e5e925871ba6c9e3e8da24ede83ea27fa91f) Updates `vmactions/freebsd-vm` from 1.1.5 to 1.1.9 - [Release notes](https://github.com/vmactions/freebsd-vm/releases) - [Commits](https://github.com/vmactions/freebsd-vm/compare/debf37ca7b7fa40e19c542ef7ba30d6054a706a4...8873d98fd1413b5977cb2f7348fe329775159892) Updates `actions/upload-artifact` from 4.4.3 to 4.6.1 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882...4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1) Updates `github/codeql-action` from 3.27.5 to 3.28.11 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/f09c1c0a94de965c15400f5634aa42fac8fb8f88...6bb031afdd8eb862ea3fc1848194185e076637e5) Updates `actions/attest-build-provenance` from 1.4.4 to 2.2.3 - [Release notes](https://github.com/actions/attest-build-provenance/releases) - [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md) - [Commits](https://github.com/actions/attest-build-provenance/compare/ef244123eb79f2f7a7e75d99086184180e6d0018...c074443f1aee8d4aeeae555aebba3282517141b2) Updates `ncipollo/release-action` from 1.14.0 to 1.16.0 - [Release notes](https://github.com/ncipollo/release-action/releases) - [Commits](https://github.com/ncipollo/release-action/compare/2c591bcc8ecdcd2db72b97d6147f871fcd833ba5...440c8c1cb0ed28b9f43e4d1d670870f059653174) Updates `actions/download-artifact` from 4.1.8 to 4.1.9 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/fa0a91b85d4f404e444e00e005971372dc801d16...cc203385981b70ca67e1cc392babf9cc229d5806) Updates `ossf/scorecard-action` from 2.4.0 to 2.4.1 - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](https://github.com/ossf/scorecard-action/compare/62b2cac7ed8198b15735ed49ab1e5cf35480ba46...f49aabe0b5af0936a0987cfb85d86b75731b0186) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-dependencies - dependency-name: peter-evans/create-pull-request dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-dependencies - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-dependencies - dependency-name: msys2/setup-msys2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-dependencies - dependency-name: vmactions/freebsd-vm dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-dependencies - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-dependencies - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-dependencies - dependency-name: actions/attest-build-provenance dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-dependencies - dependency-name: ncipollo/release-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-dependencies - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-dependencies - dependency-name: ossf/scorecard-action dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-dependencies ... Signed-off-by: dependabot[bot] * Try updating Google Benchmark to 1.9.1 * Disable Google Benchmark for MinGW --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ege Çetin <64282645+egecetin@users.noreply.github.com> Co-authored-by: seladb --- .github/workflows/auto_update.yml | 8 ++--- .github/workflows/build_and_test.yml | 20 ++++++------ .github/workflows/cifuzz.yml | 2 +- .github/workflows/codeql.yml | 4 +-- .github/workflows/package.yml | 32 +++++++++---------- .github/workflows/scorecards.yml | 6 ++-- .../PcapPlusPlus-benchmark/CMakeLists.txt | 1 + 7 files changed, 37 insertions(+), 36 deletions(-) diff --git a/.github/workflows/auto_update.yml b/.github/workflows/auto_update.yml index 6775630cbd..8592dd1381 100644 --- a/.github/workflows/auto_update.yml +++ b/.github/workflows/auto_update.yml @@ -17,7 +17,7 @@ jobs: with: ref: dev - name: Setup Python - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 + uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 with: python-version: "3.8.x" - name: Run update @@ -25,7 +25,7 @@ jobs: pip install pre-commit pre-commit autoupdate - name: Create Pull Request - uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5 + uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 with: token: ${{ secrets.PAT }} author: GitHub @@ -50,7 +50,7 @@ jobs: with: ref: dev - name: Setup Python - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 + uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 with: python-version: "3.9.x" - name: Run update @@ -58,7 +58,7 @@ jobs: python3 3rdParty/OUIDataset/create_oui_data.py mv -f PCPP_OUIDataset.json 3rdParty/OUIDataset/PCPP_OUIDataset.json - name: Create Pull Request - uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5 + uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 with: token: ${{ secrets.PAT }} author: GitHub diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 6f18b0df45..3791f6c902 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -146,7 +146,7 @@ jobs: gcovr -v -r . ${{ matrix.additional-gcov-flags }} $GCOVR_FLAGS -o coverage.xml - name: Upload Coverage Results - uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a # v5.0.7 + uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0 with: files: ./coverage.xml flags: ${{ matrix.image }},unittest @@ -321,7 +321,7 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup Python - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 + uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 with: # support version: https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json python-version: "3.12" @@ -394,7 +394,7 @@ jobs: gcovr -v -r . $GCOVR_FLAGS -o coverage.xml - name: Upload Coverage Results - uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a # v5.0.7 + uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0 if: ${{ matrix.host-arch == matrix.arch }} with: files: ./coverage.xml @@ -425,7 +425,7 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup MSYS2 - uses: msys2/setup-msys2@c52d1fa9c7492275e60fe763540fb601f5f232a1 # v2.25.0 + uses: msys2/setup-msys2@61f9e5e925871ba6c9e3e8da24ede83ea27fa91f # v2.27.0 with: msystem: ${{matrix.sys}} install: >- @@ -435,7 +435,7 @@ jobs: mingw-w64-${{matrix.env}}-make - name: Setup Python - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 + uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 with: python-version: "3.12" @@ -483,7 +483,7 @@ jobs: run: gcovr -v -g -k -r . $env:GCOVR_FLAGS.split() -o coverage.xml - name: Upload Coverage Results - uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a # v5.0.7 + uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0 with: files: ./coverage.xml flags: ${{ matrix.sys }},unittest @@ -519,7 +519,7 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup Python - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 + uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 with: python-version: "3.12" @@ -574,7 +574,7 @@ jobs: python -m pytest --root-path=../../Dist/examples_bin - name: Upload Coverage Results - uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a # v5.0.7 + uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0 with: files: ./Tests/Pcap++Test/Pcap++Coverage.xml,./Tests/Packet++Test/Packet++Coverage.xml flags: ${{ matrix.os }},unittest,${{ matrix.pcap_lib }} @@ -592,7 +592,7 @@ jobs: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Test in FreeBSD id: test - uses: vmactions/freebsd-vm@debf37ca7b7fa40e19c542ef7ba30d6054a706a4 # v1.1.5 + uses: vmactions/freebsd-vm@8873d98fd1413b5977cb2f7348fe329775159892 # v1.1.9 with: release: ${{ matrix.version }} usesh: true @@ -743,7 +743,7 @@ jobs: gcovr -v -r . $GCOVR_FLAGS -o coverage.xml - name: Upload Coverage Results - uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a # v5.0.7 + uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0 with: files: ./coverage.xml flags: xdp,unittest diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index a6c844fa46..c4d69e2a7f 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -35,7 +35,7 @@ jobs: dry-run: false sanitizer: ${{ matrix.sanitizer }} - name: Upload Crash - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 if: failure() && steps.build.outcome == 'success' with: name: artifacts diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ce610a1d98..5f128617cd 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -29,7 +29,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 + uses: github/codeql-action/init@6bb031afdd8eb862ea3fc1848194185e076637e5 # v3.28.11 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -44,4 +44,4 @@ jobs: cmake --build build -j - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 + uses: github/codeql-action/analyze@6bb031afdd8eb862ea3fc1848194185e076637e5 # v3.28.11 diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 41233e85e3..1f24276c87 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -72,13 +72,13 @@ jobs: - name: Generate artifact attestation if: github.ref_type == 'tag' - uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1.4.4 + uses: actions/attest-build-provenance@c074443f1aee8d4aeeae555aebba3282517141b2 # v2.2.3 with: subject-path: "${{ env.BUILD_DIR }}/*.tar.gz,${{ env.BUILD_DIR }}/*.deb,${{ env.BUILD_DIR }}/*.rpm" - name: Upload binaries to release if: github.ref_type == 'tag' - uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0 + uses: ncipollo/release-action@440c8c1cb0ed28b9f43e4d1d670870f059653174 # v1.16.0 with: draft: true allowUpdates: true @@ -100,7 +100,7 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Test in FreeBSD - uses: vmactions/freebsd-vm@debf37ca7b7fa40e19c542ef7ba30d6054a706a4 # v1.1.5 + uses: vmactions/freebsd-vm@8873d98fd1413b5977cb2f7348fe329775159892 # v1.1.9 with: release: ${{ matrix.version }} envs: 'BUILD_DIR' @@ -114,13 +114,13 @@ jobs: - name: Generate artifact attestation if: github.ref_type == 'tag' - uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1.4.4 + uses: actions/attest-build-provenance@c074443f1aee8d4aeeae555aebba3282517141b2 # v2.2.3 with: subject-path: "${{ env.BUILD_DIR }}/*.tar.gz" - name: Upload binaries to release if: github.ref_type == 'tag' - uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0 + uses: ncipollo/release-action@440c8c1cb0ed28b9f43e4d1d670870f059653174 # v1.16.0 with: draft: true allowUpdates: true @@ -169,13 +169,13 @@ jobs: - name: Generate artifact attestation if: github.ref_type == 'tag' - uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1.4.4 + uses: actions/attest-build-provenance@c074443f1aee8d4aeeae555aebba3282517141b2 # v2.2.3 with: subject-path: "${{ env.BUILD_DIR }}/*.tar.gz,${{ env.BUILD_DIR }}/*.pkg" - name: Upload binaries to release if: github.ref_type == 'tag' - uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0 + uses: ncipollo/release-action@440c8c1cb0ed28b9f43e4d1d670870f059653174 # v1.16.0 with: draft: true allowUpdates: true @@ -201,7 +201,7 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup MSYS2 - uses: msys2/setup-msys2@c52d1fa9c7492275e60fe763540fb601f5f232a1 # v2.25.0 + uses: msys2/setup-msys2@61f9e5e925871ba6c9e3e8da24ede83ea27fa91f # v2.27.0 with: msystem: ${{matrix.sys}} update: true @@ -240,13 +240,13 @@ jobs: - name: Generate artifact attestation if: github.ref_type == 'tag' - uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1.4.4 + uses: actions/attest-build-provenance@c074443f1aee8d4aeeae555aebba3282517141b2 # v2.2.3 with: subject-path: "${{ env.BUILD_DIR }}/*.zip" - name: Upload binaries to release if: github.ref_type == 'tag' - uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0 + uses: ncipollo/release-action@440c8c1cb0ed28b9f43e4d1d670870f059653174 # v1.16.0 with: draft: true allowUpdates: true @@ -290,13 +290,13 @@ jobs: - name: Generate artifact attestation if: github.ref_type == 'tag' - uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1.4.4 + uses: actions/attest-build-provenance@c074443f1aee8d4aeeae555aebba3282517141b2 # v2.2.3 with: subject-path: "${{ env.BUILD_DIR }}/*.zip" - name: Upload binaries to release if: github.ref_type == 'tag' - uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0 + uses: ncipollo/release-action@440c8c1cb0ed28b9f43e4d1d670870f059653174 # v1.16.0 with: draft: true allowUpdates: true @@ -353,7 +353,7 @@ jobs: mkdir -p "android-package" mv "${COMBINED_PACKAGE_DIR}" "android-package" - - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + - uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 with: path: android-package name: android-package-${{ matrix.target }}-${{ matrix.api-version }} @@ -368,7 +368,7 @@ jobs: id-token: write steps: - - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + - uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 with: pattern: android-package-* merge-multiple: true @@ -381,13 +381,13 @@ jobs: - name: Generate artifact attestation if: github.ref_type == 'tag' - uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1.4.4 + uses: actions/attest-build-provenance@c074443f1aee8d4aeeae555aebba3282517141b2 # v2.2.3 with: subject-path: "${{ env.PACKAGE_DIR }}.tar.gz" - name: Upload binaries to release if: github.ref_type == 'tag' - uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0 + uses: ncipollo/release-action@440c8c1cb0ed28b9f43e4d1d670870f059653174 # v1.16.0 with: draft: true allowUpdates: true diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 66f01c9c28..27387e107b 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -36,7 +36,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 with: results_file: results.sarif results_format: sarif @@ -58,7 +58,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 with: name: SARIF file path: results.sarif @@ -66,6 +66,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 + uses: github/codeql-action/upload-sarif@6bb031afdd8eb862ea3fc1848194185e076637e5 # v3.28.11 with: sarif_file: results.sarif diff --git a/Examples/PcapPlusPlus-benchmark/CMakeLists.txt b/Examples/PcapPlusPlus-benchmark/CMakeLists.txt index 7fc45dad16..81955134e0 100644 --- a/Examples/PcapPlusPlus-benchmark/CMakeLists.txt +++ b/Examples/PcapPlusPlus-benchmark/CMakeLists.txt @@ -7,6 +7,7 @@ set_target_properties(BenchmarkExample PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${PC if("cxx_std_14" IN_LIST CMAKE_CXX_COMPILE_FEATURES) if( (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL CMAKE_SYSTEM_PROCESSOR) + AND (NOT MINGW) AND (NOT CMAKE_OSX_ARCHITECTURES OR (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL CMAKE_OSX_ARCHITECTURES)) ) include(FetchContent) From 97be1dfe19b2fe587ef5a86a9e6997c83e841f1b Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Sun, 23 Mar 2025 10:32:06 +0200 Subject: [PATCH 28/36] Added `noexcept` specifier to custom deleters throughout the project. (#1735) --- Common++/src/SystemUtils.cpp | 2 +- Pcap++/header/PcapFilter.h | 2 +- Pcap++/header/PcapUtils.h | 4 ++-- Pcap++/src/PcapFilter.cpp | 2 +- Pcap++/src/PcapUtils.cpp | 4 ++-- Pcap++/src/PfRingDeviceList.cpp | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Common++/src/SystemUtils.cpp b/Common++/src/SystemUtils.cpp index 91e76583f4..dfb1bbef57 100644 --- a/Common++/src/SystemUtils.cpp +++ b/Common++/src/SystemUtils.cpp @@ -60,7 +60,7 @@ namespace /// A deleter that cleans up a FILE handle using pclose. struct PcloseDeleter { - void operator()(FILE* ptr) const + void operator()(FILE* ptr) const noexcept { PCLOSE(ptr); } diff --git a/Pcap++/header/PcapFilter.h b/Pcap++/header/PcapFilter.h index 3f77392650..e11a54a33d 100644 --- a/Pcap++/header/PcapFilter.h +++ b/Pcap++/header/PcapFilter.h @@ -70,7 +70,7 @@ namespace pcpp /// A deleter that cleans up a bpf_program object. struct BpfProgramDeleter { - void operator()(bpf_program* ptr) const; + void operator()(bpf_program* ptr) const noexcept; }; } // namespace internal diff --git a/Pcap++/header/PcapUtils.h b/Pcap++/header/PcapUtils.h index 7fefa0abed..511485954c 100644 --- a/Pcap++/header/PcapUtils.h +++ b/Pcap++/header/PcapUtils.h @@ -18,14 +18,14 @@ namespace pcpp /// A deleter that cleans up a pcap_t structure by calling pcap_close. struct PcapCloseDeleter { - void operator()(pcap_t* ptr) const; + void operator()(pcap_t* ptr) const noexcept; }; /// @class PcapFreeAllDevsDeleter /// A deleter that frees an interface list of pcap_if_t ptr by calling 'pcap_freealldevs' function on it. struct PcapFreeAllDevsDeleter { - void operator()(pcap_if_t* ptr) const; + void operator()(pcap_if_t* ptr) const noexcept; }; } // namespace internal diff --git a/Pcap++/src/PcapFilter.cpp b/Pcap++/src/PcapFilter.cpp index c3d905e856..65d6973df9 100644 --- a/Pcap++/src/PcapFilter.cpp +++ b/Pcap++/src/PcapFilter.cpp @@ -31,7 +31,7 @@ namespace pcpp namespace internal { - void BpfProgramDeleter::operator()(bpf_program* ptr) const + void BpfProgramDeleter::operator()(bpf_program* ptr) const noexcept { pcap_freecode(ptr); delete ptr; diff --git a/Pcap++/src/PcapUtils.cpp b/Pcap++/src/PcapUtils.cpp index df8ee5f4c7..5f3ae77024 100644 --- a/Pcap++/src/PcapUtils.cpp +++ b/Pcap++/src/PcapUtils.cpp @@ -6,12 +6,12 @@ namespace pcpp { namespace internal { - void PcapCloseDeleter::operator()(pcap_t* ptr) const + void PcapCloseDeleter::operator()(pcap_t* ptr) const noexcept { pcap_close(ptr); } - void PcapFreeAllDevsDeleter::operator()(pcap_if_t* ptr) const + void PcapFreeAllDevsDeleter::operator()(pcap_if_t* ptr) const noexcept { pcap_freealldevs(ptr); } diff --git a/Pcap++/src/PfRingDeviceList.cpp b/Pcap++/src/PfRingDeviceList.cpp index bd1be57d75..06973c09f2 100644 --- a/Pcap++/src/PfRingDeviceList.cpp +++ b/Pcap++/src/PfRingDeviceList.cpp @@ -21,7 +21,7 @@ namespace pcpp /// A deleter that cleans up a pfring structure by calling pfring_close. struct PfRingCloseDeleter { - void operator()(pfring* ptr) const + void operator()(pfring* ptr) const noexcept { pfring_close(ptr); } From 7bbe77f844c8592647e36dfeadd4ef0faf4175fa Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Sun, 23 Mar 2025 10:32:39 +0200 Subject: [PATCH 29/36] Change `PfRingDevice::m_CoreConfiguration` to std::array (#1736) * Changed m_CoreConfiguration to std::array. * Changed `clearCoreConfiguration` to for-each loop. Changed `getCOresInUseCount` to use `std::count_if`. * Added change to `constexpr` todo to `MAX_NUM_OF_CORES`. --- Common++/header/SystemUtils.h | 1 + Pcap++/header/PfRingDevice.h | 3 ++- Pcap++/src/PfRingDevice.cpp | 13 +++++-------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Common++/header/SystemUtils.h b/Common++/header/SystemUtils.h index f638a8dbb2..ad15461558 100644 --- a/Common++/header/SystemUtils.h +++ b/Common++/header/SystemUtils.h @@ -8,6 +8,7 @@ /// @file +// @todo Change to constexpr when C++17 is minimum supported version enum : uint8_t { MAX_NUM_OF_CORES = 32 diff --git a/Pcap++/header/PfRingDevice.h b/Pcap++/header/PfRingDevice.h index 6ebdb47ed8..358e0b6755 100644 --- a/Pcap++/header/PfRingDevice.h +++ b/Pcap++/header/PfRingDevice.h @@ -6,6 +6,7 @@ #include "MacAddress.h" #include "SystemUtils.h" #include "Packet.h" +#include #include #include #include @@ -57,7 +58,7 @@ namespace pcpp int m_InterfaceIndex; MacAddress m_MacAddress; int m_DeviceMTU; - CoreConfiguration m_CoreConfiguration[MAX_NUM_OF_CORES]; + std::array m_CoreConfiguration; bool m_StopThread; OnPfRingPacketsArriveCallback m_OnPacketsArriveCallback; void* m_OnPacketsArriveUserCookie; diff --git a/Pcap++/src/PfRingDevice.cpp b/Pcap++/src/PfRingDevice.cpp index 29e57cbc37..90e0caccc9 100644 --- a/Pcap++/src/PfRingDevice.cpp +++ b/Pcap++/src/PfRingDevice.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #define DEFAULT_PF_RING_SNAPLEN 1600 @@ -714,18 +715,14 @@ namespace pcpp void PfRingDevice::clearCoreConfiguration() { - for (int i = 0; i < MAX_NUM_OF_CORES; i++) - m_CoreConfiguration[i].clear(); + for (auto& config : m_CoreConfiguration) + config.clear(); } int PfRingDevice::getCoresInUseCount() const { - int res = 0; - for (int i = 0; i < MAX_NUM_OF_CORES; i++) - if (m_CoreConfiguration[i].IsInUse) - res++; - - return res; + return std::count_if(m_CoreConfiguration.begin(), m_CoreConfiguration.end(), + [](const CoreConfiguration& config) { return config.IsInUse; }); } void PfRingDevice::setPfRingDeviceAttributes() From d8e3195431841c26c0d90d407fd8e748f8277443 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Sun, 23 Mar 2025 16:43:21 +0200 Subject: [PATCH 30/36] FIxed reentrant mode allocated buffer going out of scope. (#1737) * FIxed reentrant mode allocated buffer going out of scope. * Lint --- Pcap++/src/PfRingDevice.cpp | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/Pcap++/src/PfRingDevice.cpp b/Pcap++/src/PfRingDevice.cpp index 90e0caccc9..22189335ca 100644 --- a/Pcap++/src/PfRingDevice.cpp +++ b/Pcap++/src/PfRingDevice.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #define DEFAULT_PF_RING_SNAPLEN 1600 @@ -624,23 +625,27 @@ namespace pcpp return; } - while (!this->m_StopThread) - { - // if buffer is nullptr PF_RING avoids copy of the data - uint8_t* buffer = nullptr; - uint32_t bufferLen = 0; + // Zero copy is not supported in reentrant mode + const bool zeroCopySupported = !m_ReentrantMode; - // in multi-threaded mode flag PF_RING_REENTRANT is set, and this flag doesn't work with zero copy - // so I need to allocate a buffer and set buffer to point to it - if (this->m_ReentrantMode) - { - uint8_t tempBuffer[PCPP_MAX_PACKET_SIZE]; - buffer = tempBuffer; - bufferLen = PCPP_MAX_PACKET_SIZE; - } + // If the `bufferPtr` is set to nullptr, PF_RING will use zero copy mode and sets `bufferPtr` to point to the + // packet data. + uint8_t* bufferPtr = nullptr; + uint32_t bufferLen = 0; + std::vector recvBuffer; + // If zero copy is not supported, allocate a buffer for the packet data. + if (!zeroCopySupported) + { + recvBuffer.resize(PCPP_MAX_PACKET_SIZE); + bufferPtr = recvBuffer.data(); + bufferLen = recvBuffer.size(); + } + + while (!this->m_StopThread) + { struct pfring_pkthdr pktHdr; - int recvRes = pfring_recv(ring, &buffer, bufferLen, &pktHdr, 0); + int recvRes = pfring_recv(ring, &bufferPtr, bufferLen, &pktHdr, 0); if (recvRes > 0) { // if caplen < len it means we don't have the whole packet. Treat this case as packet drop @@ -651,7 +656,7 @@ namespace pcpp // continue; // } - RawPacket rawPacket(buffer, pktHdr.caplen, pktHdr.ts, false); + RawPacket rawPacket(bufferPtr, pktHdr.caplen, pktHdr.ts, false); this->m_OnPacketsArriveCallback(&rawPacket, 1, coreId, this, this->m_OnPacketsArriveUserCookie); } else if (recvRes < 0) From 86103dabda70ed0276e9b59fcfb32c7f4c3028d9 Mon Sep 17 00:00:00 2001 From: seladb Date: Mon, 24 Mar 2025 00:10:37 -0700 Subject: [PATCH 31/36] Pin `cppcheck` to version 2.9 (#1739) * Pin cppcheck version * Fix path * Update cppcheck to 2.17.1 * Suppress cppcheck error * Remove cppcheck source after installation * Fix cppcheck issues * Fix cppcheck issues * Fix cppcheck issues * Fix cppcheck issues * Suppress `normalCheckLevelMaxBranches` * Remove `--language=c++` param * Rollback to 2.7 * Rollback to 2.7 * Try cppcheck 2.9 * Update CONTRIBUTING.md --- .github/workflows/build_and_test.yml | 5 ++++- CONTRIBUTING.md | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 3791f6c902..482e6afd4f 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -11,6 +11,7 @@ env: BUILD_DIR: Dist GCOVR_FLAGS: --gcov-ignore-parse-errors --exclude-throw-branches --filter Common --filter Pcap --filter Packet --xml CCACHE_DIR: ${{ github.workspace }}/.ccache + CPPCHECK_VERSION: 2.9 permissions: contents: read @@ -33,7 +34,9 @@ jobs: - name: Install dependencies run: | - apk update && apk add cppcheck python3-dev + apk update && apk add python3-dev + git clone --branch $CPPCHECK_VERSION --single-branch https://github.com/danmar/cppcheck.git + cd cppcheck && mkdir build && cd build && cmake .. && cmake --build . && cmake --install . && cd ../../ && rm -rf cppcheck python3 -m venv .venv . .venv/bin/activate python3 -m pip install pre-commit setuptools clang-format==19.1.6 clang-tidy==18.1.8 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 69530d8268..fe382ada55 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,7 +24,7 @@ Every code contribution to this project is highly valued and appreciated. I enco - All new APIs are well documented using Doxygen (please use @ for keywords) - Make sure that pre-commit hooks are passing by using `pre-commit run --all-files`. For pre-commit hooks you need to install `cppcheck` and `clang-format` on your system. You can install them using the following commands: - `pre-commit`: `pip install pre-commit` - - `cppcheck` (version 2.7 is recommended): + - `cppcheck` (version 2.9 is recommended): - For Linux (apt) `sudo apt install cppcheck` - For Windows (using `choco`) `choco install cppcheck --version=2.7` - For Windows (MSI install): https://github.com/danmar/cppcheck/releases/download/2.7/cppcheck-2.7-x64-Setup.msi From b9ee9d613be2e30698f3c47c61184bde547c5fd5 Mon Sep 17 00:00:00 2001 From: seladb Date: Mon, 24 Mar 2025 01:40:16 -0700 Subject: [PATCH 32/36] Add `UdpLayer::isDataValid()` (#1741) --- Packet++/header/UdpLayer.h | 11 +++++++++++ Packet++/src/IPSecLayer.cpp | 5 +++-- Packet++/src/IPv4Layer.cpp | 5 +++-- Packet++/src/IPv6Layer.cpp | 4 +++- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Packet++/header/UdpLayer.h b/Packet++/header/UdpLayer.h index 83cbc555f4..c78bc2ded9 100644 --- a/Packet++/header/UdpLayer.h +++ b/Packet++/header/UdpLayer.h @@ -64,6 +64,12 @@ namespace pcpp /// @return The checksum result uint16_t calculateChecksum(bool writeResultToPacket); + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of an UDP packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent a UDP packet + static inline bool isDataValid(const uint8_t* data, size_t dataLen); + // implement abstract methods /// Currently identifies the following next layers: DnsLayer, DhcpLayer, VxlanLayer, SipRequestLayer, @@ -86,4 +92,9 @@ namespace pcpp return OsiModelTransportLayer; } }; + + bool UdpLayer::isDataValid(const uint8_t* data, size_t dataLen) + { + return data && dataLen >= sizeof(udphdr); + } } // namespace pcpp diff --git a/Packet++/src/IPSecLayer.cpp b/Packet++/src/IPSecLayer.cpp index 445ddcb54c..5f26dc0468 100644 --- a/Packet++/src/IPSecLayer.cpp +++ b/Packet++/src/IPSecLayer.cpp @@ -63,8 +63,9 @@ namespace pcpp switch (getAHHeader()->nextHeader) { case PACKETPP_IPPROTO_UDP: - if (payloadLen >= sizeof(udphdr)) - m_NextLayer = new UdpLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = UdpLayer::isDataValid(payload, payloadLen) + ? static_cast(new UdpLayer(payload, payloadLen, this, m_Packet)) + : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); break; case PACKETPP_IPPROTO_TCP: m_NextLayer = TcpLayer::isDataValid(payload, payloadLen) diff --git a/Packet++/src/IPv4Layer.cpp b/Packet++/src/IPv4Layer.cpp index db31ac47d2..47024828b5 100644 --- a/Packet++/src/IPv4Layer.cpp +++ b/Packet++/src/IPv4Layer.cpp @@ -268,8 +268,9 @@ namespace pcpp switch (ipHdr->protocol) { case PACKETPP_IPPROTO_UDP: - if (payloadLen >= sizeof(udphdr)) - m_NextLayer = new UdpLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = UdpLayer::isDataValid(payload, payloadLen) + ? static_cast(new UdpLayer(payload, payloadLen, this, m_Packet)) + : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); break; case PACKETPP_IPPROTO_TCP: m_NextLayer = TcpLayer::isDataValid(payload, payloadLen) diff --git a/Packet++/src/IPv6Layer.cpp b/Packet++/src/IPv6Layer.cpp index e4daff0a5f..fb17d09051 100644 --- a/Packet++/src/IPv6Layer.cpp +++ b/Packet++/src/IPv6Layer.cpp @@ -222,7 +222,9 @@ namespace pcpp switch (nextHdr) { case PACKETPP_IPPROTO_UDP: - m_NextLayer = new UdpLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = UdpLayer::isDataValid(payload, payloadLen) + ? static_cast(new UdpLayer(payload, payloadLen, this, m_Packet)) + : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); break; case PACKETPP_IPPROTO_TCP: m_NextLayer = TcpLayer::isDataValid(payload, payloadLen) From 52d25b56a46a64543d91e6d6ce925e174b0c2608 Mon Sep 17 00:00:00 2001 From: seladb Date: Mon, 24 Mar 2025 23:46:01 -0700 Subject: [PATCH 33/36] Add `PPP_PPTPLayer::isDataValid()` (#1742) --- Packet++/header/GreLayer.h | 11 +++++++++++ Packet++/src/GreLayer.cpp | 4 +++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Packet++/header/GreLayer.h b/Packet++/header/GreLayer.h index b08f11ba49..38c25d64a6 100644 --- a/Packet++/header/GreLayer.h +++ b/Packet++/header/GreLayer.h @@ -359,6 +359,12 @@ namespace pcpp return reinterpret_cast(m_Data); } + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of a PPP-PPTP packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent a PPP-PPTP packet + static inline bool isDataValid(const uint8_t* data, size_t dataLen); + // implement abstract methods /// Currently identifies the following next layers: IPv4Layer, IPv6Layer. Otherwise sets PayloadLayer @@ -385,4 +391,9 @@ namespace pcpp } }; + bool PPP_PPTPLayer::isDataValid(const uint8_t* data, size_t dataLen) + { + return data && dataLen >= sizeof(ppp_pptp_header); + } + } // namespace pcpp diff --git a/Packet++/src/GreLayer.cpp b/Packet++/src/GreLayer.cpp index da8b5d7170..37eee3a879 100644 --- a/Packet++/src/GreLayer.cpp +++ b/Packet++/src/GreLayer.cpp @@ -221,7 +221,9 @@ namespace pcpp m_NextLayer = new MplsLayer(payload, payloadLen, this, m_Packet); break; case PCPP_ETHERTYPE_PPP: - m_NextLayer = new PPP_PPTPLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = PPP_PPTPLayer::isDataValid(payload, payloadLen) + ? static_cast(new PPP_PPTPLayer(payload, payloadLen, this, m_Packet)) + : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); break; case PCPP_ETHERTYPE_ETHBRIDGE: if (EthLayer::isDataValid(payload, payloadLen)) From 1c2d4e597a22877dafd3ed1396d797d0cf1ff3d7 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Thu, 27 Mar 2025 14:07:21 +0200 Subject: [PATCH 34/36] Reorders the implementation order of PcapFileDevice.cpp to match the declaration order of PcapFileDevice.h (#1745) --- Pcap++/src/PcapFileDevice.cpp | 204 +++++++++++++++++----------------- 1 file changed, 102 insertions(+), 102 deletions(-) diff --git a/Pcap++/src/PcapFileDevice.cpp b/Pcap++/src/PcapFileDevice.cpp index 079d2ab2cc..cf6ff236b2 100644 --- a/Pcap++/src/PcapFileDevice.cpp +++ b/Pcap++/src/PcapFileDevice.cpp @@ -129,6 +129,108 @@ namespace pcpp return numOfPacketsRead; } + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // PcapFileReaderDevice members + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + bool PcapFileReaderDevice::open() + { + m_NumOfPacketsRead = 0; + m_NumOfPacketsNotParsed = 0; + + if (m_PcapDescriptor != nullptr) + { + PCPP_LOG_DEBUG("Pcap descriptor already opened. Nothing to do"); + return true; + } + + char errbuf[PCAP_ERRBUF_SIZE]; +#if defined(PCAP_TSTAMP_PRECISION_NANO) + auto pcapDescriptor = internal::PcapHandle( + pcap_open_offline_with_tstamp_precision(m_FileName.c_str(), PCAP_TSTAMP_PRECISION_NANO, errbuf)); +#else + auto pcapDescriptor = internal::PcapHandle(pcap_open_offline(m_FileName.c_str(), errbuf)); +#endif + if (pcapDescriptor == nullptr) + { + PCPP_LOG_ERROR("Cannot open file reader device for filename '" << m_FileName << "': " << errbuf); + m_DeviceOpened = false; + return false; + } + + int linkLayer = pcap_datalink(pcapDescriptor.get()); + if (!RawPacket::isLinkTypeValid(linkLayer)) + { + PCPP_LOG_ERROR("Invalid link layer (" << linkLayer << ") for reader device filename '" << m_FileName + << "'"); + m_DeviceOpened = false; + return false; + } + + m_PcapLinkLayerType = static_cast(linkLayer); + +#if defined(PCAP_TSTAMP_PRECISION_NANO) + m_Precision = static_cast(pcap_get_tstamp_precision(pcapDescriptor.get())); + std::string precisionStr = + (m_Precision == FileTimestampPrecision::Nanoseconds) ? "nanoseconds" : "microseconds"; +#else + m_Precision = FileTimestampPrecision::Microseconds; + std::string precisionStr = "microseconds"; +#endif + PCPP_LOG_DEBUG("Successfully opened file reader device for filename '" << m_FileName << "' with precision " + << precisionStr); + m_PcapDescriptor = std::move(pcapDescriptor); + m_DeviceOpened = true; + return true; + } + + bool PcapFileReaderDevice::isNanoSecondPrecisionSupported() + { + return checkNanoSupport(); + } + + void PcapFileReaderDevice::getStatistics(PcapStats& stats) const + { + stats.packetsRecv = m_NumOfPacketsRead; + stats.packetsDrop = m_NumOfPacketsNotParsed; + stats.packetsDropByInterface = 0; + PCPP_LOG_DEBUG("Statistics received for reader device for filename '" << m_FileName << "'"); + } + + bool PcapFileReaderDevice::getNextPacket(RawPacket& rawPacket) + { + rawPacket.clear(); + if (m_PcapDescriptor == nullptr) + { + PCPP_LOG_ERROR("File device '" << m_FileName << "' not opened"); + return false; + } + pcap_pkthdr pkthdr; + const uint8_t* pPacketData = pcap_next(m_PcapDescriptor.get(), &pkthdr); + if (pPacketData == nullptr) + { + PCPP_LOG_DEBUG("Packet could not be read. Probably end-of-file"); + return false; + } + + uint8_t* pMyPacketData = new uint8_t[pkthdr.caplen]; + memcpy(pMyPacketData, pPacketData, pkthdr.caplen); +#if defined(PCAP_TSTAMP_PRECISION_NANO) + // because we opened with nano second precision 'tv_usec' is actually nanos + timespec ts = { pkthdr.ts.tv_sec, static_cast(pkthdr.ts.tv_usec) }; +#else + struct timeval ts = pkthdr.ts; +#endif + if (!rawPacket.setRawData(pMyPacketData, pkthdr.caplen, ts, static_cast(m_PcapLinkLayerType), + pkthdr.len)) + { + PCPP_LOG_ERROR("Couldn't set data to raw packet"); + return false; + } + m_NumOfPacketsRead++; + return true; + } + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // SnoopFileReaderDevice members // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -251,108 +353,6 @@ namespace pcpp PCPP_LOG_DEBUG("File reader closed for file '" << m_FileName << "'"); } - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // PcapFileReaderDevice members - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - bool PcapFileReaderDevice::open() - { - m_NumOfPacketsRead = 0; - m_NumOfPacketsNotParsed = 0; - - if (m_PcapDescriptor != nullptr) - { - PCPP_LOG_DEBUG("Pcap descriptor already opened. Nothing to do"); - return true; - } - - char errbuf[PCAP_ERRBUF_SIZE]; -#if defined(PCAP_TSTAMP_PRECISION_NANO) - auto pcapDescriptor = internal::PcapHandle( - pcap_open_offline_with_tstamp_precision(m_FileName.c_str(), PCAP_TSTAMP_PRECISION_NANO, errbuf)); -#else - auto pcapDescriptor = internal::PcapHandle(pcap_open_offline(m_FileName.c_str(), errbuf)); -#endif - if (pcapDescriptor == nullptr) - { - PCPP_LOG_ERROR("Cannot open file reader device for filename '" << m_FileName << "': " << errbuf); - m_DeviceOpened = false; - return false; - } - - int linkLayer = pcap_datalink(pcapDescriptor.get()); - if (!RawPacket::isLinkTypeValid(linkLayer)) - { - PCPP_LOG_ERROR("Invalid link layer (" << linkLayer << ") for reader device filename '" << m_FileName - << "'"); - m_DeviceOpened = false; - return false; - } - - m_PcapLinkLayerType = static_cast(linkLayer); - -#if defined(PCAP_TSTAMP_PRECISION_NANO) - m_Precision = static_cast(pcap_get_tstamp_precision(pcapDescriptor.get())); - std::string precisionStr = - (m_Precision == FileTimestampPrecision::Nanoseconds) ? "nanoseconds" : "microseconds"; -#else - m_Precision = FileTimestampPrecision::Microseconds; - std::string precisionStr = "microseconds"; -#endif - PCPP_LOG_DEBUG("Successfully opened file reader device for filename '" << m_FileName << "' with precision " - << precisionStr); - m_PcapDescriptor = std::move(pcapDescriptor); - m_DeviceOpened = true; - return true; - } - - bool PcapFileReaderDevice::isNanoSecondPrecisionSupported() - { - return checkNanoSupport(); - } - - void PcapFileReaderDevice::getStatistics(PcapStats& stats) const - { - stats.packetsRecv = m_NumOfPacketsRead; - stats.packetsDrop = m_NumOfPacketsNotParsed; - stats.packetsDropByInterface = 0; - PCPP_LOG_DEBUG("Statistics received for reader device for filename '" << m_FileName << "'"); - } - - bool PcapFileReaderDevice::getNextPacket(RawPacket& rawPacket) - { - rawPacket.clear(); - if (m_PcapDescriptor == nullptr) - { - PCPP_LOG_ERROR("File device '" << m_FileName << "' not opened"); - return false; - } - pcap_pkthdr pkthdr; - const uint8_t* pPacketData = pcap_next(m_PcapDescriptor.get(), &pkthdr); - if (pPacketData == nullptr) - { - PCPP_LOG_DEBUG("Packet could not be read. Probably end-of-file"); - return false; - } - - uint8_t* pMyPacketData = new uint8_t[pkthdr.caplen]; - memcpy(pMyPacketData, pPacketData, pkthdr.caplen); -#if defined(PCAP_TSTAMP_PRECISION_NANO) - // because we opened with nano second precision 'tv_usec' is actually nanos - timespec ts = { pkthdr.ts.tv_sec, static_cast(pkthdr.ts.tv_usec) }; -#else - struct timeval ts = pkthdr.ts; -#endif - if (!rawPacket.setRawData(pMyPacketData, pkthdr.caplen, ts, static_cast(m_PcapLinkLayerType), - pkthdr.len)) - { - PCPP_LOG_ERROR("Couldn't set data to raw packet"); - return false; - } - m_NumOfPacketsRead++; - return true; - } - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PcapNgFileReaderDevice members // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From ca51538e8b4d5223844c881a3c4ed01da6167836 Mon Sep 17 00:00:00 2001 From: seladb Date: Thu, 27 Mar 2025 23:30:37 -0700 Subject: [PATCH 35/36] Add Cisco HDLC layer (#1747) --- Packet++/CMakeLists.txt | 2 + Packet++/header/CiscoHdlcLayer.h | 104 ++++++++++++ Packet++/header/Packet.h | 6 +- Packet++/header/ProtocolType.h | 3 + Packet++/src/CiscoHdlcLayer.cpp | 127 +++++++++++++++ Packet++/src/Packet.cpp | 16 +- README.md | 101 ++++++------ Tests/Packet++Test/CMakeLists.txt | 1 + .../PacketExamples/CiscoHDLC-IPv4.dat | 1 + .../PacketExamples/CiscoHDLC-IPv6.dat | 1 + .../PacketExamples/CiscoHDLC-SLARP.dat | 1 + .../PacketExamples/CiscoHDLC.pcap | Bin 0 -> 264 bytes Tests/Packet++Test/TestDefinition.h | 5 + Tests/Packet++Test/Tests/CiscoHdlcTests.cpp | 152 ++++++++++++++++++ Tests/Packet++Test/main.cpp | 4 + 15 files changed, 468 insertions(+), 56 deletions(-) create mode 100644 Packet++/header/CiscoHdlcLayer.h create mode 100644 Packet++/src/CiscoHdlcLayer.cpp create mode 100644 Tests/Packet++Test/PacketExamples/CiscoHDLC-IPv4.dat create mode 100644 Tests/Packet++Test/PacketExamples/CiscoHDLC-IPv6.dat create mode 100644 Tests/Packet++Test/PacketExamples/CiscoHDLC-SLARP.dat create mode 100644 Tests/Packet++Test/PacketExamples/CiscoHDLC.pcap create mode 100644 Tests/Packet++Test/Tests/CiscoHdlcTests.cpp diff --git a/Packet++/CMakeLists.txt b/Packet++/CMakeLists.txt index 2bae131ebd..500d078053 100644 --- a/Packet++/CMakeLists.txt +++ b/Packet++/CMakeLists.txt @@ -4,6 +4,7 @@ add_library( src/ArpLayer.cpp src/Asn1Codec.cpp src/BgpLayer.cpp + src/CiscoHdlcLayer.cpp src/CotpLayer.cpp src/DhcpLayer.cpp src/DhcpV6Layer.cpp @@ -73,6 +74,7 @@ set( header/ArpLayer.h header/Asn1Codec.h header/BgpLayer.h + header/CiscoHdlcLayer.h header/CotpLayer.h header/DhcpLayer.h header/DhcpV6Layer.h diff --git a/Packet++/header/CiscoHdlcLayer.h b/Packet++/header/CiscoHdlcLayer.h new file mode 100644 index 0000000000..fe444bdf73 --- /dev/null +++ b/Packet++/header/CiscoHdlcLayer.h @@ -0,0 +1,104 @@ +#pragma once + +#include "Layer.h" + +namespace pcpp +{ + /// @class CiscoHdlcLayer + /// Represents a Cisco HDLC protocol layer + class CiscoHdlcLayer : public Layer + { + public: + /// @enum AddressType + /// Represents Cisco HDLC address types + enum class AddressType + { + /// Unicast + Unicast = 0x0f, + /// Multicast + Multicast = 0x8f, + /// Unknown address type + Unknown + }; + + /// A constructor that creates the layer from an existing packet raw data + /// @param[in] data A pointer to the raw data + /// @param[in] dataLen Size of the data in bytes + /// @param[in] packet A pointer to the Packet instance where layer will be stored + CiscoHdlcLayer(uint8_t* data, size_t dataLen, Packet* packet) : Layer(data, dataLen, nullptr, packet, CiscoHDLC) + {} + + /// A constructor that creates a new Cisco HDLC layer + /// @param[in] address The address field value + explicit CiscoHdlcLayer(AddressType address); + + /// Default destructor for this layer + ~CiscoHdlcLayer() override = default; + + /// @return The address field enum value + AddressType getAddress() const; + + /// @return The address field raw value + uint8_t getAddressValue() const; + + /// Set the address field enum value + /// @param[in] address The address enum value to set + void setAddress(AddressType address); + + /// Set the address field value + /// @param[in] address The address value to set + void setAddressValue(uint8_t address); + + /// @return The protocol type value + uint16_t getNextProtocol() const; + + /// A static method that validates the input data + /// @param[in] data The pointer to the beginning of a byte stream of a Cisco HDLC packet + /// @param[in] dataLen The length of the byte stream + /// @return True if the data is valid and can represent a Cisco HDLC packet + static bool isDataValid(const uint8_t* data, size_t dataLen) + { + return data && dataLen >= sizeof(cisco_hdlc_header); + } + + // Overridden methods + + /// @return The size of the HDLC header which is 4 bytes + size_t getHeaderLen() const override + { + return sizeof(cisco_hdlc_header); + } + + /// Calculate the Next Protocol when possible + void computeCalculateFields() override; + + /// Parses the next layer. Currently, supports IPv4 and IPv6 + void parseNextLayer() override; + + std::string toString() const override; + + OsiModelLayer getOsiModelLayer() const override + { + return OsiModelDataLinkLayer; + } + + private: +#pragma pack(push, 1) + struct cisco_hdlc_header + { + uint8_t address; + uint8_t control; + uint16_t protocol; + }; +#pragma pack(pop) + static_assert(sizeof(cisco_hdlc_header) == 4, "cisco_hdlc_header size is not 4 bytes"); + + cisco_hdlc_header* getCiscoHdlcHeader() const + { + return reinterpret_cast(m_Data); + } + + void setNextProtocol(uint16_t protocol); + }; + +} // namespace pcpp diff --git a/Packet++/header/Packet.h b/Packet++/header/Packet.h index b430ba6c8e..d8f66d18bf 100644 --- a/Packet++/header/Packet.h +++ b/Packet++/header/Packet.h @@ -35,7 +35,8 @@ namespace pcpp /// When using this constructor an empty raw buffer is allocated (with the size of maxPacketLen) and a new /// RawPacket is created /// @param[in] maxPacketLen The expected packet length in bytes - explicit Packet(size_t maxPacketLen = 1); + /// @param[in] linkType The link type to use for this packet (the default is Ethernet) + explicit Packet(size_t maxPacketLen = 1, LinkLayerType linkType = LINKTYPE_ETHERNET); /// A constructor for creating a new packet with a buffer that is pre-allocated by the user. /// The packet is created empty (with no layers), which means the constructor doesn't parse the data in the @@ -45,7 +46,8 @@ namespace pcpp /// packet data in it. /// @param[in] buffer A pointer to a pre-allocated memory buffer /// @param[in] bufferSize The size of the buffer - Packet(uint8_t* buffer, size_t bufferSize); + /// @param[in] linkType The link type to use for this packet (the default is Ethernet) + Packet(uint8_t* buffer, size_t bufferSize, LinkLayerType linkType = LINKTYPE_ETHERNET); /// A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets /// that came from the network. When using this constructor a pointer to the RawPacket is saved (data isn't diff --git a/Packet++/header/ProtocolType.h b/Packet++/header/ProtocolType.h index a56a5b5a9a..a787457a73 100644 --- a/Packet++/header/ProtocolType.h +++ b/Packet++/header/ProtocolType.h @@ -217,6 +217,9 @@ namespace pcpp /// GTPv2 protocol const ProtocolType GTPv2 = 57; + /// Cisco HDLC protocol + const ProtocolType CiscoHDLC = 58; + /// An enum representing OSI model layers enum OsiModelLayer { diff --git a/Packet++/src/CiscoHdlcLayer.cpp b/Packet++/src/CiscoHdlcLayer.cpp new file mode 100644 index 0000000000..7fac1ae5cd --- /dev/null +++ b/Packet++/src/CiscoHdlcLayer.cpp @@ -0,0 +1,127 @@ +#include "CiscoHdlcLayer.h" +#include "Layer.h" +#include "IPv4Layer.h" +#include "IPv6Layer.h" +#include "PayloadLayer.h" +#include "EndianPortable.h" +#include + +namespace pcpp +{ + +// Protocol types for Cisco HDLC +#define CISCO_HDLC_TYPE_IP 0x0800 +#define CISCO_HDLC_TYPE_IPV6 0x86DD + + CiscoHdlcLayer::CiscoHdlcLayer(AddressType address) + { + m_DataLen = sizeof(cisco_hdlc_header); + m_Data = new uint8_t[m_DataLen]{}; + + cisco_hdlc_header* hdlcHdr = getCiscoHdlcHeader(); + hdlcHdr->address = static_cast(address == AddressType::Unknown ? AddressType::Unicast : address); + hdlcHdr->control = 0; // Always 0 for Cisco HDLC + } + + void CiscoHdlcLayer::computeCalculateFields() + { + if (m_NextLayer != nullptr) + { + switch (m_NextLayer->getProtocol()) + { + case IPv4: + { + setNextProtocol(CISCO_HDLC_TYPE_IP); + break; + } + case IPv6: + { + setNextProtocol(CISCO_HDLC_TYPE_IPV6); + break; + } + } + } + } + + void CiscoHdlcLayer::parseNextLayer() + { + auto payload = m_Data + sizeof(cisco_hdlc_header); + auto payloadLen = m_DataLen - sizeof(cisco_hdlc_header); + + auto nextProtocol = be16toh(getCiscoHdlcHeader()->protocol); + + switch (nextProtocol) + { + case CISCO_HDLC_TYPE_IP: + { + m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen) + ? static_cast(new IPv4Layer(payload, payloadLen, this, m_Packet)) + : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + break; + } + case CISCO_HDLC_TYPE_IPV6: + { + m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen) + ? static_cast(new IPv6Layer(payload, payloadLen, this, m_Packet)) + : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + break; + } + default: + { + m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + break; + } + } + } + + std::string CiscoHdlcLayer::toString() const + { + return "Cisco HDLC Layer"; + } + + CiscoHdlcLayer::AddressType CiscoHdlcLayer::getAddress() const + { + switch (static_cast(getAddressValue())) + { + case AddressType::Unicast: + case AddressType::Multicast: + { + return static_cast(getAddressValue()); + } + default: + { + return AddressType::Unknown; + } + } + } + + uint8_t CiscoHdlcLayer::getAddressValue() const + { + return getCiscoHdlcHeader()->address; + } + + void CiscoHdlcLayer::setAddress(AddressType address) + { + if (address == AddressType::Unknown) + { + throw std::invalid_argument("Cannot set the address to Address::Unknown"); + } + + setAddressValue(static_cast(address)); + } + + void CiscoHdlcLayer::setAddressValue(uint8_t address) + { + getCiscoHdlcHeader()->address = address; + } + + uint16_t CiscoHdlcLayer::getNextProtocol() const + { + return be16toh(getCiscoHdlcHeader()->protocol); + } + + void CiscoHdlcLayer::setNextProtocol(uint16_t protocol) + { + getCiscoHdlcHeader()->protocol = htobe16(protocol); + } +} // namespace pcpp diff --git a/Packet++/src/Packet.cpp b/Packet++/src/Packet.cpp index d8104aee99..c0754a8126 100644 --- a/Packet++/src/Packet.cpp +++ b/Packet++/src/Packet.cpp @@ -9,6 +9,7 @@ #include "NullLoopbackLayer.h" #include "IPv4Layer.h" #include "IPv6Layer.h" +#include "CiscoHdlcLayer.h" #include "PayloadLayer.h" #include "PacketTrailerLayer.h" #include "Logger.h" @@ -22,7 +23,7 @@ namespace pcpp { - Packet::Packet(size_t maxPacketLen) + Packet::Packet(size_t maxPacketLen, LinkLayerType linkType) : m_RawPacket(nullptr), m_FirstLayer(nullptr), m_LastLayer(nullptr), m_MaxPacketLen(maxPacketLen), m_FreeRawPacket(true), m_CanReallocateData(true) { @@ -30,17 +31,17 @@ namespace pcpp gettimeofday(&time, nullptr); uint8_t* data = new uint8_t[maxPacketLen]; memset(data, 0, maxPacketLen); - m_RawPacket = new RawPacket(data, 0, time, true, LINKTYPE_ETHERNET); + m_RawPacket = new RawPacket(data, 0, time, true, linkType); } - Packet::Packet(uint8_t* buffer, size_t bufferSize) + Packet::Packet(uint8_t* buffer, size_t bufferSize, LinkLayerType linkType) : m_RawPacket(nullptr), m_FirstLayer(nullptr), m_LastLayer(nullptr), m_MaxPacketLen(bufferSize), m_FreeRawPacket(true), m_CanReallocateData(false) { timeval time; gettimeofday(&time, nullptr); memset(buffer, 0, bufferSize); - m_RawPacket = new RawPacket(buffer, 0, time, false, LINKTYPE_ETHERNET); + m_RawPacket = new RawPacket(buffer, 0, time, false, linkType); } void Packet::setRawPacket(RawPacket* rawPacket, bool freeRawPacket, ProtocolTypeFamily parseUntil, @@ -810,6 +811,13 @@ namespace pcpp ? static_cast(new NflogLayer((uint8_t*)rawData, rawDataLen, this)) : static_cast(new PayloadLayer((uint8_t*)rawData, rawDataLen, nullptr, this)); } + else if (linkType == LINKTYPE_C_HDLC) + { + return CiscoHdlcLayer::isDataValid(rawData, rawDataLen) + ? static_cast(new CiscoHdlcLayer(const_cast(rawData), rawDataLen, this)) + : static_cast( + new PayloadLayer(const_cast(rawData), rawDataLen, nullptr, this)); + } // unknown link type return new PayloadLayer((uint8_t*)rawData, rawDataLen, nullptr, this); diff --git a/README.md b/README.md index 5bd05a0b9d..6bab270fd2 100644 --- a/README.md +++ b/README.md @@ -217,72 +217,73 @@ PcapPlusPlus currently supports parsing, editing and creation of packets of the ### Data Link Layer (L2) -1. Ethernet II -2. IEEE 802.3 Ethernet -3. LLC (Only BPDU supported) -4. Null/Loopback -5. Packet trailer (a.k.a footer or padding) -6. PPPoE -7. SLL (Linux cooked capture) -8. SLL2 (Linux cooked capture v2) -9. STP -10. VLAN -11. VXLAN -12. Wake on LAN (WoL) -13. NFLOG (Linux Netfilter NFLOG) - parsing only (no editing capabilities) +1. Cisco HDLC +2. Ethernet II +3. IEEE 802.3 Ethernet +4. LLC (Only BPDU supported) +5. Null/Loopback +6. Packet trailer (a.k.a footer or padding) +7. PPPoE +8. SLL (Linux cooked capture) +9. SLL2 (Linux cooked capture v2) +10. STP +11. VLAN +12. VXLAN +13. Wake on LAN (WoL) +14. NFLOG (Linux Netfilter NFLOG) - parsing only (no editing capabilities) ### Network Layer (L3) -14. ARP -15. GRE -16. ICMP -17. ICMPv6 -18. IGMP (IGMPv1, IGMPv2 and IGMPv3 are supported) -19. IPv4 -20. IPv6 -21. MPLS -22. NDP -23. Raw IP (IPv4 & IPv6) -24. VRRP (IPv4 & IPv6) -25. WireGuard +15. ARP +16. GRE +17. ICMP +18. ICMPv6 +19. IGMP (IGMPv1, IGMPv2 and IGMPv3 are supported) +20. IPv4 +21. IPv6 +22. MPLS +23. NDP +24. Raw IP (IPv4 & IPv6) +25. VRRP (IPv4 & IPv6) +26. WireGuard ### Transport Layer (L4) -26. COTP -27. GTP (v1 & v2) -28. IPSec AH & ESP - parsing only (no editing capabilities) -29. TCP -30. TPKT -31. UDP +27. COTP +28. GTP (v1 & v2) +29. IPSec AH & ESP - parsing only (no editing capabilities) +30. TCP +31. TPKT +32. UDP ### Session Layer (L5) -32. SDP -33. SIP +33. SDP +34. SIP ### Presentation Layer (L6) -34. SSL/TLS - parsing only (no editing capabilities) +35. SSL/TLS - parsing only (no editing capabilities) ### Application Layer (L7) -35. ASN.1 decoder and encoder -36. BGP (v4) -37. DHCP -38. DHCPv6 -39. DNS -40. FTP -41. HTTP headers (request & response) -42. LDAP -43. NTP (v3, v4) -44. Radius -45. S7 Communication (S7comm) -46. SMTP -47. SOME/IP -48. SSH - parsing only (no editing capabilities) -49. Telnet - parsing only (no editing capabilities) -50. Generic payload +36. ASN.1 decoder and encoder +37. BGP (v4) +38. DHCP +39. DHCPv6 +40. DNS +41. FTP +42. HTTP headers (request & response) +43. LDAP +44. NTP (v3, v4) +45. Radius +46. S7 Communication (S7comm) +47. SMTP +48. SOME/IP +49. SSH - parsing only (no editing capabilities) +50. Telnet - parsing only (no editing capabilities) +51. Generic payload ## DPDK And PF_RING Support diff --git a/Tests/Packet++Test/CMakeLists.txt b/Tests/Packet++Test/CMakeLists.txt index 082fb9c51b..2dfd88431a 100644 --- a/Tests/Packet++Test/CMakeLists.txt +++ b/Tests/Packet++Test/CMakeLists.txt @@ -3,6 +3,7 @@ add_executable( main.cpp Tests/Asn1Tests.cpp Tests/BgpTests.cpp + Tests/CiscoHdlcTests.cpp Tests/CotpTests.cpp Tests/DhcpTests.cpp Tests/DhcpV6Tests.cpp diff --git a/Tests/Packet++Test/PacketExamples/CiscoHDLC-IPv4.dat b/Tests/Packet++Test/PacketExamples/CiscoHDLC-IPv4.dat new file mode 100644 index 0000000000..ba1e4cb470 --- /dev/null +++ b/Tests/Packet++Test/PacketExamples/CiscoHDLC-IPv4.dat @@ -0,0 +1 @@ +0f0008004500006400000000ff01a7960a0000010a0000020800320b000000000000000000034c3cabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd \ No newline at end of file diff --git a/Tests/Packet++Test/PacketExamples/CiscoHDLC-IPv6.dat b/Tests/Packet++Test/PacketExamples/CiscoHDLC-IPv6.dat new file mode 100644 index 0000000000..c873ec7e98 --- /dev/null +++ b/Tests/Packet++Test/PacketExamples/CiscoHDLC-IPv6.dat @@ -0,0 +1 @@ +0f0086dd60000000001406002402f00000018e0100000000000055552607fcd00100230000000000b1082a6b04d20050000000000000000050000000911c0000 \ No newline at end of file diff --git a/Tests/Packet++Test/PacketExamples/CiscoHDLC-SLARP.dat b/Tests/Packet++Test/PacketExamples/CiscoHDLC-SLARP.dat new file mode 100644 index 0000000000..028a1aff55 --- /dev/null +++ b/Tests/Packet++Test/PacketExamples/CiscoHDLC-SLARP.dat @@ -0,0 +1 @@ +8f008035000000020000000500000002ffff0078f0a20000 \ No newline at end of file diff --git a/Tests/Packet++Test/PacketExamples/CiscoHDLC.pcap b/Tests/Packet++Test/PacketExamples/CiscoHDLC.pcap new file mode 100644 index 0000000000000000000000000000000000000000..9461aeefd5a889bdda0c11727513b6b87b2f24d3 GIT binary patch literal 264 zcmca|c+)~A1{MYcU}VSua(?^^^~k%)31)-%{0tlnt_%z*Aa(y4mrvtjU|pg&xmGBQX2`5@fS&|nIrn1GlSMF0QKQ1M|A G0|Nk|MpA45 literal 0 HcmV?d00001 diff --git a/Tests/Packet++Test/TestDefinition.h b/Tests/Packet++Test/TestDefinition.h index 9047e2682d..4a9d4ffc2b 100644 --- a/Tests/Packet++Test/TestDefinition.h +++ b/Tests/Packet++Test/TestDefinition.h @@ -274,3 +274,8 @@ PTF_TEST_CASE(WireGuardCookieReplyParsingTest); PTF_TEST_CASE(WireGuardTransportDataParsingTest); PTF_TEST_CASE(WireGuardCreationTest); PTF_TEST_CASE(WireGuardEditTest); + +// Implemented in CiscoHdlcTests.cpp +PTF_TEST_CASE(CiscoHdlcParsingTest); +PTF_TEST_CASE(CiscoHdlcLayerCreationTest); +PTF_TEST_CASE(CiscoHdlcLayerEditTest); diff --git a/Tests/Packet++Test/Tests/CiscoHdlcTests.cpp b/Tests/Packet++Test/Tests/CiscoHdlcTests.cpp new file mode 100644 index 0000000000..805061b764 --- /dev/null +++ b/Tests/Packet++Test/Tests/CiscoHdlcTests.cpp @@ -0,0 +1,152 @@ +#include "../TestDefinition.h" +#include "../Utils/TestUtils.h" +#include "Packet.h" +#include "CiscoHdlcLayer.h" +#include "IPv4Layer.h" +#include "IPv6Layer.h" +#include "SystemUtils.h" + +PTF_TEST_CASE(CiscoHdlcParsingTest) +{ + timeval time; + gettimeofday(&time, nullptr); + + { + READ_FILE_AND_CREATE_PACKET_LINKTYPE(1, "PacketExamples/CiscoHDLC-IPv4.dat", pcpp::LINKTYPE_C_HDLC); + + const pcpp::Packet ciscoHdlcPacket(&rawPacket1); + + PTF_ASSERT_TRUE(ciscoHdlcPacket.isPacketOfType(pcpp::CiscoHDLC)); + const auto ciscoHdlcLayer = ciscoHdlcPacket.getLayerOfType(); + + PTF_ASSERT_EQUAL(ciscoHdlcLayer->getAddress(), pcpp::CiscoHdlcLayer::AddressType::Unicast, enumclass); + PTF_ASSERT_EQUAL(ciscoHdlcLayer->getHeaderLen(), 4); + PTF_ASSERT_EQUAL(ciscoHdlcLayer->getAddressValue(), 0x0f); + PTF_ASSERT_EQUAL(ciscoHdlcLayer->getNextProtocol(), 0x800); + PTF_ASSERT_EQUAL(ciscoHdlcLayer->toString(), "Cisco HDLC Layer"); + PTF_ASSERT_EQUAL(ciscoHdlcLayer->getNextLayer()->getProtocol(), pcpp::IPv4); + } + + { + READ_FILE_AND_CREATE_PACKET_LINKTYPE(1, "PacketExamples/CiscoHDLC-IPv6.dat", pcpp::LINKTYPE_C_HDLC); + + const pcpp::Packet ciscoHdlcPacket(&rawPacket1); + + PTF_ASSERT_TRUE(ciscoHdlcPacket.isPacketOfType(pcpp::CiscoHDLC)); + const auto ciscoHdlcLayer = ciscoHdlcPacket.getLayerOfType(); + + PTF_ASSERT_EQUAL(ciscoHdlcLayer->getAddress(), pcpp::CiscoHdlcLayer::AddressType::Unicast, enumclass); + PTF_ASSERT_EQUAL(ciscoHdlcLayer->getNextProtocol(), 0x86dd); + PTF_ASSERT_EQUAL(ciscoHdlcLayer->getNextLayer()->getProtocol(), pcpp::IPv6); + } + + { + READ_FILE_AND_CREATE_PACKET_LINKTYPE(1, "PacketExamples/CiscoHDLC-SLARP.dat", pcpp::LINKTYPE_C_HDLC); + + const pcpp::Packet ciscoHdlcPacket(&rawPacket1); + + PTF_ASSERT_TRUE(ciscoHdlcPacket.isPacketOfType(pcpp::CiscoHDLC)); + const auto ciscoHdlcLayer = ciscoHdlcPacket.getLayerOfType(); + + PTF_ASSERT_EQUAL(ciscoHdlcLayer->getAddress(), pcpp::CiscoHdlcLayer::AddressType::Multicast, enumclass); + PTF_ASSERT_EQUAL(ciscoHdlcLayer->getAddressValue(), 0x8f); + PTF_ASSERT_EQUAL(ciscoHdlcLayer->getNextProtocol(), 0x8035); + PTF_ASSERT_EQUAL(ciscoHdlcLayer->getNextLayer()->getProtocol(), pcpp::GenericPayload); + } + + // Malformed Cisco HDLC + IPv4 + { + auto data = std::vector{ 0x0f, 0x00, 0x08, 0x00, 0x45, 0xc0 }; + auto rawPacket = pcpp::RawPacket(data.data(), data.size(), time, false, pcpp::LINKTYPE_C_HDLC); + + const pcpp::Packet ciscoHdlcPacket(&rawPacket); + + PTF_ASSERT_TRUE(ciscoHdlcPacket.isPacketOfType(pcpp::CiscoHDLC)); + const auto ciscoHdlcLayer = ciscoHdlcPacket.getLayerOfType(); + + PTF_ASSERT_EQUAL(ciscoHdlcLayer->getNextLayer()->getProtocol(), pcpp::GenericPayload); + } +} // CiscoHdlcParsingTest + +PTF_TEST_CASE(CiscoHdlcLayerCreationTest) +{ + timeval time; + gettimeofday(&time, nullptr); + + { + pcpp::CiscoHdlcLayer newHdlcLayer(pcpp::CiscoHdlcLayer::AddressType::Unicast); + pcpp::IPv4Layer ipv4Layer(pcpp::IPv4Address("100.16.1.2"), pcpp::IPv4Address("100.16.1.1")); + + pcpp::Packet newHdlcPacket(20, pcpp::LINKTYPE_C_HDLC); + newHdlcPacket.addLayer(&newHdlcLayer); + newHdlcPacket.addLayer(&ipv4Layer); + newHdlcPacket.computeCalculateFields(); + + READ_FILE_AND_CREATE_PACKET_LINKTYPE(1, "PacketExamples/CiscoHDLC-IPv4.dat", pcpp::LINKTYPE_C_HDLC); + + const pcpp::Packet hdlcPacket(&rawPacket1); + + const auto hdlcLayer = hdlcPacket.getLayerOfType(); + PTF_ASSERT_NOT_NULL(hdlcLayer); + PTF_ASSERT_EQUAL(newHdlcPacket.getRawPacket()->getLinkLayerType(), pcpp::LINKTYPE_C_HDLC); + + PTF_ASSERT_BUF_COMPARE(hdlcPacket.getLayerOfType()->getData(), + newHdlcPacket.getLayerOfType()->getData(), + hdlcPacket.getLayerOfType()->getHeaderLen()); + } + + { + pcpp::CiscoHdlcLayer newHdlcLayer(pcpp::CiscoHdlcLayer::AddressType::Unicast); + pcpp::IPv6Layer ipv6Layer(pcpp::IPv6Address("2402:f000:1:8e01::5555"), + pcpp::IPv6Address("2607:fcd0:100:2300::b108:2a6b")); + + pcpp::Packet newHdlcPacket(20, pcpp::LINKTYPE_C_HDLC); + newHdlcPacket.addLayer(&newHdlcLayer); + newHdlcPacket.addLayer(&ipv6Layer); + newHdlcPacket.computeCalculateFields(); + + READ_FILE_AND_CREATE_PACKET_LINKTYPE(1, "PacketExamples/CiscoHDLC-IPv6.dat", pcpp::LINKTYPE_C_HDLC); + + const pcpp::Packet hdlcPacket(&rawPacket1); + + const auto hdlcLayer = hdlcPacket.getLayerOfType(); + PTF_ASSERT_NOT_NULL(hdlcLayer); + PTF_ASSERT_EQUAL(newHdlcPacket.getRawPacket()->getLinkLayerType(), pcpp::LINKTYPE_C_HDLC); + + PTF_ASSERT_BUF_COMPARE(hdlcPacket.getLayerOfType()->getData(), + newHdlcPacket.getLayerOfType()->getData(), + hdlcPacket.getLayerOfType()->getHeaderLen()); + } +} // CiscoHdlcLayerCreationTest + +PTF_TEST_CASE(CiscoHdlcLayerEditTest) +{ + { + pcpp::CiscoHdlcLayer newHdlcLayer(pcpp::CiscoHdlcLayer::AddressType::Multicast); + + newHdlcLayer.setAddress(pcpp::CiscoHdlcLayer::AddressType::Unicast); + PTF_ASSERT_EQUAL(newHdlcLayer.getAddress(), pcpp::CiscoHdlcLayer::AddressType::Unicast, enumclass); + } + + { + pcpp::CiscoHdlcLayer newHdlcLayer(pcpp::CiscoHdlcLayer::AddressType::Unicast); + + newHdlcLayer.setAddressValue(0x8f); + PTF_ASSERT_EQUAL(newHdlcLayer.getAddress(), pcpp::CiscoHdlcLayer::AddressType::Multicast, enumclass); + } + + { + pcpp::CiscoHdlcLayer newHdlcLayer(pcpp::CiscoHdlcLayer::AddressType::Unicast); + + newHdlcLayer.setAddressValue(0x1); + PTF_ASSERT_EQUAL(newHdlcLayer.getAddress(), pcpp::CiscoHdlcLayer::AddressType::Unknown, enumclass); + } + + { + pcpp::CiscoHdlcLayer newHdlcLayer(pcpp::CiscoHdlcLayer::AddressType::Unicast); + + PTF_ASSERT_RAISES(newHdlcLayer.setAddress(pcpp::CiscoHdlcLayer::AddressType::Unknown), std::invalid_argument, + "Cannot set the address to Address::Unknown"); + } + +} // CiscoHdlcLayerEditTest diff --git a/Tests/Packet++Test/main.cpp b/Tests/Packet++Test/main.cpp index ebf1838620..a026968c93 100644 --- a/Tests/Packet++Test/main.cpp +++ b/Tests/Packet++Test/main.cpp @@ -343,5 +343,9 @@ int main(int argc, char* argv[]) PTF_RUN_TEST(WireGuardCreationTest, "wg"); PTF_RUN_TEST(WireGuardEditTest, "wg"); + PTF_RUN_TEST(CiscoHdlcParsingTest, "chdlc"); + PTF_RUN_TEST(CiscoHdlcLayerCreationTest, "chdlc"); + PTF_RUN_TEST(CiscoHdlcLayerEditTest, "chdlc"); + PTF_END_RUNNING_TESTS; } From 5b6a51ccee57da748a4345e122485d04267c170f Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Fri, 28 Mar 2025 10:40:48 +0200 Subject: [PATCH 36/36] Changes PfRingDevice::m_StopThread to atomic. (#1746) * Made m_StopThread flag atomic to prevent tearing. Encapsulated StartupBlock code for notify/wait into member functions. * Fixed type returns. * Lint --- Pcap++/header/PfRingDevice.h | 16 ++++++--- Pcap++/src/PfRingDevice.cpp | 68 +++++++++++++++++++++++------------- 2 files changed, 54 insertions(+), 30 deletions(-) diff --git a/Pcap++/header/PfRingDevice.h b/Pcap++/header/PfRingDevice.h index 358e0b6755..0f4aa2afc9 100644 --- a/Pcap++/header/PfRingDevice.h +++ b/Pcap++/header/PfRingDevice.h @@ -9,6 +9,7 @@ #include #include #include +#include #include /// @file @@ -45,11 +46,16 @@ namespace pcpp void clear(); }; - struct StartupBlock + class StartupBlock { - std::mutex Mutex; - std::condition_variable Cond; - int State = 0; + public: + void notifyStartup(); + void waitForStartup(); + + private: + std::mutex m_Mutex; + std::condition_variable m_Cv; + bool m_Ready = false; }; pfring** m_PfRingDescriptors; @@ -59,7 +65,7 @@ namespace pcpp MacAddress m_MacAddress; int m_DeviceMTU; std::array m_CoreConfiguration; - bool m_StopThread; + std::atomic m_StopThread; OnPfRingPacketsArriveCallback m_OnPacketsArriveCallback; void* m_OnPacketsArriveUserCookie; bool m_ReentrantMode; diff --git a/Pcap++/src/PfRingDevice.cpp b/Pcap++/src/PfRingDevice.cpp index 22189335ca..af189d3a70 100644 --- a/Pcap++/src/PfRingDevice.cpp +++ b/Pcap++/src/PfRingDevice.cpp @@ -496,22 +496,28 @@ namespace pcpp } catch (const std::exception& e) { + // If an exception occurred, stop all threads + m_StopThread = true; + + // Wake up the threads so they can exit + startupBlock->notifyStartup(); + + // Wait for all threads to exit + for (int coreId2 = coreId; coreId2 >= 0; coreId2--) { - std::unique_lock lock(startupBlock->Mutex); - startupBlock->State = 1; + if (!m_CoreConfiguration[coreId2].IsInUse) + continue; + m_CoreConfiguration[coreId2].RxThread.join(); } - startupBlock->Cond.notify_all(); + clearCoreConfiguration(); PCPP_LOG_ERROR(e.what()); return false; } } - { - std::unique_lock lock(startupBlock->Mutex); - startupBlock->State = 2; - } - startupBlock->Cond.notify_all(); + // Initialization complete. Start the capture threads. + startupBlock->notifyStartup(); return true; } @@ -555,22 +561,22 @@ namespace pcpp } catch (const std::exception& e) { - { - std::unique_lock lock(startupBlock->Mutex); - startupBlock->State = 1; - } - startupBlock->Cond.notify_all(); + // If an exception occurred, stop the thread + m_StopThread = true; + + // Wake up the threads so they can exit + startupBlock->notifyStartup(); + + // Wait for the thread to exit m_CoreConfiguration[0].RxThread.join(); + clearCoreConfiguration(); PCPP_LOG_ERROR(e.what()); return false; } - { - std::unique_lock lock(startupBlock->Mutex); - startupBlock->State = 2; - } - startupBlock->Cond.notify_all(); + // Initialization complete. Start the capture thread. + startupBlock->notifyStartup(); PCPP_LOG_DEBUG("Capturing started for device [" << m_DeviceName << "]"); return true; @@ -580,6 +586,7 @@ namespace pcpp { PCPP_LOG_DEBUG("Trying to stop capturing on device [" << m_DeviceName << "]"); m_StopThread = true; + for (int coreId = 0; coreId < MAX_NUM_OF_CORES; coreId++) { if (!m_CoreConfiguration[coreId].IsInUse) @@ -599,14 +606,12 @@ namespace pcpp return; } - { - std::unique_lock lock(startupBlock->Mutex); - startupBlock->Cond.wait(lock, [&] { return startupBlock->State != 0; }); + startupBlock->waitForStartup(); - if (startupBlock->State == 1) - { - return; - } + if (m_StopThread) + { + PCPP_LOG_DEBUG("Capture thread stopped during initialization."); + return; } // Startup is complete. The block is no longer needed. @@ -938,6 +943,19 @@ namespace pcpp IsAffinitySet = true; } + void PfRingDevice::StartupBlock::notifyStartup() + { + std::lock_guard lock(m_Mutex); + m_Ready = true; + m_Cv.notify_all(); + } + + void PfRingDevice::StartupBlock::waitForStartup() + { + std::unique_lock lock(m_Mutex); + m_Cv.wait(lock, [&] { return m_Ready; }); + } + } // namespace pcpp // GCOVR_EXCL_STOP