diff --git a/FPEngine.cc b/FPEngine.cc index 14423044f..2d788d8f3 100644 --- a/FPEngine.cc +++ b/FPEngine.cc @@ -118,7 +118,7 @@ FPNetworkControl::~FPNetworkControl() { /* (Re)-Initialize object's state (default parameter setup and nsock * initialization). */ -void FPNetworkControl::init(const char *ifname) { +void FPNetworkControl::init(const char *ifname, devtype iftype) { /* Init congestion control parameters */ this->cc_init(); @@ -161,7 +161,7 @@ void FPNetworkControl::init(const char *ifname) { netutil_eth_t *ethsd = NULL; /* Obtain raw socket or check that we can obtain an eth descriptor. */ - if (!raw_socket_or_eth(o.sendpref, ifname, &this->rawsd, ðsd)) { + if (!raw_socket_or_eth(o.sendpref, ifname, iftype, &this->rawsd, ðsd)) { fatal("Couldn't obtain raw socket or eth handle in %s", __func__); } @@ -1122,7 +1122,7 @@ int FPEngine6::os_scan(std::vector &Targets) { /* Initialize variables, timers, etc. */ gettimeofday(&begin_time, NULL); - global_netctl.init(Targets[0]->deviceName()); + global_netctl.init(Targets[0]->deviceName(), Targets[0]->ifType()); for (size_t i = 0; i < Targets.size(); i++) { if (o.debugging > 3) { log_write(LOG_PLAIN, "[FPEngine] Allocating FPHost6 for %s %s\n", @@ -2511,6 +2511,7 @@ int FPPacket::setEthernet(const Target *target) { else { memcpy(this->eth_hdr.srcmac, src_mac, 6); memcpy(this->eth_hdr.dstmac, dst_mac, 6); + Strncpy(this->eth_hdr.devname, devname, sizeof(this->eth_hdr.devname)); } } } diff --git a/FPEngine.h b/FPEngine.h index 4dd6c2bd2..e489534d9 100644 --- a/FPEngine.h +++ b/FPEngine.h @@ -157,7 +157,7 @@ class FPNetworkControl { public: FPNetworkControl(); ~FPNetworkControl(); - void init(const char *ifname); + void init(const char *ifname, devtype iftype); int register_caller(FPHost *newcaller); int unregister_caller(FPHost *oldcaller); int setup_sniffer(const char *iface, const char *bfp_filter); diff --git a/idle_scan.cc b/idle_scan.cc index 14139c887..c8e608c35 100644 --- a/idle_scan.cc +++ b/idle_scan.cc @@ -599,7 +599,7 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName, /* Now lets send some probes to check IP ID algorithm ... */ /* First we need a raw socket ... */ - if (!raw_socket_or_eth(o.sendpref, proxy->host.deviceName(), + if (!raw_socket_or_eth(o.sendpref, proxy->host.deviceName(), proxy->host.ifType(), &proxy->rawsd, &proxy->eth.ethsd)) { fatal("%s: Failed to open raw socket or ethernet handle", __func__); } diff --git a/libnetutil/netutil.cc b/libnetutil/netutil.cc index 7819de50c..166582568 100644 --- a/libnetutil/netutil.cc +++ b/libnetutil/netutil.cc @@ -1128,12 +1128,21 @@ int netutil_raw_socket(const char *device) { #endif } -int raw_socket_or_eth(int sendpref, const char *ifname, +int raw_socket_or_eth(int sendpref, const char *ifname, devtype iftype, int *rawsd, netutil_eth_t **ethsd) { assert(rawsd != NULL); *rawsd = -1; assert(ethsd != NULL); *ethsd = NULL; + +#ifndef WIN32 + /* In general, on Windows we need to use Ether headers. + * On other platforms, avoid it. */ + if (iftype != devt_ethernet) { + sendpref = PACKET_SEND_IP; + } +#endif + bool may_try_eth = ifname && !(sendpref & PACKET_SEND_IP_STRONG); bool may_try_ip = !(sendpref & PACKET_SEND_ETH_STRONG); bool try_eth = may_try_eth && (sendpref & PACKET_SEND_ETH); diff --git a/libnetutil/netutil.h b/libnetutil/netutil.h index 3816570d1..e338d269a 100644 --- a/libnetutil/netutil.h +++ b/libnetutil/netutil.h @@ -330,7 +330,7 @@ int netutil_raw_socket(const char *device); #define PACKET_SEND_IP_WEAK 0x08 #define PACKET_SEND_IP_STRONG 0x10 #define PACKET_SEND_IP (PACKET_SEND_IP_WEAK | PACKET_SEND_IP_STRONG) -int raw_socket_or_eth(int sendpref, const char *ifname, +int raw_socket_or_eth(int sendpref, const char *ifname, devtype iftype, int *rawsd, netutil_eth_t **ethsd); /* Takes a protocol number like IPPROTO_TCP, IPPROTO_UDP, or diff --git a/osscan2.cc b/osscan2.cc index 292a76184..0ba59c132 100644 --- a/osscan2.cc +++ b/osscan2.cc @@ -1176,8 +1176,10 @@ struct eth_nfo *HostOsScanStats::fill_eth_nfo(struct eth_nfo *eth, netutil_eth_t if (ethsd == NULL) return NULL; - memcpy(eth->srcmac, target->SrcMACAddress(), sizeof(eth->srcmac)); - memcpy(eth->dstmac, target->NextHopMACAddress(), sizeof(eth->srcmac)); + if (netutil_eth_datalink(ethsd) == DLT_EN10MB) { + memcpy(eth->srcmac, target->SrcMACAddress(), sizeof(eth->srcmac)); + memcpy(eth->dstmac, target->NextHopMACAddress(), sizeof(eth->dstmac)); + } eth->ethsd = ethsd; eth->devname[0] = '\0'; @@ -1335,8 +1337,9 @@ HostOsScan::HostOsScan(Target *t) { pd = NULL; rawsd = -1; ethsd = NULL; + int sendpref = o.sendpref; - if (!raw_socket_or_eth(o.sendpref, t->deviceName(), &rawsd, ðsd)) { + if (!raw_socket_or_eth(sendpref, t->deviceName(), t->ifType(), &rawsd, ðsd)) { fatal("%s: Failed to open raw socket or ethernet device", __func__); } if (rawsd >= 0) diff --git a/scan_engine.cc b/scan_engine.cc index 2087202cb..76ef6b6c7 100644 --- a/scan_engine.cc +++ b/scan_engine.cc @@ -956,14 +956,8 @@ void UltraScanInfo::Init(std::vector &Targets, const struct scan_lists assert(!(sendpref & PACKET_SEND_IP_STRONG)); sendpref = PACKET_SEND_ETH; } -#ifndef WIN32 - /* Windows does loopback via Npcap (eth), - * but we want to avoid that for everyone else. */ - if (Targets[0]->ifType() == devt_loopback) { - sendpref = PACKET_SEND_IP; - } -#endif - if (!raw_socket_or_eth(sendpref, Targets[0]->deviceName(), &rawsd, ðsd)) { + if (!raw_socket_or_eth(sendpref, Targets[0]->deviceName(), Targets[0]->ifType(), + &rawsd, ðsd)) { fatal("Couldn't open a raw socket or eth handle."); } /* Raw scan types also need to know the source IP. */ diff --git a/traceroute.cc b/traceroute.cc index affaa6663..e68c43162 100644 --- a/traceroute.cc +++ b/traceroute.cc @@ -837,7 +837,8 @@ TracerouteState::TracerouteState(std::vector &targets) { assert(targets.size() > 0); - if (!raw_socket_or_eth(o.sendpref, targets[0]->deviceName(), &rawsd, ðsd)) { + if (!raw_socket_or_eth(o.sendpref, targets[0]->deviceName(), targets[0]->ifType(), + &rawsd, ðsd)) { fatal("traceroute: socket troubles"); }