mirror of
https://github.com/nmap/nmap.git
synced 2025-12-07 13:11:28 +00:00
Allow layer-2 sending for non-Ethernet links; MAC addr optional
This commit is contained in:
69
FPEngine.cc
69
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].host = this;
|
||||||
this->fp_probes[this->total_probes].setPacket(ip6);
|
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].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. */
|
/* Mark as a timed probe. */
|
||||||
this->fp_probes[this->total_probes].setTimed();
|
this->fp_probes[this->total_probes].setTimed();
|
||||||
this->timed_probes++;
|
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].host = this;
|
||||||
this->fp_probes[this->total_probes].setPacket(ip6);
|
this->fp_probes[this->total_probes].setPacket(ip6);
|
||||||
this->fp_probes[this->total_probes].setProbeID("IE1");
|
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++;
|
this->total_probes++;
|
||||||
|
|
||||||
/* ICMP Probe #2: Echo Request with badly ordered extension headers */
|
/* 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].host = this;
|
||||||
this->fp_probes[this->total_probes].setPacket(ip6);
|
this->fp_probes[this->total_probes].setPacket(ip6);
|
||||||
this->fp_probes[this->total_probes].setProbeID("IE2");
|
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++;
|
this->total_probes++;
|
||||||
|
|
||||||
/* ICMP Probe #3: Neighbor Solicitation. (only sent to on-link targets) */
|
/* 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].host = this;
|
||||||
this->fp_probes[this->total_probes].setPacket(ip6);
|
this->fp_probes[this->total_probes].setPacket(ip6);
|
||||||
this->fp_probes[this->total_probes].setProbeID("NS");
|
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++;
|
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].host = this;
|
||||||
this->fp_probes[this->total_probes].setPacket(ip6);
|
this->fp_probes[this->total_probes].setPacket(ip6);
|
||||||
this->fp_probes[this->total_probes].setProbeID("U1");
|
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++;
|
this->total_probes++;
|
||||||
|
|
||||||
/* Set TECN probe */
|
/* 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].host = this;
|
||||||
this->fp_probes[this->total_probes].setPacket(ip6);
|
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].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++;
|
this->total_probes++;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
@@ -1904,7 +1916,9 @@ int FPHost6::build_probe_list() {
|
|||||||
this->fp_probes[this->total_probes].host = this;
|
this->fp_probes[this->total_probes].host = this;
|
||||||
this->fp_probes[this->total_probes].setPacket(ip6);
|
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].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++;
|
this->total_probes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2491,22 +2505,33 @@ size_t FPPacket::getLength() const {
|
|||||||
* values, like this: instance.setEthernet(NULL, NULL, NULL);
|
* values, like this: instance.setEthernet(NULL, NULL, NULL);
|
||||||
* Otherwise, pass the source address, the next hop address and the name of
|
* Otherwise, pass the source address, the next hop address and the name of
|
||||||
* the network interface the packet should be injected through. */
|
* the network interface the packet should be injected through. */
|
||||||
int FPPacket::setEthernet(const u8 *src_mac, const u8 *dst_mac, const char *devname) {
|
int FPPacket::setEthernet(const Target *target) {
|
||||||
if (src_mac == NULL || dst_mac == NULL) {
|
const char *devname = target->deviceName();
|
||||||
memset(&(this->eth_hdr), 0, sizeof(struct eth_nfo));
|
this->link_eth = false;
|
||||||
this->link_eth = false;
|
|
||||||
return OP_FAILURE;
|
|
||||||
}
|
|
||||||
memcpy(this->eth_hdr.srcmac, src_mac, 6);
|
|
||||||
memcpy(this->eth_hdr.dstmac, dst_mac, 6);
|
|
||||||
this->link_eth = true;
|
|
||||||
if (devname != NULL) {
|
if (devname != NULL) {
|
||||||
strncpy(this->eth_hdr.devname, devname, sizeof(this->eth_hdr.devname)-1);
|
netutil_eth_t *ethsd = eth_open_cached(devname);
|
||||||
if ((this->eth_hdr.ethsd = eth_open_cached(devname)) == NULL)
|
if (ethsd == NULL) {
|
||||||
fatal("%s: Failed to open ethernet device (%s)", __func__, devname);
|
error("%s: Failed to open ethernet device (%s)", __func__, devname);
|
||||||
} else {
|
}
|
||||||
this->eth_hdr.devname[0] = '\0';
|
else if (netutil_eth_can_send(ethsd)) {
|
||||||
this->eth_hdr.ethsd = NULL;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->link_eth) {
|
||||||
|
memset(&(this->eth_hdr), 0, sizeof(struct eth_nfo));
|
||||||
|
return OP_FAILURE;
|
||||||
}
|
}
|
||||||
return OP_SUCCESS;
|
return OP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,7 +167,8 @@ class FPNetworkControl {
|
|||||||
void response_reception_handler(nsock_pool nsp, nsock_event nse, void *arg);
|
void response_reception_handler(nsock_pool nsp, nsock_event nse, void *arg);
|
||||||
bool request_slots(size_t num_packets);
|
bool request_slots(size_t num_packets);
|
||||||
int cc_report_final_timeout();
|
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);
|
int setTime(const struct timeval *tv = NULL);
|
||||||
struct timeval getTime() const;
|
struct timeval getTime() const;
|
||||||
int setPacket(PacketElement *pkt);
|
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 struct eth_nfo *getEthernet() const;
|
||||||
const PacketElement *getPacket() const;
|
const PacketElement *getPacket() const;
|
||||||
size_t getLength() 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
|
aren't doing a TCP connect scan, or if we're doing a ping scan that
|
||||||
requires it. */
|
requires it. */
|
||||||
if (isRawScan()) {
|
if (isRawScan()) {
|
||||||
if (ping_scan_arp || (ping_scan_nd && o.sendpref != PACKET_SEND_IP_STRONG) || ((o.sendpref & PACKET_SEND_ETH) &&
|
const char *device = Targets[0]->deviceName();
|
||||||
(Targets[0]->ifType() == devt_ethernet
|
if (ping_scan_arp || (ping_scan_nd && o.sendpref != PACKET_SEND_IP_STRONG) || (o.sendpref & PACKET_SEND_ETH)) {
|
||||||
#ifdef WIN32
|
|
||||||
|| (Targets[0]->ifType() == devt_loopback)
|
|
||||||
#endif
|
|
||||||
))) {
|
|
||||||
/* We'll send ethernet packets with dnet */
|
/* We'll send ethernet packets with dnet */
|
||||||
ethsd = eth_open_cached(Targets[0]->deviceName());
|
ethsd = eth_open_cached(device);
|
||||||
if (ethsd == NULL)
|
if (ethsd == NULL) {
|
||||||
fatal("dnet: Failed to open device %s", Targets[0]->deviceName());
|
error("dnet: Failed to open device %s", device);
|
||||||
rawsd = -1;
|
}
|
||||||
} else {
|
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
|
#ifdef WIN32
|
||||||
win32_fatal_raw_sockets(Targets[0]->deviceName());
|
win32_fatal_raw_sockets(Targets[0]->deviceName());
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -969,13 +969,15 @@ UltraProbe *sendNDScanProbe(UltraScanInfo *USI, HostScanStats *hss,
|
|||||||
ns_dst_ip6 = *hss->target->v6hostip();
|
ns_dst_ip6 = *hss->target->v6hostip();
|
||||||
|
|
||||||
if (USI->ethsd) {
|
if (USI->ethsd) {
|
||||||
unsigned char ns_dst_mac[6] = {0x33, 0x33, 0xff};
|
if (netutil_eth_datalink(USI->ethsd) == DLT_EN10MB) {
|
||||||
ns_dst_mac[3] = ns_dst_ip6.s6_addr[13];
|
unsigned char ns_dst_mac[6] = {0x33, 0x33, 0xff};
|
||||||
ns_dst_mac[4] = ns_dst_ip6.s6_addr[14];
|
ns_dst_mac[3] = ns_dst_ip6.s6_addr[13];
|
||||||
ns_dst_mac[5] = ns_dst_ip6.s6_addr[15];
|
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.srcmac, hss->target->SrcMACAddress(), 6);
|
||||||
memcpy(eth.dstmac, ns_dst_mac, 6);
|
memcpy(eth.dstmac, ns_dst_mac, 6);
|
||||||
|
}
|
||||||
eth.ethsd = USI->ethsd;
|
eth.ethsd = USI->ethsd;
|
||||||
eth.devname[0] = '\0';
|
eth.devname[0] = '\0';
|
||||||
ethptr = ð
|
ethptr = ð
|
||||||
@@ -1159,8 +1161,10 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
|
|||||||
u16 icmp_ident = (get_random_u16() % 0xffff) + 1;
|
u16 icmp_ident = (get_random_u16() % 0xffff) + 1;
|
||||||
|
|
||||||
if (USI->ethsd) {
|
if (USI->ethsd) {
|
||||||
memcpy(eth.srcmac, hss->target->SrcMACAddress(), 6);
|
if (netutil_eth_datalink(USI->ethsd) == DLT_EN10MB) {
|
||||||
memcpy(eth.dstmac, hss->target->NextHopMACAddress(), 6);
|
memcpy(eth.srcmac, hss->target->SrcMACAddress(), 6);
|
||||||
|
memcpy(eth.dstmac, hss->target->NextHopMACAddress(), 6);
|
||||||
|
}
|
||||||
eth.ethsd = USI->ethsd;
|
eth.ethsd = USI->ethsd;
|
||||||
eth.devname[0] = '\0';
|
eth.devname[0] = '\0';
|
||||||
ethptr = ð
|
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. */
|
/* Set up the Ethernet handle if we're using that. */
|
||||||
if (ethsd != NULL) {
|
if (ethsd != NULL) {
|
||||||
memcpy(eth.srcmac, host->target->SrcMACAddress(), 6);
|
if (netutil_eth_datalink(ethsd) == DLT_EN10MB) {
|
||||||
memcpy(eth.dstmac, host->target->NextHopMACAddress(), 6);
|
memcpy(eth.srcmac, host->target->SrcMACAddress(), 6);
|
||||||
|
memcpy(eth.dstmac, host->target->NextHopMACAddress(), 6);
|
||||||
|
}
|
||||||
eth.ethsd = ethsd;
|
eth.ethsd = ethsd;
|
||||||
eth.devname[0] = '\0';
|
eth.devname[0] = '\0';
|
||||||
ethp = ð
|
ethp = ð
|
||||||
|
|||||||
Reference in New Issue
Block a user