Home page logo
/

Npcap: Nmap Project's packet sniffing library for Windows

Developing software with Npcap

Using the Npcap SDK

To build software that uses Npcap, use the latest version of the Npcap Software Development Kit (SDK). The latest SDK can be downloaded on Npcap.org. Updates to the SDK are much less frequent than updates to the Npcap binaries.

Examples

Examples of applications using Npcap are available in the Examples directory in the source distribution. Several of these examples are explored in more depth in the the section called “Npcap Development Tutorial”.

Npcap developer Yang Luo has also provided an example: UserBridge, which is a tool to redirect all packets from one interface to another.

Updating WinPcap software to Npcap

For the most part, Npcap is completely compatible with software written for WinPcap. Minor changes need to be made to the section called “DLL loading” and in some cases the section called “Service name”. However, there have been many improvements to the libpcap API between the last release of WinPcap and the current release of Npcap. Reviewing the changes may help improve performance, reliability, and maintainability of software that uses Npcap.

How to detect what version Npcap/WinPcap you are using?

Sometimes, our user software needs to detect the existence of Npcap/WinPcap at install-time or run-time. Although Npcap's GUI installer has the ability to handle this, you may want to handle it by yourself in some conditions, like you run Npcap installer in silent-mode. The run-time detection is even more useful. Your software probably has some functions that rely on Npcap's particular features (like the loopback interface). You need to know if you are running on top of Npcap or the legacy WinPcap to control whether to switch your functions on. Fortunately, Npcap provides you some methods to detect Npcap/WinPcap at install-time and run-time.

Npcap version

Npcap has a version number that is independent of WinPcap. The last release of WinPcap was version 4.1.3, but Npcap started over counting versions from 0.00. In order to make it clear to the installers and other software that Npcap is newer and more advanced, the executable file version was advanced to 5.0.0.000 at that point. The major version will always be 5 to distinguish Npcap from WinPcap. The minor version is Npcap's major version; the revision is Npcap's minor version; and the build number is an encoding of the build date. So a file version of 5.0.92.612 is Npcap 0.92, built on June 12th.

Install-time detection

You can check the existence of C:\Program Files\Npcap\NPFInstall.exe to detect Npcap's existence. If Npcap exists, you can check the file version of C:\Program Files\Npcap\NPFInstall.exe to detect Npcap e-version. The e-version also gives you the version. The NSIS code is shown below. $inst_ver is an e-version string like 5.0.7.424

        GetDllVersion "C:\Program Files\Npcap\NPFInstall.exe" $R0 $R1
        IntOp $R2 $R0 / 0x00010000
        IntOp $R3 $R0 & 0x0000FFFF
        IntOp $R4 $R1 / 0x00010000
        IntOp $R5 $R1 & 0x0000FFFF
        StrCpy $inst_ver "$R2.$R3.$R4.$R5"
      

You can check the installation options of an already installed Npcap by reading the registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\npcap\Parameters. The entries like AdminOnly, LoopbackSupport, DltNull,Dot11Support, VlanSupport, WinPcapCompatible, etc. are REG_DWORD type. A 0x00000001 value indicates the installation option is CHECKED.

Note: Prior to Npcap 0.93, these values were stored in the Services\npcap key directly.

Run-time detection

Npcap and WinPcap can be installed together on a system. Which capture library is used by the user software relies on the DLL loading path. If Npcap's wpcap.dll is loaded first, then you are using Npcap, vice versa. However, it's difficult and fragile to check the DLL loading path by yourself. Fortunately, you can use pcap_lib_version to get the Npcap/WinPcap version string.

        char *pcap_version = pcap_lib_version();
        printf("%s", pcap_version);
        // Npcap output: "Npcap version 0.92, based on libpcap version 1.8.1"
        // WinPcap output: "WinPcap version 4.1.3"
      

Npcap requires the npcap service to be running. If installed in WinPcap Compatible Mode, the npf service can be started instead. Given that npcap service is always installed in both modes, a good practice is just trying the npcap service first. If it fails, then try the npf service. This is also what most of our users do in their software based on our investigation. A code sample from Nmap is here.

For software that want to use Npcap first when Npcap and WinPcap coexist

Prerequisite: Uncheck the Install Npcap in WinPcap API-compatible Mode option at install-time (which is by default).

DLL loading

