Reviving Net::Pcap
... in which I look at how existing patches floating on the internet can be integrated into Net::Pcap to make it compile again.
Net::Pcap is dear to me, as I have a module implementing an HTTP sniffer using its network capture. So I like it when the module compiles without too much manual work.
Analysis
Net::Pcap only compiles with old versions of libpcap. Many distributions
have a newer version of libpcap
(1.9 onwards).
RHEL7 still needs the old compilation, as it ships with libpcap
1.5.3.
Libpcap 1.9 needs the new compilation declarations. There is a patch by
Petr Pisar
which I found via
Slaven's distroprefs
but that one breaks RHEL7 compatibility.
Deeper analysis
The existing patch essentially does two things:
In
Makefile.PL
, it adds a-DHAVE_PCAP_SETSAMPLING
define. A quick inspection of my locallibpcap
shows that this name is not a function exported bylibpcap
:nm -D /lib/x86_64-linux-gnu/libpcap.so |grep -i set_sampling
Having this #define on pre-1.9 versions will not compile. Looking in the
libpcap
source code, the function is guarded by a macroPCAP_AVAILABLE_1_9
, so any version oflibpcap
before that will not have it.In
stubs.inc
it removes the definitions of the typespcap_samp
andpcap_rmtauth
, because these are already defined inlibpcap
1.9.x. So, to work around this, we also need to know the version of thelibpcap
library on this machine.
Fixing
The nicest approach would be if libpcap
declares its version as #define
constants. Then the C preprocessor would do all the necessary work for us.
But this is not how things are.
The second nicest approach would be if Perl had a convenient way to dynamically
load an arbitrary loadable library and call a parameterless function that
returns a char*
. But Perl has no such thing built-in.
The next best approach is to write a minimal C program to output that string and then to capture that string from Perl using backticks:
#include <stdio.h>
#include <pcap.h>
int main(int argc, char *argv[]) {
printf("%s\n", pcap_lib_version());
}
This is the approach I took.
Future improvements
There are some improvements for my quick fix:
Error handling
Currently, if compiling
pcap_version.c
fails, the Makefile.PL will simply assume PCAP version 1.8. Some better diagnostics might be in order.Compilation of the C program
Using ExtUtils::CBuilder instead of manually calling
system()
might improve the stability. But ExtUtils::CBuilder is only in core since 5.9.3, while Net::Pcap claims compatibility down to 5.6.1.
Releasing
With the version number in hand, it becomes easy to change the removal of the
struct
definitions to conditionals on the version number. After adding the
new file pcap_version.c
to the MANIFEST
, I submitted the pull request on
Github , in the hope that the
author will release it or maybe at least other people can reuse it.