1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-22 23:49:03 +00:00

Make getNextHopMAC do ND when the dest is IPv6.

This is what setTargetNextHopMAC already did, but the code change was
not copied here. This provided a way for NSE scripts to cause an
assertion failure:

local math = require "math"
local packet = require "packet"
function portrule(host, port)
  return port.protocol == "udp"
end
function action(host, port)
  local ip_raw = bin.pack("H", "60000000000d11ff")
    .. host.bin_ip_src .. host.bin_ip
    .. bin.pack(">S", math.random(32768, 65535)) .. bin.pack(">S",
port.number)
    .. bin.pack("H", "000d8082") .. "hello"
  local p = packet.Packet:new(ip_raw, #ip_raw)
  p:udp_count_checksum()
  local s = nmap.new_dnet()
  s:ip_open()
  s:ip_send(p.buf)
end

This would fail with the message "doArp can only handle IPv4 addresses"
when ip_send called getNextHopMAC. (Only with --send-eth.)
This commit is contained in:
david
2012-09-15 14:57:34 +00:00
parent 6d0e34ad7b
commit 271045501f

View File

@@ -1967,11 +1967,11 @@ bool getNextHopMAC(const char *iface, const u8 *srcmac, const struct sockaddr_st
arp_t *a; arp_t *a;
struct arp_entry ae; struct arp_entry ae;
/* Nmap's ARP cache */ /* First, let us check the Nmap arp cache ... */
if (mac_cache_get(dstss, dstmac)) if (mac_cache_get(dstss, dstmac))
return true; return true;
/* System ARP cache */ /* Maybe the system ARP cache will be more helpful */
a = arp_open(); a = arp_open();
addr_ston((sockaddr *) dstss, &ae.arp_pa); addr_ston((sockaddr *) dstss, &ae.arp_pa);
if (arp_get(a, &ae) == 0) { if (arp_get(a, &ae) == 0) {
@@ -1982,10 +1982,18 @@ bool getNextHopMAC(const char *iface, const u8 *srcmac, const struct sockaddr_st
} }
arp_close(a); arp_close(a);
/* Send ARP */ /* OK, the last choice is to send our own damn ARP request (and
if (doArp(iface, srcmac, srcss, dstss, dstmac, PacketTrace::traceArp)) { retransmissions if necessary) to determine the MAC */
mac_cache_set(dstss, dstmac); if (dstss->ss_family == AF_INET) {
return true; if (doArp(iface, srcmac, srcss, dstss, dstmac, PacketTrace::traceArp)) {
mac_cache_set(dstss, dstmac);
return true;
}
} else if (dstss->ss_family == AF_INET6) {
if (doND(iface, srcmac, srcss, dstss, dstmac, PacketTrace::traceND)) {
mac_cache_set(dstss, dstmac);
return true;
}
} }
return false; return false;