I don't have much knowledge about the IPv6 protocol, so sorry if the question sounds stupid. When I retrieve the list of all IPv6 addresses in my network, I get a field named scope, as shown below :
inet6 addr: 2001:470:1:82::11/64 Scope:Global
inet6 addr: 2001:470:1:82::10/64 Scope:Global
inet6 addr: 2001:470:1:82::13/64 Scope:Global
inet6 addr: fe80::21d:9ff:fe69:2c50/64 Scope:Link
inet6 addr: 2001:470:1:82::12/64 Scope:Global
inet6 addr: 2001:470:1:82::15/64 Scope:Global
inet6 addr: 2001:470:1:82::14/64 Scope:Global
inet6 addr: 2001:470:1:82::5/64 Scope:Global
inet6 addr: 2001:470:1:82::17/64 Scope:Global
inet6 addr: 2001:470:1:82::6/64 Scope:Global
inet6 addr: 2001:470:1:82::16/64 Scope:Global
inet6 addr: 2001:470:1:82::7/64 Scope:Global
inet6 addr: 2001:470:1:82::19/64 Scope:Global
inet6 addr: 2001:470:1:82::8/64 Scope:Global
inet6 addr: 2001:470:1:82::18/64 Scope:Global
inet6 addr: 2001:470:1:82::9/64 Scope:Global
inet6 addr: 2001:470:1:82::1b/64 Scope:Global
inet6 addr: 2001:470:1:82::a/64 Scope:Global
inet6 addr: 2001:470:1:82::1a/64 Scope:Global
inet6 addr: 2001:470:1:82::b/64 Scope:Global
inet6 addr: 2001:470:1:82::1d/64 Scope:Global
inet6 addr: 2001:470:1:82::c/64 Scope:Global
inet6 addr: 2001:470:1:82::1c/64 Scope:Global
inet6 addr: 2001:470:1:82::d/64 Scope:Global
inet6 addr: 2001:470:1:82::1f/64 Scope:Global
inet6 addr: 2001:470:1:82::e/64 Scope:Global
inet6 addr: 2001:470:1:82::1e/64 Scope:Global
inet6 addr: 2001:470:1:82::f/64 Scope:Global
inet6 addr: ::1/128 Scope:Host
In my application, I need to get those addresses for which the scope is 'Link'. I could have used a system call to ifconfig and then parsed the output to extract corresponding addresses. But the problem is, I'm using the call to getifaddrs(), which returns a linked list of structure ifaddr, given as :
struct ifaddrs {
struct ifaddrs *ifa_next; /* Next item in list */
char *ifa_name; /* Name of interface */
unsigned int ifa_flags; /* Flags from SIOCGIFFLAGS */
struct sockaddr *ifa_addr; /* Address of interface */
struct sockaddr *ifa_netmask; /* Netmask of interface */
union {
struct sockaddr *ifu_broadaddr;
/* Broadcast address of interface */
struct sockaddr *ifu_dstaddr;
/* Point-to-point destination address */
} ifa_ifu;
#define ifa_broadaddr ifa_ifu.ifu_broadaddr
#define ifa_dstaddr ifa_ifu.ifu_dstaddr
void *ifa_data; /* Address-specific data */
};
The question is : how to get the addresses with 'Link' scope from this list ?
I don't think the scope is stored explicitly in that data structure. However, you can infer the scope from the IP address itself. See http://en.wikipedia.org/wiki/IPv6_address#Address_scopes
One way to do this would simply be to check whether the address falls within
fe80::/10
. The IPv6 address space is available from IANA, which details the possible scopes available.I downloaded the source code to net-tools (the source package for ifconfig), and it looks like they parse
/proc/net/if_inet6
. (Comments are my own additions in the following code — also the below is extremely abridged and will most certainly not compile.)So let's have a look at what the above is parsing:
So you can see the third column from the left (
0x00
Global,0x20
Link-Local, and0x10
Loopback) is the scope. Using the above constants from the net-tools code you can work out what they mean. Further investigation would be required to determine a more authoritative source for such constants, and also whether parsing/proc/net/if_inet6
is your best option.There are helper macros to assist: