mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-30 00:37:23 +01:00
LocalIP: fix showMac does not honor defaultRouteOnly
This commit is contained in:
@@ -12,7 +12,7 @@ typedef struct FFLocalIpResult
|
||||
FFstrbuf flags;
|
||||
int32_t mtu;
|
||||
int32_t speed; // in Mbps
|
||||
bool defaultRoute;
|
||||
FFLocalIpType defaultRoute;
|
||||
} FFLocalIpResult;
|
||||
|
||||
typedef struct FFLocalIpNIFlag
|
||||
|
||||
@@ -108,58 +108,22 @@ static const FFLocalIpNIFlag niFlagOptions[] = {
|
||||
{},
|
||||
};
|
||||
|
||||
static void addNewIp(FFlist* list, const char* name, const char* addr, int type, bool defaultRoute, uint64_t flags, bool firstOnly)
|
||||
typedef enum __attribute__((__packed__)) FFIPv6Type
|
||||
{
|
||||
FFLocalIpResult* ip = NULL;
|
||||
FF_IPV6_Other,
|
||||
FF_IPV6_GUA = 0b0001,
|
||||
FF_IPV6_GUA_SECONDARY = 0b0101,
|
||||
FF_IPV6_ULA = 0b0010,
|
||||
FF_IPV6_ULA_SECONDARY = 0b0110,
|
||||
FF_IPV6_TYPE_MASK = 0b0011,
|
||||
FF_IPV6_SECONDARY_FLAG = 0b1100,
|
||||
FF_IPV6_PREFERRED = UINT8_MAX,
|
||||
} FFIPv6Type;
|
||||
|
||||
FF_LIST_FOR_EACH(FFLocalIpResult, temp, *list)
|
||||
{
|
||||
if (!ffStrbufEqualS(&temp->name, name)) continue;
|
||||
ip = temp;
|
||||
if (defaultRoute) ip->defaultRoute = true;
|
||||
break;
|
||||
}
|
||||
if (!ip)
|
||||
{
|
||||
ip = (FFLocalIpResult*) ffListAdd(list);
|
||||
ffStrbufInitS(&ip->name, name);
|
||||
ffStrbufInit(&ip->ipv4);
|
||||
ffStrbufInit(&ip->ipv6);
|
||||
ffStrbufInit(&ip->mac);
|
||||
ffStrbufInit(&ip->flags);
|
||||
ip->defaultRoute = defaultRoute;
|
||||
ip->mtu = -1;
|
||||
ip->speed = -1;
|
||||
|
||||
ffLocalIpFillNIFlags(&ip->flags, flags, niFlagOptions);
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case AF_INET:
|
||||
if (ip->ipv4.length)
|
||||
{
|
||||
if (firstOnly) return;
|
||||
ffStrbufAppendC(&ip->ipv4, ',');
|
||||
}
|
||||
ffStrbufAppendS(&ip->ipv4, addr);
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (ip->ipv6.length)
|
||||
{
|
||||
if (firstOnly) return;
|
||||
ffStrbufAppendC(&ip->ipv6, ',');
|
||||
}
|
||||
ffStrbufAppendS(&ip->ipv6, addr);
|
||||
break;
|
||||
case -1:
|
||||
ffStrbufSetS(&ip->mac, addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool isIPv6AddressPreferred(struct ifaddrs* ifa, struct sockaddr_in6* addr)
|
||||
static FFIPv6Type getIpType(struct ifaddrs* ifa)
|
||||
{
|
||||
struct sockaddr_in6* addr = (struct sockaddr_in6*) ifa->ifa_addr;
|
||||
|
||||
#ifndef IN6_IS_ADDR_GLOBAL
|
||||
#define IN6_IS_ADDR_GLOBAL(a) \
|
||||
((((const uint32_t *) (a))[0] & htonl(0x70000000)) == htonl(0x20000000))
|
||||
@@ -168,8 +132,13 @@ static bool isIPv6AddressPreferred(struct ifaddrs* ifa, struct sockaddr_in6* add
|
||||
#define IN6_IS_ADDR_UNIQUE_LOCAL(a) \
|
||||
((((const uint32_t *) (a))[0] & htonl(0xfe000000)) == htonl(0xfc000000))
|
||||
#endif
|
||||
if (!IN6_IS_ADDR_GLOBAL(&addr->sin6_addr) && !IN6_IS_ADDR_UNIQUE_LOCAL(&addr->sin6_addr))
|
||||
return false;
|
||||
FFIPv6Type result = FF_IPV6_Other;
|
||||
if (IN6_IS_ADDR_GLOBAL(&addr->sin6_addr))
|
||||
result = FF_IPV6_GUA;
|
||||
else if (IN6_IS_ADDR_UNIQUE_LOCAL(&addr->sin6_addr))
|
||||
result = FF_IPV6_ULA;
|
||||
else
|
||||
return FF_IPV6_Other;
|
||||
|
||||
#ifdef SIOCGIFAFLAG_IN6
|
||||
static int sockfd = 0;
|
||||
@@ -184,26 +153,26 @@ static bool isIPv6AddressPreferred(struct ifaddrs* ifa, struct sockaddr_in6* add
|
||||
if (sockfd > 0) fcntl(sockfd, F_SETFD, FD_CLOEXEC);
|
||||
#endif
|
||||
}
|
||||
if (sockfd < 0) return true; // Give up
|
||||
if (sockfd < 0) return result;
|
||||
|
||||
struct in6_ifreq ifr6 = {};
|
||||
ffStrCopy(ifr6.ifr_name, ifa->ifa_name, IFNAMSIZ);
|
||||
ifr6.ifr_addr = *addr;
|
||||
|
||||
if (ioctl(sockfd, SIOCGIFAFLAG_IN6, &ifr6) != 0)
|
||||
return true;
|
||||
return result;
|
||||
|
||||
#ifdef IN6_IFF_PREFER_SOURCE
|
||||
if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_PREFER_SOURCE)
|
||||
return true;
|
||||
return FF_IPV6_PREFERRED;
|
||||
#endif
|
||||
return !(ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_DEPRECATED | IN6_IFF_TEMPORARY | IN6_IFF_TENTATIVE | IN6_IFF_DUPLICATED
|
||||
if (ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_DEPRECATED | IN6_IFF_TEMPORARY | IN6_IFF_TENTATIVE | IN6_IFF_DUPLICATED
|
||||
#ifdef IN6_IFF_OPTIMISTIC
|
||||
| IN6_IFF_OPTIMISTIC
|
||||
#endif
|
||||
));
|
||||
)) result |= FF_IPV6_SECONDARY_FLAG;
|
||||
return result;
|
||||
#elif __linux__
|
||||
FF_UNUSED(ifa);
|
||||
|
||||
static FFlist addresses = {};
|
||||
if (addresses.elementSize == 0)
|
||||
{
|
||||
@@ -230,38 +199,99 @@ static bool isIPv6AddressPreferred(struct ifaddrs* ifa, struct sockaddr_in6* add
|
||||
--addresses.length;
|
||||
}
|
||||
}
|
||||
if (addresses.capacity == 0) return true; // Give up
|
||||
if (addresses.capacity == 0) return result;
|
||||
|
||||
FF_LIST_FOR_EACH(struct in6_addr, entry, addresses)
|
||||
{
|
||||
if (memcmp(&addr->sin6_addr, entry, sizeof(struct in6_addr)) == 0)
|
||||
return true;
|
||||
return result;
|
||||
}
|
||||
return false;
|
||||
result |= FF_IPV6_SECONDARY_FLAG;
|
||||
return result;
|
||||
#elif __sun
|
||||
if (ifa->ifa_flags & IFF_PREFERRED)
|
||||
return true;
|
||||
return !(ifa->ifa_flags & (IFF_DEPRECATED | IFF_TEMPORARY | IFF_DUPLICATE));
|
||||
return FF_IPV6_PREFERRED;
|
||||
if (ifa->ifa_flags & (IFF_DEPRECATED | IFF_TEMPORARY | IFF_DUPLICATE))
|
||||
result |= FF_IPV6_SECONDARY_FLAG;
|
||||
return result;
|
||||
#else
|
||||
return true;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
struct ifaddrs* mac;
|
||||
FFlist /*<struct ifaddrs*>*/ ipv4;
|
||||
FFlist /*<struct ifaddrs*>*/ ipv6;
|
||||
} FFAdapter;
|
||||
|
||||
static void appendIpv4(const FFLocalIpOptions* options, FFstrbuf* buffer, const struct ifaddrs* ifa)
|
||||
{
|
||||
struct sockaddr_in* ipv4 = (struct sockaddr_in*) ifa->ifa_addr;
|
||||
|
||||
char addressBuffer[INET_ADDRSTRLEN + 16];
|
||||
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
|
||||
|
||||
if (options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT)
|
||||
{
|
||||
struct sockaddr_in* netmask = (struct sockaddr_in*) ifa->ifa_netmask;
|
||||
int cidr = __builtin_popcount(netmask->sin_addr.s_addr);
|
||||
if (cidr != 0)
|
||||
{
|
||||
size_t len = strlen(addressBuffer);
|
||||
snprintf(addressBuffer + len, 16, "/%d", cidr);
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer->length) ffStrbufAppendC(buffer, ',');
|
||||
ffStrbufAppendS(buffer, addressBuffer);
|
||||
}
|
||||
|
||||
static void appendIpv6(const FFLocalIpOptions* options, FFstrbuf* buffer, const struct ifaddrs* ifa)
|
||||
{
|
||||
struct sockaddr_in6* ipv6 = (struct sockaddr_in6*) ifa->ifa_addr;
|
||||
|
||||
char addressBuffer[INET6_ADDRSTRLEN + 16];
|
||||
inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN);
|
||||
|
||||
if (options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT)
|
||||
{
|
||||
struct sockaddr_in6* netmask = (struct sockaddr_in6*) ifa->ifa_netmask;
|
||||
int cidr = 0;
|
||||
static_assert(sizeof(netmask->sin6_addr) % sizeof(uint64_t) == 0, "");
|
||||
for (uint32_t i = 0; i < sizeof(netmask->sin6_addr) / sizeof(uint64_t); ++i)
|
||||
cidr += __builtin_popcountll(((uint64_t*) &netmask->sin6_addr)[i]);
|
||||
if (cidr != 0)
|
||||
{
|
||||
size_t len = strlen(addressBuffer);
|
||||
snprintf(addressBuffer + len, 16, "/%d", cidr);
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer->length) ffStrbufAppendC(buffer, ',');
|
||||
ffStrbufAppendS(buffer, addressBuffer);
|
||||
}
|
||||
|
||||
const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
{
|
||||
struct ifaddrs* ifAddrStruct = NULL;
|
||||
if(getifaddrs(&ifAddrStruct) < 0)
|
||||
return "getifaddrs(&ifAddrStruct) failed";
|
||||
|
||||
const FFNetifDefaultRouteResult* defaultRouteV4 = ffNetifGetDefaultRouteV4();
|
||||
const FFNetifDefaultRouteResult* defaultRouteV6 = ffNetifGetDefaultRouteV6();
|
||||
|
||||
FF_LIST_AUTO_DESTROY adapters = ffListCreate(sizeof(FFAdapter));
|
||||
|
||||
for (struct ifaddrs* ifa = ifAddrStruct; ifa; ifa = ifa->ifa_next)
|
||||
{
|
||||
if (!ifa->ifa_addr)
|
||||
continue;
|
||||
|
||||
#ifdef IFF_RUNNING
|
||||
#ifdef IFF_RUNNING
|
||||
if (!(ifa->ifa_flags & IFF_RUNNING))
|
||||
continue;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ((ifa->ifa_flags & IFF_LOOPBACK) && !(options->showType & FF_LOCALIP_TYPE_LOOP_BIT))
|
||||
continue;
|
||||
@@ -269,107 +299,182 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
if (options->namePrefix.length && strncmp(ifa->ifa_name, options->namePrefix.chars, options->namePrefix.length) != 0)
|
||||
continue;
|
||||
|
||||
uint64_t flags = options->showType & FF_LOCALIP_TYPE_FLAGS_BIT ? ifa->ifa_flags : 0;
|
||||
if (!(options->showType & FF_LOCALIP_TYPE_MAC_BIT) &&
|
||||
ifa->ifa_addr->sa_family != AF_INET && ifa->ifa_addr->sa_family != AF_INET6)
|
||||
continue;
|
||||
|
||||
if (ifa->ifa_addr->sa_family == AF_INET)
|
||||
if (options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT)
|
||||
{
|
||||
if (!(options->showType & FF_LOCALIP_TYPE_IPV4_BIT))
|
||||
continue;
|
||||
if (!ffStrEquals(defaultRouteV4->ifName, ifa->ifa_name) &&
|
||||
!ffStrEquals(defaultRouteV6->ifName, ifa->ifa_name))
|
||||
continue;
|
||||
}
|
||||
|
||||
struct sockaddr_in* ipv4 = (struct sockaddr_in*) ifa->ifa_addr;
|
||||
FFAdapter* adapter = NULL;
|
||||
FF_LIST_FOR_EACH(FFAdapter, x, adapters)
|
||||
{
|
||||
if (ffStrEquals(x->mac->ifa_name, ifa->ifa_name))
|
||||
{
|
||||
adapter = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!adapter)
|
||||
{
|
||||
adapter = ffListAdd(&adapters);
|
||||
*adapter = (FFAdapter) {
|
||||
.mac = ifa,
|
||||
.ipv4 = ffListCreate(sizeof(struct ifaddrs*)),
|
||||
.ipv6 = ffListCreate(sizeof(struct ifaddrs*)),
|
||||
};
|
||||
}
|
||||
|
||||
switch (ifa->ifa_addr->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
if (options->showType & FF_LOCALIP_TYPE_IPV4_BIT)
|
||||
*FF_LIST_ADD(struct ifaddrs*, adapter->ipv4) = ifa;
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (options->showType & FF_LOCALIP_TYPE_IPV6_BIT)
|
||||
*FF_LIST_ADD(struct ifaddrs*, adapter->ipv6) = ifa;
|
||||
break;
|
||||
#if __FreeBSD__ || __OpenBSD__ || __APPLE__ || __NetBSD__ || __HAIKU__
|
||||
case AF_LINK: adapter->mac = ifa; break;
|
||||
#elif !__sun
|
||||
case AF_PACKET: adapter->mac = ifa; break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
FF_LIST_FOR_EACH(FFAdapter, adapter, adapters)
|
||||
{
|
||||
FFLocalIpResult* item = FF_LIST_ADD(FFLocalIpResult, *results);
|
||||
ffStrbufInitS(&item->name, adapter->mac->ifa_name);
|
||||
ffStrbufInit(&item->ipv4);
|
||||
ffStrbufInit(&item->ipv6);
|
||||
ffStrbufInit(&item->mac);
|
||||
ffStrbufInit(&item->flags);
|
||||
item->defaultRoute = FF_LOCALIP_TYPE_NONE;
|
||||
item->mtu = -1;
|
||||
item->speed = -1;
|
||||
|
||||
if (options->showType & FF_LOCALIP_TYPE_FLAGS_BIT)
|
||||
ffLocalIpFillNIFlags(&item->flags, adapter->mac->ifa_flags, niFlagOptions);
|
||||
|
||||
if ((options->showType & FF_LOCALIP_TYPE_IPV4_BIT))
|
||||
{
|
||||
bool isDefaultRouteIf = ffStrEquals(defaultRouteV4->ifName, adapter->mac->ifa_name);
|
||||
|
||||
if (isDefaultRouteIf) item->defaultRoute |= FF_LOCALIP_TYPE_IPV4_BIT;
|
||||
|
||||
const FFNetifDefaultRouteResult* defaultRoute = ffNetifGetDefaultRouteV4();
|
||||
bool isDefaultRouteIf = ffStrEquals(defaultRoute->ifName, ifa->ifa_name);
|
||||
if (options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT)
|
||||
{
|
||||
if (!isDefaultRouteIf)
|
||||
continue;
|
||||
|
||||
if (!(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT))
|
||||
{
|
||||
bool isPreferredSourceAddr = defaultRoute->preferredSourceAddrV4 == 0 || ipv4->sin_addr.s_addr == defaultRoute->preferredSourceAddrV4;
|
||||
if (!isPreferredSourceAddr)
|
||||
continue;
|
||||
}
|
||||
goto v6;
|
||||
}
|
||||
|
||||
char addressBuffer[INET_ADDRSTRLEN + 16];
|
||||
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
|
||||
|
||||
if (options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT)
|
||||
if (!(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT))
|
||||
{
|
||||
struct sockaddr_in* netmask = (struct sockaddr_in*) ifa->ifa_netmask;
|
||||
int cidr = __builtin_popcount(netmask->sin_addr.s_addr);
|
||||
if (cidr != 0)
|
||||
struct ifaddrs* ifa = NULL;
|
||||
if (isDefaultRouteIf && defaultRouteV4->preferredSourceAddrV4 != 0) // preferredSourceAddrV4 is only set for the default route
|
||||
{
|
||||
size_t len = strlen(addressBuffer);
|
||||
snprintf(addressBuffer + len, 16, "/%d", cidr);
|
||||
FF_LIST_FOR_EACH(struct ifaddrs*, pifa, adapter->ipv4)
|
||||
{
|
||||
struct sockaddr_in* ipv4 = (struct sockaddr_in*) (*pifa)->ifa_addr;
|
||||
if (ipv4->sin_addr.s_addr == defaultRouteV4->preferredSourceAddrV4)
|
||||
{
|
||||
ifa = *pifa;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ifa)
|
||||
appendIpv4(options, &item->ipv4, ifa);
|
||||
else if (adapter->ipv4.length > 0)
|
||||
appendIpv4(options, &item->ipv4, *FF_LIST_GET(struct ifaddrs*, adapter->ipv4, 0));
|
||||
}
|
||||
|
||||
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET, isDefaultRouteIf, flags, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT));
|
||||
}
|
||||
else if (ifa->ifa_addr->sa_family == AF_INET6)
|
||||
{
|
||||
if (!(options->showType & FF_LOCALIP_TYPE_IPV6_BIT))
|
||||
continue;
|
||||
|
||||
const FFNetifDefaultRouteResult* defaultRoute = ffNetifGetDefaultRouteV6();
|
||||
bool isDefaultRouteIf = ffStrEquals(defaultRoute->ifName, ifa->ifa_name);
|
||||
if ((options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT) && !isDefaultRouteIf)
|
||||
continue;
|
||||
|
||||
struct sockaddr_in6* ipv6 = (struct sockaddr_in6 *)ifa->ifa_addr;
|
||||
if (!(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT) && !isIPv6AddressPreferred(ifa, ipv6))
|
||||
continue;
|
||||
|
||||
char addressBuffer[INET6_ADDRSTRLEN + 16];
|
||||
inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN);
|
||||
|
||||
if (options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT)
|
||||
else
|
||||
{
|
||||
struct sockaddr_in6* netmask = (struct sockaddr_in6*) ifa->ifa_netmask;
|
||||
int cidr = 0;
|
||||
static_assert(sizeof(netmask->sin6_addr) % sizeof(uint64_t) == 0, "");
|
||||
for (uint32_t i = 0; i < sizeof(netmask->sin6_addr) / sizeof(uint64_t); ++i)
|
||||
cidr += __builtin_popcountll(((uint64_t*) &netmask->sin6_addr)[i]);
|
||||
if (cidr != 0)
|
||||
{
|
||||
size_t len = strlen(addressBuffer);
|
||||
snprintf(addressBuffer + len, 16, "/%d", cidr);
|
||||
}
|
||||
FF_LIST_FOR_EACH(struct ifaddrs*, pifa, adapter->ipv4)
|
||||
appendIpv4(options, &item->ipv4, *pifa);
|
||||
}
|
||||
}
|
||||
v6:
|
||||
if ((options->showType & FF_LOCALIP_TYPE_IPV6_BIT))
|
||||
{
|
||||
bool isDefaultRouteIf = ffStrEquals(defaultRouteV6->ifName, adapter->mac->ifa_name);
|
||||
|
||||
if (isDefaultRouteIf) item->defaultRoute |= FF_LOCALIP_TYPE_IPV6_BIT;
|
||||
|
||||
if (options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT)
|
||||
{
|
||||
if (!isDefaultRouteIf)
|
||||
goto mac;
|
||||
}
|
||||
|
||||
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET6, isDefaultRouteIf, flags, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT));
|
||||
}
|
||||
#if __FreeBSD__ || __OpenBSD__ || __APPLE__ || __NetBSD__ || __HAIKU__
|
||||
else if (ifa->ifa_addr->sa_family == AF_LINK)
|
||||
{
|
||||
if (!(options->showType & FF_LOCALIP_TYPE_MAC_BIT))
|
||||
continue;
|
||||
if (!(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT))
|
||||
{
|
||||
struct ifaddrs* selected = NULL;
|
||||
struct ifaddrs* secondary = NULL;
|
||||
|
||||
char addressBuffer[32];
|
||||
uint8_t* ptr = (uint8_t*) LLADDR((struct sockaddr_dl *)ifa->ifa_addr);
|
||||
snprintf(addressBuffer, ARRAY_SIZE(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
|
||||
addNewIp(results, ifa->ifa_name, addressBuffer, -1, false, flags, false);
|
||||
FF_LIST_FOR_EACH(struct ifaddrs*, pifa, adapter->ipv6)
|
||||
{
|
||||
FFIPv6Type type = getIpType(*pifa);
|
||||
if (type == FF_IPV6_PREFERRED)
|
||||
{
|
||||
selected = *pifa;
|
||||
break;
|
||||
}
|
||||
else if (type == FF_IPV6_GUA && !selected)
|
||||
selected = *pifa;
|
||||
else if (type == FF_IPV6_ULA && !secondary)
|
||||
secondary = *pifa;
|
||||
}
|
||||
if (!selected) selected = secondary;
|
||||
|
||||
if (selected)
|
||||
appendIpv6(options, &item->ipv6, selected);
|
||||
else if (adapter->ipv6.length > 0)
|
||||
appendIpv6(options, &item->ipv6, *FF_LIST_GET(struct ifaddrs*, adapter->ipv6, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_LIST_FOR_EACH(struct ifaddrs*, pifa, adapter->ipv6)
|
||||
appendIpv6(options, &item->ipv6, *pifa);
|
||||
}
|
||||
}
|
||||
mac:
|
||||
#ifndef __sun
|
||||
if (options->showType & FF_LOCALIP_TYPE_MAC_BIT)
|
||||
{
|
||||
if (adapter->mac->ifa_addr)
|
||||
{
|
||||
#if __FreeBSD__ || __OpenBSD__ || __APPLE__ || __NetBSD__ || __HAIKU__
|
||||
uint8_t* ptr = (uint8_t*) LLADDR((struct sockaddr_dl *)adapter->mac->ifa_addr);
|
||||
#else
|
||||
uint8_t* ptr = ((struct sockaddr_ll *)adapter->mac->ifa_addr)->sll_addr;
|
||||
#endif
|
||||
ffStrbufSetF(&item->mac, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
else if (ifa->ifa_addr->sa_family == AF_PACKET)
|
||||
{
|
||||
if (!(options->showType & FF_LOCALIP_TYPE_MAC_BIT))
|
||||
continue;
|
||||
|
||||
char addressBuffer[32];
|
||||
uint8_t* ptr = ((struct sockaddr_ll *)ifa->ifa_addr)->sll_addr;
|
||||
snprintf(addressBuffer, ARRAY_SIZE(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
|
||||
addNewIp(results, ifa->ifa_name, addressBuffer, -1, false, flags, false);
|
||||
}
|
||||
(void) adapter;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ifAddrStruct) freeifaddrs(ifAddrStruct);
|
||||
FF_LIST_FOR_EACH(FFAdapter, adapter, adapters)
|
||||
{
|
||||
ffListDestroy(&adapter->ipv4);
|
||||
ffListDestroy(&adapter->ipv6);
|
||||
}
|
||||
|
||||
if (ifAddrStruct)
|
||||
{
|
||||
freeifaddrs(ifAddrStruct);
|
||||
ifAddrStruct = NULL;
|
||||
}
|
||||
|
||||
if ((options->showType & FF_LOCALIP_TYPE_MTU_BIT) || (options->showType & FF_LOCALIP_TYPE_SPEED_BIT)
|
||||
#ifdef __sun
|
||||
|
||||
@@ -54,9 +54,6 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
|
||||
if (ip->ipv6.length) ffStrbufAppendC(&ip->ipv6, ',');
|
||||
ffStrbufAppendS(&ip->ipv6, addr);
|
||||
break;
|
||||
case -1:
|
||||
ffStrbufSetS(&ip->mac, addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,18 +89,12 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
return "GetAdaptersAddresses() failed";
|
||||
}
|
||||
|
||||
uint32_t defaultRouteIfIndex = ffNetifGetDefaultRouteV4()->ifIndex;
|
||||
|
||||
// Iterate through all of the adapters
|
||||
for (IP_ADAPTER_ADDRESSES* adapter = adapter_addresses; adapter; adapter = adapter->Next)
|
||||
{
|
||||
if (adapter->OperStatus != IfOperStatusUp)
|
||||
continue;
|
||||
|
||||
bool isDefaultRoute = adapter->IfIndex == defaultRouteIfIndex;
|
||||
if ((options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT) && !isDefaultRoute)
|
||||
continue;
|
||||
|
||||
bool isLoop = adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK;
|
||||
if (isLoop && !(options->showType & FF_LOCALIP_TYPE_LOOP_BIT))
|
||||
continue;
|
||||
@@ -115,16 +106,6 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
if (options->namePrefix.length && strncmp(name, options->namePrefix.chars, options->namePrefix.length) != 0)
|
||||
continue;
|
||||
|
||||
if (options->showType & FF_LOCALIP_TYPE_MAC_BIT && adapter->PhysicalAddressLength == 6)
|
||||
{
|
||||
char addressBuffer[32];
|
||||
uint8_t* ptr = adapter->PhysicalAddress;
|
||||
snprintf(addressBuffer, ARRAY_SIZE(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
|
||||
addNewIp(results, name, addressBuffer, -1, newIp, isDefaultRoute);
|
||||
newIp = false;
|
||||
}
|
||||
|
||||
uint32_t typesToAdd = options->showType & (FF_LOCALIP_TYPE_IPV4_BIT | FF_LOCALIP_TYPE_IPV6_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT);
|
||||
|
||||
for (IP_ADAPTER_UNICAST_ADDRESS* ifa = adapter->FirstUnicastAddress; ifa; ifa = ifa->Next)
|
||||
@@ -136,6 +117,10 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
{
|
||||
if (!(typesToAdd & (FF_LOCALIP_TYPE_IPV4_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT))) continue;
|
||||
|
||||
bool isDefaultRoute = ((options->showType & FF_LOCALIP_TYPE_IPV4_BIT) && ffNetifGetDefaultRouteV4()->ifIndex == adapter->IfIndex);
|
||||
if ((options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT) && !isDefaultRoute)
|
||||
continue;
|
||||
|
||||
SOCKADDR_IN* ipv4 = (SOCKADDR_IN*) ifa->Address.lpSockaddr;
|
||||
char addressBuffer[INET_ADDRSTRLEN + 6];
|
||||
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
|
||||
@@ -156,6 +141,10 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
{
|
||||
if (!(typesToAdd & (FF_LOCALIP_TYPE_IPV6_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT))) continue;
|
||||
|
||||
bool isDefaultRoute = ((options->showType & FF_LOCALIP_TYPE_IPV6_BIT) && ffNetifGetDefaultRouteV6()->ifIndex == adapter->IfIndex);
|
||||
if ((options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT) && !isDefaultRoute)
|
||||
continue;
|
||||
|
||||
SOCKADDR_IN6* ipv6 = (SOCKADDR_IN6*) ifa->Address.lpSockaddr;
|
||||
char addressBuffer[INET6_ADDRSTRLEN + 6];
|
||||
inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN);
|
||||
@@ -183,6 +172,11 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
result->mtu = (int32_t) adapter->Mtu;
|
||||
if (options->showType & FF_LOCALIP_TYPE_FLAGS_BIT)
|
||||
ffLocalIpFillNIFlags(&result->flags, adapter->Flags, niFlagOptions);
|
||||
if (options->showType & FF_LOCALIP_TYPE_MAC_BIT && adapter->PhysicalAddressLength == 6)
|
||||
{
|
||||
uint8_t* ptr = adapter->PhysicalAddress;
|
||||
ffStrbufSetF(&result->mac, "%02x:%02x:%02x:%02x:%02x:%02x", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,9 +91,11 @@ static void printIp(FFLocalIpResult* ip, bool markDefaultRoute, FFstrbuf* buffer
|
||||
}
|
||||
if (ip->flags.length)
|
||||
{
|
||||
if (buffer->length) ffStrbufAppendS(buffer, " <");
|
||||
bool flag = buffer->length > 0;
|
||||
if (flag) ffStrbufAppendS(buffer, " <");
|
||||
ffStrbufAppend(buffer, &ip->flags);
|
||||
ffStrbufAppendC(buffer, '>');
|
||||
if (flag)
|
||||
ffStrbufAppendC(buffer, '>');
|
||||
}
|
||||
if (markDefaultRoute && ip->defaultRoute)
|
||||
ffStrbufAppendS(buffer, " *");
|
||||
|
||||
@@ -120,3 +120,9 @@ static inline void ffListClear(FFlist* list)
|
||||
assert((listVar).capacity > (index)); \
|
||||
(itemType*)(listVar).data + (index); \
|
||||
})
|
||||
|
||||
#define FF_LIST_ADD(itemType, listVar) \
|
||||
({ \
|
||||
assert(sizeof(itemType) == (listVar).elementSize); \
|
||||
(itemType*) ffListAdd(&(listVar)); \
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user