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}