Detect IPv6 address flags at interface discovery on Linux.

This commit is contained in:
Roy Marples 2014-01-19 22:35:52 +00:00
parent 2fae05d02b
commit 5e2809cafc
2 changed files with 34 additions and 5 deletions

View File

@ -833,11 +833,40 @@ if_route6(const struct rt6 *rt, int action)
}
int
in6_addr_flags(__unused const char *ifname,
__unused const struct in6_addr *addr)
in6_addr_flags(const char *ifname, const struct in6_addr *addr)
{
FILE *fp;
char *ent, address[33], name[IF_NAMESIZE + 1];
unsigned int ifindex;
int prefix, scope, flags, i, ret;
struct in6_addr addr6;
static const char *hex = "0123456789abcdef";
/* How do I get IPv6 address flags on Linux? */
return 0;
fp = fopen("/proc/net/if_inet6", "r");
if (fp == NULL)
return -1;
while ((ent = get_line(fp))) {
i = sscanf(ent, "%32[a-f0-9] %x %x %x %x %16s\n",
address, &ifindex, &prefix, &scope, &flags, name);
if (i != 6 || strlen(address) != 32) {
fclose(fp);
errno = ENOTSUP;
return -1;
}
if (strcmp(ifname, name))
continue;
for (i = 0; i < 16; i++) {
addr6.s6_addr[i] =
((strchr(hex, address[i * 2]) - hex) << 4) |
(strchr(hex, address[i * 2 + 1]) - hex);
}
if (IN6_ARE_ADDR_EQUAL(addr, &addr6)) {
fclose(fp);
return flags;
}
}
fclose(fp);
errno = ESRCH;
return -1;
}
#endif

2
ipv6.c
View File

@ -510,7 +510,7 @@ ipv6_handleifa(int cmd, struct if_head *ifs, const char *ifname,
/* Safety, remove tentative addresses */
if (cmd == RTM_NEWADDR) {
if (flags & IN6_IFF_TENTATIVE)
if (flags & (IN6_IFF_TENTATIVE | IN6_IFF_DUPLICATED))
cmd = RTM_DELADDR;
#ifdef IN6_IFF_DETACHED
if (flags & IN6_IFF_DETACHED)