Skip to content

Commit

Permalink
Centralized duplicated code for fetching device interfaces from libpcap.
Browse files Browse the repository at this point in the history
  • Loading branch information
Dimi1010 committed May 27, 2024
1 parent 9660636 commit 87c4855
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 37 deletions.
2 changes: 2 additions & 0 deletions Pcap++/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
add_library(
Pcap++
src/DeviceUtils.cpp
$<$<BOOL:${PCAPPP_USE_DPDK}>:src/DpdkDevice.cpp>
$<$<BOOL:${PCAPPP_USE_DPDK}>:src/DpdkDeviceList.cpp>
$<$<BOOL:${PCAPPP_USE_DPDK_KNI}>:src/KniDevice.cpp>
Expand All @@ -25,6 +26,7 @@ add_library(

set(public_headers
header/Device.h
header/DeviceUtils.h
header/MemoryUtils.h
header/NetworkUtils.h
header/PcapDevice.h
Expand Down
32 changes: 32 additions & 0 deletions Pcap++/header/DeviceUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

/// @file

#include <memory>
#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<pcap_if_t, PcapFreeAllDevsDeleter> 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<pcap_if_t, PcapFreeAllDevsDeleter> getAllRemotePcapDevices(const IPAddress& ipAddress, uint16_t port, pcap_rmtauth* pRmAuth = nullptr);
}
}
47 changes: 47 additions & 0 deletions Pcap++/src/DeviceUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "DeviceUtils.h"

#include <array>
#include <string>

#include "pcap.h"
#include "Logger.h"
#include "IpAddress.h"

namespace pcpp
{
namespace internal
{
std::unique_ptr<pcap_if_t, PcapFreeAllDevsDeleter> getAllLocalPcapDevices()
{
pcap_if_t* interfaceListRaw;
std::array<char, PCAP_ERRBUF_SIZE> 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<pcap_if_t, internal::PcapFreeAllDevsDeleter>(interfaceListRaw);
}
std::unique_ptr<pcap_if_t, PcapFreeAllDevsDeleter> getAllRemotePcapDevices(const IPAddress& ipAddress, uint16_t port, pcap_rmtauth* pRmAuth)
{
PCPP_LOG_DEBUG("Searching remote devices on IP: " << ipAddress << " and port: " << port);
std::array<char, PCAP_BUF_SIZE> remoteCaptureString;
std::array<char, PCAP_ERRBUF_SIZE> 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<pcap_if_t, internal::PcapFreeAllDevsDeleter>(interfaceListRaw);
}
}
}
17 changes: 8 additions & 9 deletions Pcap++/src/PcapLiveDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "pcap.h"
#include <thread>
#include "Logger.h"
#include "DeviceUtils.h"
#include "SystemUtils.h"
#include "MemoryUtils.h"
#include <string.h>
Expand Down Expand Up @@ -408,16 +409,14 @@ PcapLiveDevice* PcapLiveDevice::clone() const { return clone(SmartPtrApi).releas
std::unique_ptr<PcapLiveDevice> PcapLiveDevice::clone(SmartPtrApiTag apiTag) const
{
std::unique_ptr<pcap_if_t, internal::PcapFreeAllDevsDeleter> 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<pcap_if_t, internal::PcapFreeAllDevsDeleter>(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)
Expand Down
16 changes: 7 additions & 9 deletions Pcap++/src/PcapLiveDeviceList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -33,16 +34,13 @@ PcapLiveDeviceList::PcapLiveDeviceList()
void PcapLiveDeviceList::init()
{
std::unique_ptr<pcap_if_t, internal::PcapFreeAllDevsDeleter> 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<pcap_if_t, internal::PcapFreeAllDevsDeleter>(interfaceListRaw);
interfaceList = internal::getAllLocalPcapDevices();
}
catch (const std::exception& e)
{
PCPP_LOG_ERROR(e.what());
}

PCPP_LOG_DEBUG("Pcap lib version info: " << IPcapDevice::getPcapLibVersionInfo());
Expand Down
28 changes: 9 additions & 19 deletions Pcap++/src/PcapRemoteDeviceList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "Logger.h"
#include "IpUtils.h"
#include "IpAddressUtils.h"
#include "DeviceUtils.h"
#include "MemoryUtils.h"
#include "pcap.h"
#include <ws2tcpip.h>
Expand Down Expand Up @@ -66,17 +67,6 @@ std::unique_ptr<PcapRemoteDeviceList> PcapRemoteDeviceList::getRemoteDeviceList(

std::unique_ptr<PcapRemoteDeviceList> PcapRemoteDeviceList::getRemoteDeviceList(const IPAddress& ipAddress, uint16_t port, std::shared_ptr<PcapRemoteAuthentication> 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)
Expand All @@ -87,16 +77,16 @@ std::unique_ptr<PcapRemoteDeviceList> PcapRemoteDeviceList::getRemoteDeviceList(
}

std::unique_ptr<pcap_if_t, internal::PcapFreeAllDevsDeleter> 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<pcap_if_t, internal::PcapFreeAllDevsDeleter>(interfaceListRaw);
interfaceList = internal::getAllRemotePcapDevices(ipAddress, port, pRmAuth);
}

catch (const std::exception& e)
{
PCPP_LOG_ERROR(e.what());
return nullptr;
}

std::vector<std::shared_ptr<PcapRemoteDevice>> remoteDeviceList;
for (pcap_if_t* currInterface = interfaceList.get(); currInterface != nullptr; currInterface = currInterface->next)
{
Expand Down

0 comments on commit 87c4855

Please sign in to comment.