mirror of
https://github.com/nmap/nmap.git
synced 2025-12-28 02:19:04 +00:00
Make changes for IPv6-only interfaces on Solaris.
First try SIOCGLIFFLAGS with an IPv4 socket, then again with an IPv6 socket if that fails. Use that same socket for the other ioctl queries. Avoid adding an IPv6 alias address that is the same as an IPv6 primary address. This is the same as an existing check in the IPv4 case. Fix a loop exit boundary condition check.
This commit is contained in:
@@ -143,7 +143,7 @@ intf_open(void)
|
||||
setsockopt(intf->fd, SOL_SOCKET, SO_BROADCAST,
|
||||
(const char *) &one, sizeof(one));
|
||||
|
||||
#if defined(SIOCGIFNETMASK_IN6) || defined(SIOCGIFNETMASK6)
|
||||
#if defined(SIOCGLIFCONF) || defined(SIOCGIFNETMASK_IN6) || defined(SIOCGIFNETMASK6)
|
||||
if ((intf->fd6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
|
||||
# ifdef EPROTONOSUPPORT
|
||||
if (errno != EPROTONOSUPPORT)
|
||||
@@ -398,6 +398,7 @@ int
|
||||
_intf_get_noalias(intf_t *intf, struct intf_entry *entry)
|
||||
{
|
||||
struct lifreq lifr;
|
||||
int fd;
|
||||
|
||||
/* Get interface index. */
|
||||
entry->intf_index = if_nametoindex(entry->intf_name);
|
||||
@@ -406,8 +407,14 @@ _intf_get_noalias(intf_t *intf, struct intf_entry *entry)
|
||||
|
||||
strlcpy(lifr.lifr_name, entry->intf_name, sizeof(lifr.lifr_name));
|
||||
|
||||
/* Get interface flags. */
|
||||
if (ioctl(intf->fd, SIOCGLIFFLAGS, &lifr) < 0)
|
||||
/* Get interface flags. Here he also check whether we need to use fd or
|
||||
* fd6 in the rest of the function. Using the wrong address family in
|
||||
* the ioctls gives ENXIO on Solaris. */
|
||||
if (ioctl(intf->fd, SIOCGLIFFLAGS, &lifr) >= 0)
|
||||
fd = intf->fd;
|
||||
else if (intf->fd6 == -1 || ioctl(intf->fd6, SIOCGLIFFLAGS, &lifr) >= 0)
|
||||
fd = intf->fd6;
|
||||
else
|
||||
return (-1);
|
||||
|
||||
entry->intf_flags = intf_iff_to_flags(lifr.lifr_flags);
|
||||
@@ -415,7 +422,7 @@ _intf_get_noalias(intf_t *intf, struct intf_entry *entry)
|
||||
|
||||
/* Get interface MTU. */
|
||||
#ifdef SIOCGLIFMTU
|
||||
if (ioctl(intf->fd, SIOCGLIFMTU, &lifr) < 0)
|
||||
if (ioctl(fd, SIOCGLIFMTU, &lifr) < 0)
|
||||
#endif
|
||||
return (-1);
|
||||
entry->intf_mtu = lifr.lifr_mtu;
|
||||
@@ -424,15 +431,15 @@ _intf_get_noalias(intf_t *intf, struct intf_entry *entry)
|
||||
entry->intf_link_addr.addr_type = ADDR_TYPE_NONE;
|
||||
|
||||
/* Get primary interface address. */
|
||||
if (ioctl(intf->fd, SIOCGLIFADDR, &lifr) == 0) {
|
||||
if (ioctl(fd, SIOCGLIFADDR, &lifr) == 0) {
|
||||
addr_ston((struct sockaddr *)&lifr.lifr_addr, &entry->intf_addr);
|
||||
if (ioctl(intf->fd, SIOCGLIFNETMASK, &lifr) < 0)
|
||||
if (ioctl(fd, SIOCGLIFNETMASK, &lifr) < 0)
|
||||
return (-1);
|
||||
addr_stob((struct sockaddr *)&lifr.lifr_addr, &entry->intf_addr.addr_bits);
|
||||
}
|
||||
/* Get other addresses. */
|
||||
if (entry->intf_type == INTF_TYPE_TUN) {
|
||||
if (ioctl(intf->fd, SIOCGLIFDSTADDR, &lifr) == 0) {
|
||||
if (ioctl(fd, SIOCGLIFDSTADDR, &lifr) == 0) {
|
||||
if (addr_ston((struct sockaddr *)&lifr.lifr_addr,
|
||||
&entry->intf_dst_addr) < 0)
|
||||
return (-1);
|
||||
@@ -604,8 +611,11 @@ _intf_get_aliases(intf_t *intf, struct intf_entry *entry)
|
||||
if (ioctl(intf->fd, SIOCGIFNETMASK, &tmplifr) == 0)
|
||||
addr_stob((struct sockaddr *)&tmplifr.lifr_addr, &ap->addr_bits);
|
||||
} else if (ap->addr_type == ADDR_TYPE_IP6 && intf->fd6 != -1) {
|
||||
if (memcmp(&ap->addr_ip6, &entry->intf_addr.addr_ip6, IP6_ADDR_LEN) == 0 ||
|
||||
memcmp(&ap->addr_ip6, &entry->intf_dst_addr.addr_ip6, IP6_ADDR_LEN) == 0)
|
||||
continue;
|
||||
strlcpy(tmplifr.lifr_name, lifr->lifr_name, sizeof(tmplifr.lifr_name));
|
||||
if (ioctl(intf->fd, SIOCGLIFNETMASK, &tmplifr) == 0) {
|
||||
if (ioctl(intf->fd6, SIOCGLIFNETMASK, &tmplifr) == 0) {
|
||||
addr_stob((struct sockaddr *)&tmplifr.lifr_addr,
|
||||
&ap->addr_bits);
|
||||
}
|
||||
@@ -909,7 +919,7 @@ intf_loop(intf_t *intf, intf_handler callback, void *arg)
|
||||
if (strcmp(lifr->lifr_name, plifr->lifr_name) == 0)
|
||||
break;
|
||||
}
|
||||
if (lifr > intf->lifc.lifc_req && plifr < llifr)
|
||||
if (lifr > intf->lifc.lifc_req && plifr < lifr)
|
||||
continue;
|
||||
|
||||
memset(ebuf, 0, sizeof(ebuf));
|
||||
|
||||
Reference in New Issue
Block a user