diff --git a/Pcap++/CMakeLists.txt b/Pcap++/CMakeLists.txt index 3007f889eb..c85c96d6ae 100644 --- a/Pcap++/CMakeLists.txt +++ b/Pcap++/CMakeLists.txt @@ -1,5 +1,6 @@ add_library( Pcap++ + src/DeviceUtils.cpp $<$:src/DpdkDevice.cpp> $<$:src/DpdkDeviceList.cpp> $<$:src/KniDevice.cpp> @@ -25,6 +26,7 @@ add_library( set(public_headers header/Device.h + header/DeviceUtils.h header/MemoryUtils.h header/NetworkUtils.h header/PcapDevice.h diff --git a/Pcap++/header/DeviceUtils.h b/Pcap++/header/DeviceUtils.h new file mode 100644 index 0000000000..db7c2206df --- /dev/null +++ b/Pcap++/header/DeviceUtils.h @@ -0,0 +1,32 @@ +#pragma once + +/// @file + +#include +#include "IpAddress.h" +#include "MemoryUtils.h" + +// Forward declaration +struct pcap_rmtauth; + +namespace pcpp +{ + namespace internal + { + /** + * Fetches a list of all network devices on the local machine that LibPcap/WinPcap/NPcap can find. + * @return A smart pointer to an interface list structure. + * @throws std::runtime_error The system encountered an error fetching the devices. + */ + std::unique_ptr getAllLocalPcapDevices(); + /** + * Fetches a list of all network devices on a remote machine that LibPcap/WinPcap/NPcap can find. + * @param[in] ipAddress IP address of the remote machine. + * @param[in] port Port to use when connecting to the remote machine. + * @param[in] pRmAuth Pointer to an authentication structure to use when connecting to the remote machine. Nullptr if no authentication is required. + * @return A smart pointer to an interface list structure. + * @throws std::runtime_error The system encountered an error fetching the devices. + */ + std::unique_ptr getAllRemotePcapDevices(const IPAddress& ipAddress, uint16_t port, pcap_rmtauth* pRmAuth = nullptr); + } +} \ No newline at end of file diff --git a/Pcap++/src/DeviceUtils.cpp b/Pcap++/src/DeviceUtils.cpp new file mode 100644 index 0000000000..522fe8b60f --- /dev/null +++ b/Pcap++/src/DeviceUtils.cpp @@ -0,0 +1,47 @@ +#include "DeviceUtils.h" + +#include +#include + +#include "pcap.h" +#include "Logger.h" +#include "IpAddress.h" + +namespace pcpp +{ + namespace internal + { + std::unique_ptr getAllLocalPcapDevices() + { + pcap_if_t* interfaceListRaw; + std::array errbuf; + int err = pcap_findalldevs(&interfaceListRaw, errbuf.data()); + if (err < 0) + { + throw std::runtime_error("Error searching for devices: " + std::string(errbuf.begin(), errbuf.end())); + } + // Assigns the raw pointer to the smart pointer with specialized deleter. + return std::unique_ptr(interfaceListRaw); + } + std::unique_ptr getAllRemotePcapDevices(const IPAddress& ipAddress, uint16_t port, pcap_rmtauth* pRmAuth) + { + PCPP_LOG_DEBUG("Searching remote devices on IP: " << ipAddress << " and port: " << port); + std::array remoteCaptureString; + std::array errorBuf; + if (pcap_createsrcstr(remoteCaptureString.data(), PCAP_SRC_IFREMOTE, ipAddress.toString().c_str(), + std::to_string(port).c_str(), nullptr, errorBuf.data()) != 0) + { + throw std::runtime_error("Error creating the remote connection string. Error: " + std::string(errorBuf.begin(), errorBuf.end())); + } + + PCPP_LOG_DEBUG("Remote capture string: " << remoteCaptureString.data()); + + pcap_if_t* interfaceListRaw; + if (pcap_findalldevs_ex(remoteCaptureString.data(), pRmAuth, &interfaceListRaw, errorBuf.data()) < 0) + { + throw std::runtime_error("Error retrieving device on remote machine. Error: " + std::string(errorBuf.begin(), errorBuf.end())); + } + return std::unique_ptr(interfaceListRaw); + } + } +} \ No newline at end of file diff --git a/Pcap++/src/PcapLiveDevice.cpp b/Pcap++/src/PcapLiveDevice.cpp index d5cd4cdbfd..c6dc326beb 100644 --- a/Pcap++/src/PcapLiveDevice.cpp +++ b/Pcap++/src/PcapLiveDevice.cpp @@ -10,6 +10,7 @@ #include "pcap.h" #include #include "Logger.h" +#include "DeviceUtils.h" #include "SystemUtils.h" #include "MemoryUtils.h" #include @@ -408,16 +409,14 @@ PcapLiveDevice* PcapLiveDevice::clone() const { return clone(SmartPtrApi).releas std::unique_ptr PcapLiveDevice::clone(SmartPtrApiTag apiTag) const { std::unique_ptr interfaceList; + try { - pcap_if_t* interfaceListRaw; - char errbuf[PCAP_ERRBUF_SIZE]; - int err = pcap_findalldevs(&interfaceListRaw, errbuf); - if (err < 0) - { - PCPP_LOG_ERROR("Error searching for devices: " << errbuf); - return nullptr; - } - interfaceList = std::unique_ptr(interfaceListRaw); + interfaceList = internal::getAllLocalPcapDevices(); + } + catch (const std::exception& e) + { + PCPP_LOG_ERROR(e.what()); + return nullptr; } for (pcap_if_t* currInterface = interfaceList.get(); currInterface != nullptr; currInterface = currInterface->next) diff --git a/Pcap++/src/PcapLiveDeviceList.cpp b/Pcap++/src/PcapLiveDeviceList.cpp index 68f283b4a6..9553d98152 100644 --- a/Pcap++/src/PcapLiveDeviceList.cpp +++ b/Pcap++/src/PcapLiveDeviceList.cpp @@ -4,6 +4,7 @@ #include "IpAddressUtils.h" #include "PcapLiveDeviceList.h" #include "Logger.h" +#include "DeviceUtils.h" #include "SystemUtils.h" #include "MemoryUtils.h" #include "pcap.h" @@ -33,16 +34,13 @@ PcapLiveDeviceList::PcapLiveDeviceList() void PcapLiveDeviceList::init() { std::unique_ptr interfaceList; + try { - pcap_if_t* interfaceListRaw; - char errbuf[PCAP_ERRBUF_SIZE]; - int err = pcap_findalldevs(&interfaceListRaw, errbuf); - if (err < 0) - { - PCPP_LOG_ERROR("Error searching for devices: " << errbuf); - } - // Assigns the raw pointer to the smart pointer with specialized deleter. - interfaceList = std::unique_ptr(interfaceListRaw); + interfaceList = internal::getAllLocalPcapDevices(); + } + catch (const std::exception& e) + { + PCPP_LOG_ERROR(e.what()); } PCPP_LOG_DEBUG("Pcap lib version info: " << IPcapDevice::getPcapLibVersionInfo()); diff --git a/Pcap++/src/PcapRemoteDeviceList.cpp b/Pcap++/src/PcapRemoteDeviceList.cpp index 46b2f340f0..d2fb17c2b1 100644 --- a/Pcap++/src/PcapRemoteDeviceList.cpp +++ b/Pcap++/src/PcapRemoteDeviceList.cpp @@ -6,6 +6,7 @@ #include "Logger.h" #include "IpUtils.h" #include "IpAddressUtils.h" +#include "DeviceUtils.h" #include "MemoryUtils.h" #include "pcap.h" #include @@ -66,17 +67,6 @@ std::unique_ptr PcapRemoteDeviceList::getRemoteDeviceList( std::unique_ptr PcapRemoteDeviceList::getRemoteDeviceList(const IPAddress& ipAddress, uint16_t port, std::shared_ptr remoteAuth) { - PCPP_LOG_DEBUG("Searching remote devices on IP: " << ipAddress << " and port: " << port); - char remoteCaptureString[PCAP_BUF_SIZE]; - char errorBuf[PCAP_ERRBUF_SIZE]; - if (pcap_createsrcstr(remoteCaptureString, PCAP_SRC_IFREMOTE, ipAddress.toString().c_str(), std::to_string(port).c_str(), nullptr, errorBuf) != 0) - { - PCPP_LOG_ERROR("Error in creating the remote connection string. Error was: " << errorBuf); - return nullptr; - } - - PCPP_LOG_DEBUG("Remote capture string: " << remoteCaptureString); - pcap_rmtauth* pRmAuth = nullptr; pcap_rmtauth rmAuth; if (remoteAuth != nullptr) @@ -87,16 +77,16 @@ std::unique_ptr PcapRemoteDeviceList::getRemoteDeviceList( } std::unique_ptr interfaceList; + try { - pcap_if_t* interfaceListRaw; - if (pcap_findalldevs_ex(remoteCaptureString, pRmAuth, &interfaceListRaw, errorBuf) < 0) - { - PCPP_LOG_ERROR("Error retrieving device on remote machine. Error string is: " << errorBuf); - return nullptr; - } - interfaceList = std::unique_ptr(interfaceListRaw); + interfaceList = internal::getAllRemotePcapDevices(ipAddress, port, pRmAuth); } - + catch (const std::exception& e) + { + PCPP_LOG_ERROR(e.what()); + return nullptr; + } + std::vector> remoteDeviceList; for (pcap_if_t* currInterface = interfaceList.get(); currInterface != nullptr; currInterface = currInterface->next) {