4
4
#include "common/netif/netif.h"
5
5
#include "util/mallocHelper.h"
6
6
#include "util/windows/unicode.h"
7
+ #include "util/debug.h"
7
8
#include "localip.h"
8
9
9
10
#define FF_LOCALIP_NIFLAG (name ) { IP_ADAPTER_##name, #name }
@@ -23,103 +24,146 @@ static const FFLocalIpNIFlag niFlagOptions[] = {
23
24
{},
24
25
};
25
26
26
- static void addNewIp (FFlist * list , const char * name , const char * addr , int type , bool newIp , bool defaultRoute )
27
- {
28
- FFLocalIpResult * ip = NULL ;
29
-
30
- if (newIp )
31
- {
32
- ip = (FFLocalIpResult * ) ffListAdd (list );
33
- ffStrbufInitS (& ip -> name , name );
34
- ffStrbufInit (& ip -> ipv4 );
35
- ffStrbufInit (& ip -> ipv6 );
36
- ffStrbufInit (& ip -> mac );
37
- ffStrbufInit (& ip -> flags );
38
- ip -> defaultRoute = defaultRoute ;
39
- ip -> speed = -1 ;
40
- ip -> mtu = -1 ;
41
- }
42
- else
43
- {
44
- ip = FF_LIST_GET (FFLocalIpResult , * list , list -> length - 1 );
45
- }
46
-
47
- switch (type )
48
- {
49
- case AF_INET :
50
- if (ip -> ipv4 .length ) ffStrbufAppendC (& ip -> ipv4 , ',' );
51
- ffStrbufAppendS (& ip -> ipv4 , addr );
52
- break ;
53
- case AF_INET6 :
54
- if (ip -> ipv6 .length ) ffStrbufAppendC (& ip -> ipv6 , ',' );
55
- ffStrbufAppendS (& ip -> ipv6 , addr );
56
- break ;
57
- }
58
- }
59
-
60
27
const char * ffDetectLocalIps (const FFLocalIpOptions * options , FFlist * results )
61
28
{
29
+ FF_DEBUG ("Starting local IP detection with showType=0x%X, namePrefix='%.*s'" ,
30
+ options -> showType , (int )options -> namePrefix .length , options -> namePrefix .chars );
31
+
62
32
IP_ADAPTER_ADDRESSES * FF_AUTO_FREE adapter_addresses = NULL ;
63
33
64
34
// Multiple attempts in case interfaces change while
65
35
// we are in the middle of querying them.
66
36
DWORD adapter_addresses_buffer_size = 0 ;
67
37
for (int attempts = 0 ;; ++ attempts )
68
38
{
39
+ FF_DEBUG ("Attempt %d to get adapter addresses, buffer size: %lu" , attempts + 1 , adapter_addresses_buffer_size );
40
+
69
41
if (adapter_addresses_buffer_size )
70
42
{
71
43
adapter_addresses = (IP_ADAPTER_ADDRESSES * )realloc (adapter_addresses , adapter_addresses_buffer_size );
72
44
assert (adapter_addresses );
73
45
}
74
46
47
+ DWORD family = options -> showType & FF_LOCALIP_TYPE_IPV4_BIT
48
+ ? options -> showType & FF_LOCALIP_TYPE_IPV6_BIT ? AF_UNSPEC : AF_INET
49
+ : AF_INET6 ;
50
+ FF_DEBUG ("Calling GetAdaptersAddresses with family=%u, flags=0x%X" , (unsigned )family ,
51
+ GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER );
52
+
75
53
DWORD error = GetAdaptersAddresses (
76
- options -> showType & FF_LOCALIP_TYPE_IPV4_BIT
77
- ? options -> showType & FF_LOCALIP_TYPE_IPV6_BIT ? AF_UNSPEC : AF_INET
78
- : AF_INET6 ,
54
+ family ,
79
55
GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER ,
80
56
NULL ,
81
57
adapter_addresses ,
82
58
& adapter_addresses_buffer_size );
83
59
84
60
if (error == ERROR_SUCCESS )
61
+ {
62
+ FF_DEBUG ("GetAdaptersAddresses succeeded on attempt %d" , attempts + 1 );
85
63
break ;
64
+ }
86
65
else if (ERROR_BUFFER_OVERFLOW == error && attempts < 4 )
66
+ {
67
+ FF_DEBUG ("Buffer overflow, need %lu bytes, retrying" , adapter_addresses_buffer_size );
87
68
continue ;
69
+ }
88
70
else
71
+ {
72
+ FF_DEBUG ("GetAdaptersAddresses failed with error %lu after %d attempts" , error , attempts + 1 );
89
73
return "GetAdaptersAddresses() failed" ;
74
+ }
90
75
}
91
76
77
+ int adapterCount = 0 ;
78
+ int processedCount = 0 ;
79
+
92
80
// Iterate through all of the adapters
93
81
for (IP_ADAPTER_ADDRESSES * adapter = adapter_addresses ; adapter ; adapter = adapter -> Next )
94
82
{
83
+ adapterCount ++ ;
84
+
85
+ FF_DEBUG ("Processing adapter %d: IfIndex=%u, IfType=%u, OperStatus=%u" ,
86
+ adapterCount , (unsigned )adapter -> IfIndex , (unsigned )adapter -> IfType , (unsigned )adapter -> OperStatus );
87
+
95
88
if (adapter -> OperStatus != IfOperStatusUp )
89
+ {
90
+ FF_DEBUG ("Skipping adapter %u (not operational, status=%d)" , (unsigned )adapter -> IfIndex , adapter -> OperStatus );
96
91
continue ;
92
+ }
97
93
98
94
bool isLoop = adapter -> IfType == IF_TYPE_SOFTWARE_LOOPBACK ;
95
+ FF_DEBUG ("Adapter %u: isLoopback=%s" , (unsigned )adapter -> IfIndex , isLoop ? "true" : "false" );
96
+
99
97
if (isLoop && !(options -> showType & FF_LOCALIP_TYPE_LOOP_BIT ))
98
+ {
99
+ FF_DEBUG ("Skipping loopback adapter %u (loopback not requested)" , (unsigned )adapter -> IfIndex );
100
100
continue ;
101
-
102
- bool newIp = true;
101
+ }
103
102
104
103
char name [128 ];
105
104
WideCharToMultiByte (CP_UTF8 , 0 , adapter -> FriendlyName , -1 , name , ARRAY_SIZE (name ), NULL , NULL );
105
+ FF_DEBUG ("Adapter %u name: '%s'" , (unsigned )adapter -> IfIndex , name );
106
+
106
107
if (options -> namePrefix .length && strncmp (name , options -> namePrefix .chars , options -> namePrefix .length ) != 0 )
108
+ {
109
+ FF_DEBUG ("Skipping adapter %u (name doesn't match prefix '%.*s')" ,
110
+ (unsigned )adapter -> IfIndex , (int )options -> namePrefix .length , options -> namePrefix .chars );
107
111
continue ;
112
+ }
113
+
114
+ if (options -> showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT )
115
+ {
116
+ if (!((options -> showType & FF_LOCALIP_TYPE_IPV4_BIT ) && ffNetifGetDefaultRouteV4 ()-> ifIndex == adapter -> IfIndex ) &&
117
+ !((options -> showType & FF_LOCALIP_TYPE_IPV6_BIT ) && ffNetifGetDefaultRouteV6 ()-> ifIndex == adapter -> IfIndex ))
118
+ {
119
+ FF_DEBUG ("Skipping interface %u (not default route interface)" , (unsigned )adapter -> IfIndex );
120
+ continue ;
121
+ }
122
+ }
123
+
124
+ processedCount ++ ;
125
+ FF_DEBUG ("Creating result item for adapter %u ('%s')" , (unsigned )adapter -> IfIndex , name );
126
+
127
+ FFLocalIpResult * item = (FFLocalIpResult * ) ffListAdd (results );
128
+ ffStrbufInitS (& item -> name , name );
129
+ ffStrbufInit (& item -> ipv4 );
130
+ ffStrbufInit (& item -> ipv6 );
131
+ ffStrbufInit (& item -> mac );
132
+ ffStrbufInit (& item -> flags );
133
+ item -> defaultRoute = FF_LOCALIP_TYPE_NONE ;
134
+ item -> speed = -1 ;
135
+ item -> mtu = -1 ;
108
136
109
137
uint32_t typesToAdd = options -> showType & (FF_LOCALIP_TYPE_IPV4_BIT | FF_LOCALIP_TYPE_IPV6_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT );
138
+ FF_DEBUG ("Types to add for adapter %u: 0x%X" , (unsigned )adapter -> IfIndex , typesToAdd );
139
+
140
+ int ipv4Count = 0 , ipv6Count = 0 ;
110
141
111
142
for (IP_ADAPTER_UNICAST_ADDRESS * ifa = adapter -> FirstUnicastAddress ; ifa ; ifa = ifa -> Next )
112
143
{
144
+ FF_DEBUG ("Processing unicast address: family=%d, DadState=%d" ,
145
+ ifa -> Address .lpSockaddr -> sa_family , ifa -> DadState );
146
+
113
147
if (!(options -> showType & FF_LOCALIP_TYPE_ALL_IPS_BIT ) && ifa -> DadState != IpDadStatePreferred )
148
+ {
149
+ FF_DEBUG ("Skipping address (DadState=%d, not preferred)" , ifa -> DadState );
114
150
continue ;
151
+ }
115
152
116
153
if (ifa -> Address .lpSockaddr -> sa_family == AF_INET )
117
154
{
118
- if (!(typesToAdd & (FF_LOCALIP_TYPE_IPV4_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT ))) continue ;
155
+ if (!(typesToAdd & (FF_LOCALIP_TYPE_IPV4_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT )))
156
+ {
157
+ FF_DEBUG ("Skipping IPv4 address (not requested in typesToAdd=0x%X)" , typesToAdd );
158
+ continue ;
159
+ }
119
160
120
161
bool isDefaultRoute = ((options -> showType & FF_LOCALIP_TYPE_IPV4_BIT ) && ffNetifGetDefaultRouteV4 ()-> ifIndex == adapter -> IfIndex );
121
162
if ((options -> showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT ) && !isDefaultRoute )
163
+ {
164
+ FF_DEBUG ("Skipping IPv4 address (not on default route interface)" );
122
165
continue ;
166
+ }
123
167
124
168
SOCKADDR_IN * ipv4 = (SOCKADDR_IN * ) ifa -> Address .lpSockaddr ;
125
169
char addressBuffer [INET_ADDRSTRLEN + 6 ];
@@ -131,19 +175,30 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
131
175
snprintf (addressBuffer + len , 6 , "/%u" , (unsigned ) ifa -> OnLinkPrefixLength );
132
176
}
133
177
134
- addNewIp (results , name , addressBuffer , AF_INET , newIp , isDefaultRoute );
135
- newIp = false;
178
+ FF_DEBUG ("Adding IPv4 address: %s (isDefaultRoute=%s)" , addressBuffer , isDefaultRoute ? "true" : "false" );
136
179
180
+ if (item -> ipv4 .length ) ffStrbufAppendC (& item -> ipv4 , ',' );
181
+ ffStrbufAppendS (& item -> ipv4 , addressBuffer );
182
+ if (isDefaultRoute ) item -> defaultRoute |= FF_LOCALIP_TYPE_IPV4_BIT ;
183
+
184
+ ipv4Count ++ ;
137
185
typesToAdd &= ~(unsigned ) FF_LOCALIP_TYPE_IPV4_BIT ;
138
186
if (typesToAdd == 0 ) break ;
139
187
}
140
188
else if (ifa -> Address .lpSockaddr -> sa_family == AF_INET6 )
141
189
{
142
- if (!(typesToAdd & (FF_LOCALIP_TYPE_IPV6_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT ))) continue ;
190
+ if (!(typesToAdd & (FF_LOCALIP_TYPE_IPV6_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT )))
191
+ {
192
+ FF_DEBUG ("Skipping IPv6 address (not requested in typesToAdd=0x%X)" , typesToAdd );
193
+ continue ;
194
+ }
143
195
144
196
bool isDefaultRoute = ((options -> showType & FF_LOCALIP_TYPE_IPV6_BIT ) && ffNetifGetDefaultRouteV6 ()-> ifIndex == adapter -> IfIndex );
145
197
if ((options -> showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT ) && !isDefaultRoute )
198
+ {
199
+ FF_DEBUG ("Skipping IPv6 address (not on default route interface)" );
146
200
continue ;
201
+ }
147
202
148
203
SOCKADDR_IN6 * ipv6 = (SOCKADDR_IN6 * ) ifa -> Address .lpSockaddr ;
149
204
char addressBuffer [INET6_ADDRSTRLEN + 6 ];
@@ -155,30 +210,45 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
155
210
snprintf (addressBuffer + len , 6 , "/%u" , (unsigned ) ifa -> OnLinkPrefixLength );
156
211
}
157
212
158
- addNewIp (results , name , addressBuffer , AF_INET6 , newIp , isDefaultRoute );
159
- newIp = false;
213
+ FF_DEBUG ("Adding IPv6 address: %s (isDefaultRoute=%s)" , addressBuffer , isDefaultRoute ? "true" : "false" );
214
+
215
+ if (item -> ipv6 .length ) ffStrbufAppendC (& item -> ipv6 , ',' );
216
+ ffStrbufAppendS (& item -> ipv6 , addressBuffer );
217
+ if (isDefaultRoute ) item -> defaultRoute |= FF_LOCALIP_TYPE_IPV6_BIT ;
160
218
219
+ ipv6Count ++ ;
161
220
typesToAdd &= ~(unsigned ) FF_LOCALIP_TYPE_IPV6_BIT ;
162
221
if (typesToAdd == 0 ) break ;
163
222
}
164
223
}
165
224
166
- if (!newIp )
225
+ FF_DEBUG ("Adapter %u: collected %d IPv4 and %d IPv6 addresses" , (unsigned )adapter -> IfIndex , ipv4Count , ipv6Count );
226
+
227
+ if (options -> showType & FF_LOCALIP_TYPE_SPEED_BIT )
167
228
{
168
- FFLocalIpResult * result = FF_LIST_GET (FFLocalIpResult , * results , results -> length - 1 );
169
- if (options -> showType & FF_LOCALIP_TYPE_SPEED_BIT )
170
- result -> speed = (int32_t ) (adapter -> ReceiveLinkSpeed / 1000000 );
171
- if (options -> showType & FF_LOCALIP_TYPE_MTU_BIT )
172
- result -> mtu = (int32_t ) adapter -> Mtu ;
173
- if (options -> showType & FF_LOCALIP_TYPE_FLAGS_BIT )
174
- ffLocalIpFillNIFlags (& result -> flags , adapter -> Flags , niFlagOptions );
175
- if (options -> showType & FF_LOCALIP_TYPE_MAC_BIT && adapter -> PhysicalAddressLength == 6 )
176
- {
177
- uint8_t * ptr = adapter -> PhysicalAddress ;
178
- ffStrbufSetF (& result -> mac , "%02x:%02x:%02x:%02x:%02x:%02x" , ptr [0 ], ptr [1 ], ptr [2 ], ptr [3 ], ptr [4 ], ptr [5 ]);
179
- }
229
+ item -> speed = (int32_t ) (adapter -> ReceiveLinkSpeed / 1000000 );
230
+ FF_DEBUG ("Adapter %u speed: %d Mbps (raw: %llu)" , (unsigned )adapter -> IfIndex , item -> speed , adapter -> ReceiveLinkSpeed );
231
+ }
232
+ if (options -> showType & FF_LOCALIP_TYPE_MTU_BIT )
233
+ {
234
+ item -> mtu = (int32_t ) adapter -> Mtu ;
235
+ FF_DEBUG ("Adapter %u MTU: %d" , (unsigned )adapter -> IfIndex , item -> mtu );
236
+ }
237
+ if (options -> showType & FF_LOCALIP_TYPE_FLAGS_BIT )
238
+ {
239
+ ffLocalIpFillNIFlags (& item -> flags , adapter -> Flags , niFlagOptions );
240
+ FF_DEBUG ("Adapter %u flags: 0x%lX -> '%s'" , (unsigned )adapter -> IfIndex , adapter -> Flags , item -> flags .chars );
241
+ }
242
+ if (options -> showType & FF_LOCALIP_TYPE_MAC_BIT && adapter -> PhysicalAddressLength == 6 )
243
+ {
244
+ uint8_t * ptr = adapter -> PhysicalAddress ;
245
+ ffStrbufSetF (& item -> mac , "%02x:%02x:%02x:%02x:%02x:%02x" , ptr [0 ], ptr [1 ], ptr [2 ], ptr [3 ], ptr [4 ], ptr [5 ]);
246
+ FF_DEBUG ("Adapter %u MAC: %s" , (unsigned )adapter -> IfIndex , item -> mac .chars );
180
247
}
181
248
}
182
249
250
+ FF_DEBUG ("Local IP detection completed: scanned %d adapters, processed %d, results count: %u" ,
251
+ adapterCount , processedCount , results -> length );
252
+
183
253
return NULL ;
184
254
}
0 commit comments