-
Notifications
You must be signed in to change notification settings - Fork 675
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Centralize code for fetching pcap devices. #1434
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
6a2fefa
Added device utilities header for pcap device utility functions.
Dimi1010 e98e6b3
Replaced usages of pcap_findalldevs(_ex) with internal::getAll(Local/…
Dimi1010 1167bd1
Removed code creating pcap_capture string as it is unused.
Dimi1010 535bc76
Fixed returning nullptr on clone fail.
Dimi1010 c09f664
Merge remote-tracking branch 'upstream/dev' into feature/pcap-device-…
Dimi1010 0d91ddf
Renamed MemoryUtils to PcapUtils.
Dimi1010 9a5e638
Moved getAllRemotePcapDevices to anonymous namespace in PcapRemoteDev…
Dimi1010 68b8632
Removed duplicate of PcapCloseDeleter.
Dimi1010 fb685bf
Remoted internal utilitiy headers from the public header list.
Dimi1010 9b0c9c7
Merge branch 'dev' into feature/pcap-device-utils
Dimi1010 f343771
Removed unused forward declare.
Dimi1010 617273e
Added doxygen conditionals to exclude the internal classes from the p…
Dimi1010 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#pragma once | ||
|
||
/// @file | ||
|
||
#include <memory> | ||
#include "IpAddress.h" | ||
#include "PcapUtils.h" | ||
|
||
namespace pcpp | ||
{ | ||
/// @cond PCPP_INTERNAL | ||
|
||
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(); | ||
} | ||
|
||
/// @endcond | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#pragma once | ||
|
||
// Forward declarations | ||
struct pcap; | ||
typedef pcap pcap_t; | ||
struct pcap_if; | ||
typedef pcap_if pcap_if_t; | ||
|
||
namespace pcpp | ||
{ | ||
/// @cond PCPP_INTERNAL | ||
|
||
namespace internal | ||
{ | ||
/** | ||
* @class PcapCloseDeleter | ||
* A deleter that cleans up a pcap_t structure by calling pcap_close. | ||
*/ | ||
struct PcapCloseDeleter | ||
{ | ||
void operator()(pcap_t* ptr) const; | ||
}; | ||
|
||
/** | ||
* @class PcapFreeAllDevsDeleter | ||
* A deleter that frees an interface list of pcap_if_t ptr by calling 'pcap_freealldevs' function on it. | ||
*/ | ||
struct PcapFreeAllDevsDeleter | ||
{ | ||
void operator()(pcap_if_t* ptr) const; | ||
}; | ||
} | ||
|
||
/// @endcond | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#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); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,8 @@ | |
#include "IpAddressUtils.h" | ||
#include "PcapLiveDeviceList.h" | ||
#include "Logger.h" | ||
#include "PcapUtils.h" | ||
#include "DeviceUtils.h" | ||
#include "SystemUtils.h" | ||
#include "pcap.h" | ||
#include <string.h> | ||
|
@@ -39,32 +41,30 @@ PcapLiveDeviceList::~PcapLiveDeviceList() | |
|
||
void PcapLiveDeviceList::init() | ||
{ | ||
pcap_if_t* interfaceList; | ||
char errbuf[PCAP_ERRBUF_SIZE]; | ||
int err = pcap_findalldevs(&interfaceList, errbuf); | ||
if (err < 0) | ||
std::unique_ptr<pcap_if_t, internal::PcapFreeAllDevsDeleter> interfaceList; | ||
try | ||
{ | ||
interfaceList = internal::getAllLocalPcapDevices(); | ||
} | ||
catch (const std::exception& e) | ||
{ | ||
PCPP_LOG_ERROR("Error searching for devices: " << errbuf); | ||
PCPP_LOG_ERROR(e.what()); | ||
} | ||
|
||
PCPP_LOG_DEBUG("Pcap lib version info: " << IPcapDevice::getPcapLibVersionInfo()); | ||
|
||
pcap_if_t* currInterface = interfaceList; | ||
while (currInterface != nullptr) | ||
|
||
for (pcap_if_t* currInterface = interfaceList.get(); currInterface != nullptr; currInterface = currInterface->next) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice catch |
||
{ | ||
#if defined(_WIN32) | ||
PcapLiveDevice* dev = new WinPcapLiveDevice(currInterface, true, true, true); | ||
#else //__linux__, __APPLE__, __FreeBSD__ | ||
PcapLiveDevice* dev = new PcapLiveDevice(currInterface, true, true, true); | ||
#endif | ||
currInterface = currInterface->next; | ||
m_LiveDeviceList.insert(m_LiveDeviceList.end(), dev); | ||
} | ||
|
||
setDnsServers(); | ||
|
||
PCPP_LOG_DEBUG("Freeing live device data"); | ||
pcap_freealldevs(interfaceList); | ||
} | ||
|
||
void PcapLiveDeviceList::setDnsServers() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
#include "PcapRemoteDeviceList.h" | ||
#include "Logger.h" | ||
#include "IpUtils.h" | ||
#include "PcapUtils.h" | ||
#include "IpAddressUtils.h" | ||
#include "pcap.h" | ||
#include <array> | ||
|
@@ -13,58 +14,80 @@ | |
namespace pcpp | ||
{ | ||
|
||
namespace | ||
{ | ||
/** | ||
* Fetches a list of all network devices on a remote machine that 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, internal::PcapFreeAllDevsDeleter> getAllRemotePcapDevices(const IPAddress& ipAddress, uint16_t port, pcap_rmtauth* pRmAuth = nullptr) | ||
{ | ||
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); | ||
} | ||
} | ||
|
||
PcapRemoteDeviceList* PcapRemoteDeviceList::getRemoteDeviceList(const IPAddress& ipAddress, uint16_t port) | ||
{ | ||
return PcapRemoteDeviceList::getRemoteDeviceList(ipAddress, port, NULL); | ||
} | ||
|
||
PcapRemoteDeviceList* PcapRemoteDeviceList::getRemoteDeviceList(const IPAddress& ipAddress, uint16_t port, PcapRemoteAuthentication* remoteAuth) | ||
{ | ||
PCPP_LOG_DEBUG("Searching remote devices on IP: " << ipAddress << " and port: " << port); | ||
char remoteCaptureString[PCAP_BUF_SIZE]; | ||
char errbuf[PCAP_ERRBUF_SIZE]; | ||
std::ostringstream portAsString; | ||
portAsString << port; | ||
if (pcap_createsrcstr(remoteCaptureString, PCAP_SRC_IFREMOTE, ipAddress.toString().c_str(), portAsString.str().c_str(), NULL, errbuf) != 0) | ||
{ | ||
PCPP_LOG_ERROR("Error in creating the remote connection string. Error was: " << errbuf); | ||
return NULL; | ||
} | ||
|
||
PCPP_LOG_DEBUG("Remote capture string: " << remoteCaptureString); | ||
|
||
pcap_rmtauth* pRmAuth = NULL; | ||
pcap_rmtauth* pRmAuth = nullptr; | ||
pcap_rmtauth rmAuth; | ||
if (remoteAuth != NULL) | ||
if (remoteAuth != nullptr) | ||
{ | ||
PCPP_LOG_DEBUG("Authentication requested. Username: " << remoteAuth->userName << ", Password: " << remoteAuth->password); | ||
rmAuth = remoteAuth->getPcapRmAuth(); | ||
pRmAuth = &rmAuth; | ||
} | ||
|
||
pcap_if_t* interfaceList; | ||
char errorBuf[PCAP_ERRBUF_SIZE]; | ||
if (pcap_findalldevs_ex(remoteCaptureString, pRmAuth, &interfaceList, errorBuf) < 0) | ||
std::unique_ptr<pcap_if_t, internal::PcapFreeAllDevsDeleter> interfaceList; | ||
try | ||
{ | ||
PCPP_LOG_ERROR("Error retrieving device on remote machine. Error string is: " << errorBuf); | ||
return NULL; | ||
interfaceList = getAllRemotePcapDevices(ipAddress, port, pRmAuth); | ||
} | ||
catch (const std::exception& e) | ||
{ | ||
PCPP_LOG_ERROR(e.what()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||
return nullptr; | ||
} | ||
|
||
PcapRemoteDeviceList* resultList = new PcapRemoteDeviceList(); | ||
resultList->setRemoteMachineIpAddress(ipAddress); | ||
resultList->setRemoteMachinePort(port); | ||
resultList->setRemoteAuthentication(remoteAuth); | ||
|
||
pcap_if_t* currInterface = interfaceList; | ||
while (currInterface != NULL) | ||
|
||
for (pcap_if_t* currInterface = interfaceList.get(); currInterface != nullptr; currInterface = currInterface->next) | ||
{ | ||
PcapRemoteDevice* pNewRemoteDevice = new PcapRemoteDevice(currInterface, resultList->m_RemoteAuthentication, | ||
resultList->getRemoteMachineIpAddress(), resultList->getRemoteMachinePort()); | ||
resultList->m_RemoteDeviceList.push_back(pNewRemoteDevice); | ||
currInterface = currInterface->next; | ||
} | ||
|
||
pcap_freealldevs(interfaceList); | ||
return resultList; | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#include "PcapUtils.h" | ||
|
||
#include "pcap.h" | ||
|
||
namespace pcpp | ||
{ | ||
namespace internal | ||
{ | ||
void PcapCloseDeleter::operator()(pcap_t* ptr) const { pcap_close(ptr); } | ||
|
||
void PcapFreeAllDevsDeleter::operator()(pcap_if_t* ptr) const { pcap_freealldevs(ptr); } | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
recommend to have a meaningful error message here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error messages are actually the same as before. It is just that the DeviceUtil functions have the error messages thrown in a
runtime_error
as the exception reason and this code catches that and logs the message in the exception.