44#include "common/netif/netif.h"
55#include "util/mallocHelper.h"
66#include "util/windows/unicode.h"
7+ #include "util/debug.h"
78#include "localip.h"
89
910#define FF_LOCALIP_NIFLAG (name ) { IP_ADAPTER_##name, #name }
@@ -23,103 +24,146 @@ static const FFLocalIpNIFlag niFlagOptions[] = {
2324 {},
2425};
2526
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-
6027const char * ffDetectLocalIps (const FFLocalIpOptions * options , FFlist * results )
6128{
29+ FF_DEBUG ("Starting local IP detection with showType=0x%X, namePrefix='%.*s'" ,
30+ options -> showType , (int )options -> namePrefix .length , options -> namePrefix .chars );
31+
6232 IP_ADAPTER_ADDRESSES * FF_AUTO_FREE adapter_addresses = NULL ;
6333
6434 // Multiple attempts in case interfaces change while
6535 // we are in the middle of querying them.
6636 DWORD adapter_addresses_buffer_size = 0 ;
6737 for (int attempts = 0 ;; ++ attempts )
6838 {
39+ FF_DEBUG ("Attempt %d to get adapter addresses, buffer size: %lu" , attempts + 1 , adapter_addresses_buffer_size );
40+
6941 if (adapter_addresses_buffer_size )
7042 {
7143 adapter_addresses = (IP_ADAPTER_ADDRESSES * )realloc (adapter_addresses , adapter_addresses_buffer_size );
7244 assert (adapter_addresses );
7345 }
7446
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+
7553 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 ,
7955 GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER ,
8056 NULL ,
8157 adapter_addresses ,
8258 & adapter_addresses_buffer_size );
8359
8460 if (error == ERROR_SUCCESS )
61+ {
62+ FF_DEBUG ("GetAdaptersAddresses succeeded on attempt %d" , attempts + 1 );
8563 break ;
64+ }
8665 else if (ERROR_BUFFER_OVERFLOW == error && attempts < 4 )
66+ {
67+ FF_DEBUG ("Buffer overflow, need %lu bytes, retrying" , adapter_addresses_buffer_size );
8768 continue ;
69+ }
8870 else
71+ {
72+ FF_DEBUG ("GetAdaptersAddresses failed with error %lu after %d attempts" , error , attempts + 1 );
8973 return "GetAdaptersAddresses() failed" ;
74+ }
9075 }
9176
77+ int adapterCount = 0 ;
78+ int processedCount = 0 ;
79+
9280 // Iterate through all of the adapters
9381 for (IP_ADAPTER_ADDRESSES * adapter = adapter_addresses ; adapter ; adapter = adapter -> Next )
9482 {
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+
9588 if (adapter -> OperStatus != IfOperStatusUp )
89+ {
90+ FF_DEBUG ("Skipping adapter %u (not operational, status=%d)" , (unsigned )adapter -> IfIndex , adapter -> OperStatus );
9691 continue ;
92+ }
9793
9894 bool isLoop = adapter -> IfType == IF_TYPE_SOFTWARE_LOOPBACK ;
95+ FF_DEBUG ("Adapter %u: isLoopback=%s" , (unsigned )adapter -> IfIndex , isLoop ? "true" : "false" );
96+
9997 if (isLoop && !(options -> showType & FF_LOCALIP_TYPE_LOOP_BIT ))
98+ {
99+ FF_DEBUG ("Skipping loopback adapter %u (loopback not requested)" , (unsigned )adapter -> IfIndex );
100100 continue ;
101-
102- bool newIp = true;
101+ }
103102
104103 char name [128 ];
105104 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+
106107 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 );
107111 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 ;
108136
109137 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 ;
110141
111142 for (IP_ADAPTER_UNICAST_ADDRESS * ifa = adapter -> FirstUnicastAddress ; ifa ; ifa = ifa -> Next )
112143 {
144+ FF_DEBUG ("Processing unicast address: family=%d, DadState=%d" ,
145+ ifa -> Address .lpSockaddr -> sa_family , ifa -> DadState );
146+
113147 if (!(options -> showType & FF_LOCALIP_TYPE_ALL_IPS_BIT ) && ifa -> DadState != IpDadStatePreferred )
148+ {
149+ FF_DEBUG ("Skipping address (DadState=%d, not preferred)" , ifa -> DadState );
114150 continue ;
151+ }
115152
116153 if (ifa -> Address .lpSockaddr -> sa_family == AF_INET )
117154 {
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+ }
119160
120161 bool isDefaultRoute = ((options -> showType & FF_LOCALIP_TYPE_IPV4_BIT ) && ffNetifGetDefaultRouteV4 ()-> ifIndex == adapter -> IfIndex );
121162 if ((options -> showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT ) && !isDefaultRoute )
163+ {
164+ FF_DEBUG ("Skipping IPv4 address (not on default route interface)" );
122165 continue ;
166+ }
123167
124168 SOCKADDR_IN * ipv4 = (SOCKADDR_IN * ) ifa -> Address .lpSockaddr ;
125169 char addressBuffer [INET_ADDRSTRLEN + 6 ];
@@ -131,19 +175,30 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
131175 snprintf (addressBuffer + len , 6 , "/%u" , (unsigned ) ifa -> OnLinkPrefixLength );
132176 }
133177
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" );
136179
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 ++ ;
137185 typesToAdd &= ~(unsigned ) FF_LOCALIP_TYPE_IPV4_BIT ;
138186 if (typesToAdd == 0 ) break ;
139187 }
140188 else if (ifa -> Address .lpSockaddr -> sa_family == AF_INET6 )
141189 {
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+ }
143195
144196 bool isDefaultRoute = ((options -> showType & FF_LOCALIP_TYPE_IPV6_BIT ) && ffNetifGetDefaultRouteV6 ()-> ifIndex == adapter -> IfIndex );
145197 if ((options -> showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT ) && !isDefaultRoute )
198+ {
199+ FF_DEBUG ("Skipping IPv6 address (not on default route interface)" );
146200 continue ;
201+ }
147202
148203 SOCKADDR_IN6 * ipv6 = (SOCKADDR_IN6 * ) ifa -> Address .lpSockaddr ;
149204 char addressBuffer [INET6_ADDRSTRLEN + 6 ];
@@ -155,30 +210,45 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
155210 snprintf (addressBuffer + len , 6 , "/%u" , (unsigned ) ifa -> OnLinkPrefixLength );
156211 }
157212
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 ;
160218
219+ ipv6Count ++ ;
161220 typesToAdd &= ~(unsigned ) FF_LOCALIP_TYPE_IPV6_BIT ;
162221 if (typesToAdd == 0 ) break ;
163222 }
164223 }
165224
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 )
167228 {
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 );
180247 }
181248 }
182249
250+ FF_DEBUG ("Local IP detection completed: scanned %d adapters, processed %d, results count: %u" ,
251+ adapterCount , processedCount , results -> length );
252+
183253 return NULL ;
184254}
0 commit comments