diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a74028c1..1d3d1f4d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,17 @@ if(WIN32) endif() find_package(Corrade REQUIRED) + +# After the first find_package() triggers conan install, load conan_toolchain.cmake to set +# CMAKE_PROGRAM_PATH so that tool_requires (e.g. protoc) are preferred over system versions. +# include_guard() in conan_toolchain.cmake makes this safe when -DCMAKE_TOOLCHAIN_FILE is also used. +get_property(_conan_generators GLOBAL PROPERTY CONAN_GENERATORS_FOLDER) +if(_conan_generators AND EXISTS "${_conan_generators}/conan_toolchain.cmake") + include("${_conan_generators}/conan_toolchain.cmake") + unset(PROTOC_PROGRAM CACHE) +endif() +unset(_conan_generators) + include(sanitizer) if(CODE_COVERAGE) include(CodeCoverage) diff --git a/cmake/conan_provider.cmake b/cmake/conan_provider.cmake index 5f71be451..5d89097f1 100644 --- a/cmake/conan_provider.cmake +++ b/cmake/conan_provider.cmake @@ -135,10 +135,14 @@ function(detect_arch arch) endfunction() -function(detect_cxx_standard cxx_standard) +function(detect_cxx_standard compiler cxx_standard) set(${cxx_standard} ${CMAKE_CXX_STANDARD} PARENT_SCOPE) if(CMAKE_CXX_EXTENSIONS) - set(${cxx_standard} "gnu${CMAKE_CXX_STANDARD}" PARENT_SCOPE) + if(compiler STREQUAL "msvc") + set(${cxx_standard} "${CMAKE_CXX_STANDARD}" PARENT_SCOPE) + else() + set(${cxx_standard} "gnu${CMAKE_CXX_STANDARD}" PARENT_SCOPE) + endif() endif() endfunction() @@ -356,8 +360,10 @@ macro(append_compiler_executables_configuration) # Not necessary to warn if RC not defined endif() if(NOT "x${_conan_compilers_list}" STREQUAL "x") - string(REPLACE ";" "," _conan_compilers_list "${_conan_compilers_list}") - string(APPEND profile "tools.build:compiler_executables={${_conan_compilers_list}}\n") + if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + string(REPLACE ";" "," _conan_compilers_list "${_conan_compilers_list}") + string(APPEND profile "tools.build:compiler_executables={${_conan_compilers_list}}\n") + endif() endif() unset(_conan_c_compiler) unset(_conan_cpp_compiler) @@ -370,7 +376,7 @@ function(detect_host_profile output_file) detect_os(os os_api_level os_sdk os_subsystem os_version) detect_arch(arch) detect_compiler(compiler compiler_version compiler_runtime compiler_runtime_type) - detect_cxx_standard(compiler_cppstd) + detect_cxx_standard(${compiler} compiler_cppstd) detect_lib_cxx(compiler_libcxx) detect_build_type(build_type) @@ -461,10 +467,9 @@ endfunction() function(conan_install) - cmake_parse_arguments(ARGS conan_args ${ARGN}) set(conan_output_folder ${CMAKE_BINARY_DIR}/conan) # Invoke "conan install" with the provided arguments - set(conan_args ${conan_args} -of=${conan_output_folder}) + set(conan_args -of=${conan_output_folder}) message(STATUS "CMake-Conan: conan install ${CMAKE_SOURCE_DIR} ${conan_args} ${ARGN}") @@ -567,7 +572,7 @@ macro(conan_provide_dependency method package_name) get_property(_conan_install_success GLOBAL PROPERTY CONAN_INSTALL_SUCCESS) if(NOT _conan_install_success) find_program(CONAN_COMMAND "conan" REQUIRED) - conan_get_version(${CONAN_COMMAND} CONAN_CURRENT_VERSION) + conan_get_version("${CONAN_COMMAND}" CONAN_CURRENT_VERSION) conan_version_check(MINIMUM ${CONAN_MINIMUM_VERSION} CURRENT ${CONAN_CURRENT_VERSION}) message(STATUS "CMake-Conan: first find_package() found. Installing dependencies with Conan") if("default" IN_LIST CONAN_HOST_PROFILE OR "default" IN_LIST CONAN_BUILD_PROFILE) @@ -580,30 +585,59 @@ macro(conan_provide_dependency method package_name) construct_profile_argument(_build_profile_flags CONAN_BUILD_PROFILE) if(EXISTS "${CMAKE_SOURCE_DIR}/conanfile.py") file(READ "${CMAKE_SOURCE_DIR}/conanfile.py" outfile) - if(NOT "${outfile}" MATCHES ".*CMakeDeps.*") - message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile") + if(NOT "${outfile}" MATCHES ".*CMakeConfigDeps.*") + message(WARNING "Cmake-conan: CMakeConfigDeps generator was not defined in the conanfile") endif() - set(generator "") elseif (EXISTS "${CMAKE_SOURCE_DIR}/conanfile.txt") file(READ "${CMAKE_SOURCE_DIR}/conanfile.txt" outfile) - if(NOT "${outfile}" MATCHES ".*CMakeDeps.*") - message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile. " - "Please define the generator as it will be mandatory in the future") + if(NOT "${outfile}" MATCHES ".*CMakeConfigDeps.*") + message(WARNING "Cmake-conan: CMakeConfigDeps generator was not defined in the conanfile") endif() - set(generator "-g;CMakeDeps") endif() + get_property(_multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if(NOT _multiconfig_generator) - message(STATUS "CMake-Conan: Installing single configuration ${CMAKE_BUILD_TYPE}") - conan_install(${_host_profile_flags} ${_build_profile_flags} ${CONAN_INSTALL_ARGS} ${generator}) + + if(DEFINED CONAN_INSTALL_BUILD_CONFIGURATIONS) + # Configurations are specified by the project or user + set(_build_configs "${CONAN_INSTALL_BUILD_CONFIGURATIONS}") + list(LENGTH _build_configs _build_configs_length) + if(NOT _multiconfig_generator AND _build_configs_length GREATER 1) + message(FATAL_ERROR "cmake-conan: when using a single-config CMake generator, " + "please only specify a single configuration in CONAN_INSTALL_BUILD_CONFIGURATIONS") + endif() + unset(_build_configs_length) else() - message(STATUS "CMake-Conan: Installing both Debug and Release") - conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Release ${CONAN_INSTALL_ARGS} ${generator}) - conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Debug ${CONAN_INSTALL_ARGS} ${generator}) + # No configuration overrides, provide sensible defaults + if(_multiconfig_generator) + set(_build_configs Release Debug) + else() + set(_build_configs ${CMAKE_BUILD_TYPE}) + endif() + endif() + + list(JOIN _build_configs ", " _build_configs_msg) + message(STATUS "CMake-Conan: Installing configuration(s): ${_build_configs_msg}") + foreach(_build_config IN LISTS _build_configs) + set(_self_build_config "") + if(NOT _multiconfig_generator AND NOT _build_config STREQUAL "${CMAKE_BUILD_TYPE}") + set(_self_build_config -s &:build_type=${CMAKE_BUILD_TYPE}) + endif() + conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=${_build_config} ${_self_build_config} ${CONAN_INSTALL_ARGS}) + endforeach() + + get_property(_conan_generators_folder GLOBAL PROPERTY CONAN_GENERATORS_FOLDER) + if(EXISTS "${_conan_generators_folder}/conan_cmakedeps_paths.cmake") + message(STATUS "CMake-Conan: Loading conan_cmakedeps_paths.cmake file") + include(${_conan_generators_folder}/conan_cmakedeps_paths.cmake) + endif() + + unset(_self_build_config) + unset(_multiconfig_generator) + unset(_build_configs) + unset(_build_configs_msg) unset(_host_profile_flags) unset(_build_profile_flags) - unset(_multiconfig_generator) unset(_conan_install_success) else() message(STATUS "CMake-Conan: find_package(${ARGV1}) found, 'conan install' already ran") diff --git a/conanfile.py b/conanfile.py index 2a01b519a..c6ecd3e9e 100644 --- a/conanfile.py +++ b/conanfile.py @@ -21,7 +21,7 @@ def requirements(self): else: self.requires("npcap/1.70") self.requires("opentelemetry-cpp/1.17.0") - self.requires("pcapplusplus/23.09") + self.requires("pcapplusplus/24.09") self.requires("protobuf/5.27.0") self.requires("sigslot/1.2.2") self.requires("fmt/10.2.1", force=True) diff --git a/libs/visor_dns/DnsLayer.cpp b/libs/visor_dns/DnsLayer.cpp index a38354b0b..d220177e9 100644 --- a/libs/visor_dns/DnsLayer.cpp +++ b/libs/visor_dns/DnsLayer.cpp @@ -182,7 +182,7 @@ bool DnsLayer::parseResources(bool queryOnly, bool additionalOnly, bool forcePar m_ResourceList = newGenResource; curResource = m_ResourceList; } else { - curResource->setNexResource(newGenResource); + curResource->setNextResource(newGenResource); curResource = curResource->getNextResource(); } @@ -458,11 +458,11 @@ DnsResource *DnsLayer::addResource(DnsResourceType resType, const std::string &n // set next resource for new resource. This must happen here for extendLayer to succeed if (curResource != NULL) { if (curResource->getType() > newResource->getType()) - newResource->setNexResource(m_ResourceList); + newResource->setNextResource(m_ResourceList); else - newResource->setNexResource(curResource->getNextResource()); + newResource->setNextResource(curResource->getNextResource()); } else // curResource != NULL - newResource->setNexResource(m_ResourceList); + newResource->setNextResource(m_ResourceList); // extend layer to make room for the new resource if (!extendLayer(newResourceOffsetInLayer, newResource->getSize(), newResource)) { @@ -476,7 +476,7 @@ DnsResource *DnsLayer::addResource(DnsResourceType resType, const std::string &n // connect the new resource to the layer's resource list if (curResource != NULL) { - curResource->setNexResource(newResource); + curResource->setNextResource(newResource); // this means the new resource is the first of it's type if (curResource->getType() < newResource->getType()) { setFirstResource(resType, newResource); @@ -522,9 +522,9 @@ DnsQuery *DnsLayer::addQuery(const std::string &name, DnsType dnsType, DnsClass // set next resource for new query. This must happen here for extendLayer to succeed if (curQuery != NULL) - newQuery->setNexResource(curQuery->getNextResource()); + newQuery->setNextResource(curQuery->getNextResource()); else - newQuery->setNexResource(m_ResourceList); + newQuery->setNextResource(m_ResourceList); // extend layer to make room for the new query if (!extendLayer(newQueryOffsetInLayer, newQuery->getSize(), newQuery)) { @@ -538,7 +538,7 @@ DnsQuery *DnsLayer::addQuery(const std::string &name, DnsType dnsType, DnsClass // connect the new query to the layer's resource list if (curQuery != NULL) - curQuery->setNexResource(newQuery); + curQuery->setNextResource(newQuery); else // curQuery == NULL, meaning this is the first query { m_ResourceList = newQuery; @@ -747,7 +747,7 @@ bool DnsLayer::removeResource(IDnsResource *resourceToRemove) // remove resourceToRemove from the resources linked list if (m_ResourceList != resourceToRemove) { - prevResource->setNexResource(resourceToRemove->getNextResource()); + prevResource->setNextResource(resourceToRemove->getNextResource()); } else { m_ResourceList = resourceToRemove->getNextResource(); } diff --git a/libs/visor_dns/DnsLayer.h b/libs/visor_dns/DnsLayer.h index c28c4e742..2cd16432a 100644 --- a/libs/visor_dns/DnsLayer.h +++ b/libs/visor_dns/DnsLayer.h @@ -1,5 +1,4 @@ -#ifndef PV_PACKETPP_DNS_LAYER -#define PV_PACKETPP_DNS_LAYER +#pragma once #ifdef __GNUC__ #pragma GCC diagnostic push @@ -501,4 +500,3 @@ struct dnshdr { } // namespace visor -#endif /* PV_PACKETPP_DNS_LAYER */ diff --git a/libs/visor_dns/DnsLayerEnums.h b/libs/visor_dns/DnsLayerEnums.h index 59c3c43d2..f49afe871 100644 --- a/libs/visor_dns/DnsLayerEnums.h +++ b/libs/visor_dns/DnsLayerEnums.h @@ -1,156 +1,81 @@ -#ifndef PV_PACKETPP_DNS_LAYER_ENUMS -#define PV_PACKETPP_DNS_LAYER_ENUMS +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -/// @file - -/** - * \namespace visor - */ -namespace visor::lib::dns { -/** - * An enum for all possible DNS record types - */ -enum DnsType { - /** IPv4 address record */ - DNS_TYPE_A = 1, - /** Name Server record */ - DNS_TYPE_NS, - /** Obsolete, replaced by MX */ - DNS_TYPE_MD, - /** Obsolete, replaced by MX */ - DNS_TYPE_MF, - /** Canonical name record */ - DNS_TYPE_CNAME, - /** Start of Authority record */ - DNS_TYPE_SOA, - /** mailbox domain name record */ - DNS_TYPE_MB, - /** mail group member record */ - DNS_TYPE_MG, - /** mail rename domain name record */ - DNS_TYPE_MR, - /** NULL record */ - DNS_TYPE_NULL_R, - /** well known service description record */ - DNS_TYPE_WKS, - /** Pointer record */ - DNS_TYPE_PTR, - /** Host information record */ - DNS_TYPE_HINFO, - /** mailbox or mail list information record */ - DNS_TYPE_MINFO, - /** Mail exchanger record */ - DNS_TYPE_MX, - /** Text record */ - DNS_TYPE_TXT, - /** Responsible person record */ - DNS_TYPE_RP, - /** AFS database record */ - DNS_TYPE_AFSDB, - /** DNS X25 resource record */ - DNS_TYPE_X25, - /** Integrated Services Digital Network record */ - DNS_TYPE_ISDN, - /** Route Through record */ - DNS_TYPE_RT, - /** network service access point address record */ - DNS_TYPE_NSAP, - /** network service access point address pointer record */ - DNS_TYPE_NSAP_PTR, - /** Signature record */ - DNS_TYPE_SIG, - /** Key record */ - DNS_TYPE_KEY, - /** Mail Mapping Information record */ - DNS_TYPE_PX, - /** DNS Geographical Position record */ - DNS_TYPE_GPOS, - /** IPv6 address record */ - DNS_TYPE_AAAA, - /** Location record */ - DNS_TYPE_LOC, - /** Obsolete record */ - DNS_TYPE_NXT, - /** DNS Endpoint Identifier record */ - DNS_TYPE_EID, - /** DNS Nimrod Locator record */ - DNS_TYPE_NIMLOC, - /** Service locator record */ - DNS_TYPE_SRV, - /** Asynchronous Transfer Mode address record */ - DNS_TYPE_ATMA, - /** Naming Authority Pointer record */ - DNS_TYPE_NAPTR, - /** Key eXchanger record */ - DNS_TYPE_KX, - /** Certificate record */ - DNS_TYPE_CERT, - /** Obsolete, replaced by AAAA type */ - DNS_TYPE_A6, - /** Delegation Name record */ - DNS_TYPE_DNAM, - /** Kitchen sink record */ - DNS_TYPE_SINK, - /** Option record */ - DNS_TYPE_OPT, - /** Address Prefix List record */ - DNS_TYPE_APL, - /** Delegation signer record */ - DNS_TYPE_DS, - /** SSH Public Key Fingerprint record */ - DNS_TYPE_SSHFP, - /** IPsec Key record */ - DNS_TYPE_IPSECKEY, - /** DNSSEC signature record */ - DNS_TYPE_RRSIG, - /** Next-Secure record */ - DNS_TYPE_NSEC, - /** DNS Key record */ - DNS_TYPE_DNSKEY, - /** DHCP identifier record */ - DNS_TYPE_DHCID, - /** NSEC record version 3 */ - DNS_TYPE_NSEC3, - /** NSEC3 parameters */ - DNS_TYPE_NSEC3PARAM, - /** All cached records */ - DNS_TYPE_ALL = 255 - }; +#pragma once +#include - /** - * An enum for all possible DNS classes - */ - enum DnsClass - { - /** Internet class */ - DNS_CLASS_IN = 1, - /** Internet class with QU flag set to True */ - DNS_CLASS_IN_QU = 32769, - /** Chaos class */ - DNS_CLASS_CH = 3, - /** Hesiod class */ - DNS_CLASS_HS = 4, - /** ANY class */ - DNS_CLASS_ANY = 255 - }; +namespace visor::lib::dns { +// DNS record types +using pcpp::DnsType; +using pcpp::DNS_TYPE_A; +using pcpp::DNS_TYPE_NS; +using pcpp::DNS_TYPE_MD; +using pcpp::DNS_TYPE_MF; +using pcpp::DNS_TYPE_CNAME; +using pcpp::DNS_TYPE_SOA; +using pcpp::DNS_TYPE_MB; +using pcpp::DNS_TYPE_MG; +using pcpp::DNS_TYPE_MR; +using pcpp::DNS_TYPE_NULL_R; +using pcpp::DNS_TYPE_WKS; +using pcpp::DNS_TYPE_PTR; +using pcpp::DNS_TYPE_HINFO; +using pcpp::DNS_TYPE_MINFO; +using pcpp::DNS_TYPE_MX; +using pcpp::DNS_TYPE_TXT; +using pcpp::DNS_TYPE_RP; +using pcpp::DNS_TYPE_AFSDB; +using pcpp::DNS_TYPE_X25; +using pcpp::DNS_TYPE_ISDN; +using pcpp::DNS_TYPE_RT; +using pcpp::DNS_TYPE_NSAP; +using pcpp::DNS_TYPE_NSAP_PTR; +using pcpp::DNS_TYPE_SIG; +using pcpp::DNS_TYPE_KEY; +using pcpp::DNS_TYPE_PX; +using pcpp::DNS_TYPE_GPOS; +using pcpp::DNS_TYPE_AAAA; +using pcpp::DNS_TYPE_LOC; +using pcpp::DNS_TYPE_NXT; +using pcpp::DNS_TYPE_EID; +using pcpp::DNS_TYPE_NIMLOC; +using pcpp::DNS_TYPE_SRV; +using pcpp::DNS_TYPE_ATMA; +using pcpp::DNS_TYPE_NAPTR; +using pcpp::DNS_TYPE_KX; +using pcpp::DNS_TYPE_CERT; +using pcpp::DNS_TYPE_A6; +using pcpp::DNS_TYPE_DNAM; +using pcpp::DNS_TYPE_SINK; +using pcpp::DNS_TYPE_OPT; +using pcpp::DNS_TYPE_APL; +using pcpp::DNS_TYPE_DS; +using pcpp::DNS_TYPE_SSHFP; +using pcpp::DNS_TYPE_IPSECKEY; +using pcpp::DNS_TYPE_RRSIG; +using pcpp::DNS_TYPE_NSEC; +using pcpp::DNS_TYPE_DNSKEY; +using pcpp::DNS_TYPE_DHCID; +using pcpp::DNS_TYPE_NSEC3; +using pcpp::DNS_TYPE_NSEC3PARAM; +using pcpp::DNS_TYPE_ALL; - /** - * An enum for representing the 4 types of possible DNS records - */ - enum DnsResourceType - { - /** DNS query record */ - DnsQueryType = 0, - /** DNS answer record */ - DnsAnswerType = 1, - /** DNS authority record */ - DnsAuthorityType = 2, - /** DNS additional record */ - DnsAdditionalType = 3 - }; +// DNS classes +using pcpp::DnsClass; +using pcpp::DNS_CLASS_IN; +using pcpp::DNS_CLASS_IN_QU; +using pcpp::DNS_CLASS_CH; +using pcpp::DNS_CLASS_HS; +using pcpp::DNS_CLASS_ANY; -} +// DNS resource record types +using pcpp::DnsResourceType; +using pcpp::DnsQueryType; +using pcpp::DnsAnswerType; +using pcpp::DnsAuthorityType; +using pcpp::DnsAdditionalType; -#endif // PV_PACKETPP_DNS_LAYER_ENUMS +} // namespace visor::lib::dns diff --git a/libs/visor_dns/DnsResource.cpp b/libs/visor_dns/DnsResource.cpp index 97ad533c9..231e011ea 100644 --- a/libs/visor_dns/DnsResource.cpp +++ b/libs/visor_dns/DnsResource.cpp @@ -307,8 +307,15 @@ void DnsResource::setTTL(uint32_t newTTL) size_t DnsResource::getDataLength() const { - uint16_t dataLength{0}; - memcpy(&dataLength, (getRawData() + m_NameLength + 2 * sizeof(uint16_t) + sizeof(uint32_t)), sizeof(dataLength)); + size_t sizeToRead = m_NameLength + 2 * sizeof(uint16_t) + sizeof(uint32_t); + + // Heap buffer overflow may occur here, check boundary of m_DnsLayer->m_Data first + // Due to dataLength which is uint16_t, here m_DnsLayer->m_Data must have at least 2 bytes to read + if (m_DnsLayer && m_OffsetInLayer + sizeToRead >= m_DnsLayer->m_DataLen - 1) { + return 0; + } + + uint16_t dataLength = *(uint16_t *)(getRawData() + sizeToRead); return be16toh(dataLength); } diff --git a/libs/visor_dns/DnsResource.h b/libs/visor_dns/DnsResource.h index 429c886c9..25911c4df 100644 --- a/libs/visor_dns/DnsResource.h +++ b/libs/visor_dns/DnsResource.h @@ -1,5 +1,4 @@ -#ifndef PV_PACKETPP_DNS_RESOURCE -#define PV_PACKETPP_DNS_RESOURCE +#pragma once #include "DnsLayer.h" #include "DnsLayerEnums.h" @@ -47,7 +46,7 @@ class IDnsResource void encodeName(const std::string& decodedName, char* result, size_t& resultLen); IDnsResource* getNextResource() const { return m_NextResource; } - void setNexResource(IDnsResource* next) { m_NextResource = next; } + void setNextResource(IDnsResource* next) { m_NextResource = next; } uint8_t* getRawData() const; @@ -140,7 +139,7 @@ class IDnsResource private: DnsQuery(DnsLayer* dnsLayer, size_t offsetInLayer) : IDnsResource(dnsLayer, offsetInLayer) {} - DnsQuery(uint8_t* emptyRawData) : IDnsResource(emptyRawData) {} + explicit DnsQuery(uint8_t* emptyRawData) : IDnsResource(emptyRawData) {} public: virtual ~DnsQuery() {} @@ -242,4 +241,3 @@ class IDnsResource } -#endif // PV_PACKETPP_DNS_RESOURCE diff --git a/libs/visor_dns/DnsResourceData.cpp b/libs/visor_dns/DnsResourceData.cpp index e13821d5e..375eb4f7f 100644 --- a/libs/visor_dns/DnsResourceData.cpp +++ b/libs/visor_dns/DnsResourceData.cpp @@ -40,9 +40,12 @@ void IDnsResourceData::encodeName(const std::string &decodedName, char *result, StringDnsResourceData::StringDnsResourceData(const uint8_t *dataPtr, size_t dataLen, IDnsResource *dnsResource) { - char tempResult[256]; - decodeName((const char *)dataPtr, tempResult, dnsResource); - m_Data = tempResult; + if (dataPtr && dataLen > 0) { + char tempResult[256]; + decodeName((const char *)dataPtr, tempResult, dnsResource); + m_Data = tempResult; + } else + PCPP_LOG_ERROR("Cannot decode name, dataPtr is NULL or length is 0"); } bool StringDnsResourceData::toByteArr(uint8_t *arr, size_t &arrLength, IDnsResource *dnsResource) const @@ -64,7 +67,7 @@ IPv4DnsResourceData::IPv4DnsResourceData(const uint8_t *dataPtr, size_t dataLen) bool IPv4DnsResourceData::toByteArr(uint8_t *arr, size_t &arrLength, IDnsResource *dnsResource) const { - if (!m_Data.isValid()) { + if (m_Data == pcpp::IPv4Address::Zero) { PCPP_LOG_ERROR("Cannot convert IPv4 address to byte array because address is not valid"); return false; } @@ -86,7 +89,7 @@ IPv6DnsResourceData::IPv6DnsResourceData(const uint8_t *dataPtr, size_t dataLen) bool IPv6DnsResourceData::toByteArr(uint8_t *arr, size_t &arrLength, IDnsResource *dnsResource) const { - if (!m_Data.isValid()) { + if (m_Data == pcpp::IPv6Address::Zero) { PCPP_LOG_ERROR("Cannot convert IPv6 address to byte array because address is not valid"); return false; } @@ -98,11 +101,14 @@ bool IPv6DnsResourceData::toByteArr(uint8_t *arr, size_t &arrLength, IDnsResourc MxDnsResourceData::MxDnsResourceData(uint8_t *dataPtr, size_t dataLen, IDnsResource *dnsResource) { - uint16_t preference = be16toh(*(uint16_t *)dataPtr); - char tempMX[256]; - decodeName((const char *)(dataPtr + sizeof(preference)), tempMX, dnsResource); - m_Data.preference = preference; - m_Data.mailExchange = tempMX; + if (dataPtr && dataLen > 0) { + uint16_t preference = be16toh(*(uint16_t *)dataPtr); + char tempMX[256]; + decodeName((const char *)(dataPtr + sizeof(preference)), tempMX, dnsResource); + m_Data.preference = preference; + m_Data.mailExchange = tempMX; + } else + PCPP_LOG_ERROR("Cannot decode name, dataPtr is NULL or length is 0"); } MxDnsResourceData::MxDnsResourceData(const uint16_t &preference, const std::string &mailExchange) @@ -119,7 +125,7 @@ bool MxDnsResourceData::operator==(const MxDnsResourceData &other) const void MxDnsResourceData::setMxData(uint16_t preference, std::string mailExchange) { m_Data.preference = preference; - m_Data.mailExchange = mailExchange; + m_Data.mailExchange = std::move(mailExchange); } std::string MxDnsResourceData::toString() const diff --git a/libs/visor_dns/DnsResourceData.h b/libs/visor_dns/DnsResourceData.h index 4c80d3172..f71a256b4 100644 --- a/libs/visor_dns/DnsResourceData.h +++ b/libs/visor_dns/DnsResourceData.h @@ -1,5 +1,4 @@ -#ifndef PV_PACKETPP_DNS_RESOURCE_DATA -#define PV_PACKETPP_DNS_RESOURCE_DATA +#pragma once #include "DnsResource.h" #include @@ -387,10 +386,6 @@ namespace visor::lib::dns { */ bool operator==(const GenericDnsResourceData& other) const; - const uint8_t* getData() const { return m_Data; } - - size_t getDataLen() const { return m_DataLen; } - // implement abstract methods std::string toString() const; @@ -399,4 +394,3 @@ namespace visor::lib::dns { } -#endif // PV_PACKETPP_DNS_RESOURCE_DATA diff --git a/libs/visor_utils/utils.cpp b/libs/visor_utils/utils.cpp index e9ca8d431..da4e38cfe 100644 --- a/libs/visor_utils/utils.cpp +++ b/libs/visor_utils/utils.cpp @@ -1,5 +1,6 @@ #include "utils.h" #include "EndianPortable.h" +#include #include #include #include @@ -70,12 +71,10 @@ std::optional match_subnet(IPv6subnetList &ipv6_ bool match_subnet(IPv4subnetList &ipv4_list, IPv6subnetList &ipv6_list, const std::string &ip_val) { - pcpp::IPv4Address ipv4; - pcpp::IPv6Address ipv6; - if (ipv4 = pcpp::IPv4Address(ip_val); ipv4.isValid()) { - return match_subnet(ipv4_list, ipv4.toInt()).has_value(); - } else if (ipv6 = pcpp::IPv6Address(ip_val); ipv6.isValid()) { - return match_subnet(ipv6_list, ipv6.toBytes()).has_value(); + if (pcpp::IPv4Address::isValidIPv4Address(ip_val)) { + return match_subnet(ipv4_list, pcpp::IPv4Address(ip_val).toInt()).has_value(); + } else if (pcpp::IPv6Address::isValidIPv6Address(ip_val)) { + return match_subnet(ipv6_list, pcpp::IPv6Address(ip_val).toBytes()).has_value(); } return false; } diff --git a/src/handlers/dhcp/DhcpStreamHandler.cpp b/src/handlers/dhcp/DhcpStreamHandler.cpp index 76f9ad35e..3287d109d 100644 --- a/src/handlers/dhcp/DhcpStreamHandler.cpp +++ b/src/handlers/dhcp/DhcpStreamHandler.cpp @@ -272,7 +272,7 @@ void DhcpMetricsBucket::new_dhcp_transaction(bool deep, pcpp::DhcpLayer *payload // lock for write std::unique_lock lock(_mutex); - if (auto client_ip = payload->getYourIpAddress(); client_ip.isValid()) { + if (auto client_ip = payload->getYourIpAddress(); client_ip != pcpp::IPv4Address::Zero) { _dhcp_topClients.update(xact.mac_address + "/" + xact.hostname + "/" + client_ip.toString()); } } @@ -307,7 +307,7 @@ void DhcpMetricsBucket::process_dhcp_v6_layer(bool deep, pcpp::DhcpV6Layer *dhcp pcpp::EthLayer *ethLayer = payload->getLayerOfType(); pcpp::IPv6Layer *ipv6Layer = payload->getLayerOfType(); if (ethLayer && ipv6Layer) { - if (auto ipv6 = ipv6Layer->getSrcIPv6Address(); ipv6.isValid()) { + if (auto ipv6 = ipv6Layer->getSrcIPv6Address(); ipv6 != pcpp::IPv6Address::Zero) { _dhcp_topServers.update(ethLayer->getSourceMac().toString() + "/" + ipv6.toString()); } } diff --git a/src/handlers/dns/v1/DnsStreamHandler.cpp b/src/handlers/dns/v1/DnsStreamHandler.cpp index 42d250200..7f8843825 100644 --- a/src/handlers/dns/v1/DnsStreamHandler.cpp +++ b/src/handlers/dns/v1/DnsStreamHandler.cpp @@ -1352,7 +1352,7 @@ void DnsMetricsManager::process_dns_layer(DnsLayer &payload, PacketDirection dir // base event new_event(stamp); // process in the "live" bucket. this will parse the resources if we are deep sampling - live_bucket()->process_dns_layer(_deep_sampling_now, payload, l3, static_cast(l4), port, suffix_size); + live_bucket()->process_dns_layer(_deep_sampling_now, payload, l3, pcpp_to_protocol(l4), port, suffix_size); if (group_enabled(group::DnsMetrics::DnsTransactions)) { // handle dns transactions (query/response pairs) diff --git a/src/handlers/dns/v1/DnsStreamHandler.h b/src/handlers/dns/v1/DnsStreamHandler.h index 3f4afa42d..fbf3b993b 100644 --- a/src/handlers/dns/v1/DnsStreamHandler.h +++ b/src/handlers/dns/v1/DnsStreamHandler.h @@ -55,11 +55,22 @@ enum Protocol : uint64_t { DNSTAP_TCP = dnstap::SocketProtocol::TCP, DNSTAP_DOT = dnstap::SocketProtocol::DOT, DNSTAP_DOH = dnstap::SocketProtocol::DOH, - PCPP_TCP = pcpp::TCP, - PCPP_UDP = pcpp::UDP, - PCPP_UNKOWN = pcpp::UnknownProtocol + // PCPP values use explicit constants to avoid collisions with dnstap values (1-7) + // after pcaplusplus 24.09 renumbered pcpp::TCP=4, pcpp::UDP=5 + PCPP_UNKOWN = 0x100, + PCPP_UDP = 0x101, + PCPP_TCP = 0x102, }; +inline Protocol pcpp_to_protocol(pcpp::ProtocolType t) +{ + if (t == pcpp::TCP) + return PCPP_TCP; + if (t == pcpp::UDP) + return PCPP_UDP; + return PCPP_UNKOWN; +} + class DnsMetricsBucket final : public visor::AbstractMetricsBucket { protected: diff --git a/src/handlers/dns/v1/tests/test_dns_layer.cpp b/src/handlers/dns/v1/tests/test_dns_layer.cpp index 4c7c52898..245bad2a2 100644 --- a/src/handlers/dns/v1/tests/test_dns_layer.cpp +++ b/src/handlers/dns/v1/tests/test_dns_layer.cpp @@ -37,7 +37,7 @@ TEST_CASE("Ensure we use only pktvisor DnsLayer", "[pcap][ipv4][dns]") pcpp::RawPacket rawPacket; while (reader->getNextPacket(rawPacket)) { - pcpp::Packet dnsRequest(&rawPacket, pcpp::TCP | pcpp::UDP); + pcpp::Packet dnsRequest(&rawPacket, pcpp::OsiModelTransportLayer); if (dnsRequest.isPacketOfType(pcpp::UDP)) { CHECK(dnsRequest.getLayerOfType() != nullptr); } else { diff --git a/src/handlers/dns/v2/DnsStreamHandler.cpp b/src/handlers/dns/v2/DnsStreamHandler.cpp index 5db51a3da..ebafece0a 100644 --- a/src/handlers/dns/v2/DnsStreamHandler.cpp +++ b/src/handlers/dns/v2/DnsStreamHandler.cpp @@ -1113,7 +1113,7 @@ void DnsMetricsManager::process_dns_layer(DnsLayer &payload, PacketDirection dir auto xact = _pair_manager[xact_dir].xact_map->maybe_end_transaction(DnsXactID(flowkey, payload.getDnsHeader()->transactionID), stamp); live_bucket()->dir_setup(xact_dir); if (xact.first == Result::Valid && !xact.second.filtered) { - live_bucket()->new_dns_transaction(_deep_sampling_now, _pair_manager[xact_dir].per_90th, payload, xact_dir, xact.second, l3, static_cast(l4), port, suffix_size); + live_bucket()->new_dns_transaction(_deep_sampling_now, _pair_manager[xact_dir].per_90th, payload, xact_dir, xact.second, l3, pcpp_to_protocol(l4), port, suffix_size); } else if (xact.second.filtered) { // query was filtered out live_bucket()->process_filtered(); diff --git a/src/handlers/dns/v2/DnsStreamHandler.h b/src/handlers/dns/v2/DnsStreamHandler.h index f90e7a1b7..ca9a48f5e 100644 --- a/src/handlers/dns/v2/DnsStreamHandler.h +++ b/src/handlers/dns/v2/DnsStreamHandler.h @@ -67,11 +67,22 @@ enum Protocol : uint64_t { DNSTAP_CRYPT_UDP = dnstap::SocketProtocol::DNSCryptUDP, DNSTAP_CRYPT_TCP = dnstap::SocketProtocol::DNSCryptTCP, DNSTAP_DOQ = dnstap::SocketProtocol::DOQ, - PCPP_TCP = pcpp::TCP, - PCPP_UDP = pcpp::UDP, - PCPP_UNKOWN = pcpp::UnknownProtocol + // PCPP values use explicit constants to avoid collisions with dnstap values (1-7) + // after pcaplusplus 24.09 renumbered pcpp::TCP=4, pcpp::UDP=5 + PCPP_UNKOWN = 0x100, + PCPP_UDP = 0x101, + PCPP_TCP = 0x102, }; +inline Protocol pcpp_to_protocol(pcpp::ProtocolType t) +{ + if (t == pcpp::TCP) + return PCPP_TCP; + if (t == pcpp::UDP) + return PCPP_UDP; + return PCPP_UNKOWN; +} + struct DnsDirection { struct Counters { Counter xacts; diff --git a/src/handlers/dns/v2/tests/test_dns_layer.cpp b/src/handlers/dns/v2/tests/test_dns_layer.cpp index d5f15a2b9..fb4c0a494 100644 --- a/src/handlers/dns/v2/tests/test_dns_layer.cpp +++ b/src/handlers/dns/v2/tests/test_dns_layer.cpp @@ -38,7 +38,7 @@ TEST_CASE("Ensure we use only pktvisor DnsLayer", "[pcap][ipv4][dns]") pcpp::RawPacket rawPacket; while (reader->getNextPacket(rawPacket)) { - pcpp::Packet dnsRequest(&rawPacket, pcpp::TCP | pcpp::UDP); + pcpp::Packet dnsRequest(&rawPacket, pcpp::OsiModelTransportLayer); if (dnsRequest.isPacketOfType(pcpp::UDP)) { CHECK(dnsRequest.getLayerOfType() != nullptr); } else { diff --git a/src/handlers/flow/FlowStreamHandler.cpp b/src/handlers/flow/FlowStreamHandler.cpp index 023def7dc..59c0da29a 100644 --- a/src/handlers/flow/FlowStreamHandler.cpp +++ b/src/handlers/flow/FlowStreamHandler.cpp @@ -111,7 +111,7 @@ void FlowStreamHandler::start() if (config_exists("device_map")) { auto devices = config_get>("device_map"); for (const auto &device : devices->get_all_keys()) { - if (!pcpp::IPv4Address(device).isValid() && !pcpp::IPv6Address(device).isValid()) { + if (!pcpp::IPv4Address::isValidIPv4Address(device) && !pcpp::IPv6Address::isValidIPv6Address(device)) { throw StreamHandlerException(fmt::format("FlowHandler: 'device_map' config has an invalid device IP: {}", device)); } DeviceEnrich enrich_device; @@ -217,9 +217,9 @@ void FlowStreamHandler::start() if (config_exists("only_device_interfaces")) { auto devices = config_get>("only_device_interfaces"); for (const auto &device : devices->get_all_keys()) { - if (pcpp::IPv4Address(device).isValid()) { + if (pcpp::IPv4Address::isValidIPv4Address(device)) { _device_interfaces_list[device] = _parse_interfaces(devices->config_get(device)); - } else if (pcpp::IPv6Address(device).isValid()) { + } else if (pcpp::IPv6Address::isValidIPv6Address(device)) { _device_interfaces_list[device] = _parse_interfaces(devices->config_get(device)); } else { throw StreamHandlerException(fmt::format("FlowHandler: 'only_device_interfaces' filter has an invalid device IP: {}", device)); @@ -314,12 +314,12 @@ void FlowStreamHandler::process_sflow_cb(const SFSample &payload, [[maybe_unused FlowPacket packet(agentId, stamp); if (_f_enabled[Filters::OnlyDeviceInterfaces]) { - if (auto ipv4 = pcpp::IPv4Address(packet.device_id); ipv4.isValid() && std::none_of(_device_interfaces_list.begin(), _device_interfaces_list.end(), [packet](const auto &item) { + if (pcpp::IPv4Address::isValidIPv4Address(packet.device_id) && std::none_of(_device_interfaces_list.begin(), _device_interfaces_list.end(), [packet](const auto &item) { return packet.device_id == item.first; })) { _metrics->process_filtered(stamp, payload.elements.size(), packet.device_id); return; - } else if (auto ipv6 = pcpp::IPv6Address(packet.device_id); ipv6.isValid() && std::none_of(_device_interfaces_list.begin(), _device_interfaces_list.end(), [packet](const auto &item) { + } else if (pcpp::IPv6Address::isValidIPv6Address(packet.device_id) && std::none_of(_device_interfaces_list.begin(), _device_interfaces_list.end(), [packet](const auto &item) { return packet.device_id == item.first; })) { _metrics->process_filtered(stamp, payload.elements.size(), packet.device_id); @@ -403,12 +403,12 @@ void FlowStreamHandler::process_netflow_cb(const std::string &senderIP, const NF FlowPacket packet(senderIP, stamp); if (_f_enabled[Filters::OnlyDeviceInterfaces]) { - if (auto ipv4 = pcpp::IPv4Address(packet.device_id); ipv4.isValid() && std::none_of(_device_interfaces_list.begin(), _device_interfaces_list.end(), [packet](const auto &item) { + if (pcpp::IPv4Address::isValidIPv4Address(packet.device_id) && std::none_of(_device_interfaces_list.begin(), _device_interfaces_list.end(), [packet](const auto &item) { return packet.device_id == item.first; })) { _metrics->process_filtered(stamp, payload.flows.size(), packet.device_id); return; - } else if (auto ipv6 = pcpp::IPv6Address(packet.device_id); ipv6.isValid() && std::none_of(_device_interfaces_list.begin(), _device_interfaces_list.end(), [packet](const auto &item) { + } else if (pcpp::IPv6Address::isValidIPv6Address(packet.device_id) && std::none_of(_device_interfaces_list.begin(), _device_interfaces_list.end(), [packet](const auto &item) { return packet.device_id == item.first; })) { _metrics->process_filtered(stamp, payload.flows.size(), packet.device_id); @@ -1363,7 +1363,7 @@ void FlowMetricsBucket::process_interface(bool deep, FlowInterface *iface, const std::string application_src; std::string application_dst; std::string ip; - if (!flow.is_ipv6 && flow.ipv4_in.isValid()) { + if (!flow.is_ipv6 && flow.ipv4_in != pcpp::IPv4Address::Zero) { group_enabled(group::FlowMetrics::Cardinality) ? iface->srcIPCard.update(flow.ipv4_in.toInt()) : void(); if (auto ipv4 = cache.lru_ipv4_list.getValue(flow.ipv4_in.toInt()); ipv4.has_value()) { ip = ipv4.value(); @@ -1379,7 +1379,7 @@ void FlowMetricsBucket::process_interface(bool deep, FlowInterface *iface, const iface->directionTopN.at(type).topSrcIPPort.update(application_src, aggregator); } _process_geo_metrics(iface, type, flow.ipv4_in, aggregator); - } else if (flow.is_ipv6 && flow.ipv6_in.isValid()) { + } else if (flow.is_ipv6 && flow.ipv6_in != pcpp::IPv6Address::Zero) { group_enabled(group::FlowMetrics::Cardinality) ? iface->srcIPCard.update(reinterpret_cast(flow.ipv6_in.toBytes()), 16) : void(); auto ipv6_str = flow.ipv6_in.toString(); if (auto ipv6 = cache.lru_ipv6_list.getValue(ipv6_str); ipv6.has_value()) { @@ -1397,7 +1397,7 @@ void FlowMetricsBucket::process_interface(bool deep, FlowInterface *iface, const } _process_geo_metrics(iface, type, flow.ipv6_in, aggregator); } - if (!flow.is_ipv6 && flow.ipv4_out.isValid()) { + if (!flow.is_ipv6 && flow.ipv4_out != pcpp::IPv4Address::Zero) { group_enabled(group::FlowMetrics::Cardinality) ? iface->dstIPCard.update(flow.ipv4_out.toInt()) : void(); if (auto ipv4 = cache.lru_ipv4_list.getValue(flow.ipv4_out.toInt()); ipv4.has_value()) { ip = ipv4.value(); @@ -1413,7 +1413,7 @@ void FlowMetricsBucket::process_interface(bool deep, FlowInterface *iface, const iface->directionTopN.at(type).topDstIPPort.update(application_dst, aggregator); } _process_geo_metrics(iface, type, flow.ipv4_out, aggregator); - } else if (flow.is_ipv6 && flow.ipv6_out.isValid()) { + } else if (flow.is_ipv6 && flow.ipv6_out != pcpp::IPv6Address::Zero) { group_enabled(group::FlowMetrics::Cardinality) ? iface->dstIPCard.update(reinterpret_cast(flow.ipv6_out.toBytes()), 16) : void(); auto ipv6_str = flow.ipv6_out.toString(); if (auto ipv6 = cache.lru_ipv6_list.getValue(ipv6_str); ipv6.has_value()) { diff --git a/src/handlers/net/v1/NetStreamHandler.cpp b/src/handlers/net/v1/NetStreamHandler.cpp index 5ade9ca2a..f5aed4f9a 100644 --- a/src/handlers/net/v1/NetStreamHandler.cpp +++ b/src/handlers/net/v1/NetStreamHandler.cpp @@ -742,21 +742,21 @@ void NetworkMetricsBucket::process_net_layer(NetworkPacket &packet) _payload_size.update(packet.payload_size); - if (packet.l3 == pcpp::IPv4 && packet.ipv4_in.isValid()) { + if (packet.l3 == pcpp::IPv4 && packet.ipv4_in != pcpp::IPv4Address::Zero) { group_enabled(group::NetMetrics::Cardinality) ? _srcIPCard.update(packet.ipv4_in.toInt()) : void(); group_enabled(group::NetMetrics::TopIps) ? _topIPv4.update(packet.ipv4_in.toInt()) : void(); _process_geo_metrics(packet.ipv4_in); - } else if (packet.l3 == pcpp::IPv6 && packet.ipv6_in.isValid()) { + } else if (packet.l3 == pcpp::IPv6 && packet.ipv6_in != pcpp::IPv6Address::Zero) { group_enabled(group::NetMetrics::Cardinality) ? _srcIPCard.update(reinterpret_cast(packet.ipv6_in.toBytes()), 16) : void(); group_enabled(group::NetMetrics::TopIps) ? _topIPv6.update(packet.ipv6_in.toString()) : void(); _process_geo_metrics(packet.ipv6_in); } - if (packet.l3 == pcpp::IPv4 && packet.ipv4_out.isValid()) { + if (packet.l3 == pcpp::IPv4 && packet.ipv4_out != pcpp::IPv4Address::Zero) { group_enabled(group::NetMetrics::Cardinality) ? _dstIPCard.update(packet.ipv4_out.toInt()) : void(); group_enabled(group::NetMetrics::TopIps) ? _topIPv4.update(packet.ipv4_out.toInt()) : void(); _process_geo_metrics(packet.ipv4_out); - } else if (packet.l3 == pcpp::IPv6 && packet.ipv6_out.isValid()) { + } else if (packet.l3 == pcpp::IPv6 && packet.ipv6_out != pcpp::IPv6Address::Zero) { group_enabled(group::NetMetrics::Cardinality) ? _dstIPCard.update(reinterpret_cast(packet.ipv6_out.toBytes()), 16) : void(); group_enabled(group::NetMetrics::TopIps) ? _topIPv6.update(packet.ipv6_out.toString()) : void(); _process_geo_metrics(packet.ipv6_out); diff --git a/src/handlers/net/v2/NetStreamHandler.cpp b/src/handlers/net/v2/NetStreamHandler.cpp index 225f60ed4..bad6150de 100644 --- a/src/handlers/net/v2/NetStreamHandler.cpp +++ b/src/handlers/net/v2/NetStreamHandler.cpp @@ -694,21 +694,21 @@ void NetworkMetricsBucket::process_net_layer(NetworkPacket &packet) data.payload_size.update(packet.payload_size); - if (packet.l3 == pcpp::IPv4 && packet.ipv4_src.isValid()) { + if (packet.l3 == pcpp::IPv4 && packet.ipv4_src != pcpp::IPv4Address::Zero) { group_enabled(group::NetMetrics::Cardinality) ? data.ipCard.update(packet.ipv4_src.toInt()) : void(); group_enabled(group::NetMetrics::TopIps) ? data.topIPv4.update(packet.ipv4_src.toInt()) : void(); _process_geo_metrics(data, packet.ipv4_src); - } else if (packet.l3 == pcpp::IPv6 && packet.ipv6_src.isValid()) { + } else if (packet.l3 == pcpp::IPv6 && packet.ipv6_src != pcpp::IPv6Address::Zero) { group_enabled(group::NetMetrics::Cardinality) ? data.ipCard.update(reinterpret_cast(packet.ipv6_src.toBytes()), 16) : void(); group_enabled(group::NetMetrics::TopIps) ? data.topIPv6.update(packet.ipv6_src.toString()) : void(); _process_geo_metrics(data, packet.ipv6_src); } - if (packet.l3 == pcpp::IPv4 && packet.ipv4_dst.isValid()) { + if (packet.l3 == pcpp::IPv4 && packet.ipv4_dst != pcpp::IPv4Address::Zero) { group_enabled(group::NetMetrics::Cardinality) ? data.ipCard.update(packet.ipv4_dst.toInt()) : void(); group_enabled(group::NetMetrics::TopIps) ? data.topIPv4.update(packet.ipv4_dst.toInt()) : void(); _process_geo_metrics(data, packet.ipv4_dst); - } else if (packet.l3 == pcpp::IPv6 && packet.ipv6_dst.isValid()) { + } else if (packet.l3 == pcpp::IPv6 && packet.ipv6_dst != pcpp::IPv6Address::Zero) { group_enabled(group::NetMetrics::Cardinality) ? data.ipCard.update(reinterpret_cast(packet.ipv6_dst.toBytes()), 16) : void(); group_enabled(group::NetMetrics::TopIps) ? data.topIPv6.update(packet.ipv6_dst.toString()) : void(); _process_geo_metrics(data, packet.ipv6_dst); diff --git a/src/inputs/netprobe/NetProbeInputStream.cpp b/src/inputs/netprobe/NetProbeInputStream.cpp index e8bc702b8..629475bca 100644 --- a/src/inputs/netprobe/NetProbeInputStream.cpp +++ b/src/inputs/netprobe/NetProbeInputStream.cpp @@ -109,9 +109,8 @@ void NetProbeInputStream::start() port = static_cast(config->config_get("port")); } auto target = config->config_get("target"); - auto ip = pcpp::IPAddress(target); - if (ip.isValid()) { - _ip_list[key] = {ip, port}; + if (pcpp::IPv4Address::isValidIPv4Address(target) || pcpp::IPv6Address::isValidIPv6Address(target)) { + _ip_list[key] = {pcpp::IPAddress(target), port}; continue; } auto dot = target.find("."); diff --git a/src/inputs/netprobe/PingProbe.cpp b/src/inputs/netprobe/PingProbe.cpp index 974549b01..e402f1fd5 100644 --- a/src/inputs/netprobe/PingProbe.cpp +++ b/src/inputs/netprobe/PingProbe.cpp @@ -122,7 +122,7 @@ void PingReceiver::_setup_receiver() bool PingProbe::start(std::shared_ptr io_loop) { - if (_init || (!_ip.isValid() && _dns.empty())) { + if (_init || ((_ip.isIPv4() ? _ip.getIPv4() == pcpp::IPv4Address::Zero : _ip.getIPv6() == pcpp::IPv6Address::Zero) && _dns.empty())) { return false; } diff --git a/src/inputs/netprobe/TcpProbe.cpp b/src/inputs/netprobe/TcpProbe.cpp index 2cb61f978..9874c42de 100644 --- a/src/inputs/netprobe/TcpProbe.cpp +++ b/src/inputs/netprobe/TcpProbe.cpp @@ -15,7 +15,7 @@ namespace visor::input::netprobe { bool TcpProbe::start(std::shared_ptr io_loop) { - if (_init || (!_ip.isValid() && _dns.empty())) { + if (_init || ((_ip.isIPv4() ? _ip.getIPv4() == pcpp::IPv4Address::Zero : _ip.getIPv6() == pcpp::IPv6Address::Zero) && _dns.empty())) { return false; } diff --git a/src/inputs/pcap/PcapInputStream.cpp b/src/inputs/pcap/PcapInputStream.cpp index c1cbf1875..7a0858705 100644 --- a/src/inputs/pcap/PcapInputStream.cpp +++ b/src/inputs/pcap/PcapInputStream.cpp @@ -161,8 +161,8 @@ void PcapInputStream::start() if (_cur_pcap_source == PcapSource::libpcap) { pcpp::PcapLiveDevice *pcapDevice; // extract pcap live device by interface name or IP address - if (interfaceIP4.isValid() || interfaceIP6.isValid()) { - if (interfaceIP4.isValid()) { + if (interfaceIP4 != pcpp::IPv4Address::Zero || interfaceIP6 != pcpp::IPv6Address::Zero) { + if (interfaceIP4 != pcpp::IPv4Address::Zero) { pcapDevice = pcpp::PcapLiveDeviceList::getInstance().getPcapLiveDeviceByIp(interfaceIP4); } else { pcapDevice = pcpp::PcapLiveDeviceList::getInstance().getPcapLiveDeviceByIp(interfaceIP6); @@ -311,7 +311,7 @@ void PcapInputStream::_generate_mock_traffic() pcpp::MacAddress host_mac("00:50:43:11:22:33"); pcpp::IPv4Address host_ip("192.168.0.1"); - pcpp::MacAddress other_mac("aa:bb:cc:dd:" + std::string('a' + std::rand() % 26, 2)); + pcpp::MacAddress other_mac(fmt::format("aa:bb:cc:dd:{:02x}:{:02x}", std::rand() % 256, std::rand() % 256)); pcpp::IPv4Address other_ip("10.0.0." + std::to_string(std::rand() % 255)); // create a new Ethernet layer @@ -384,7 +384,7 @@ void PcapInputStream::process_raw_packet(pcpp::RawPacket *rawPacket) return true; }(); pcpp::ProtocolType l3(pcpp::UnknownProtocol), l4(pcpp::UnknownProtocol); - pcpp::Packet packet(rawPacket, pcpp::TCP | pcpp::UDP); + pcpp::Packet packet(rawPacket, pcpp::OsiModelTransportLayer); if (packet.isPacketOfType(pcpp::IPv4)) { l3 = pcpp::IPv4; } else if (packet.isPacketOfType(pcpp::IPv6)) { @@ -576,38 +576,44 @@ void PcapInputStream::_open_libpcap_iface(const std::string &bpfFilter) void PcapInputStream::_get_hosts_from_libpcap_iface() { - auto addrs = _pcapDevice->getAddresses(); - for (auto i : addrs) { - if (!i.addr) { +#ifndef _WIN32 + ifaddrs *ifap = nullptr; + if (getifaddrs(&ifap) != 0 || ifap == nullptr) { + return; + } + const std::string devName = _pcapDevice->getName(); + for (ifaddrs *i = ifap; i != nullptr; i = i->ifa_next) { + if (i->ifa_addr == nullptr || i->ifa_name == nullptr || devName != i->ifa_name) { continue; } char buf[INET6_ADDRSTRLEN]; - pcpp::internal::sockaddr2string(i.addr, buf); - std::string ip(buf); - if (i.addr->sa_family == AF_INET) { - auto adrcvt = pcpp::internal::sockaddr2in_addr(i.addr); - if (!adrcvt) { - throw PcapException("couldn't parse IPv4 address on device"); - } - auto nmcvt = pcpp::internal::sockaddr2in_addr(i.netmask); - if (!nmcvt) { - throw PcapException("couldn't parse IPv4 netmask address on device"); + if (i->ifa_addr->sa_family == AF_INET) { + auto ip4 = reinterpret_cast(i->ifa_addr); + inet_ntop(AF_INET, &ip4->sin_addr, buf, sizeof(buf)); + uint8_t prefix = 32; + if (i->ifa_netmask) { + auto nm = reinterpret_cast(i->ifa_netmask); + prefix = static_cast(__builtin_popcount(ntohl(nm->sin_addr.s_addr))); } - uint8_t cidr = lib::utils::get_cidr(nmcvt->s_addr); - _hostIPv4.push_back({*adrcvt, cidr, ip + "/" + std::to_string(cidr)}); - } else if (i.addr->sa_family == AF_INET6) { - auto adrcvt = pcpp::internal::sockaddr2in6_addr(i.addr); - if (!adrcvt) { - throw PcapException("couldn't parse IPv6 address on device"); + std::string cidr = std::string(buf) + "/" + std::to_string(prefix); + _hostIPv4.push_back({ip4->sin_addr, prefix, cidr}); + } else if (i->ifa_addr->sa_family == AF_INET6) { + auto ip6 = reinterpret_cast(i->ifa_addr); + inet_ntop(AF_INET6, &ip6->sin6_addr, buf, sizeof(buf)); + uint8_t prefix = 128; + if (i->ifa_netmask) { + auto nm6 = reinterpret_cast(i->ifa_netmask); + prefix = 0; + for (int b = 0; b < 16; ++b) { + prefix += static_cast(__builtin_popcount(nm6->sin6_addr.s6_addr[b])); + } } - auto nmcvt = pcpp::internal::sockaddr2in6_addr(i.netmask); - if (!nmcvt) { - throw PcapException("couldn't parse IPv6 netmask address on device"); - } - uint8_t cidr = lib::utils::get_cidr(nmcvt->s6_addr, 16); - _hostIPv6.push_back({*adrcvt, cidr, ip + "/" + std::to_string(cidr)}); + std::string cidr = std::string(buf) + "/" + std::to_string(prefix); + _hostIPv6.push_back({ip6->sin6_addr, prefix, cidr}); } } + freeifaddrs(ifap); +#endif } void PcapInputStream::info_json(json &j) const