From c1d16550dc2dce9387a9fbf2d3db2c1ffe013d75 Mon Sep 17 00:00:00 2001 From: dmiller Date: Wed, 28 Jan 2026 21:36:15 +0000 Subject: [PATCH] Consolidate and improve error checks for missing source MAC. See #2711 --- FPEngine.cc | 25 ++----------------------- Target.cc | 40 ++++++++++++++++++++++++++++++++++++++++ Target.h | 1 + idle_scan.cc | 8 ++------ libnetutil/netutil.cc | 4 ++-- osscan2.cc | 9 ++++----- scan_engine_raw.cc | 16 +++++++++------- traceroute.cc | 7 +------ 8 files changed, 61 insertions(+), 49 deletions(-) diff --git a/FPEngine.cc b/FPEngine.cc index e0a27f75a..15122695a 100644 --- a/FPEngine.cc +++ b/FPEngine.cc @@ -2493,29 +2493,8 @@ size_t FPPacket::getLength() const { * Otherwise, pass the source address, the next hop address and the name of * the network interface the packet should be injected through. */ int FPPacket::setEthernet(const Target *target) { - const char *devname = target->deviceName(); - this->link_eth = false; - if (devname != NULL) { - netutil_eth_t *ethsd = eth_open_cached(devname); - if (ethsd == NULL) { - error("%s: Failed to open ethernet device (%s)", __func__, devname); - } - else if (netutil_eth_can_send(ethsd)) { - this->link_eth = true; - Strncpy(this->eth_hdr.devname, devname, sizeof(this->eth_hdr.devname)); - if (netutil_eth_datalink(ethsd) == DLT_EN10MB){ - const u8 *src_mac = target->SrcMACAddress(); - const u8 *dst_mac = target->NextHopMACAddress(); - if (src_mac == NULL || dst_mac == NULL) { - this->link_eth = false; - } - else { - memcpy(this->eth_hdr.srcmac, src_mac, 6); - memcpy(this->eth_hdr.dstmac, dst_mac, 6); - } - } - } - } + eth_nfo *eth = target->FillEthNfo(&this->eth_hdr, NULL); + this->link_eth = (eth != NULL); if (!this->link_eth) { memset(&(this->eth_hdr), 0, sizeof(struct eth_nfo)); diff --git a/Target.cc b/Target.cc index 983679379..813f6e6b3 100644 --- a/Target.cc +++ b/Target.cc @@ -497,6 +497,46 @@ const u8 *Target::NextHopMACAddress() const { return (NextHopMACaddress_set)? NextHopMACaddress : NULL; } +eth_nfo *Target::FillEthNfo(eth_nfo *eth, netutil_eth_t *ethsd) const { + assert(eth != NULL); + const char *devname = this->deviceName(); + if (devname == NULL) { + return NULL; + } + if (ethsd == NULL) { + ethsd = eth_open_cached(devname); + } + else { + eth->ethsd = ethsd; + } + if (ethsd == NULL) { + error("%s: Failed to open device (%s)", __func__, devname); + return NULL; + } + if (!netutil_eth_can_send(ethsd)) { + error("%s: Cannot send on device (%s)", __func__, devname); + return NULL; + } + if (netutil_eth_datalink(ethsd) == DLT_EN10MB){ + const u8 *src_mac = this->SrcMACAddress(); + if (src_mac == NULL) { + error("%s: Cannot determine source MAC for %s", __func__, this->targetipstr()); + return NULL; + } + const u8 *dst_mac = this->NextHopMACAddress(); + if (dst_mac == NULL) { + error("%s: Cannot determine next hop MAC for %s", __func__, this->targetipstr()); + return NULL; + } + assert(eth->srcmac != NULL && eth->dstmac != NULL); + memcpy(eth->srcmac, src_mac, 6); + memcpy(eth->dstmac, dst_mac, 6); + } + + Strncpy(eth->devname, devname, sizeof(eth->devname)); + return eth; +} + int Target::osscanPerformed(void) const { return osscan_flag; } diff --git a/Target.h b/Target.h index 62b72d8df..5caf99542 100644 --- a/Target.h +++ b/Target.h @@ -237,6 +237,7 @@ class Target { const u8 *MACAddress() const; const u8 *SrcMACAddress() const; const u8 *NextHopMACAddress() const; + eth_nfo *FillEthNfo(eth_nfo *eth, netutil_eth_t *ethsd) const; /* Set the device names so that they can be returned by deviceName() and deviceFullName(). The normal name may not include alias diff --git a/idle_scan.cc b/idle_scan.cc index c8e608c35..483ba25b9 100644 --- a/idle_scan.cc +++ b/idle_scan.cc @@ -606,9 +606,7 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName, if (proxy->eth.ethsd != NULL) { if (!setTargetNextHopMAC(&proxy->host)) fatal("%s: Failed to determine dst MAC address for Idle proxy", __func__); - memcpy(proxy->eth.srcmac, proxy->host.SrcMACAddress(), 6); - memcpy(proxy->eth.dstmac, proxy->host.NextHopMACAddress(), 6); - proxy->ethptr = &proxy->eth; + proxy->ethptr = proxy->host.FillEthNfo(&proxy->eth, proxy->eth.ethsd); } else { unblock_socket(proxy->rawsd); @@ -1000,10 +998,8 @@ static int idlescan_countopen2(struct idle_proxy_info *proxy, if (proxy->rawsd < 0) { if (!setTargetNextHopMAC(target)) fatal("%s: Failed to determine dst MAC address for Idle proxy", __func__); - memcpy(eth.srcmac, target->SrcMACAddress(), 6); - memcpy(eth.dstmac, target->NextHopMACAddress(), 6); eth.ethsd = eth_open_cached(target->deviceName()); - if (eth.ethsd == NULL) + if (eth.ethsd == NULL || target->FillEthNfo(ð, eth.ethsd) == NULL) fatal("%s: Failed to open ethernet device (%s)", __func__, target->deviceName()); } else eth.ethsd = NULL; diff --git a/libnetutil/netutil.cc b/libnetutil/netutil.cc index 830bf4c92..d17a0759a 100644 --- a/libnetutil/netutil.cc +++ b/libnetutil/netutil.cc @@ -1168,7 +1168,6 @@ int raw_socket_or_eth(int sendpref, const char *ifname, devtype iftype, try_ip = may_try_ip; netutil_eth_t *e = eth_open_cached(ifname); - *ethsd = e; if (e == NULL) { netutil_error("dnet: failed to open device %s", ifname); } @@ -1177,6 +1176,7 @@ int raw_socket_or_eth(int sendpref, const char *ifname, devtype iftype, e = NULL; } else { + *ethsd = e; break; } } @@ -1194,8 +1194,8 @@ int raw_socket_or_eth(int sendpref, const char *ifname, devtype iftype, } #endif int sd = netutil_raw_socket(ifname); - *rawsd = sd; if (sd >= 0) { + *rawsd = sd; break; } } diff --git a/osscan2.cc b/osscan2.cc index 0ba59c132..788d1ab17 100644 --- a/osscan2.cc +++ b/osscan2.cc @@ -1176,12 +1176,11 @@ struct eth_nfo *HostOsScanStats::fill_eth_nfo(struct eth_nfo *eth, netutil_eth_t if (ethsd == NULL) return NULL; - if (netutil_eth_datalink(ethsd) == DLT_EN10MB) { - memcpy(eth->srcmac, target->SrcMACAddress(), sizeof(eth->srcmac)); - memcpy(eth->dstmac, target->NextHopMACAddress(), sizeof(eth->dstmac)); + eth = target->FillEthNfo(eth, ethsd); + if (eth) { + eth->ethsd = ethsd; + eth->devname[0] = '\0'; } - eth->ethsd = ethsd; - eth->devname[0] = '\0'; return eth; } diff --git a/scan_engine_raw.cc b/scan_engine_raw.cc index 97ebe13e4..e0b0f2a16 100644 --- a/scan_engine_raw.cc +++ b/scan_engine_raw.cc @@ -970,12 +970,19 @@ UltraProbe *sendNDScanProbe(UltraScanInfo *USI, HostScanStats *hss, if (USI->ethsd) { if (netutil_eth_datalink(USI->ethsd) == DLT_EN10MB) { + const u8 *src_mac = hss->target->SrcMACAddress(); + if (src_mac) { + memcpy(eth.srcmac, src_mac, 6); + } + else { + error("%s: Cannot determine source MAC for %s", __func__, + hss->target->targetipstr()); + } unsigned char ns_dst_mac[6] = {0x33, 0x33, 0xff}; ns_dst_mac[3] = ns_dst_ip6.s6_addr[13]; ns_dst_mac[4] = ns_dst_ip6.s6_addr[14]; ns_dst_mac[5] = ns_dst_ip6.s6_addr[15]; - memcpy(eth.srcmac, hss->target->SrcMACAddress(), 6); memcpy(eth.dstmac, ns_dst_mac, 6); } eth.ethsd = USI->ethsd; @@ -1161,13 +1168,8 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss, u16 icmp_ident = (get_random_u16() % 0xffff) + 1; if (USI->ethsd) { - if (netutil_eth_datalink(USI->ethsd) == DLT_EN10MB) { - memcpy(eth.srcmac, hss->target->SrcMACAddress(), 6); - memcpy(eth.dstmac, hss->target->NextHopMACAddress(), 6); - } - eth.ethsd = USI->ethsd; + ethptr = hss->target->FillEthNfo(ð, USI->ethsd); eth.devname[0] = '\0'; - ethptr = ð } if (o.magic_port_set) diff --git a/traceroute.cc b/traceroute.cc index e68c43162..eae28f31a 100644 --- a/traceroute.cc +++ b/traceroute.cc @@ -596,13 +596,8 @@ void Probe::send(int rawsd, netutil_eth_t *ethsd, struct timeval *now) { /* Set up the Ethernet handle if we're using that. */ if (ethsd != NULL) { - if (netutil_eth_datalink(ethsd) == DLT_EN10MB) { - memcpy(eth.srcmac, host->target->SrcMACAddress(), 6); - memcpy(eth.dstmac, host->target->NextHopMACAddress(), 6); - } - eth.ethsd = ethsd; + ethp = host->target->FillEthNfo(ð, ethsd); eth.devname[0] = '\0'; - ethp = ð } else { ethp = NULL; }