diff --git a/Pcap++/header/PcapLiveDevice.h b/Pcap++/header/PcapLiveDevice.h index 4a2e66d262..e37e27d7cd 100644 --- a/Pcap++/header/PcapLiveDevice.h +++ b/Pcap++/header/PcapLiveDevice.h @@ -80,16 +80,30 @@ namespace pcpp friend class PcapLiveDeviceList; protected: + /// @struct DeviceInterfaceDetails + /// @brief A struct that contains all details of a network interface. + struct DeviceInterfaceDetails + { + explicit DeviceInterfaceDetails(pcap_if_t* pInterface); + /// @brief Name of the device. + std::string name; + /// @brief Description of the device. + std::string description; + /// @brief IP addresses associated with the device. + std::vector addresses; + /// @brief Flag to indicate if the device is a loopback device. + bool isLoopback; + }; + // This is a second descriptor for the same device. It is needed because of a bug // that occurs in libpcap on Linux (on Windows using WinPcap/Npcap it works well): // It's impossible to capture packets sent by the same descriptor pcap_t* m_PcapSendDescriptor; int m_PcapSelectableFd; - std::string m_Name; - std::string m_Description; - bool m_IsLoopback; + DeviceInterfaceDetails m_InterfaceDetails; + // NOTE@Dimi: Possibly pull mtu, mac address and default gateway in the interface details. + // They only appear to be set in the constructor and not modified afterwards. uint32_t m_DeviceMtu; - std::vector m_Addresses; MacAddress m_MacAddress; IPv4Address m_DefaultGateway; std::thread m_CaptureThread; @@ -114,11 +128,12 @@ namespace pcpp bool m_UsePoll; // c'tor is not public, there should be only one for every interface (created by PcapLiveDeviceList) - PcapLiveDevice(pcap_if_t* pInterface, bool calculateMTU, bool calculateMacAddress, + PcapLiveDevice(pcap_if_t* pInterface, bool calculateMTU, bool calculateMacAddress, bool calculateDefaultGateway) + : PcapLiveDevice(DeviceInterfaceDetails(pInterface), calculateMTU, calculateMacAddress, + calculateDefaultGateway) + {} + PcapLiveDevice(DeviceInterfaceDetails interfaceDetails, bool calculateMTU, bool calculateMacAddress, bool calculateDefaultGateway); - // copy c'tor is not public - PcapLiveDevice(const PcapLiveDevice& other); - PcapLiveDevice& operator=(const PcapLiveDevice& other); void setDeviceMtu(); void setDeviceMacAddress(); @@ -252,6 +267,8 @@ namespace pcpp } }; + PcapLiveDevice(const PcapLiveDevice& other) = delete; + PcapLiveDevice& operator=(const PcapLiveDevice& other) = delete; /** * A destructor for this class */ @@ -270,7 +287,7 @@ namespace pcpp */ std::string getName() const { - return m_Name; + return m_InterfaceDetails.name; } /** @@ -279,7 +296,7 @@ namespace pcpp */ std::string getDesc() const { - return m_Description; + return m_InterfaceDetails.description; } /** @@ -287,7 +304,7 @@ namespace pcpp */ bool getLoopback() const { - return m_IsLoopback; + return m_InterfaceDetails.isLoopback; } /** @@ -307,24 +324,13 @@ namespace pcpp } /** - * @return A vector containing all addresses defined for this interface, each in pcap_addr_t struct - * @deprecated This method is deprecated and will be removed in future versions. Please use getIPAddresses() - * instead. + * @return A vector containing all IP addresses defined for this interface. */ - // clang-format off - // Breaking the macro into multiple lines causes doxygen to cause a fit. - PCPP_DEPRECATED("This method is deprecated and will be removed in future versions. Please use getIPAddresses() instead.") - // clang-format on - const std::vector& getAddresses() const + std::vector getIPAddresses() const { - return m_Addresses; + return m_InterfaceDetails.addresses; } - /** - * @return A vector containing all IP addresses defined for this interface. - */ - std::vector getIPAddresses() const; - /** * @return The MAC address for this interface */ @@ -637,14 +643,12 @@ namespace pcpp * Clones the current device class * @return Pointer to the copied class */ - PcapLiveDevice* clone() const; + virtual PcapLiveDevice* clone() const; void getStatistics(IPcapDevice::PcapStats& stats) const override; protected: pcap_t* doOpen(const DeviceConfiguration& config); - - virtual PcapLiveDevice* cloneInternal(pcap_if_t& devInterface) const; }; } // namespace pcpp diff --git a/Pcap++/header/PcapRemoteDevice.h b/Pcap++/header/PcapRemoteDevice.h index b0c366cb2f..8158be244c 100644 --- a/Pcap++/header/PcapRemoteDevice.h +++ b/Pcap++/header/PcapRemoteDevice.h @@ -93,6 +93,12 @@ namespace pcpp // c'tor is private, as only PcapRemoteDeviceList should create instances of it, and it'll create only one for // every remote interface PcapRemoteDevice(pcap_if_t* iface, std::shared_ptr remoteAuthentication, + const IPAddress& remoteMachineIP, uint16_t remoteMachinePort) + : PcapRemoteDevice(DeviceInterfaceDetails(iface), std::move(remoteAuthentication), remoteMachineIP, + remoteMachinePort) + {} + PcapRemoteDevice(DeviceInterfaceDetails deviceInterface, + std::shared_ptr remoteAuthentication, const IPAddress& remoteMachineIP, uint16_t remoteMachinePort); public: @@ -155,6 +161,8 @@ namespace pcpp bool open() override; void getStatistics(IPcapDevice::PcapStats& stats) const override; + + PcapRemoteDevice* clone() const override; }; } // namespace pcpp diff --git a/Pcap++/header/WinPcapLiveDevice.h b/Pcap++/header/WinPcapLiveDevice.h index 816a96cf05..c199428e32 100644 --- a/Pcap++/header/WinPcapLiveDevice.h +++ b/Pcap++/header/WinPcapLiveDevice.h @@ -26,12 +26,17 @@ namespace pcpp int m_MinAmountOfDataToCopyFromKernelToApplication; // c'tor is not public, there should be only one for every interface (created by PcapLiveDeviceList) - WinPcapLiveDevice(pcap_if_t* iface, bool calculateMTU, bool calculateMacAddress, bool calculateDefaultGateway); - // copy c'tor is not public - WinPcapLiveDevice(const WinPcapLiveDevice& other); - WinPcapLiveDevice& operator=(const WinPcapLiveDevice& other); + WinPcapLiveDevice(pcap_if_t* iface, bool calculateMTU, bool calculateMacAddress, bool calculateDefaultGateway) + : WinPcapLiveDevice(DeviceInterfaceDetails(iface), calculateMTU, calculateMacAddress, + calculateDefaultGateway) + {} + WinPcapLiveDevice(DeviceInterfaceDetails interfaceDetails, bool calculateMTU, bool calculateMacAddress, + bool calculateDefaultGateway); public: + WinPcapLiveDevice(const WinPcapLiveDevice& other) = delete; + WinPcapLiveDevice& operator=(const WinPcapLiveDevice& other) = delete; + LiveDeviceType getDeviceType() const override { return WinPcapDevice; @@ -69,8 +74,7 @@ namespace pcpp return m_MinAmountOfDataToCopyFromKernelToApplication; } - protected: - WinPcapLiveDevice* cloneInternal(pcap_if_t& devInterface) const override; + WinPcapLiveDevice* clone() const override; }; } // namespace pcpp diff --git a/Pcap++/src/PcapLiveDevice.cpp b/Pcap++/src/PcapLiveDevice.cpp index 5faa7c4dca..6eef2111d2 100644 --- a/Pcap++/src/PcapLiveDevice.cpp +++ b/Pcap++/src/PcapLiveDevice.cpp @@ -84,31 +84,44 @@ namespace pcpp } #endif - PcapLiveDevice::PcapLiveDevice(pcap_if_t* pInterface, bool calculateMTU, bool calculateMacAddress, + PcapLiveDevice::DeviceInterfaceDetails::DeviceInterfaceDetails(pcap_if_t* pInterface) + : name(pInterface->name), isLoopback(pInterface->flags & PCAP_IF_LOOPBACK) + { + if (pInterface->description != nullptr) + description = pInterface->description; + for (pcap_addr* current = pInterface->addresses; current != nullptr; current = current->next) + { + in_addr* ipv4Addr = internal::try_sockaddr2in_addr(current->addr); + if (ipv4Addr != nullptr) + { + addresses.push_back(IPv4Address(ipv4Addr->s_addr)); + continue; + } + in6_addr* ipv6Addr = internal::try_sockaddr2in6_addr(current->addr); + if (ipv6Addr != nullptr) + { + addresses.push_back(IPv6Address(ipv6Addr->s6_addr)); + continue; + } + } + } + + PcapLiveDevice::PcapLiveDevice(DeviceInterfaceDetails interfaceDetails, bool calculateMTU, bool calculateMacAddress, bool calculateDefaultGateway) - : IPcapDevice(), m_PcapSendDescriptor(nullptr), m_PcapSelectableFd(-1), m_DefaultGateway(IPv4Address::Zero), - m_UsePoll(false) + : IPcapDevice(), m_PcapSendDescriptor(nullptr), m_PcapSelectableFd(-1), + m_InterfaceDetails(std::move(interfaceDetails)), m_DefaultGateway(IPv4Address::Zero), m_UsePoll(false) { m_DeviceMtu = 0; m_LinkType = LINKTYPE_ETHERNET; - m_IsLoopback = (pInterface->flags & 0x1) == PCAP_IF_LOOPBACK; - - m_Name = pInterface->name; - if (pInterface->description != nullptr) - m_Description = pInterface->description; - PCPP_LOG_DEBUG("Added live device: name=" << m_Name << "; desc=" << m_Description); - PCPP_LOG_DEBUG(" Addresses:"); - while (pInterface->addresses != nullptr) - { - m_Addresses.insert(m_Addresses.end(), *(pInterface->addresses)); - pInterface->addresses = pInterface->addresses->next; - if (Logger::getInstance().isDebugEnabled(PcapLogModuleLiveDevice) && pInterface->addresses != nullptr && - pInterface->addresses->addr != nullptr) + if (Logger::getInstance().isDebugEnabled(PcapLogModuleLiveDevice)) + { + PCPP_LOG_DEBUG("Added live device: name=" << m_InterfaceDetails.name + << "; desc=" << m_InterfaceDetails.description); + PCPP_LOG_DEBUG(" Addresses:"); + for (auto const& address : m_InterfaceDetails.addresses) { - std::array addrAsString; - internal::sockaddr2string(pInterface->addresses->addr, addrAsString.data(), addrAsString.size()); - PCPP_LOG_DEBUG(" " << addrAsString.data()); + PCPP_LOG_DEBUG(" " << address.toString()); } } @@ -197,7 +210,7 @@ namespace pcpp void PcapLiveDevice::captureThreadMain() { - PCPP_LOG_DEBUG("Started capture thread for device '" << m_Name << "'"); + PCPP_LOG_DEBUG("Started capture thread for device '" << m_InterfaceDetails.name << "'"); m_CaptureThreadStarted = true; if (m_CaptureCallbackMode) @@ -223,12 +236,12 @@ namespace pcpp } } } - PCPP_LOG_DEBUG("Ended capture thread for device '" << m_Name << "'"); + PCPP_LOG_DEBUG("Ended capture thread for device '" << m_InterfaceDetails.name << "'"); } void PcapLiveDevice::statsThreadMain() { - PCPP_LOG_DEBUG("Started stats thread for device '" << m_Name << "'"); + PCPP_LOG_DEBUG("Started stats thread for device '" << m_InterfaceDetails.name << "'"); while (!m_StopThread) { PcapStats stats; @@ -236,13 +249,13 @@ namespace pcpp m_cbOnStatsUpdate(stats, m_cbOnStatsUpdateUserCookie); multiPlatformSleep(m_IntervalToUpdateStats); } - PCPP_LOG_DEBUG("Ended stats thread for device '" << m_Name << "'"); + PCPP_LOG_DEBUG("Ended stats thread for device '" << m_InterfaceDetails.name << "'"); } pcap_t* PcapLiveDevice::doOpen(const DeviceConfiguration& config) { char errbuf[PCAP_ERRBUF_SIZE] = { '\0' }; - std::string device_name = m_Name; + std::string device_name = m_InterfaceDetails.name; if (device_name == NFLOG_IFACE) { @@ -351,7 +364,7 @@ namespace pcpp { if (m_DeviceOpened) { - PCPP_LOG_DEBUG("Device '" << m_Name << "' already opened"); + PCPP_LOG_DEBUG("Device '" << m_InterfaceDetails.name << "' already opened"); return true; } @@ -359,7 +372,7 @@ namespace pcpp internal::PcapHandle pcapSendDescriptor; // It's not possible to have two open instances of the same NFLOG device:group - if (m_Name == NFLOG_IFACE) + if (m_InterfaceDetails.name == NFLOG_IFACE) { pcapSendDescriptor = nullptr; } @@ -368,13 +381,13 @@ namespace pcpp pcapSendDescriptor = internal::PcapHandle(doOpen(config)); } - if (pcapDescriptor == nullptr || (m_Name != NFLOG_IFACE && pcapSendDescriptor == nullptr)) + if (pcapDescriptor == nullptr || (m_InterfaceDetails.name != NFLOG_IFACE && pcapSendDescriptor == nullptr)) { m_DeviceOpened = false; return false; } - PCPP_LOG_DEBUG("Device '" << m_Name << "' opened"); + PCPP_LOG_DEBUG("Device '" << m_InterfaceDetails.name << "' opened"); m_PcapDescriptor = std::move(pcapDescriptor); // The send descriptor is held as a raw pointer as it can sometimes be the same as the receive descriptor m_PcapSendDescriptor = pcapSendDescriptor.release(); @@ -408,7 +421,7 @@ namespace pcpp { if (m_PcapDescriptor == nullptr && m_PcapSendDescriptor == nullptr) { - PCPP_LOG_DEBUG("Device '" << m_Name << "' already closed"); + PCPP_LOG_DEBUG("Device '" << m_InterfaceDetails.name << "' already closed"); return; } @@ -422,38 +435,12 @@ namespace pcpp } m_DeviceOpened = false; - PCPP_LOG_DEBUG("Device '" << m_Name << "' closed"); + PCPP_LOG_DEBUG("Device '" << m_InterfaceDetails.name << "' closed"); } PcapLiveDevice* PcapLiveDevice::clone() const { - std::unique_ptr interfaceList; - try - { - 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) - { - if (!std::strcmp(currInterface->name, getName().c_str())) - { - return cloneInternal(*currInterface); - } - } - - PCPP_LOG_ERROR("Can't find interface " << getName().c_str()); - return nullptr; - } - - PcapLiveDevice* PcapLiveDevice::cloneInternal(pcap_if_t& devInterface) const - { - return new PcapLiveDevice(&devInterface, true, true, true); + return new PcapLiveDevice(m_InterfaceDetails, true, true, true); } bool PcapLiveDevice::startCapture(OnPacketArrivesCallback onPacketArrives, void* onPacketArrivesUserCookie) @@ -474,13 +461,13 @@ namespace pcpp { if (!m_DeviceOpened || m_PcapDescriptor == nullptr) { - PCPP_LOG_ERROR("Device '" << m_Name << "' not opened"); + PCPP_LOG_ERROR("Device '" << m_InterfaceDetails.name << "' not opened"); return false; } if (m_CaptureThreadStarted) { - PCPP_LOG_ERROR("Device '" << m_Name << "' already capturing traffic"); + PCPP_LOG_ERROR("Device '" << m_InterfaceDetails.name << "' already capturing traffic"); return false; } @@ -499,7 +486,7 @@ namespace pcpp std::this_thread::yield(); } PCPP_LOG_DEBUG("Successfully created capture thread for device '" - << m_Name << "'. Thread id: " << m_CaptureThread.get_id()); + << m_InterfaceDetails.name << "'. Thread id: " << m_CaptureThread.get_id()); if (onStatsUpdate != nullptr && intervalInSecondsToUpdateStats > 0) { @@ -508,7 +495,7 @@ namespace pcpp m_StatsThread = std::thread(&pcpp::PcapLiveDevice::statsThreadMain, this); m_StatsThreadStarted = true; PCPP_LOG_DEBUG("Successfully created stats thread for device '" - << m_Name << "'. Thread id: " << m_StatsThread.get_id()); + << m_InterfaceDetails.name << "'. Thread id: " << m_StatsThread.get_id()); } return true; @@ -518,13 +505,13 @@ namespace pcpp { if (!m_DeviceOpened || m_PcapDescriptor == nullptr) { - PCPP_LOG_ERROR("Device '" << m_Name << "' not opened"); + PCPP_LOG_ERROR("Device '" << m_InterfaceDetails.name << "' not opened"); return false; } if (captureActive()) { - PCPP_LOG_ERROR("Device '" << m_Name << "' already capturing traffic"); + PCPP_LOG_ERROR("Device '" << m_InterfaceDetails.name << "' already capturing traffic"); return false; } @@ -541,7 +528,7 @@ namespace pcpp } PCPP_LOG_DEBUG("Successfully created capture thread for device '" - << m_Name << "'. Thread id: " << m_CaptureThread.get_id()); + << m_InterfaceDetails.name << "'. Thread id: " << m_CaptureThread.get_id()); return true; } @@ -551,13 +538,13 @@ namespace pcpp { if (!m_DeviceOpened || m_PcapDescriptor == nullptr) { - PCPP_LOG_ERROR("Device '" << m_Name << "' not opened"); + PCPP_LOG_ERROR("Device '" << m_InterfaceDetails.name << "' not opened"); return 0; } if (captureActive()) { - PCPP_LOG_ERROR("Device '" << m_Name << "' already capturing traffic"); + PCPP_LOG_ERROR("Device '" << m_InterfaceDetails.name << "' already capturing traffic"); return 0; } @@ -680,15 +667,15 @@ namespace pcpp PCPP_LOG_DEBUG("Stopping capture thread, waiting for it to join..."); m_CaptureThread.join(); m_CaptureThreadStarted = false; - PCPP_LOG_DEBUG("Capture thread stopped for device '" << m_Name << "'"); + PCPP_LOG_DEBUG("Capture thread stopped for device '" << m_InterfaceDetails.name << "'"); } - PCPP_LOG_DEBUG("Capture thread stopped for device '" << m_Name << "'"); + PCPP_LOG_DEBUG("Capture thread stopped for device '" << m_InterfaceDetails.name << "'"); if (m_StatsThreadStarted) { PCPP_LOG_DEBUG("Stopping stats thread, waiting for it to join..."); m_StatsThread.join(); m_StatsThreadStarted = false; - PCPP_LOG_DEBUG("Stats thread stopped for device '" << m_Name << "'"); + PCPP_LOG_DEBUG("Stats thread stopped for device '" << m_InterfaceDetails.name << "'"); } m_StopThread = false; @@ -704,7 +691,7 @@ namespace pcpp pcap_stat pcapStats; if (pcap_stats(m_PcapDescriptor.get(), &pcapStats) < 0) { - PCPP_LOG_ERROR("Error getting statistics from live device '" << m_Name << "'"); + PCPP_LOG_ERROR("Error getting statistics from live device '" << m_InterfaceDetails.name << "'"); } stats.packetsRecv = pcapStats.ps_recv; @@ -754,7 +741,7 @@ namespace pcpp if (!m_DeviceOpened) { - PCPP_LOG_ERROR("Device '" << m_Name << "' not opened!"); + PCPP_LOG_ERROR("Device '" << m_InterfaceDetails.name << "' not opened!"); return false; } @@ -841,7 +828,7 @@ namespace pcpp { #if defined(_WIN32) - if (m_IsLoopback) + if (m_InterfaceDetails.isLoopback) { PCPP_LOG_DEBUG("Npcap Loopback Adapter - MTU is insignificant, setting MTU to max value (0xffffffff)"); m_DeviceMtu = 0xffffffff; @@ -849,7 +836,7 @@ namespace pcpp } uint32_t mtuValue = 0; - LPADAPTER adapter = PacketOpenAdapter(const_cast(m_Name.c_str())); + LPADAPTER adapter = PacketOpenAdapter(const_cast(m_InterfaceDetails.name.c_str())); if (adapter == nullptr) { PCPP_LOG_ERROR("Error in retrieving MTU: Adapter is nullptr"); @@ -893,7 +880,7 @@ namespace pcpp struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, m_Name.c_str(), sizeof(ifr.ifr_name) - 1); + strncpy(ifr.ifr_name, m_InterfaceDetails.name.c_str(), sizeof(ifr.ifr_name) - 1); int socketfd = -1; try @@ -924,7 +911,7 @@ namespace pcpp { #if defined(_WIN32) - LPADAPTER adapter = PacketOpenAdapter(const_cast(m_Name.c_str())); + LPADAPTER adapter = PacketOpenAdapter(const_cast(m_InterfaceDetails.name.c_str())); if (adapter == nullptr) { PCPP_LOG_ERROR("Error in retrieving MAC address: Adapter is nullptr"); @@ -964,7 +951,7 @@ namespace pcpp struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, m_Name.c_str(), sizeof(ifr.ifr_name) - 1); + strncpy(ifr.ifr_name, m_InterfaceDetails.name.c_str(), sizeof(ifr.ifr_name) - 1); int socketfd = -1; try @@ -997,7 +984,7 @@ namespace pcpp mib[2] = 0; mib[3] = AF_LINK; mib[4] = NET_RT_IFLIST; - mib[5] = if_nametoindex(m_Name.c_str()); + mib[5] = if_nametoindex(m_InterfaceDetails.name.c_str()); if (mib[5] == 0) { @@ -1049,7 +1036,7 @@ namespace pcpp PIP_ADAPTER_INFO curAdapterInfo = adapterInfo; while (curAdapterInfo != nullptr) { - if (m_Name.find(curAdapterInfo->AdapterName) != std::string::npos) + if (m_InterfaceDetails.name.find(curAdapterInfo->AdapterName) != std::string::npos) { try { @@ -1077,7 +1064,7 @@ namespace pcpp std::stringstream lineStream(line); std::string interfaceName; std::getline(lineStream, interfaceName, '\t'); - if (interfaceName != m_Name) + if (interfaceName != m_InterfaceDetails.name) continue; std::string interfaceDest; @@ -1177,7 +1164,7 @@ namespace pcpp PCPP_LOG_ERROR("Error retrieving default gateway address: " << inet_ntoa(*gateAddr) << ": " << e.what()); } #elif defined(__FreeBSD__) - std::string command = "netstat -nr | grep default | grep " + m_Name; + std::string command = "netstat -nr | grep default | grep " + m_InterfaceDetails.name; std::string ifaceInfo = executeShellCommand(command); if (ifaceInfo == "") { @@ -1206,79 +1193,18 @@ namespace pcpp #endif } - std::vector PcapLiveDevice::getIPAddresses() const - { - std::vector results; - for (const auto& address : m_Addresses) - { - in_addr* ipv4Addr = internal::try_sockaddr2in_addr(address.addr); - if (ipv4Addr != nullptr) - { - results.push_back(IPv4Address(ipv4Addr->s_addr)); - continue; - } - - in6_addr* ipv6Addr = internal::try_sockaddr2in6_addr(address.addr); - if (ipv6Addr != nullptr) - { - results.push_back(IPv6Address(ipv6Addr->s6_addr)); - continue; - } - } - - return results; - } - IPv4Address PcapLiveDevice::getIPv4Address() const { - for (const auto& addrIter : m_Addresses) - { - if (Logger::getInstance().isDebugEnabled(PcapLogModuleLiveDevice) && addrIter.addr != nullptr) - { - std::array addrAsString; - internal::sockaddr2string(addrIter.addr, addrAsString.data(), addrAsString.size()); - PCPP_LOG_DEBUG("Searching address " << addrAsString.data()); - } - - in_addr* currAddr = internal::try_sockaddr2in_addr(addrIter.addr); - if (currAddr == nullptr) - { - PCPP_LOG_DEBUG("Address is nullptr"); - continue; - } - - try - { - return IPv4Address(currAddr->s_addr); - } - catch (const std::exception&) - { - continue; - } - } - - return IPv4Address::Zero; + auto const& addresses = m_InterfaceDetails.addresses; + auto it = std::find_if(addresses.begin(), addresses.end(), [](const IPAddress& addr) { return addr.isIPv4(); }); + return it != addresses.end() ? it->getIPv4() : IPv4Address::Zero; } IPv6Address PcapLiveDevice::getIPv6Address() const { - for (const auto& addrIter : m_Addresses) - { - if (Logger::getInstance().isDebugEnabled(PcapLogModuleLiveDevice) && addrIter.addr != nullptr) - { - std::array addrAsString; - internal::sockaddr2string(addrIter.addr, addrAsString.data(), addrAsString.size()); - PCPP_LOG_DEBUG("Searching address " << addrAsString.data()); - } - in6_addr* currAddr = internal::try_sockaddr2in6_addr(addrIter.addr); - if (currAddr == nullptr) - { - PCPP_LOG_DEBUG("Address is nullptr"); - continue; - } - return IPv6Address(currAddr->s6_addr); - } - return IPv6Address::Zero; + auto const& addresses = m_InterfaceDetails.addresses; + auto it = std::find_if(addresses.begin(), addresses.end(), [](const IPAddress& addr) { return addr.isIPv6(); }); + return it != addresses.end() ? it->getIPv6() : IPv6Address::Zero; } IPv4Address PcapLiveDevice::getDefaultGateway() const diff --git a/Pcap++/src/PcapLiveDeviceList.cpp b/Pcap++/src/PcapLiveDeviceList.cpp index 14cf09e570..9fb46b4ce4 100644 --- a/Pcap++/src/PcapLiveDeviceList.cpp +++ b/Pcap++/src/PcapLiveDeviceList.cpp @@ -278,68 +278,22 @@ namespace pcpp PcapLiveDevice* PcapLiveDeviceList::getPcapLiveDeviceByIp(const IPv4Address& ipAddr) const { - PCPP_LOG_DEBUG("Searching all live devices..."); - for (const auto& devicePtr : m_LiveDeviceList) - { - PCPP_LOG_DEBUG("Searching device '" << devicePtr->m_Name << "'. Searching all addresses..."); - for (const auto& addressInfo : devicePtr->m_Addresses) - { - if (Logger::getInstance().isDebugEnabled(PcapLogModuleLiveDevice) && addressInfo.addr != nullptr) - { - std::array addrAsString; - internal::sockaddr2string(addressInfo.addr, addrAsString.data(), addrAsString.size()); - PCPP_LOG_DEBUG("Searching address " << addrAsString.data()); - } - - in_addr* currAddr = internal::try_sockaddr2in_addr(addressInfo.addr); - if (currAddr == nullptr) - { - PCPP_LOG_DEBUG("Address is nullptr"); - continue; - } - - if (*currAddr == ipAddr) - { - PCPP_LOG_DEBUG("Found matched address!"); - return devicePtr.get(); - } - } - } - - return nullptr; + auto it = std::find_if(m_LiveDeviceList.begin(), m_LiveDeviceList.end(), + [&ipAddr](std::unique_ptr const& devPtr) { + auto devIP = devPtr->getIPv4Address(); + return devIP == ipAddr; + }); + return it != m_LiveDeviceList.end() ? it->get() : nullptr; } PcapLiveDevice* PcapLiveDeviceList::getPcapLiveDeviceByIp(const IPv6Address& ip6Addr) const { - PCPP_LOG_DEBUG("Searching all live devices..."); - for (const auto& devicePtr : m_LiveDeviceList) - { - PCPP_LOG_DEBUG("Searching device '" << devicePtr->m_Name << "'. Searching all addresses..."); - for (const auto& addressInfo : devicePtr->m_Addresses) - { - if (Logger::getInstance().isDebugEnabled(PcapLogModuleLiveDevice) && addressInfo.addr != nullptr) - { - std::array addrAsString; - internal::sockaddr2string(addressInfo.addr, addrAsString.data(), addrAsString.size()); - PCPP_LOG_DEBUG("Searching address " << addrAsString.data()); - } - - in6_addr* currAddr = internal::try_sockaddr2in6_addr(addressInfo.addr); - if (currAddr == nullptr) - { - PCPP_LOG_DEBUG("Address is nullptr"); - continue; - } - - if (*currAddr == ip6Addr) - { - PCPP_LOG_DEBUG("Found matched address!"); - return devicePtr.get(); - } - } - } - - return nullptr; + auto it = std::find_if(m_LiveDeviceList.begin(), m_LiveDeviceList.end(), + [&ip6Addr](std::unique_ptr const& devPtr) { + auto devIP = devPtr->getIPv6Address(); + return devIP == ip6Addr; + }); + return it != m_LiveDeviceList.end() ? it->get() : nullptr; } PcapLiveDevice* PcapLiveDeviceList::getPcapLiveDeviceByIp(const std::string& ipAddrAsString) const diff --git a/Pcap++/src/PcapRemoteDevice.cpp b/Pcap++/src/PcapRemoteDevice.cpp index e4e037df17..d27ccbc5c2 100644 --- a/Pcap++/src/PcapRemoteDevice.cpp +++ b/Pcap++/src/PcapRemoteDevice.cpp @@ -16,9 +16,10 @@ namespace pcpp return result; } - PcapRemoteDevice::PcapRemoteDevice(pcap_if_t* iface, std::shared_ptr remoteAuthentication, + PcapRemoteDevice::PcapRemoteDevice(DeviceInterfaceDetails deviceInterface, + std::shared_ptr remoteAuthentication, const IPAddress& remoteMachineIP, uint16_t remoteMachinePort) - : PcapLiveDevice(iface, false, false, false), m_RemoteMachineIpAddress(remoteMachineIP), + : PcapLiveDevice(std::move(deviceInterface), false, false, false), m_RemoteMachineIpAddress(remoteMachineIP), m_RemoteMachinePort(remoteMachinePort), m_RemoteAuthentication(std::move(remoteAuthentication)) { PCPP_LOG_DEBUG("MTU calculation isn't supported for remote devices. Setting MTU to 1514"); @@ -28,9 +29,9 @@ namespace pcpp bool PcapRemoteDevice::open() { char errbuf[PCAP_ERRBUF_SIZE]; - int flags = - PCAP_OPENFLAG_PROMISCUOUS | PCAP_OPENFLAG_NOCAPTURE_RPCAP; // PCAP_OPENFLAG_DATATX_UDP doesn't always work - PCPP_LOG_DEBUG("Opening device '" << m_Name << "'"); + // PCAP_OPENFLAG_DATATX_UDP doesn't always work + int flags = PCAP_OPENFLAG_PROMISCUOUS | PCAP_OPENFLAG_NOCAPTURE_RPCAP; + PCPP_LOG_DEBUG("Opening device '" << m_InterfaceDetails.name << "'"); pcap_rmtauth* pRmAuth = nullptr; pcap_rmtauth rmAuth; if (m_RemoteAuthentication != nullptr) @@ -39,8 +40,8 @@ namespace pcpp pRmAuth = &rmAuth; } - m_PcapDescriptor = - internal::PcapHandle(pcap_open(m_Name.c_str(), PCPP_MAX_PACKET_SIZE, flags, 250, pRmAuth, errbuf)); + m_PcapDescriptor = internal::PcapHandle( + pcap_open(m_InterfaceDetails.name.c_str(), PCPP_MAX_PACKET_SIZE, flags, 250, pRmAuth, errbuf)); if (m_PcapDescriptor == nullptr) { PCPP_LOG_ERROR("Error opening device. Error was: " << errbuf); @@ -64,7 +65,7 @@ namespace pcpp return false; } - PCPP_LOG_DEBUG("Device '" << m_Name << "' opened"); + PCPP_LOG_DEBUG("Device '" << m_InterfaceDetails.name << "' opened"); return true; } @@ -76,7 +77,7 @@ namespace pcpp if (allocatedMemory < static_cast(sizeof(pcap_stat))) { PCPP_LOG_ERROR("Error getting statistics from live device '" - << m_Name << "': WinPcap did not allocate the entire struct"); + << m_InterfaceDetails.name << "': WinPcap did not allocate the entire struct"); return; } stats.packetsRecv = tempStats->ps_capt; @@ -96,4 +97,10 @@ namespace pcpp return MacAddress::Zero; } + PcapRemoteDevice* PcapRemoteDevice::clone() const + { + return new PcapRemoteDevice(m_InterfaceDetails, m_RemoteAuthentication, m_RemoteMachineIpAddress, + m_RemoteMachinePort); + } + } // namespace pcpp diff --git a/Pcap++/src/PcapRemoteDeviceList.cpp b/Pcap++/src/PcapRemoteDeviceList.cpp index 368529789a..b725f3b817 100644 --- a/Pcap++/src/PcapRemoteDeviceList.cpp +++ b/Pcap++/src/PcapRemoteDeviceList.cpp @@ -160,70 +160,22 @@ namespace pcpp PcapRemoteDevice* PcapRemoteDeviceList::getRemoteDeviceByIP(const IPv4Address& ip4Addr) const { - PCPP_LOG_DEBUG("Searching all remote devices in list..."); - for (ConstRemoteDeviceListIterator devIter = m_RemoteDeviceList.begin(); devIter != m_RemoteDeviceList.end(); - devIter++) - { - PCPP_LOG_DEBUG("Searching device '" << (*devIter)->m_Name << "'. Searching all addresses..."); - for (const auto& addrIter : (*devIter)->m_Addresses) - { - if (Logger::getInstance().isDebugEnabled(PcapLogModuleRemoteDevice) && addrIter.addr != nullptr) - { - std::array addrAsString; - internal::sockaddr2string(addrIter.addr, addrAsString.data(), addrAsString.size()); - PCPP_LOG_DEBUG("Searching address " << addrAsString.data()); - } - - in_addr* currAddr = internal::try_sockaddr2in_addr(addrIter.addr); - if (currAddr == nullptr) - { - PCPP_LOG_DEBUG("Address is nullptr"); - continue; - } - - if (*currAddr == ip4Addr) - { - PCPP_LOG_DEBUG("Found matched address!"); - return (*devIter); - } - } - } - - return nullptr; + auto it = std::find_if(m_RemoteDeviceList.begin(), m_RemoteDeviceList.end(), + [&ip4Addr](PcapRemoteDevice const* devPtr) { + auto devIP = devPtr->getIPv4Address(); + return devIP == ip4Addr; + }); + return it != m_RemoteDeviceList.end() ? *it : nullptr; } PcapRemoteDevice* PcapRemoteDeviceList::getRemoteDeviceByIP(const IPv6Address& ip6Addr) const { - PCPP_LOG_DEBUG("Searching all remote devices in list..."); - for (ConstRemoteDeviceListIterator devIter = m_RemoteDeviceList.begin(); devIter != m_RemoteDeviceList.end(); - devIter++) - { - PCPP_LOG_DEBUG("Searching device '" << (*devIter)->m_Name << "'. Searching all addresses..."); - for (const auto& addrIter : (*devIter)->m_Addresses) - { - if (Logger::getInstance().isDebugEnabled(PcapLogModuleRemoteDevice) && addrIter.addr != nullptr) - { - std::array addrAsString; - internal::sockaddr2string(addrIter.addr, addrAsString.data(), addrAsString.size()); - PCPP_LOG_DEBUG("Searching address " << addrAsString.data()); - } - - in6_addr* currAddr = internal::try_sockaddr2in6_addr(addrIter.addr); - if (currAddr == nullptr) - { - PCPP_LOG_DEBUG("Address is nullptr"); - continue; - } - - if (*currAddr == ip6Addr) - { - PCPP_LOG_DEBUG("Found matched address!"); - return (*devIter); - } - } - } - - return nullptr; + auto it = std::find_if(m_RemoteDeviceList.begin(), m_RemoteDeviceList.end(), + [&ip6Addr](PcapRemoteDevice const* devPtr) { + auto devIP = devPtr->getIPv6Address(); + return devIP == ip6Addr; + }); + return it != m_RemoteDeviceList.end() ? *it : nullptr; } PcapRemoteDeviceList::~PcapRemoteDeviceList() diff --git a/Pcap++/src/WinPcapLiveDevice.cpp b/Pcap++/src/WinPcapLiveDevice.cpp index 94f20f2cd3..2630045060 100644 --- a/Pcap++/src/WinPcapLiveDevice.cpp +++ b/Pcap++/src/WinPcapLiveDevice.cpp @@ -8,9 +8,9 @@ namespace pcpp { - WinPcapLiveDevice::WinPcapLiveDevice(pcap_if_t* iface, bool calculateMTU, bool calculateMacAddress, - bool calculateDefaultGateway) - : PcapLiveDevice(iface, calculateMTU, calculateMacAddress, calculateDefaultGateway) + WinPcapLiveDevice::WinPcapLiveDevice(DeviceInterfaceDetails interfaceDetails, bool calculateMTU, + bool calculateMacAddress, bool calculateDefaultGateway) + : PcapLiveDevice(std::move(interfaceDetails), calculateMTU, calculateMacAddress, calculateDefaultGateway) { m_MinAmountOfDataToCopyFromKernelToApplication = 16000; } @@ -21,14 +21,14 @@ namespace pcpp { if (!m_DeviceOpened || m_PcapDescriptor == nullptr) { - PCPP_LOG_ERROR("Device '" << m_Name << "' not opened"); + PCPP_LOG_ERROR("Device '" << m_InterfaceDetails.name << "' not opened"); return false; } // Put the interface in capture mode if (pcap_setmode(m_PcapDescriptor.get(), MODE_CAPT) < 0) { - PCPP_LOG_ERROR("Error setting the capture mode for device '" << m_Name << "'"); + PCPP_LOG_ERROR("Error setting the capture mode for device '" << m_InterfaceDetails.name << "'"); return false; } @@ -41,14 +41,14 @@ namespace pcpp { if (!m_DeviceOpened || m_PcapDescriptor == nullptr) { - PCPP_LOG_ERROR("Device '" << m_Name << "' not opened"); + PCPP_LOG_ERROR("Device '" << m_InterfaceDetails.name << "' not opened"); return false; } // Put the interface in statistics mode if (pcap_setmode(m_PcapDescriptor.get(), MODE_STAT) < 0) { - PCPP_LOG_ERROR("Error setting the statistics mode for device '" << m_Name << "'"); + PCPP_LOG_ERROR("Error setting the statistics mode for device '" << m_InterfaceDetails.name << "'"); return false; } @@ -59,7 +59,7 @@ namespace pcpp { if (!m_DeviceOpened || m_PcapDescriptor == nullptr) { - PCPP_LOG_ERROR("Device '" << m_Name << "' not opened"); + PCPP_LOG_ERROR("Device '" << m_InterfaceDetails.name << "' not opened"); return 0; } @@ -131,9 +131,9 @@ namespace pcpp return true; } - WinPcapLiveDevice* WinPcapLiveDevice::cloneInternal(pcap_if_t& devInterface) const + WinPcapLiveDevice* WinPcapLiveDevice::clone() const { - return new WinPcapLiveDevice(&devInterface, true, true, true); + return new WinPcapLiveDevice(m_InterfaceDetails, true, true, true); } } // namespace pcpp diff --git a/Tests/Pcap++Test/Tests/LiveDeviceTests.cpp b/Tests/Pcap++Test/Tests/LiveDeviceTests.cpp index 8f39ab9576..a8ee8dbad8 100644 --- a/Tests/Pcap++Test/Tests/LiveDeviceTests.cpp +++ b/Tests/Pcap++Test/Tests/LiveDeviceTests.cpp @@ -1022,6 +1022,12 @@ PTF_TEST_CASE(TestRemoteCapture) remoteDevice->close(); + // Check clone method produces correct pointer. + pcpp::PcapLiveDevice* remoteDeviceCloned = remoteDevice->clone(); + auto devCopyTeardown = DeviceTeardown(remoteDeviceCloned, true); + PTF_ASSERT_NOT_NULL(remoteDeviceCloned); + PTF_ASSERT_NOT_NULL(dynamic_cast(remoteDeviceCloned)); + delete remoteDevices; // the device object is already deleted, cannot close it