1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-15 20:29:03 +00:00

Enable Nmap, Nping to use Npcap over Winpcap if available.

This commit is contained in:
dmiller
2016-06-14 14:16:46 +00:00
parent 7a9ab13bee
commit 67fd101b01
11 changed files with 233 additions and 22 deletions

View File

@@ -143,6 +143,10 @@
#define DLI_ERROR VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND)
#endif
#define PCAP_DRIVER_NONE 0
#define PCAP_DRIVER_WINPCAP 1
#define PCAP_DRIVER_NPCAP 2
extern NmapOps o;
/* internal functions */
@@ -163,14 +167,15 @@ void win_pre_init() {
fatal("failed to start winsock.\n");
}
/* Check if the NPF service is running on Windows, and try to start it if it's
/* Check if the NPCAP service is running on Windows, and try to start it if it's
not. Return true if it was running or we were able to start it, false
otherwise. */
static bool start_npf() {
static bool start_service(const char *svcname) {
SC_HANDLE scm, npf;
SERVICE_STATUS service;
bool npf_running;
int ret;
char startsvc[32];
scm = NULL;
npf = NULL;
@@ -180,7 +185,7 @@ static bool start_npf() {
error("Error in OpenSCManager");
goto quit_error;
}
npf = OpenService(scm, "npf", SC_MANAGER_CONNECT | SERVICE_QUERY_STATUS);
npf = OpenService(scm, svcname, SC_MANAGER_CONNECT | SERVICE_QUERY_STATUS);
if (npf == NULL) {
error("Error in OpenService");
goto quit_error;
@@ -195,19 +200,20 @@ static bool start_npf() {
if (npf_running) {
if (o.debugging > 1)
log_write(LOG_PLAIN, "NPF service is already running.\n");
log_write(LOG_PLAIN, "%s service is already running.\n", svcname);
return true;
}
/* NPF is not running. Try to start it. */
/* Service is not running. Try to start it. */
if (o.debugging > 1)
log_write(LOG_PLAIN, "NPF service is not running.\n");
log_write(LOG_PLAIN, "%s service is not running.\n", svcname);
ret = (int) ShellExecute(0, "runas", "net.exe", "start npf", 0, SW_HIDE);
Snprintf(startsvc, 32, "start %s", svcname);
ret = (int) ShellExecute(0, "runas", "net.exe", startsvc, 0, SW_HIDE);
if (ret <= 32) {
error("Unable to start NPF service: ShellExecute returned %d.\n\
Resorting to unprivileged (non-administrator) mode.", ret);
error("Unable to start %s service: ShellExecute returned %d.\n\
Resorting to unprivileged (non-administrator) mode.", svcname, ret);
return false;
}
@@ -246,6 +252,27 @@ static void init_dll_path()
}
}
/* If we find the Npcap driver, allow Nmap to load Npcap DLLs from the "\System32\Npcap" directory. */
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) {
pfatal("Error in SetDllDirectory");
}
else {
len = GetSystemDirectory(sysdir_name, 480); // be safe
if (!len)
pfatal("Error in GetSystemDirectory (%d)", GetLastError());
strcat(sysdir_name, "\\Npcap");
if (SetDllDirectory(sysdir_name) == 0)
pfatal("Error in SetDllDirectory(\"System32\\Npcap\")");
}
}
/* Requires that win_pre_init() has already been called, also that
options processing has been done so that o.debugging is
available */
@@ -258,6 +285,7 @@ void win_init()
PMIB_IPADDRTABLE pIp = 0;
int i;
int numipsleft;
int pcap_driver;
init_dll_path();
@@ -284,6 +312,17 @@ void win_init()
o.have_pcap = true;
if(o.debugging > 2) printf("Trying to initialize WinPcap\n");
if (start_service("npcap"))
pcap_driver = PCAP_DRIVER_NPCAP;
else if (start_service("npf"))
pcap_driver = PCAP_DRIVER_WINPCAP;
else
pcap_driver = PCAP_DRIVER_NONE;
if (pcap_driver == PCAP_DRIVER_NPCAP)
init_npcap_dll_path();
pcapMutex = CreateMutex(NULL, 0, "Global\\DnetPcapHangAvoidanceMutex");
wait = WaitForSingleObject(pcapMutex, INFINITE);
PacketGetAdapterNames(pcaplist, &len);
@@ -306,7 +345,7 @@ void win_init()
--unprivileged. In that case don't bother them with a
potential UAC dialog when starting NPF. */
if (o.isr00t)
o.have_pcap = o.have_pcap && start_npf();
o.have_pcap = o.have_pcap && ((bool) pcap_driver);
}
#ifdef _MSC_VER
__except (1) {