Skip to content

Commit 89fc9f2

Browse files
committed
Make tcpdump find wpcap.dll on Windows if it's not in the system library.
See https://npcap.com/guide/npcap-devguide.html#npcap-feature-native-dll-implicitly for details on what's being done. Fix #1226.
1 parent c20547a commit 89fc9f2

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,9 @@ add_executable(tcpdump ${TCPDUMP_SOURCE_LIST_C})
14181418
if(NOT C_ADDITIONAL_FLAGS STREQUAL "")
14191419
set_target_properties(tcpdump PROPERTIES COMPILE_FLAGS ${C_ADDITIONAL_FLAGS})
14201420
endif()
1421+
if(NOT "${PCAP_LINK_FLAGS}" STREQUAL "")
1422+
set_target_properties(tcpdump PROPERTIES LINK_FLAGS ${PCAP_LINK_FLAGS})
1423+
endif()
14211424
target_link_libraries(tcpdump netdissect ${TCPDUMP_LINK_LIBRARIES})
14221425

14231426
######################################

cmake/Modules/FindPCAP.cmake

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,42 @@ if(WIN32)
6161
if(PCAP_FOUND)
6262
set(PCAP_LIBRARIES ${PCAP_LIBRARY})
6363
set(PCAP_INCLUDE_DIRS ${PCAP_INCLUDE_DIR})
64+
65+
#
66+
# We need to look for wpcap.dll in \Windows\System32\Npcap first,
67+
# as either:
68+
#
69+
# 1) WinPcap isn't installed and Npcap isn't installed in "WinPcap
70+
# API-compatible Mode", so there's no wpcap.dll in
71+
# \Windows\System32, only in \Windows\System32\Npcap;
72+
#
73+
# 2) WinPcap is installed and Npcap isn't installed in "WinPcap
74+
# API-compatible Mode", so the wpcap.dll in \Windows\System32
75+
# is a WinPcap DLL, but we'd prefer an Npcap DLL (we should
76+
# work with either one if we're configured against WinPcap,
77+
# and we'll probably require Npcap if we're configured againt
78+
# it), and that's in \Windows\System32\Npcap;
79+
#
80+
# 3) Npcap is installed in "WinPcap API-compatible Mode", so both
81+
# \Windows\System32 and \Windows\System32\Npcap have an Npcap
82+
# wpcap.dll.
83+
#
84+
# Unfortunately, Windows has no notion of an rpath, so we can't
85+
# set the rpath to include \Windows\System32\Npcap at link time;
86+
# what we need to do is to link wpcap as a delay-load DLL and
87+
# add \Windows\System32\Npcap to the DLL search path early in
88+
# main() with a call to SetDllDirectory().
89+
#
90+
# We add /delayload:wpcap.dll to the linker options here.
91+
#
92+
# See https://npcap.com/guide/npcap-devguide.html#npcap-feature-native-dll-implicitly
93+
#
94+
set(PCAP_LINK_FLAGS /delayload:wpcap.dll)
95+
96+
#
97+
# Delay-loading libraries means we need to link with delayimp.lib.
98+
#
99+
set(PCAP_LIBRARIES ${PCAP_LIBRARIES} delayimp.lib)
64100
endif()
65101
else(WIN32)
66102
#

tcpdump.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,42 @@ main(int argc, char **argv)
14371437
netdissect_options Ndo;
14381438
netdissect_options *ndo = &Ndo;
14391439

1440+
#ifdef _WIN32
1441+
/*
1442+
* We need to look for wpcap.dll in \Windows\System32\Npcap first,
1443+
* as either:
1444+
*
1445+
* 1) WinPcap isn't installed and Npcap isn't installed in "WinPcap
1446+
* API-compatible Mode", so there's no wpcap.dll in
1447+
* \Windows\System32, only in \Windows\System32\Npcap;
1448+
*
1449+
* 2) WinPcap is installed and Npcap isn't installed in "WinPcap
1450+
* API-compatible Mode", so the wpcap.dll in \Windows\System32
1451+
* is a WinPcap DLL, but we'd prefer an Npcap DLL (we should
1452+
* work with either one if we're configured against WinPcap,
1453+
* and we'll probably require Npcap if we're configured againt
1454+
* it), and that's in \Windows\System32\Npcap;
1455+
*
1456+
* 3) Npcap is installed in "WinPcap API-compatible Mode", so both
1457+
* \Windows\System32 and \Windows\System32\Npcap have an Npcap
1458+
* wpcap.dll.
1459+
*
1460+
* Unfortunately, Windows has no notion of an rpath, so we can't
1461+
* set the rpath to include \Windows\System32\Npcap at link time;
1462+
* what we need to do is to link wpcap as a delay-load DLL and
1463+
* add \Windows\System32\Npcap to the DLL search path early in
1464+
* main() with a call to SetDllDirectory().
1465+
*
1466+
* The same applies to packet.dll.
1467+
*
1468+
* We add \Windows\System32\Npcap here.
1469+
*
1470+
* See https://npcap.com/guide/npcap-devguide.html#npcap-feature-native-dll-implicitly
1471+
*/
1472+
if (!SetDllDirectoryA("C:\\Windows\\System32\\Npcap"))
1473+
error("SetDllDirectory failed");
1474+
#endif
1475+
14401476
/*
14411477
* Initialize the netdissect code.
14421478
*/

0 commit comments

Comments
 (0)