diff --git a/idle_scan.cc b/idle_scan.cc index 492186a9a..927f98ea2 100644 --- a/idle_scan.cc +++ b/idle_scan.cc @@ -378,7 +378,7 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName, memcpy(proxy->eth.dstmac, proxy->host.NextHopMACAddress(), 6); proxy->eth.ethsd = eth_open_cached(proxy->host.deviceName()); if (proxy->eth.ethsd == NULL) - fatal("%s: Failed to open ethernet device (%s)", __func__, proxy->host.deviceName()); + fatal_eth_open_failure(__func__, proxy->host.deviceName()); proxy->rawsd = -1; proxy->ethptr = &proxy->eth; } else { @@ -682,7 +682,7 @@ static int idlescan_countopen2(struct idle_proxy_info *proxy, memcpy(eth.dstmac, target->NextHopMACAddress(), 6); eth.ethsd = eth_open_cached(target->deviceName()); if (eth.ethsd == NULL) - fatal("%s: Failed to open ethernet device (%s)", __func__, target->deviceName()); + fatal_eth_open_failure(__func__, target->deviceName()); } else eth.ethsd = NULL; /* I start by sending out the SYN pr0bez */ diff --git a/nmap_error.cc b/nmap_error.cc index 082059a47..b8b33baaf 100644 --- a/nmap_error.cc +++ b/nmap_error.cc @@ -199,3 +199,26 @@ void gh_perror(const char *err, ...) { fflush(stderr); return; } + +/* Report a failure to open an Ethernet device and exit through fatal. On + Windows, shows a hint about privileges. */ +void fatal_eth_open_failure(const char *func, const char *devname) { +#if WIN32 + error("\ +On Windows, this problem can be caused by a lack of privileges under\n\ +User Account Control (UAC). Start an elevated command prompt by\n\ +right-clicking on the command prompt shortcut and selecting \"Run as\n\ +Administrator\". Then enter the command\n\ +\n\ + net start npf\n\ +\n\ +This will load the Netgroup Packet Filter (NPF) service and allow Nmap\n\ +to run. Running Nmap or Zenmap under \"Run as Administrator\" also has\n\ +the side effect of loading NPF.\n\ +\n\ +You should have to do this only once per reboot. If you're not able to\n\ +do any of these things, try the --unprivileged option to avoid the use\n\ +of any raw network operations.\n"); +#endif + fatal("%s: Failed to open ethernet device (%s)", func, devname); \ +} diff --git a/nmap_error.h b/nmap_error.h index 0e93771df..2cf39aeed 100644 --- a/nmap_error.h +++ b/nmap_error.h @@ -130,6 +130,8 @@ void pfatal(const char *err, ...) void gh_perror(const char *err, ...) __attribute__ ((format (printf, 1, 2))); +void fatal_eth_open_failure(const char *func, const char *devname); + #ifdef __cplusplus } #endif diff --git a/nse_nsock.cc b/nse_nsock.cc index 90b0cbfaf..f801495e4 100644 --- a/nse_nsock.cc +++ b/nse_nsock.cc @@ -1980,7 +1980,7 @@ eth_t *ldnet_eth_open_cached(const char *device) dem = (dnet_eth_map *) safe_zalloc(sizeof(dnet_eth_map)); dem->eth = eth_open(device); if (!dem->eth) - fatal("Unable to open dnet on ethernet interface %s", device); + fatal_eth_open_failure(__func__, device); dem->references = 1; dnet_eth_cache[key] = dem; return dem->eth; diff --git a/osscan2.cc b/osscan2.cc index 812a669c9..d8ea105d9 100644 --- a/osscan2.cc +++ b/osscan2.cc @@ -926,7 +926,7 @@ HostOsScan::HostOsScan(Target *t) { if ((o.sendpref & PACKET_SEND_ETH) && t->ifType() == devt_ethernet) { if ((ethsd = eth_open_cached(t->deviceName())) == NULL) - fatal("%s: Failed to open ethernet device (%s)", __func__, t->deviceName()); + fatal_eth_open_failure(__func__, t->deviceName()); rawsd = -1; } else { /* Init our raw socket */ diff --git a/scan_engine.cc b/scan_engine.cc index 98817890f..ee98c71e0 100644 --- a/scan_engine.cc +++ b/scan_engine.cc @@ -1616,7 +1616,7 @@ void UltraScanInfo::Init(vector &Targets, struct scan_lists *pts, styp /* We'll send ethernet packets with dnet */ ethsd = eth_open_cached(Targets[0]->deviceName()); if (ethsd == NULL) - fatal("dnet: Failed to open device %s", Targets[0]->deviceName()); + fatal_eth_open_failure(__func__, Targets[0]->deviceName()); rawsd = -1; } else { /* Initialize a raw socket */ diff --git a/tcpip.cc b/tcpip.cc index 8fb7d0494..271a3988e 100644 --- a/tcpip.cc +++ b/tcpip.cc @@ -1459,7 +1459,7 @@ static int send_ip_packet_eth(struct eth_nfo *eth, u8 *packet, unsigned int pack if (!eth->ethsd) { ethsd = eth_open_cached(eth->devname); if (!ethsd) - fatal("%s: Failed to open ethernet device (%s)", __func__, eth->devname); + fatal_eth_open_failure(__func__, eth->devname); } else { ethsd = eth->ethsd; } @@ -2717,7 +2717,7 @@ static bool doArp(const char *dev, const u8 *srcmac, /* Prepare probe and sending stuff */ ethsd = eth_open_cached(dev); if (!ethsd) - fatal("%s: failed to open device %s", __func__, dev); + fatal_eth_open_failure(__func__, dev); eth_pack_hdr(frame, ETH_ADDR_BROADCAST, *srcmac, ETH_TYPE_ARP); arp_pack_hdr_ethip(frame + ETH_HDR_LEN, ARP_OP_REQUEST, *srcmac, srcsin->sin_addr, ETH_ADDR_BROADCAST, diff --git a/traceroute.cc b/traceroute.cc index 787414ccb..1b493579f 100644 --- a/traceroute.cc +++ b/traceroute.cc @@ -764,7 +764,7 @@ TracerouteState::TracerouteState(std::vector &targets) { if ((o.sendpref & PACKET_SEND_ETH) && targets[0]->ifType() == devt_ethernet) { ethsd = eth_open_cached(targets[0]->deviceName()); if (ethsd == NULL) - fatal("dnet: failed to open device %s", targets[0]->deviceName()); + fatal_eth_open_failure(__func__, targets[0]->deviceName()); rawsd = -1; } else { #ifdef WIN32