Npcap installs its DLLs into C:\Windows\System32\Npcap\ instead of WinPcap's C:\Windows\System32\. Because of how Windows' DLL search path works, your application will use WinPcap first by default when Npcap and WinPcap coexist, as C:\Windows\System32\ is prior to C:\Windows\System32\Npcap\. So when Npcap and WinPcap coexist, an application that want to use Npcap instead of WinPcap must make C:\Windows\System32\Npcap\ precedent to the C:\Windows\System32\ in the DLL search path. Here are two ways to modify this search path to make your application load Npcap's DLLs first, based on how your application links Npcap/WinPcap's library (wpcap.dll).

If the application implicitly links wpcap.dll

Implicit linking means that either you specified wpcap.lib in your Project Properties -> Configuration Properties -> Linker -> Input -> Additional Dependencies in Visual Studio, or specified #pragma comment(linker, "wpcap.lib") in your code.

You need to do the following two steps:

  • Specify wpcap.dll as a delay-loaded DLL: In Visual Studio, open the Project Properties window. Go to: Configuration Properties -> Linker -> Input -> Delay Loaded Dlls. Enter wpcap.dll in that option.

  • Before calling any wpcap.dll functions, call SetDllDirectory to add C:\Windows\System32\Npcap\ to DLL search path.

Here is an example called WinDump, a simple packet capture tool using Npcap/WinPcap. And this commit makes it able to use Npcap first when Npcap and WinPcap coexist.

If the application explicitly links wpcap.dll

Explicit linking means that you explicitly called LoadLibrary to load wpcap.dll and called GetProcAddress to get the function pointers.

You need to do the following one step:

  • Before calling LoadLibrary to load wpcap.dll, call SetDllDirectory to add C:\Windows\System32\Npcap\ to DLL search path.

The function init_npcap_dll_path is provided in the following example: WinDump

Service name

Npcap uses service name npcap instead of WinPcap's npf with WinPcap Compatible Mode OFF. So applications using net start npf for starting service must change to this: run net start npcap first, if it fails, then try net start npf.

For software that uses Npcap loopback feature

Prerequisite: Check the Support loopback traffic ("Npcap Loopback Adapter" will be created) option at install-time.

Npcap's loopback adapter device is based on Microsoft KM-TEST Loopback Adapter (Win8 and Win10) or Microsoft Loopback Adapter (Vista, Win7). It is an Ethernet adapter, and Npcap has changed its behavior and renamed it to Npcap Loopback Adapter, to make it see the real loopback traffic only.

The IP address of Npcap Loopback Adapter is usually like 169.254.x.x. However, this IP is totally meaningless. Software using Npcap should regard this interface's IP address as 127.0.0.1 (IPv4) and ::1 (IPv6). This work can't be done by Npcap because Windows forbids any IP address to be configured as 127.0.0.1 or ::1 as they're reserved.

The MAC address of Npcap Loopback Adapter is usually like 02:00:4C:4F:4F:50. However, this address is meaningless too. Software using Npcap should think this interface doesn't own a MAC address, as the loopback traffic never goes to link layer. For software using Npcap to capture loopback traffic, the MAC addresses in captured data will be all zeros (aka 00:00:00:00:00:00). For software using Npcap to send loopback traffic, any MAC addresses can be specified as they will be ignored. But notice that ether_type in Ethernet header should be set correctly. Only IPv4 and IPv6 are accepted. Other values like ARP will be ignored. (You don't need an ARP request for loopback interface)

The MTU of Npcap Loopback Adapter is hard-coded to 65536 by Npcap. Software using Npcap should get this value automatically and no special handling is needed. This value is arbitrary and does not imply a limitation on the Windows loopback stack, so it may be possible to capture packets with a size larger than the adapter's MTU.

Don't try to make OID requests to Npcap Loopback Adapter except OID_GEN_MAXIMUM_TOTAL_SIZE (MTU). Those requests will still succeed like other adapters do, but they only make sense for NDIS adapters and Npcap doesn't even use the NDIS way to handle the loopback traffic. The only handled OID request by Npcap is OID_GEN_MAXIMUM_TOTAL_SIZE. If you query its value, you will always get 65550 (65536 + 14). If you try to set its value, the operation will always fail.

