mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Allow layer-2 sending for non-Ethernet links; MAC addr optional
This commit is contained in:
63
FPEngine.cc
63
FPEngine.cc
@@ -1725,7 +1725,9 @@ int FPHost6::build_probe_list() {
|
||||
this->fp_probes[this->total_probes].host = this;
|
||||
this->fp_probes[this->total_probes].setPacket(ip6);
|
||||
this->fp_probes[this->total_probes].setProbeID(TCP_DESCS[i].id);
|
||||
this->fp_probes[this->total_probes].setEthernet(this->target_host->SrcMACAddress(), this->target_host->NextHopMACAddress(), this->target_host->deviceName());
|
||||
if (this->netctl->l2_frames()) {
|
||||
this->fp_probes[this->total_probes].setEthernet(this->target_host);
|
||||
}
|
||||
/* Mark as a timed probe. */
|
||||
this->fp_probes[this->total_probes].setTimed();
|
||||
this->timed_probes++;
|
||||
@@ -1766,7 +1768,9 @@ int FPHost6::build_probe_list() {
|
||||
this->fp_probes[this->total_probes].host = this;
|
||||
this->fp_probes[this->total_probes].setPacket(ip6);
|
||||
this->fp_probes[this->total_probes].setProbeID("IE1");
|
||||
this->fp_probes[this->total_probes].setEthernet(this->target_host->SrcMACAddress(), this->target_host->NextHopMACAddress(), this->target_host->deviceName());
|
||||
if (this->netctl->l2_frames()) {
|
||||
this->fp_probes[this->total_probes].setEthernet(this->target_host);
|
||||
}
|
||||
this->total_probes++;
|
||||
|
||||
/* ICMP Probe #2: Echo Request with badly ordered extension headers */
|
||||
@@ -1803,7 +1807,9 @@ int FPHost6::build_probe_list() {
|
||||
this->fp_probes[this->total_probes].host = this;
|
||||
this->fp_probes[this->total_probes].setPacket(ip6);
|
||||
this->fp_probes[this->total_probes].setProbeID("IE2");
|
||||
this->fp_probes[this->total_probes].setEthernet(this->target_host->SrcMACAddress(), this->target_host->NextHopMACAddress(), this->target_host->deviceName());
|
||||
if (this->netctl->l2_frames()) {
|
||||
this->fp_probes[this->total_probes].setEthernet(this->target_host);
|
||||
}
|
||||
this->total_probes++;
|
||||
|
||||
/* ICMP Probe #3: Neighbor Solicitation. (only sent to on-link targets) */
|
||||
@@ -1833,7 +1839,9 @@ int FPHost6::build_probe_list() {
|
||||
this->fp_probes[this->total_probes].host = this;
|
||||
this->fp_probes[this->total_probes].setPacket(ip6);
|
||||
this->fp_probes[this->total_probes].setProbeID("NS");
|
||||
this->fp_probes[this->total_probes].setEthernet(this->target_host->SrcMACAddress(), this->target_host->NextHopMACAddress(), this->target_host->deviceName());
|
||||
if (this->netctl->l2_frames()) {
|
||||
this->fp_probes[this->total_probes].setEthernet(this->target_host);
|
||||
}
|
||||
this->total_probes++;
|
||||
}
|
||||
|
||||
@@ -1862,7 +1870,9 @@ int FPHost6::build_probe_list() {
|
||||
this->fp_probes[this->total_probes].host = this;
|
||||
this->fp_probes[this->total_probes].setPacket(ip6);
|
||||
this->fp_probes[this->total_probes].setProbeID("U1");
|
||||
this->fp_probes[this->total_probes].setEthernet(this->target_host->SrcMACAddress(), this->target_host->NextHopMACAddress(), this->target_host->deviceName());
|
||||
if (this->netctl->l2_frames()) {
|
||||
this->fp_probes[this->total_probes].setEthernet(this->target_host);
|
||||
}
|
||||
this->total_probes++;
|
||||
|
||||
/* Set TECN probe */
|
||||
@@ -1879,7 +1889,9 @@ int FPHost6::build_probe_list() {
|
||||
this->fp_probes[this->total_probes].host = this;
|
||||
this->fp_probes[this->total_probes].setPacket(ip6);
|
||||
this->fp_probes[this->total_probes].setProbeID(TCP_DESCS[i].id);
|
||||
this->fp_probes[this->total_probes].setEthernet(this->target_host->SrcMACAddress(), this->target_host->NextHopMACAddress(), this->target_host->deviceName());
|
||||
if (this->netctl->l2_frames()) {
|
||||
this->fp_probes[this->total_probes].setEthernet(this->target_host);
|
||||
}
|
||||
this->total_probes++;
|
||||
}
|
||||
i++;
|
||||
@@ -1904,7 +1916,9 @@ int FPHost6::build_probe_list() {
|
||||
this->fp_probes[this->total_probes].host = this;
|
||||
this->fp_probes[this->total_probes].setPacket(ip6);
|
||||
this->fp_probes[this->total_probes].setProbeID(TCP_DESCS[i].id);
|
||||
this->fp_probes[this->total_probes].setEthernet(this->target_host->SrcMACAddress(), this->target_host->NextHopMACAddress(), this->target_host->deviceName());
|
||||
if (this->netctl->l2_frames()) {
|
||||
this->fp_probes[this->total_probes].setEthernet(this->target_host);
|
||||
}
|
||||
this->total_probes++;
|
||||
}
|
||||
|
||||
@@ -2491,22 +2505,33 @@ size_t FPPacket::getLength() const {
|
||||
* values, like this: instance.setEthernet(NULL, NULL, NULL);
|
||||
* 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 u8 *src_mac, const u8 *dst_mac, const char *devname) {
|
||||
if (src_mac == NULL || dst_mac == NULL) {
|
||||
memset(&(this->eth_hdr), 0, sizeof(struct eth_nfo));
|
||||
int FPPacket::setEthernet(const Target *target) {
|
||||
const char *devname = target->deviceName();
|
||||
this->link_eth = false;
|
||||
return OP_FAILURE;
|
||||
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;
|
||||
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);
|
||||
this->link_eth = true;
|
||||
if (devname != NULL) {
|
||||
strncpy(this->eth_hdr.devname, devname, sizeof(this->eth_hdr.devname)-1);
|
||||
if ((this->eth_hdr.ethsd = eth_open_cached(devname)) == NULL)
|
||||
fatal("%s: Failed to open ethernet device (%s)", __func__, devname);
|
||||
} else {
|
||||
this->eth_hdr.devname[0] = '\0';
|
||||
this->eth_hdr.ethsd = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->link_eth) {
|
||||
memset(&(this->eth_hdr), 0, sizeof(struct eth_nfo));
|
||||
return OP_FAILURE;
|
||||
}
|
||||
return OP_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -167,7 +167,8 @@ class FPNetworkControl {
|
||||
void response_reception_handler(nsock_pool nsp, nsock_event nse, void *arg);
|
||||
bool request_slots(size_t num_packets);
|
||||
int cc_report_final_timeout();
|
||||
|
||||
// Do we need to send l2 (ethernet) frames?
|
||||
bool l2_frames() { return (rawsd < 0); }
|
||||
};
|
||||
|
||||
/* +-----------+
|
||||
@@ -249,7 +250,7 @@ class FPPacket {
|
||||
int setTime(const struct timeval *tv = NULL);
|
||||
struct timeval getTime() const;
|
||||
int setPacket(PacketElement *pkt);
|
||||
int setEthernet(const u8 *src_mac, const u8 *dst_mac, const char *devname);
|
||||
int setEthernet(const Target *target);
|
||||
const struct eth_nfo *getEthernet() const;
|
||||
const PacketElement *getPacket() const;
|
||||
size_t getLength() const;
|
||||
|
||||
@@ -949,18 +949,23 @@ void UltraScanInfo::Init(std::vector<Target *> &Targets, const struct scan_lists
|
||||
aren't doing a TCP connect scan, or if we're doing a ping scan that
|
||||
requires it. */
|
||||
if (isRawScan()) {
|
||||
if (ping_scan_arp || (ping_scan_nd && o.sendpref != PACKET_SEND_IP_STRONG) || ((o.sendpref & PACKET_SEND_ETH) &&
|
||||
(Targets[0]->ifType() == devt_ethernet
|
||||
#ifdef WIN32
|
||||
|| (Targets[0]->ifType() == devt_loopback)
|
||||
#endif
|
||||
))) {
|
||||
const char *device = Targets[0]->deviceName();
|
||||
if (ping_scan_arp || (ping_scan_nd && o.sendpref != PACKET_SEND_IP_STRONG) || (o.sendpref & PACKET_SEND_ETH)) {
|
||||
/* 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());
|
||||
rawsd = -1;
|
||||
} else {
|
||||
ethsd = eth_open_cached(device);
|
||||
if (ethsd == NULL) {
|
||||
error("dnet: Failed to open device %s", device);
|
||||
}
|
||||
else if (!netutil_eth_can_send(ethsd)) {
|
||||
ethsd = NULL;
|
||||
}
|
||||
/* If eth failed, we can fall back to raw socket. The only exception is
|
||||
* ARP ping, which needs Ethernet link. */
|
||||
if (ping_scan_arp && (ethsd == NULL || netutil_eth_datalink(ethsd) != DLT_EN10MB)) {
|
||||
fatal("ARP ping not supported on %s", device);
|
||||
}
|
||||
}
|
||||
if (ethsd == NULL) {
|
||||
#ifdef WIN32
|
||||
win32_fatal_raw_sockets(Targets[0]->deviceName());
|
||||
#endif
|
||||
|
||||
@@ -969,6 +969,7 @@ UltraProbe *sendNDScanProbe(UltraScanInfo *USI, HostScanStats *hss,
|
||||
ns_dst_ip6 = *hss->target->v6hostip();
|
||||
|
||||
if (USI->ethsd) {
|
||||
if (netutil_eth_datalink(USI->ethsd) == DLT_EN10MB) {
|
||||
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];
|
||||
@@ -976,6 +977,7 @@ UltraProbe *sendNDScanProbe(UltraScanInfo *USI, HostScanStats *hss,
|
||||
|
||||
memcpy(eth.srcmac, hss->target->SrcMACAddress(), 6);
|
||||
memcpy(eth.dstmac, ns_dst_mac, 6);
|
||||
}
|
||||
eth.ethsd = USI->ethsd;
|
||||
eth.devname[0] = '\0';
|
||||
ethptr = ð
|
||||
@@ -1159,8 +1161,10 @@ 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;
|
||||
eth.devname[0] = '\0';
|
||||
ethptr = ð
|
||||
|
||||
@@ -596,8 +596,10 @@ 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;
|
||||
eth.devname[0] = '\0';
|
||||
ethp = ð
|
||||
|
||||
Reference in New Issue
Block a user