master
c 93 lines 2.22 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "windows_api.h"
4
5 #include <winsock2.h>
6 #include <ws2tcpip.h>
7 #include <iphlpapi.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <stdbool.h>
11
12
13 struct netdata_windows_ip_labels {
14 char *local_iface;
15 char *ipaddr;
16 bool initialized;
17 } default_ip = {
18 .local_iface = NULL,
19 .ipaddr = NULL,
20 .initialized = false
21 };
22
23 int netdata_fill_default_ip()
24 {
25 if (default_ip.initialized)
26 return 0;
27
28 default_ip.initialized = true;
29
30 MIB_IPFORWARDROW route;
31 DWORD dest = 0;
32 if (GetBestRoute(dest, 0, &route) != NO_ERROR) {
33 return -1;
34 }
35
36 DWORD ifIndex = route.dwForwardIfIndex;
37
38 ULONG bufLen = 15000;
39 PIP_ADAPTER_ADDRESSES adapters = (PIP_ADAPTER_ADDRESSES)malloc(bufLen);
40 if (!adapters) {
41 return 1;
42 }
43
44 int ret = GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, NULL, adapters, &bufLen);
45 if (ret != NO_ERROR) {
46 goto end_ip_detection;
47 }
48
49 PIP_ADAPTER_ADDRESSES aa = adapters;
50 while (aa) {
51 if (aa->IfIndex == ifIndex) {
52 char iface[1024];
53 size_t required_size = wcstombs(NULL , aa->FriendlyName, 0) + 1;
54 wcstombs(iface, aa->FriendlyName, required_size);
55 default_ip.local_iface = strdup(iface);
56
57 PIP_ADAPTER_UNICAST_ADDRESS ua = aa->FirstUnicastAddress;
58 while (ua) {
59 if (ua->Address.lpSockaddr->sa_family == AF_INET) {
60 char ipstr[INET_ADDRSTRLEN];
61 struct sockaddr_in *sa_in = (struct sockaddr_in *)ua->Address.lpSockaddr;
62 inet_ntop(AF_INET, &(sa_in->sin_addr), ipstr, sizeof(ipstr));
63 default_ip.ipaddr = strdup(ipstr);
64 goto end_ip_detection;
65 }
66 ua = ua->Next;
67 }
68 break;
69 }
70 aa = aa->Next;
71 }
72
73 ret = NO_ERROR;
74 end_ip_detection:
75 free(adapters);
76 return ret;
77 }
78
79 char *netdata_win_local_interface()
80 {
81 if (!default_ip.initialized)
82 netdata_fill_default_ip();
83
84 return default_ip.local_iface;
85 }
86
87 char *netdata_win_local_ip()
88 {
89 if (!default_ip.initialized)
90 netdata_fill_default_ip();
91
92 return default_ip.ipaddr;
93 }