Change
if (ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
with
if (ifa->ifa_addr == NULL)
continue;
if ((strcmp("lo", ifa->ifa_name) == 0) ||
!(ifa->ifa_flags & (IFF_RUNNING)))
continue;
family = ifa->ifa_addr->sa_family;
and add this line just after the other includes
#include <net/if.h>
The added lines just check for "lo" interface name, contained into ifa->ifa_name
, and check the flags of the interfaces. Testing IFF_RUNNING bit ( look at net/if.h
for further definitions) will return only running interfaces.
If you want to check other feature of the interfaces, just check for this flags (taken from net/if.h
)
- IFF_UP Interface is running.
- IFF_BROADCAST Valid broadcast address set.
- IFF_DEBUG Internal debugging flag.
- IFF_LOOPBACK Interface is a loopback interface.
- IFF_POINTOPOINT Interface is a point-to-point link.
- IFF_RUNNING Resources allocated.
- IFF_NOARP No arp protocol, L2 destination address not set.
- IFF_PROMISC Interface is in promiscuous mode.
- IFF_NOTRAILERS Avoid use of trailers.
- IFF_ALLMULTI Receive all multicast packets.
- IFF_MASTER Master of a load balancing bundle.
- IFF_SLAVE Slave of a load balancing bundle.
- IFF_MULTICAST Supports multicast
- IFF_PORTSEL Is able to select media type via ifmap.
- IFF_AUTOMEDIA Auto media selection active.
- IFF_DYNAMIC The addresses are lost when the interface goes down.
- IFF_LOWER_UP Driver signals L1 up (since Linux 2.6.17)
- IFF_DORMANT Driver signals dormant (since Linux 2.6.17)
- IFF_ECHO Echo sent packets (since Linux 2.6.25)
EDIT
if you need to discriminate IPV6 GUA and ULA address use this macros
#ifndef IN6_IS_ADDR_GLOBAL
#define IN6_IS_ADDR_GLOBAL(a) \
((((__const uint32_t *) (a))[0] & htonl(0x70000000)) \
== htonl (0x20000000))
#endif /* IS ADDR GLOBAL */
#ifndef IN6_IS_ADDR_ULA
#define IN6_IS_ADDR_ULA(a) \
((((__const uint32_t *) (a))[0] & htonl(0xfe000000)) \
== htonl (0xfc000000))
#endif /* IS ADDR ULA */
the parameter must be taken from ((sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;