1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-03 05:09:14 +00:00

Set source and destination interfaces as rtattrs.

Scans using the -e option could use the correct interface but the wrong
source address.

Thanks to Taburiss S for the report and John Bond for help debugging.
http://seclists.org/nmap-dev/2013/q1/269
http://seclists.org/nmap-dev/2013/q1/327
This commit is contained in:
david
2013-03-08 05:35:07 +00:00
parent 96d9d6fc51
commit 39687a80b1

View File

@@ -3023,20 +3023,25 @@ static int set_sockaddr(struct sockaddr_storage *ss, int af, void *data) {
/* Add rtattrs to a netlink message specifying a source or destination address.
rta_type must be RTA_SRC or RTA_DST. This function adds either 1 or 2
rtattrs: it always adds either an RTA_SRC or RTA_DST, depending on rta_type.
It also adds either RTA_IIF or RTA_OIF if the address family is AF_INET6 and
the sockaddr_in6 has a non-zero sin6_scope_id. */
If ifindex is not 0, it is the index of the interface to use. The function
adds either RTA_OIF if rta_type is RTA_DST, and either of ifindex and
sin6_scope_id is nonzero. */
static void add_rtattr_addr(struct nlmsghdr *nlmsg,
struct rtattr **rtattr, unsigned int *len,
unsigned char rta_type,
const struct sockaddr_storage *ss) {
const struct sockaddr_storage *ss,
int ifindex) {
struct rtmsg *rtmsg;
const void *addr;
size_t addrlen;
int ifindex;
assert(rta_type == RTA_SRC || rta_type == RTA_DST);
ifindex = 0;
if (rta_type == RTA_SRC) {
/* Ignore the interface specification if we are setting an RTA_SRC attribute
(it may still get set by the scope_id below). */
ifindex = 0;
}
if (ss->ss_family == AF_INET) {
addr = &((struct sockaddr_in *) ss)->sin_addr.s_addr;
@@ -3046,7 +3051,8 @@ static void add_rtattr_addr(struct nlmsghdr *nlmsg,
addr = sin6->sin6_addr.s6_addr;
addrlen = IP6_ADDR_LEN;
ifindex = sin6->sin6_scope_id;
if (ifindex == 0)
ifindex = sin6->sin6_scope_id;
} else {
netutil_fatal("%s: unknown address family %d", __func__, ss->ss_family);
}
@@ -3091,6 +3097,7 @@ static int route_dst_netlink(const struct sockaddr_storage *dst,
struct nlmsghdr *nlmsg;
struct rtmsg *rtmsg;
struct rtattr *rtattr;
int intf_index;
unsigned char buf[512];
unsigned int len;
int fd, rc;
@@ -3106,6 +3113,16 @@ static int route_dst_netlink(const struct sockaddr_storage *dst,
if (rc == -1)
netutil_fatal("%s: cannot bind AF_NETLINK socket: %s", __func__, strerror(errno));
struct interface_info *ii;
ii = NULL;
intf_index = 0;
if (device != NULL && device[0] != '\0') {
ii = getInterfaceByName(device, dst->ss_family);
if (ii == NULL)
netutil_fatal("Could not find interface %s which was specified by -e", device);
intf_index = ii->ifindex;
}
memset(buf, 0, sizeof(buf));
nlmsg = (struct nlmsghdr *) buf;
@@ -3122,10 +3139,10 @@ static int route_dst_netlink(const struct sockaddr_storage *dst,
len = sizeof(buf) - ((unsigned char *) RTM_RTA(rtmsg) - buf);
/* Add rtattrs for destination address and interface. */
add_rtattr_addr(nlmsg, &rtattr, &len, RTA_DST, dst);
add_rtattr_addr(nlmsg, &rtattr, &len, RTA_DST, dst, intf_index);
if (spoofss != NULL) {
/* Add rtattrs for source address and interface. */
add_rtattr_addr(nlmsg, &rtattr, &len, RTA_SRC, spoofss);
add_rtattr_addr(nlmsg, &rtattr, &len, RTA_SRC, spoofss, intf_index);
}
iov.iov_base = nlmsg;
@@ -3165,14 +3182,6 @@ static int route_dst_netlink(const struct sockaddr_storage *dst,
if (spoofss != NULL)
rnfo->srcaddr = *spoofss;
struct interface_info *ii;
ii = NULL;
if (device != NULL && device[0] != '\0') {
ii = getInterfaceByName(device, dst->ss_family);
if (ii == NULL)
netutil_fatal("Could not find interface %s which was specified by -e", device);
}
for (rtattr = RTM_RTA(rtmsg); RTA_OK(rtattr, len); rtattr = RTA_NEXT(rtattr, len)) {
if (rtattr->rta_type == RTA_GATEWAY) {
rc = set_sockaddr(&rnfo->nexthop, dst->ss_family, RTA_DATA(rtattr));