To conclude, a software that wants to support Npcap loopback feature should do these steps:

  • Detect Npcap Loopback Adapter's presence, by reading registry value LoopbackSupport at key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\npcap\Parameters. If LoopbackSupport is 0x00000001, then the adapter's device name is in the LoopbackAdapter REG_SZ value. Then perform the following steps.

  • Treat the IP address of Npcap Loopback Adapter as 127.0.0.1 (IPv4) and ::1 (IPv6).

  • Treat the MAC address of Npcap Loopback Adapter as 00:00:00:00:00:00.

  • If you use IP Helper API to get adapter list, you will get an interface named like Loopback Pseudo-Interface 1. This interface is a DUMMY interface by Microsoft and can't be seen in NDIS layer. And it also takes the 127.0.0.1/::1 IP address. A good practice for software is merging the entry of Npcap Loopback Adapter and the entry of Loopback Pseudo-Interface 1 into one entry, like what I have implemented for Nmap (see the Other code (for developers) part).

  • Don't make use of OID requests for Npcap Loopback Adapter except OID_GEN_MAXIMUM_TOTAL_SIZE requests.

For software that uses Npcap raw 802.11 feature

Prerequisite: Check the Support raw 802.11 traffic (and monitor mode) for wireless adapters option at install-time.

Steps

  • Install the latest version Npcap with the Support raw 802.11 traffic (and monitor mode) for wireless adapters option checked in the installation wizard. With this option checked, Npcap will see packets with Radiotap + 802.11 headers for wireless adapters. Otherwise, Npcap will see packets with fake Ethernet headers for wireless adapters.

  • Run WlanHelper.exe with Administrator privilege. If you use -i, follow the interactive prompts to choose your wireless adapter and select Network Monitor mode. WlanHelper.exe also supports parameters to be used in an API manner, run WlanHelper.exe -h for details.

  • Use the Npcap API from your user software as usual. For example, launch Wireshark and capture on the wireless adapter, viewingall 802.11 packets (data + control + management).

  • If you need to return to Managed Mode, run WlanHelper.exe again, following the prompts or selecting the appropriate command-line options to switch off the Monitor Mode.

Tips

  • You can use WlanHelper.exe tool to switch on the Monitor Mode in order to see 802.11 control and management packets. You can also use the pcap_set_rfmon function within your code, as Wireshark does.

  • Switching on the Monitor Mode will disconnect your wireless network from the AP, you can switch back to Managed Mode using the same WlanHelper.exe tool.

  • The WlanHelper.exe tool is installed to %SYSTEMROOT%\System32\Npcap after installing Npcap.

Terminology

Managed Mode (for Linux) = Extensible Station Mode (aka ExtSTA, for Windows)

Monitor Mode (for Linux) = Network Monitor Mode (aka NetMon, for Windows)

Master Mode (for Linux) = Extensible Access Point (aka ExtAP, for Windows)

WlanHelper

WlanHelper is used to set/get the operation mode (like Monitor Mode) for a wireless adapter on Windows. WlanHelper tries to follow the grammar of iwconfig, a wireless management tool for Linux. So if you rename WlanHelper.exe to iwconfig.exe, your command lines for WlanHelper will be exactly the same with the iwconfig tool.

WlanHelper's Usage

Note: WlanHelper must run under Administrator privilege.

Interactive way

Run WlanHelper with the -i option.

Command-line API way
  • Run netsh wlan show interfaces, get the Name or GUID for the interface.

  • Run WlanHelper -h to see the man page.

