Skip to content

Commit b2addc1

Browse files
leoparenteclaude
andcommitted
chore: add local pcapplusplus recipe with Clang 17 VLA fix
PcapLiveDevice.cpp:841 uses a VLA which Clang 17 rejects as an error. Replaces uint8_t buf[len] with std::vector<uint8_t> buf(len) and updates the two pointer uses to buf.data(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent b80b25b commit b2addc1

3 files changed

Lines changed: 131 additions & 0 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
sources:
2+
"23.09":
3+
url: "https://github.com/seladb/PcapPlusPlus/archive/v23.09.tar.gz"
4+
sha256: "608292f7d2a2e1b7af26adf89347597a6131547eea4e513194bc4f584a40fe74"
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import os
2+
from conan import ConanFile
3+
from conan.tools.build import check_min_cppstd
4+
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps
5+
from conan.tools.files import copy, get, rmdir, replace_in_file
6+
from conan.tools.scm import Version
7+
from conan.errors import ConanInvalidConfiguration
8+
9+
10+
required_conan_version = ">=2"
11+
12+
13+
class PcapplusplusConan(ConanFile):
14+
name = "pcapplusplus"
15+
license = "Unlicense"
16+
description = "PcapPlusPlus is a multiplatform C++ library for capturing, parsing and crafting of network packets"
17+
topics = ("pcap", "network", "security", "packet")
18+
url = "https://github.com/netboxlabs/pktvisor"
19+
homepage = "https://github.com/seladb/PcapPlusPlus"
20+
settings = "os", "arch", "build_type", "compiler"
21+
package_type = "library"
22+
options = {
23+
"fPIC": [True, False],
24+
"shared": [True, False],
25+
"immediate_mode": [True, False],
26+
}
27+
default_options = {
28+
"fPIC": True,
29+
"shared": False,
30+
"immediate_mode": False,
31+
}
32+
33+
implements = ["auto_shared_fpic"]
34+
35+
def requirements(self):
36+
if self.settings.os == "Windows":
37+
self.requires("npcap/1.70")
38+
else:
39+
self.requires("libpcap/1.10.1")
40+
41+
def validate(self):
42+
if Version(self.version) <= "25.05" and self.options.shared and self.settings.os == "Windows":
43+
raise ConanInvalidConfiguration(f"{self.ref} does not support Windows shared builds for now")
44+
check_min_cppstd(self, 11)
45+
if self.settings.os not in ("FreeBSD", "Linux", "Macos", "Windows"):
46+
raise ConanInvalidConfiguration(f"{self.settings.os} is not supported")
47+
48+
def validate_build(self):
49+
compiler_version = Version(self.settings.compiler.version)
50+
if self.settings.compiler == "gcc" and compiler_version < "5.1":
51+
raise ConanInvalidConfiguration("PcapPlusPlus requires GCC >= 5.1")
52+
53+
def source(self):
54+
get(self, **self.conan_data["sources"][self.version], strip_root=True)
55+
self._patch_sources()
56+
57+
def generate(self):
58+
deps = CMakeDeps(self)
59+
deps.generate()
60+
tc = CMakeToolchain(self)
61+
tc.cache_variables["PCAPPP_BUILD_TESTS"] = False
62+
tc.cache_variables["PCAPPP_BUILD_EXAMPLES"] = False
63+
tc.cache_variables["BUILD_SHARED_LIBS"] = self.options.shared
64+
tc.generate()
65+
66+
def layout(self):
67+
cmake_layout(self, src_folder="src")
68+
69+
def _patch_sources(self):
70+
replace_in_file(self, os.path.join(self.source_folder, "CMakeLists.txt"),
71+
"set(CMAKE_CXX_STANDARD 11)",
72+
"")
73+
# Fix VLA in PcapLiveDevice.cpp for Clang 17+ (macOS/FreeBSD)
74+
# uint8_t buf[len] is a VLA which is an error in standard C++
75+
pcap_live = os.path.join(self.source_folder, "Pcap++", "src", "PcapLiveDevice.cpp")
76+
replace_in_file(self, pcap_live,
77+
'#include "IpUtils.h"',
78+
'#include "IpUtils.h"\n#include <vector>')
79+
replace_in_file(self, pcap_live,
80+
"uint8_t buf[len];",
81+
"std::vector<uint8_t> buf(len);")
82+
replace_in_file(self, pcap_live,
83+
"if (sysctl(mib, 6, buf, &len, nullptr, 0) < 0)",
84+
"if (sysctl(mib, 6, buf.data(), &len, nullptr, 0) < 0)")
85+
replace_in_file(self, pcap_live,
86+
"struct if_msghdr*ifm = (struct if_msghdr *)buf;",
87+
"struct if_msghdr*ifm = (struct if_msghdr *)buf.data();")
88+
89+
def build(self):
90+
cmake = CMake(self)
91+
cmake.configure()
92+
cmake.build()
93+
94+
def package(self):
95+
copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"), keep_path=False)
96+
cmake = CMake(self)
97+
cmake.install()
98+
rmdir(self, os.path.join(self.package_folder, "lib", "cmake"))
99+
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))
100+
101+
def package_info(self):
102+
self.cpp_info.set_property("cmake_file_name", "PcapPlusPlus")
103+
self.cpp_info.set_property("cmake_target_name", "PcapPlusPlus::PcapPlusPlus")
104+
105+
self.cpp_info.components["common"].libs = ["Common++"]
106+
if self.settings.os == "Windows":
107+
self.cpp_info.components["common"].system_libs = ["ws2_32", "iphlpapi"]
108+
109+
self.cpp_info.components["packet"].libs = ["Packet++"]
110+
self.cpp_info.components["packet"].requires = ["common"]
111+
112+
self.cpp_info.components["pcap"].libs = ["Pcap++"]
113+
self.cpp_info.components["pcap"].requires = ["common", "packet"]
114+
if self.settings.os == "Windows":
115+
self.cpp_info.components["pcap"].requires.append("npcap::npcap")
116+
self.cpp_info.components["pcap"].system_libs = ["ws2_32", "iphlpapi"]
117+
self.cpp_info.components["pcap"].defines = ["WPCAP", "HAVE_REMOTE"]
118+
else:
119+
self.cpp_info.components["pcap"].requires.append("libpcap::libpcap")
120+
121+
if self.settings.os == "Macos":
122+
self.cpp_info.components["pcap"].frameworks = ["CoreFoundation", "SystemConfiguration"]
123+
elif self.settings.os in ("Linux", "FreeBSD"):
124+
self.cpp_info.components["pcap"].system_libs = ["pthread"]

recipes/pcapplusplus/config.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
versions:
2+
"23.09":
3+
folder: cmake

0 commit comments

Comments
 (0)