Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## dev #2034 +/- ##
==========================================
+ Coverage 83.46% 83.68% +0.22%
==========================================
Files 312 312
Lines 54858 55467 +609
Branches 11819 11996 +177
==========================================
+ Hits 45787 46418 +631
+ Misses 7864 7861 -3
+ Partials 1207 1188 -19
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
The reason for this change is that the link type of RAW_IP_PCAP_PATH is LINKTYPE_DLT_RAW1 (value of 12), which in libpcap is translated to LINKTYPE_RAW (value of 101): https://github.com/the-tcpdump-group/libpcap/blob/master/pcap-common.c#L1399-L1400
LINKTYPE_RAW doesn't have good support in BPF filters, so I replaced it with LINKTYPE_NULL
|
Can we deprecate the Nano precision supported methods instead of outright removing them (we can make them always return |
You're right, it's better to deprecate than to remove them altogether. Added back in d16a361 |
Dimi1010
left a comment
There was a problem hiding this comment.
Looked through the reader device. Will look through the writer later.
… same handler for reading and writing in append mode
| }; | ||
|
|
||
| static bool checkNanoSupport() | ||
| LinkLayerType toLinkLayerType(uint32_t value) |
There was a problem hiding this comment.
I think you can check if it is invalid at the beginning and simply call static_cast<LinkLayerType>(value) to avoid the long switch.
There was a problem hiding this comment.
LinkLayerType is not a packed enum, tho. There are gaps, e.g. there are no enum names for values between 14(iirc) and 50.
There was a problem hiding this comment.
Yes, there are more gaps, for example: between 51 - 100, 101 - 104, 114 - 117, and more. There's is no easy way to do this conversion
Pcap++/src/PcapFileDevice.cpp
Outdated
| if (m_DeviceOpened || m_PcapFile.is_open()) | ||
| { | ||
| // TODO: Ambiguity in API | ||
| // If appendMode is required but the file is already opened in write mode. | ||
| PCPP_LOG_DEBUG("Pcap descriptor already opened. Nothing to do"); | ||
| return true; | ||
| PCPP_LOG_ERROR("File already opened"); | ||
| return false; |
There was a problem hiding this comment.
Maybe seperate the checks to make the error message correct.
There was a problem hiding this comment.
Do we even need to store m_DeviceOpened? We could make it to instead infer if the device is opened purely, though m_PcapFile.is_open()?
There was a problem hiding this comment.
If we rely just on m_PcapFile.is_open() we need to always close the file if something goes wrong in open() after we open it. We can use a temp file for this and transfer the ownership to m_PcapFile in the end of open(), like this:
std::fstream pcapFile;
pcapFile.open(m_FileName, flags);
// The rest of the method
m_PcapFile = std::move(pcapFile);
return true;We can do the same in PcapFileReaderDevice. Please let me know what you think.
EDIT: if we do that we also need to override isOpened() and ignore m_DeviceOpened that is defined in IFileDevice...
There was a problem hiding this comment.
Implemented in this commit: 8174ba1
If you think we shouldn't I can revert this commit.
There was a problem hiding this comment.
Hmm, I like the construct as local -> move, as we don't maintain any state if open fails midway, for example if header is partial, broken or something.
EDIT: if we do that we also need to override isOpened() and ignore m_DeviceOpened that is defined in IFileDevice...
Honestly, forgot about that detail. I think it would be better to keep the m_DeviceOpened as it was for now to keep the PR simple.
When this PR is merged I think we can simplify some of the upper interfaces. Some examples:
IFileDeviceinheritsIPcapDevice- this is only becausem_PcapDescriptorwas used in pcap parsing.
This leads to all file devices having a pcap handle member. I think we can drop that and inherit directly fromIFilterableDevice?- Drop the
closeoverride onIFileDevice(and the destructor body) as there wouldn't be a pcap descriptor to close.
There was a problem hiding this comment.
When this PR is merged I think we can simplify some of the upper interfaces. Some examples:
* `IFileDevice` inherits `IPcapDevice` - this is only because `m_PcapDescriptor` was used in pcap parsing. This leads to all file devices having a pcap handle member. I think we can drop that and inherit directly from `IFilterableDevice`? * Drop the `close` override on `IFileDevice` (and the destructor body) as there wouldn't be a pcap descriptor to close.
Yes, I was planning to do it in follow up PRs. The ultimate goal is to not require libpcap at all, like the other capture engines, but it will take time because we need to figure out the BPF filtering...
Honestly, forgot about that detail. I think it would be better to keep the
m_DeviceOpenedas it was for now to keep the PR simple.
So do you suggest I revert the override of isOpened() and continue using m_DeviceOpened for now?
There was a problem hiding this comment.
The ultimate goal is to not require libpcap at all, like the other capture engines, but it will take time because we need to figure out the BPF filtering...
Hmm. Curious as to why tho. I see the benefit for standalone read / write, but I think keeping the libpcap dependency for filtering support seems ok? The only issue would be modularising the code so that it can be compiled without filter support.
So do you suggest I revert the override of
isOpened()and continue usingm_DeviceOpenedfor now?
Yeah, we can leave it to use the logic from IFileDevice for now.
There was a problem hiding this comment.
Yeah, we can leave it to use the logic from
IFileDevicefor now.
Sure, done in this commit: f6b92ea
There was a problem hiding this comment.
Hmm. Curious as to why tho. I see the benefit for standalone read / write, but I think keeping the
libpcapdependency for filtering support seems ok? The only issue would be modularising the code so that it can be compiled without filter support.
Today libpcap / Npcap / WinPcap are different from the other capture engines we support because they are always linked, even if an app doesn't need them. For example: if someone wants to write an application that uses PcapPlusPlus with DPDK, they still have to link libpcap.
The long term goal is to remove this dependency:
- People can build PcapPlusPlus with any capture engine, and libpcap is just one of the options
- libpcap is just used as a capture engine, same as DPDK, WinDivert, AF_XDP, etc. That's why handling files shouldn't depend on libpcap
This PR implements parsing and writing pcap files without using libpcap. It's a rewrite of
PcapFileReaderDeviceandPcapFileWriterDeviceclasses.This change preserves the interface of these classes and deprecates
PcapFileReaderDevice::isNanoSecondPrecisionSupported()andPcapFileWriterDevice::isNanoSecondPrecisionSupported()which always returntrue.The tests, specifically in
FileTests.cpp, were heavily refactored, mostly added more tests, and changed tests that are less relevant.After this change, the only part that will still use libpcap is setting and matching BPF filters. I'm thinking how to remove libpcap dependency here as well, but will be done in a separate PR.