libpcap doesn't do anything (Windows)

245 Views Asked by At

For 2 days now I am trying to get a simple packet live capture to work with libpcap and npcap on Windows 11. I am using MSYS2-compiled MinGW GCC compiler. I have installed libpcap through pacman and linked it. I have installed npcap with wireless support as well as the loopback driver, LWF, LWF with wireless support, and the WFP callout driver (through NPFInstall.exe). The npcap service is running and wireshark works well on its own. My Wi-Fi network adapter does not support monitor mode, so I couldn't try that with WlanHelper.exe

The code I first tested was:

#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>

static void init_npcap_dll_path ()
{
    BOOL(WINAPI *SetDllDirectory)(LPCTSTR);
    char sysdir_name[512];
    int len;

    SetDllDirectory = (BOOL(WINAPI *)(LPCTSTR)) GetProcAddress(GetModuleHandle("kernel32.dll"), "SetDllDirectoryA");

    if(SetDllDirectory == NULL)
    {
        printf("Error in SetDllDirectory\n");
    }
    else
    {
        len = GetSystemDirectory(sysdir_name, 480);

        if(!len) printf("Error in GetSystemDirectory (%d)\n", GetLastError());

        strcat(sysdir_name, "\\Npcap");

        if(SetDllDirectory(sysdir_name) == 0)
            printf("Error in SetDllDirectory(\"System32\\Npcap\")\n");
    }
}

int main (void)
{
    /* No error here: */
    init_npcap_dll_path();

    /* Modules were loaded successfully */
    HMODULE lib1 = LoadLibrary("wpcap");
    HMODULE lib2 = LoadLibrary("Packet");

    char errbuf[PCAP_ERRBUF_SIZE];
    char *dev = "\\Device\\NPF_{B4B56B26-D9F1-49CF-831F-DD58B7DA5ACC}";
    //char *dev = "b4b56b26-d9f1-49cf-831f-dd58b7da5acc"; /* Tried this as well */

    pcap_t* handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);

    if(handle == NULL)
    {
        fprintf(stderr, "Could not open device %s: %s\n", dev, errbuf);
        return 2;
    }

    return 0;
}

And the pcap error was that "live packet capture is not supported on this system".

Moreover, even a simple network adapter lookup doesn't work:

char *dev = pcap_lookupdev(errbuf);

if(dev == NULL)
{
    fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
    return(2);
}

The error reads "no suitable device found"

Running the application as admin does nothing. I really don't know what else I could try to get it working, except maybe using VS and linking the .lib files from the npcap SDK implicitly...

What could I be doing wrong?

2

There are 2 best solutions below

3
Tom On

The error is use of LoadLibrary, see LoadLibraryA function

correct use of LoadLibrary is:

HMODULE hModule = LoadLibrary("xxxxxxx.dll");
if(hModule == NULL)
{
    // error warning
}

And if you use LoadLibrary, why not use GetProcAddress, see GetProcAddress function

Then you need define a poniter of function, like this:

typedef int (*pFunc)(int a , int b)

Then use GetProcAddress

pFunc PPPfunc = (pFunc)GetProcAddress(hModule, "NameOfFunction");
int d = PPPfunc(1, 2);
5
user16139739 On

If you are building your program with the MSYS2 libpcap package (as "I have installed libpcap through pacman" implies), then, unless the libpcap in that package was compiled on a system that has Npcap and the Npcap SDK installed, and the build process for that package told CMake where the Npcap SDK is installed, then the libpcap in that package will not support packet capture (and shouldn't be advertised by he MSYS2 package site as being "for packet capture"!).

Note that there are both "libpcap" and "mingw-w64-libpcap" packages on the MSYS2 packages site. They do not seem to indicate what the difference is between the packages; you might try uninstalling whichever one you installed, install the other one, and see if that works.

You also might want to file an issue on one or both of those packages on the MSYS2 MINGW-packages issues list if one or both of them doesn't support packet capture.

I don't know if there's a way to, in MinGW, link with a program with an SDK that provides a Visual Studio .lib file, but, if that's supported, you might want to install the Npcap SDK and build with that, instead.

(Note also that using LoadLibrary() to load the wpcap and Packet libraries, without doing anything with the handles you get back from that, does absolutely nothing useful.)

wireshark works well on its own

That's because Wireshark dynamically loads wpcap with LoadLibrary(), gets pointers to all of the libpcap functions that Wireshark uses with GetProcAddress(), and has code to call the libpcap functions using those pointers, done in a fashion similar to the way Tom describes in his answer. That means that it directly calls (through pointers) the Npcap versions of the libpcap functions, and Npcap is built to support packet capture, so that works.

The code in Wireshark to do this is... complicated, for reasons having to do with Wireshark supporting multiple versions of libpcap, with different capabilities, on both UN*Xes and Windows (both WinPcap and Npcap). You probably don't need all that complication - just follow Tom's suggestion.