-static int compare_family(const struct ifaddrs *a,
- const struct ifaddrs *b,
- int family) {
- int afamily = a->ifa_addr->sa_family;
- int bfamily = b->ifa_addr->sa_family;
- if(afamily != bfamily) {
- /* Preferred family wins */
- if(afamily == family) return 1;
- if(bfamily == family) return -1;
- /* Either there's no preference or it doesn't help. Prefer IPv4 */
- if(afamily == AF_INET) return 1;
- if(bfamily == AF_INET) return -1;
- /* Failing that prefer IPv6 */
- if(afamily == AF_INET6) return 1;
- if(bfamily == AF_INET6) return -1;
- }
- return 0;
-}
-
-static int compare_flags(const struct ifaddrs *a,
- const struct ifaddrs *b) {
- unsigned aflags = a->ifa_flags, bflags = b->ifa_flags;
- /* Up interfaces are better than down ones */
- unsigned aup = aflags & IFF_UP, bup = bflags & IFF_UP;
- if(aup != bup)
- return aup > bup ? 1 : -1;
-#if IFF_DYNAMIC
- /* Static addresses are better than dynamic */
- unsigned adynamic = aflags & IFF_DYNAMIC, bdynamic = bflags & IFF_DYNAMIC;
- if(adynamic != bdynamic)
- return adynamic < bdynamic ? 1 : -1;
-#endif
- unsigned aloopback = aflags & IFF_LOOPBACK, bloopback = bflags & IFF_LOOPBACK;
- /* Static addresses are better than dynamic */
- if(aloopback != bloopback)
- return aloopback < bloopback ? 1 : -1;
- return 0;
-}
-
-static int compare_interfaces(const struct ifaddrs *a,
- const struct ifaddrs *b,
- int family) {
- int c;
- if((c = compare_family(a, b, family))) return c;
- return compare_flags(a, b);
-}
-