From d1ed4db9a070fe25d1014004e6b3f9b5b00f2804 Mon Sep 17 00:00:00 2001 From: Ashutosh Agrawal Date: Sun, 7 Dec 2025 19:26:16 -0800 Subject: [PATCH] Remove binary zip file and download PcapPlusPlus during build - Replace 17MB pcappp_v24.09.zip binary with wget download from GitHub - Download from official release: github.com/seladb/PcapPlusPlus/archive/refs/tags/v24.09.tar.gz - Add SHA256 checksum verification (b14998ecf5718c2bfb6f709060e53f7ef67639b98bf2222a3cd23d820d70acdc) - Fix patch file paths to apply cleanly (remove PcapPlusPlus-24.09/ prefix) - Add .gitignore to exclude downloaded artifacts Addresses review comment from saiarcot895 on PR #67 --- dhcp4relay/.gitignore | 15 ++++++++++++++ dhcp4relay/Makefile | 19 +++++++++++++++--- ...-dhcpv4-relay-accept-random-src-port.patch | 6 +++--- dhcp4relay/pcappp_v24.09.zip | Bin 16988791 -> 0 bytes 4 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 dhcp4relay/.gitignore delete mode 100644 dhcp4relay/pcappp_v24.09.zip diff --git a/dhcp4relay/.gitignore b/dhcp4relay/.gitignore new file mode 100644 index 0000000..1d89f39 --- /dev/null +++ b/dhcp4relay/.gitignore @@ -0,0 +1,15 @@ +# Build artifacts +build/ +build-test/ +*.o +*.d +*.gcda +*.gcno +*.gcov +*.html +*.xml + +# PcapPlusPlus downloaded files +PcapPlusPlus-*/ +PcapPlusPlus-*.tar.gz +pcappp.stamp diff --git a/dhcp4relay/Makefile b/dhcp4relay/Makefile index eda86cc..31eaa39 100644 --- a/dhcp4relay/Makefile +++ b/dhcp4relay/Makefile @@ -15,9 +15,11 @@ GCOVR := gcovr LD_PCAPPLUSPLUS_LIB := -lPcap++ -lPacket++ -lCommon++ -#pcap plus plus zip file pcappp_v24.09.zip +# PcapPlusPlus library configuration PCAPPPVAR := 24.09 -PCAPPPZIP_FILE := pcappp_v${PCAPPPVAR}.zip +PCAPPP_URL := https://github.com/seladb/PcapPlusPlus/archive/refs/tags/v$(PCAPPPVAR).tar.gz +PCAPPP_TARBALL := PcapPlusPlus-$(PCAPPPVAR).tar.gz +PCAPPP_SHA256 := b14998ecf5718c2bfb6f709060e53f7ef67639b98bf2222a3cd23d820d70acdc PCAPPLUSPLUS_DIR := $(WORKING_DIR)/PcapPlusPlus-$(PCAPPPVAR) PCAPPP_DONE = $(WORKING_DIR)/pcappp.stamp INCLUDE_DIR = $(PCAPPLUSPLUS_DIR)/include @@ -34,10 +36,20 @@ PWD := $(shell pwd) .PHONY: $(PCAPPP_DONE) $(PCAPPP_DONE): + # Download PcapPlusPlus from official GitHub release if not already present + if [ ! -f $(PCAPPP_TARBALL) ]; then \ + echo "Downloading PcapPlusPlus v$(PCAPPPVAR)..."; \ + wget -O $(PCAPPP_TARBALL) $(PCAPPP_URL); \ + fi + + # Verify checksum + echo "$(PCAPPP_SHA256) $(PCAPPP_TARBALL)" | sha256sum -c - + # Remove stale files rm -rf $(PCAPPLUSPLUS_DIR) - unzip ${PCAPPPZIP_FILE} + # Extract tarball (GitHub tarball extracts to PcapPlusPlus- without 'v' prefix) + tar xzf $(PCAPPP_TARBALL) pushd $(PCAPPLUSPLUS_DIR) # Create a git repository here for stg to apply patches @@ -98,6 +110,7 @@ uninstall: clean: -$(RM) $(BUILD_DIR) $(BUILD_TEST_DIR) *.html *.xml + -$(RM) $(PCAPPLUSPLUS_DIR) $(PCAPPP_TARBALL) $(PCAPPP_DONE) $(FIND) . -name *.gcda -exec rm -f {} \; $(FIND) . -name *.gcno -exec rm -f {} \; $(FIND) . -name *.gcov -exec rm -f {} \; diff --git a/dhcp4relay/patch/0001-dhcpv4-relay-accept-random-src-port.patch b/dhcp4relay/patch/0001-dhcpv4-relay-accept-random-src-port.patch index f0729b6..ac9ab57 100644 --- a/dhcp4relay/patch/0001-dhcpv4-relay-accept-random-src-port.patch +++ b/dhcp4relay/patch/0001-dhcpv4-relay-accept-random-src-port.patch @@ -1,7 +1,7 @@ -diff --git a/PcapPlusPlus-24.09/Packet++/header/DhcpLayer.h b/PcapPlusPlus-24.09/Packet++/header/DhcpLayer.h +diff --git a/Packet++/header/DhcpLayer.h b/Packet++/header/DhcpLayer.h index 435becb..282d739 100644 ---- a/PcapPlusPlus-24.09/Packet++/header/DhcpLayer.h -+++ b/PcapPlusPlus-24.09/Packet++/header/DhcpLayer.h +--- a/Packet++/header/DhcpLayer.h ++++ b/Packet++/header/DhcpLayer.h @@ -881,8 +881,8 @@ namespace pcpp bool DhcpLayer::isDhcpPorts(uint16_t portSrc, uint16_t portDst) diff --git a/dhcp4relay/pcappp_v24.09.zip b/dhcp4relay/pcappp_v24.09.zip deleted file mode 100644 index cdbbd6ce9d80e1f1eadb1d30f770841465b393e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16988791 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