Example 1. WlanHelper Man

              C:\> WlanHelper.exe
              WlanHelper for Npcap 0.91 ( http://npcap.org )
              Usage: WlanHelper [Commands]
              or: WlanHelper {Interface Name or GUID} [Options]

              OPTIONS:
              mode                  : Get interface operation mode
              mode <managed|monitor|master|..>  : Set interface operation mode
              modes                 : Get all operation modes supported by the interface, comma-separated
              channel               : Get interface channel
              channel <1-14>            : Set interface channel (only works in monitor mode)
              freq                  : Get interface frequency
              freq <VALUE>              : Set interface frequency (only works in monitor mode)
              modu                  : Get interface modulation
              modu <dsss|fhss|irbaseband|ofdm|hrdsss|erp|ht|vht|ihv (VALUE)|..> : Set interface modulation
              modus                 : Get all modulations supported by the interface, comma-separated

              COMMANDS:
              -i                    : Enter the interactive mode
              -h                    : Print this help summary page

              OPERATION MODES:
              managed   : The Extensible Station (ExtSTA) operation mode
              monitor   : The Network Monitor (NetMon) operation mode
              master    : The Extensible Access Point (ExtAP) operation mode (supported from Windows 7 and later)
              wfd_device    : The Wi-Fi Direct Device operation mode (supported from Windows 8 and later)
              wfd_owner : The Wi-Fi Direct Group Owner operation mode (supported from Windows 8 and later)
              wfd_client    : The Wi-Fi Direct Client operation mode (supported from Windows 8 and later)

              802.11 MODULATIONS (https://en.wikipedia.org/wiki/IEEE_802.11):
              802.11-1997   : dsss, fhss
              802.11a   : ofdm
              802.11b   : dsss
              802.11g   : ofdm
              802.11n   : mimo-ofdm
              802.11ac  : mimo-ofdm

              EXAMPLES:
              WlanHelper Wi-Fi mode
              WlanHelper 42dfd47a-2764-43ac-b58e-3df569c447da channel 11
              WlanHelper 42dfd47a-2764-43ac-b58e-3df569c447da freq 2
              WlanHelper "Wireless Network Connection" mode monitor

              SEE THE MAN PAGE (https://github.com/nmap/npcap) FOR MORE OPTIONS AND EXAMPLES
            

An example:

Example 2. WlanHelper API Usage

              C:\> netsh wlan show interfaces

              There is 1 interface on the system:

              Name                   : <Wi-Fi>
              Description            : Qualcomm Atheros AR9485WB-EG Wireless Network Adapter
              GUID                   : <42dfd47a-2764-43ac-b58e-3df569c447da>
              Physical address       : a4:db:30:d9:3a:9a
              State                  : connected
              SSID                   : LUO-PC_Network
              BSSID                  : d8:15:0d:72:8c:18
              Network type           : Infrastructure
              Radio type             : 802.11n
              Authentication         : WPA2-Personal
              Cipher                 : CCMP
              Connection mode        : Auto Connect
              Channel                : 1
              Receive rate (Mbps)    : 150
              Transmit rate (Mbps)   : 150
              Signal                 : 100%
              Profile                : LUO-PC_Network

              Hosted network status  : Not available

              C:\> WlanHelper.exe <wi-fi> mode
              managed
              C:\> WlanHelper.exe <wi-fi> mode monitor
              Success
              C:\> WlanHelper.exe <wi-fi> mode 
              monitor
              C:\> WlanHelper.exe <wi-fi> mode managed
              Success
              C:\> WlanHelper.exe <wi-fi> mode
              managed
            

The Npcap API

The Npcap API is exported by wpcap.dll and is the Windows port of libpcap. The API and functions are described in the pcap(1) man page.

Extensions to libpcap for Windows

There are a few extensions to libpcap that exist only on Windows. Software that uses these extensions will not be portable to non-Windows systems. The following is a brief list of these extensions and their purpose.

pcap_setbuff

Sets the size of the kernel buffer associated with an adapter.

int pcap_setbuff(pcap_t *p, int dim);

dim specifies the size of the buffer in bytes. The return value is 0 when the call succeeds, -1 otherwise. If an old buffer was already created with a previous call to pcap_setbuff(), it is deleted and its content is discarded. pcap_open_live() creates a 1 MByte buffer by default.

pcap_setmode

Sets the working mode of the interface.

int pcap_setmode(pcap_t *p, int mode);

Valid values for mode are MODE_CAPT (default capture mode) and MODE_STAT (statistical mode). See the section called “Gathering Statistics on the network traffic” for details about statistical mode.

pcap_setmintocopy

Sets the minumum amount of data received by the kernel in a single call.

int pcap_setmintocopy(pcap_t *p, int size);

This function changes the minimum amount of data in the kernel buffer that causes a read from the application to return (unless the timeout expires). If the value of size is large, the kernel is forced to wait the arrival of several packets before copying the data to the user. This guarantees a low number of system calls, i.e. low processor usage, and is a good setting for applications like packet-sniffers and protocol analyzers. Vice versa, in presence of a small value for this variable, the kernel will copy the packets as soon as the application is ready to receive them. This is useful for real time applications that need the best responsiveness from the kernel. pcap_open_live() sets a default size value of 16000 bytes.

Portability note: libpcap provides the pcap_set_immediate_mode() function for applications that need to receive packets as soon as they arrive. This removes the need to use the non-portable pcap_setmintocopy() for this purpose.

pcap_getevent

Returns the handle of the event associated with the interface.

HANDLE pcap_getevent(pcap_t *p);

This event can be passed to functions like WaitForSingleObject() or WaitForMultipleObjects() to wait until the driver's buffer contains some data without performing a read.

We disourage the use of this function because it is not portable.

pcap_oid_get_request and pcap_oid_set_request

Send an OID request to the underlying NDIS drivers

int pcap_oid_get_request(pcap_t *, bpf_u_int32, void *, size_t *);int pcap_oid_set_request(pcap_t *, bpf_u_int32, const void *, size_t *);
Queuing sent packets with pcap_send_queue

Npcap has the ability to queue multiple raw packets for transmission on the network in a single call. This is more efficient than issuing a series of pcap_sendpacket(), because the packets are buffered in the kernel driver, so the number of context switches is reduced.

pcap_send_queue* pcap_sendqueue_alloc(u_int memsize);void pcap_sendqueue_destroy(pcap_send_queue* queue);

Allocate a send queue as a buffer of memsize bytes. The pcap_send_queue allocated can be freed with pcap_sendqueue_destroy().

int pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data);

pcap_sendqueue_queue() adds a packet at the end of the send queue pointed by the queue parameter. pkt_header points to a pcap_pkthdr structure with the timestamp and the length of the packet, pkt_data points to a buffer with the data of the packet.

The pcap_pkthdr structure is the same used by Npcap and libpcap to store the packets in a file, therefore sending a capture file is straightforward. 'Raw packet' means that the sending application will have to include the protocol headers, since every packet is sent to the network 'as is'. The CRC of the packets needs not to be calculated, because it will be transparently added by the network interface.

u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync);

This function transmits the content of a queue to the wire. p is a pointer to the adapter on which the packets will be sent, queue points to a pcap_send_queue structure containing the packets to send), sync determines if the send operation must be synchronized: if it is non-zero, the packets are sent respecting the timestamps, otherwise they are sent as fast as possible.

