master ohmu/fastfetch-openbsd / src / common / impl / netif_windows.c
ohmu  ·  2026-10-15
 1#include "common/netif.h"
 2
 3#include <ws2tcpip.h> // AF_INET6, IN6_IS_ADDR_UNSPECIFIED
 4#include <iphlpapi.h>
 5
 6bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
 7    PMIB_IPFORWARD_TABLE2 pIpForwardTable = nullptr;
 8
 9    if (!NETIO_SUCCESS(GetIpForwardTable2(AF_INET, &pIpForwardTable))) {
10        return false;
11    }
12
13    bool foundDefault = false;
14    uint32_t smallestMetric = UINT32_MAX;
15
16    for (ULONG i = 0; i < pIpForwardTable->NumEntries; ++i) {
17        MIB_IPFORWARD_ROW2* row = &pIpForwardTable->Table[i];
18
19        if (row->DestinationPrefix.PrefixLength == 0 &&
20            row->DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr == 0) {
21            MIB_IF_ROW2 ifRow = {
22                .InterfaceIndex = row->InterfaceIndex,
23            };
24            if (NETIO_SUCCESS(GetIfEntry2(&ifRow)) && ifRow.OperStatus == IfOperStatusUp) {
25                MIB_IPINTERFACE_ROW ipInterfaceRow = {
26                    .Family = AF_INET,
27                    .InterfaceIndex = row->InterfaceIndex,
28                };
29
30                uint32_t realMetric = row->Metric /* Metric offset */;
31
32                if (NETIO_SUCCESS(GetIpInterfaceEntry(&ipInterfaceRow))) {
33                    realMetric += ipInterfaceRow.Metric /* Interface metric */;
34                }
35
36                if (realMetric < smallestMetric) {
37                    smallestMetric = realMetric;
38                    result->ifIndex = row->InterfaceIndex;
39                    foundDefault = true;
40                }
41            }
42        }
43    }
44
45    FreeMibTable(pIpForwardTable);
46
47    return foundDefault;
48}
49
50bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
51    PMIB_IPFORWARD_TABLE2 pIpForwardTable = nullptr;
52
53    if (!NETIO_SUCCESS(GetIpForwardTable2(AF_INET6, &pIpForwardTable))) {
54        return false;
55    }
56
57    bool foundDefault = false;
58    uint32_t smallestMetric = UINT32_MAX;
59
60    for (ULONG i = 0; i < pIpForwardTable->NumEntries; ++i) {
61        MIB_IPFORWARD_ROW2* row = &pIpForwardTable->Table[i];
62
63        if (row->DestinationPrefix.PrefixLength == 0 &&
64            IN6_IS_ADDR_UNSPECIFIED(&row->DestinationPrefix.Prefix.Ipv6.sin6_addr)) {
65            MIB_IF_ROW2 ifRow = {
66                .InterfaceIndex = row->InterfaceIndex,
67            };
68            if (NETIO_SUCCESS(GetIfEntry2(&ifRow)) && ifRow.OperStatus == IfOperStatusUp) {
69                MIB_IPINTERFACE_ROW ipInterfaceRow = {
70                    .Family = AF_INET6,
71                    .InterfaceIndex = row->InterfaceIndex,
72                };
73
74                uint32_t realMetric = row->Metric /* Metric offset */;
75
76                if (NETIO_SUCCESS(GetIpInterfaceEntry(&ipInterfaceRow))) {
77                    realMetric += ipInterfaceRow.Metric /* Interface metric */;
78                }
79
80                if (realMetric < smallestMetric) {
81                    smallestMetric = realMetric;
82                    result->ifIndex = row->InterfaceIndex;
83                    foundDefault = true;
84                }
85            }
86        }
87    }
88
89    FreeMibTable(pIpForwardTable);
90
91    return foundDefault;
92}