On platforms supporting sa_len, NEXTIFR would skip over sa_len bytes
starting at the beginning of ifr_addr, and assume that was the end of
the struct. (The idea being that a large address such as a sockaddr_in6
could overflow the nominal struct boundary.) This logic was wrong when
there was something else in the union bigger than sa_len; we would
increment into somewhere in the middle of the same struct.
This exhibited itself on NetBSD, where struct ifreq has a
sockaddr_storage member in its internal union:
struct ifreq {
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
struct sockaddr_storage ifru_space;
No, we skip over sa_len bytes, or to the nominal end of the struct,
whichever is larger.
Unix Network Programming gets this wrong too; in figure 17.8 they do
ptr += sizeof(ifr->ifr_name) + max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);
This is a (hopefully temporary) workaround for these virtual interfaces
on Solaris. They don't work for Nmap because they don't allow packet
sniffing, but you can use one of the physical interfaces they're
composed of.
An IPMP interface is a special kind of interface made up of other
interfaces. The other interfaces are hidden by default unless this flag
is passed to ioctl(SIOCGLIFCONF). This allows me to scan over an IPMP
interface in a simple setup.
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.
The IPv6 loopback interface on AIX has both IFF_BROADCAST and IFF_LOOPBACK set. Checking IFF_BROADCAST first erroneously makes it appear as an Ethernet device.