The return value is the amount of bytes actually sent. If it is smaller than the size parameter, an error occurred during the send. The error can be caused by a driver/adapter problem or by an inconsistent/bogus send queue.

Performance note: When sync is set to TRUE, the packets are synchronized in the kernel with a high precision timestamp. This requires a non-negligible amount of CPU, but allows normally to send the packets with a precision of some microseconds (depending on the accuracy of the performance counter of the machine). Such a precision cannot be reached sending the packets with pcap_sendpacket().

pcap_stats_ex
struct pcap_stat *pcap_stats_ex(pcap_t *p, int *pcap_stat_size);

pcap_stats_ex() extends the pcap_stats() allowing to return more statistical parameters than the old call. One of the advantages of this new call is that the pcap_stat structure is not allocated by the user; instead, it is returned back by the system. This allow to extend the pcap_stat structure without affecting backward compatibility on older applications. These will simply check at the values of the members at the beginning of the structure, while only newest applications are able to read new statistical values, which are appended in tail.

To be sure not to read a piece of memory which has not been allocated by the system, the variable pcap_stat_size will return back the size of the structure pcap_stat allocated by the system.

p: pointer to the pcap_t currently in use. pcap_stat_size: pointer to an integer that will contain (when the function returns back) the size of the structure pcap_stat as it has been allocated by the system.

The function returns a pointer to a pcap_stat structure, that will contain the statistics related to the current device. The return value is NULL in case of errors, and the error text can be obtained with pcap_perror() or pcap_geterr().

pcap_setuserbuffer

Sets the size of the buffer that accepts packets from the kernel driver.

int pcap_setuserbuffer(pcap_t *p, int size);

The size of the packet buffer is a parameter that can sensibly influence the performance of the capture process, since this buffer will contain the packets received from the the Npcap driver. The driver is able to return several packets using a single read call, and the number of packets transferable to the application in a call is limited only by the size of this buffer. Therefore setting a larger buffer siz can noticeably decrease the number of system calls, reducing the impact of the capture process on the processor.

[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]