add winpcap 4.0.2 from url http://www.winpcap.org/
[natblaster.git] / winpcap / packetNtx / Dll / AdInfo.c
blob304351b6c78e18c002a710ad8a46091088e8af8f
1 /*
2 * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
3 * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the Politecnico di Torino, CACE Technologies
16 * nor the names of its contributors may be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 This file contains the support functions used by packet.dll to retrieve information about installed
36 adapters, like
38 - the adapter list
39 - the device associated to any adapter and the description of the adapter
40 - physical parameters like the linkspeed or the link layer type
41 - the IP and link layer addresses */
43 #define UNICODE 1
45 #pragma warning (disable : 4127) //conditional expression is constant. Used for do{}while(FALSE) loops.
47 #if (MSC_VER < 1300)
48 #pragma warning (disable : 4710) // inline function not expanded. used for strsafe functions
49 #endif
51 #include <packet32.h>
52 #include "Packet32-Int.h"
53 #include "debug.h"
55 #ifdef HAVE_WANPACKET_API
56 #include "wanpacket/wanpacket.h"
57 #endif //HAVE_WANPACKET_API
59 #include <windows.h>
60 #include <windowsx.h>
61 #include <Iphlpapi.h>
65 #include <strsafe.h>
67 #include <ntddndis.h>
69 #include <WpcapNames.h>
71 static BOOLEAN PacketAddFakeNdisWanAdapter();
73 PADAPTER_INFO g_AdaptersInfoList = NULL; ///< Head of the adapter information list. This list is populated when packet.dll is linked by the application.
74 HANDLE g_AdaptersInfoMutex = NULL; ///< Mutex that protects the adapter information list. NOTE: every API that takes an ADAPTER_INFO as parameter assumes that it has been called with the mutex acquired.
76 extern FARPROC g_GetAdaptersAddressesPointer;
78 #ifdef HAVE_AIRPCAP_API
79 extern AirpcapGetLastErrorHandler g_PAirpcapGetLastError;
80 extern AirpcapGetDeviceListHandler g_PAirpcapGetDeviceList;
81 extern AirpcapFreeDeviceListHandler g_PAirpcapFreeDeviceList;
82 extern AirpcapOpenHandler g_PAirpcapOpen;
83 extern AirpcapCloseHandler g_PAirpcapClose;
84 extern AirpcapGetLinkTypeHandler g_PAirpcapGetLinkType;
85 extern AirpcapSetKernelBufferHandler g_PAirpcapSetKernelBuffer;
86 extern AirpcapSetFilterHandler g_PAirpcapSetFilter;
87 extern AirpcapGetMacAddressHandler g_PAirpcapGetMacAddress;
88 extern AirpcapSetMinToCopyHandler g_PAirpcapSetMinToCopy;
89 extern AirpcapGetReadEventHandler g_PAirpcapGetReadEvent;
90 extern AirpcapReadHandler g_PAirpcapRead;
91 extern AirpcapGetStatsHandler g_PAirpcapGetStats;
92 #endif /* HAVE_AIRPCAP_API */
94 #ifdef HAVE_DAG_API
95 extern dagc_open_handler g_p_dagc_open;
96 extern dagc_close_handler g_p_dagc_close;
97 extern dagc_getlinktype_handler g_p_dagc_getlinktype;
98 extern dagc_getlinkspeed_handler g_p_dagc_getlinkspeed;
99 extern dagc_finddevs_handler g_p_dagc_finddevs;
100 extern dagc_freedevs_handler g_p_dagc_freedevs;
101 #endif /* HAVE_DAG_API */
103 /// Title of error windows
104 TCHAR szWindowTitle[] = TEXT("PACKET.DLL");
106 ULONG inet_addrU(const WCHAR *cp);
108 extern HKEY WinpcapKey;
109 extern WCHAR *WinPcapKeyBuffer;
112 /*!
113 \brief Gets the link layer of an adapter, querying the registry.
114 \param AdapterObject Handle to an open adapter.
115 \param type Pointer to a NetType structure that will be filled by the function.
116 \return If the function succeeds, the return value is nonzero, otherwise the return value is zero.
118 This function retrieves from the registry the link layer and the speed (in bps) of an opened adapter.
119 These values are copied in the NetType structure provided by the user.
120 The LinkType field of the type parameter can have one of the following values:
122 - NdisMedium802_3: Ethernet (802.3)
123 - NdisMediumWan: WAN
124 - NdisMedium802_5: Token Ring (802.5)
125 - NdisMediumFddi: FDDI
126 - NdisMediumAtm: ATM
127 - NdisMediumArcnet878_2: ARCNET (878.2)
129 static BOOLEAN PacketGetLinkLayerFromRegistry(LPADAPTER AdapterObject, NetType *type)
131 BOOLEAN Status;
132 ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
133 PPACKET_OID_DATA OidData;
135 TRACE_ENTER("PacketGetLinkLayerFromRegistry");
137 OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
138 if (OidData == NULL) {
139 TRACE_PRINT("PacketGetLinkLayerFromRegistry failed");
140 TRACE_EXIT("PacketGetLinkLayerFromRegistry");
141 return FALSE;
143 //get the link-layer type
144 OidData->Oid = OID_GEN_MEDIA_IN_USE;
145 OidData->Length = sizeof (ULONG);
146 Status = PacketRequest(AdapterObject,FALSE,OidData);
147 type->LinkType=*((UINT*)OidData->Data);
149 //get the link-layer speed
150 OidData->Oid = OID_GEN_LINK_SPEED;
151 OidData->Length = sizeof (ULONG);
152 Status = PacketRequest(AdapterObject,FALSE,OidData);
154 if (Status == TRUE)
156 type->LinkSpeed=*((UINT*)OidData->Data)*100;
159 GlobalFreePtr (OidData);
161 TRACE_PRINT2("Media:%.010d" "\t" "Speed=%0.10I64u",
162 type->LinkType,
163 type->LinkSpeed);
165 TRACE_EXIT("PacketGetLinkLayerFromRegistry");
166 return Status;
171 \brief Scan the registry to retrieve the IP addresses of an adapter.
172 \param AdapterName String that contains the name of the adapter.
173 \param buffer A user allocated array of npf_if_addr that will be filled by the function.
174 \param NEntries Size of the array (in npf_if_addr).
175 \return If the function succeeds, the return value is nonzero.
177 This function grabs from the registry information like the IP addresses, the netmasks
178 and the broadcast addresses of an interface. The buffer passed by the user is filled with
179 npf_if_addr structures, each of which contains the data for a single address. If the buffer
180 is full, the reaming addresses are dropeed, therefore set its dimension to sizeof(npf_if_addr)
181 if you want only the first address.
183 static BOOLEAN PacketGetAddressesFromRegistry(LPCSTR AdapterNameA, npf_if_addr* buffer, PLONG NEntries)
185 WCHAR *IfNameW;
186 WCHAR AdapterNameW[ADAPTER_NAME_LENGTH];
187 HKEY SystemKey;
188 HKEY InterfaceKey;
189 HKEY ParametersKey;
190 HKEY TcpIpKey;
191 HKEY UnderTcpKey;
192 LONG status;
193 WCHAR String[1024+1];
194 DWORD RegType;
195 ULONG BufLen;
196 DWORD DHCPEnabled;
197 struct sockaddr_in *TmpAddr, *TmpBroad;
198 LONG naddrs,nmasks,StringPos;
199 DWORD ZeroBroadcast;
201 // Old registry based WinPcap names
203 // UINT RegQueryLen;
204 // WCHAR npfDeviceNamesPrefix[MAX_WINPCAP_KEY_CHARS];
205 WCHAR npfDeviceNamesPrefix[MAX_WINPCAP_KEY_CHARS] = NPF_DEVICE_NAMES_PREFIX_WIDECHAR;
207 TRACE_ENTER("PacketGetAddressesFromRegistry");
209 StringCchPrintfW(AdapterNameW, ADAPTER_NAME_LENGTH, L"%S", AdapterNameA);
211 IfNameW = wcsrchr(AdapterNameW, L'\\');
212 if (IfNameW == NULL)
213 IfNameW = AdapterNameW;
214 else
215 IfNameW++;
218 // Old registry based WinPcap names
220 // RegQueryLen = sizeof(npfDeviceNamesPrefix)/sizeof(npfDeviceNamesPrefix[0]);
222 // if (QueryWinPcapRegistryStringW(TEXT(NPF_DEVICES_PREFIX_REG_KEY), npfDeviceNamesPrefix, &RegQueryLen, NPF_DEVICE_NAMES_PREFIX_WIDECHAR) == FALSE && RegQueryLen == 0)
223 // return FALSE;
225 // if (wcsncmp(ifname, npfDeviceNamesPrefix, RegQueryLen) == 0)
226 // ifname += RegQueryLen;
228 if (wcsncmp(IfNameW, npfDeviceNamesPrefix, wcslen(npfDeviceNamesPrefix)) == 0)
229 IfNameW += wcslen(npfDeviceNamesPrefix);
231 if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"), 0, KEY_READ, &UnderTcpKey) == ERROR_SUCCESS)
233 status = RegOpenKeyEx(UnderTcpKey,IfNameW,0,KEY_READ,&TcpIpKey);
234 if (status != ERROR_SUCCESS) {
235 RegCloseKey(UnderTcpKey);
236 goto fail;
239 else
241 // Query the registry key with the interface's adresses
242 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&SystemKey);
243 if (status != ERROR_SUCCESS)
244 goto fail;
245 status = RegOpenKeyEx(SystemKey,IfNameW,0,KEY_READ,&InterfaceKey);
246 if (status != ERROR_SUCCESS) {
247 RegCloseKey(SystemKey);
248 RegCloseKey(UnderTcpKey);
249 goto fail;
251 RegCloseKey(SystemKey);
252 status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey);
253 if (status != ERROR_SUCCESS) {
254 RegCloseKey(InterfaceKey);
255 RegCloseKey(UnderTcpKey);
256 goto fail;
258 RegCloseKey(InterfaceKey);
259 status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey);
260 if (status != ERROR_SUCCESS) {
261 RegCloseKey(ParametersKey);
262 RegCloseKey(UnderTcpKey);
263 goto fail;
265 RegCloseKey(ParametersKey);
266 BufLen = sizeof String;
269 BufLen = 4;
270 /* Try to detect if the interface has a zero broadcast addr */
271 status=RegQueryValueEx(TcpIpKey,TEXT("UseZeroBroadcast"),NULL,&RegType,(LPBYTE)&ZeroBroadcast,&BufLen);
272 if (status != ERROR_SUCCESS)
273 ZeroBroadcast=0;
275 BufLen = 4;
276 /* See if DHCP is used by this system */
277 status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen);
278 if (status != ERROR_SUCCESS)
279 DHCPEnabled=0;
282 /* Retrieve the adrresses */
283 if(DHCPEnabled){
285 BufLen = sizeof String;
286 // Open the key with the addresses
287 status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
288 if (status != ERROR_SUCCESS) {
289 RegCloseKey(TcpIpKey);
290 RegCloseKey(UnderTcpKey);
291 goto fail;
294 // scan the key to obtain the addresses
295 StringPos = 0;
296 for(naddrs = 0;naddrs <* NEntries;naddrs++){
297 TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress);
299 if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
300 TmpAddr->sin_family = AF_INET;
302 TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast);
303 TmpBroad->sin_family = AF_INET;
304 if(ZeroBroadcast==0)
305 TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255
306 else
307 TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0
309 while(*(String + StringPos) != 0)StringPos++;
310 StringPos++;
312 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
313 break;
315 else break;
318 BufLen = sizeof String;
319 // Open the key with the netmasks
320 status = RegQueryValueEx(TcpIpKey,TEXT("DhcpSubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen);
321 if (status != ERROR_SUCCESS) {
322 RegCloseKey(TcpIpKey);
323 RegCloseKey(UnderTcpKey);
324 goto fail;
327 // scan the key to obtain the masks
328 StringPos = 0;
329 for(nmasks = 0;nmasks < *NEntries;nmasks++){
330 TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask);
332 if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
333 TmpAddr->sin_family = AF_INET;
335 while(*(String + StringPos) != 0)StringPos++;
336 StringPos++;
338 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
339 break;
341 else break;
344 // The number of masks MUST be equal to the number of adresses
345 if(nmasks != naddrs){
346 RegCloseKey(TcpIpKey);
347 RegCloseKey(UnderTcpKey);
348 goto fail;
352 else{
354 BufLen = sizeof String;
355 // Open the key with the addresses
356 status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
357 if (status != ERROR_SUCCESS) {
358 RegCloseKey(TcpIpKey);
359 RegCloseKey(UnderTcpKey);
360 goto fail;
363 // scan the key to obtain the addresses
364 StringPos = 0;
365 for(naddrs = 0;naddrs < *NEntries;naddrs++){
366 TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress);
368 if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
369 TmpAddr->sin_family = AF_INET;
371 TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast);
372 TmpBroad->sin_family = AF_INET;
373 if(ZeroBroadcast==0)
374 TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255
375 else
376 TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0
378 while(*(String + StringPos) != 0)StringPos++;
379 StringPos++;
381 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
382 break;
384 else break;
387 BufLen = sizeof String;
388 // Open the key with the netmasks
389 status = RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen);
390 if (status != ERROR_SUCCESS) {
391 RegCloseKey(TcpIpKey);
392 RegCloseKey(UnderTcpKey);
393 goto fail;
396 // scan the key to obtain the masks
397 StringPos = 0;
398 for(nmasks = 0;nmasks <* NEntries;nmasks++){
399 TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask);
401 if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
402 TmpAddr->sin_family = AF_INET;
404 while(*(String + StringPos) != 0)StringPos++;
405 StringPos++;
407 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
408 break;
410 else break;
413 // The number of masks MUST be equal to the number of adresses
414 if(nmasks != naddrs){
415 RegCloseKey(TcpIpKey);
416 RegCloseKey(UnderTcpKey);
417 goto fail;
422 *NEntries = naddrs + 1;
424 RegCloseKey(TcpIpKey);
425 RegCloseKey(UnderTcpKey);
427 if (status != ERROR_SUCCESS) {
428 goto fail;
431 TRACE_PRINT("Successfully retrieved the addresses from the registry.");
432 TRACE_EXIT("PacketGetAddressesFromRegistry");
433 return TRUE;
435 fail:
437 TRACE_PRINT("Failed retrieving the addresses from the registry.");
438 TRACE_EXIT("PacketGetAddressesFromRegistry");
439 return FALSE;
442 #ifdef HAVE_IPHELPER_API
444 \brief Adds the IPv6 addresses of an adapter to the ADAPTER_INFO structure that describes it.
445 \param AdInfo Pointer to the ADAPTER_INFO structure that keeps the information about the adapter.
446 \return If the function succeeds, the function returns TRUE.
448 \note the structure pointed by AdInfo must be initialized the an properly filled. In particular, AdInfo->Name
449 must be a valid capture device name.
450 \note uses the GetAdaptersAddresses() Ip Helper API function, so it works only on systems where IP Helper API
451 provides it (WinXP and successive).
452 \note we suppose that we are called after having acquired the g_AdaptersInfoMutex mutex
454 static BOOLEAN PacketAddIP6Addresses(PADAPTER_INFO AdInfo)
456 ULONG BufLen;
457 PIP_ADAPTER_ADDRESSES AdBuffer, TmpAddr;
458 PCHAR OrName;
459 PIP_ADAPTER_UNICAST_ADDRESS UnicastAddr;
460 struct sockaddr_storage *Addr;
461 INT AddrLen;
463 // Old registry based WinPcap names
465 // UINT RegQueryLen;
466 // CHAR npfDeviceNamesPrefix[MAX_WINPCAP_KEY_CHARS];
467 CHAR npfDeviceNamesPrefix[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_COMPLETE_DEVICE_PREFIX;
469 TRACE_ENTER("PacketAddIP6Addresses");
471 if(g_GetAdaptersAddressesPointer == NULL)
473 TRACE_PRINT("GetAdaptersAddressesPointer not available on the system, simply returning success...");
475 TRACE_EXIT("PacketAddIP6Addresses");
476 return TRUE; // GetAdaptersAddresses() not present on this system,
477 } // return immediately.
479 if(g_GetAdaptersAddressesPointer(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST| GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_FRIENDLY_NAME, NULL, NULL, &BufLen) != ERROR_BUFFER_OVERFLOW)
481 TRACE_PRINT("PacketAddIP6Addresses: GetAdaptersAddresses Failed while retrieving the needed buffer size");
483 TRACE_EXIT("PacketAddIP6Addresses");
484 return FALSE;
487 TRACE_PRINT("PacketAddIP6Addresses, retrieved needed storage for the call");
489 AdBuffer = GlobalAllocPtr(GMEM_MOVEABLE, BufLen);
490 if (AdBuffer == NULL)
492 TRACE_PRINT("PacketAddIP6Addresses: GlobalAlloc Failed");
493 TRACE_EXIT("PacketAddIP6Addresses");
494 return FALSE;
497 if(g_GetAdaptersAddressesPointer(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST| GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_FRIENDLY_NAME, NULL, AdBuffer, &BufLen) != ERROR_SUCCESS)
499 TRACE_PRINT("PacketGetIP6Addresses: GetAdaptersAddresses Failed while retrieving the addresses");
500 GlobalFreePtr(AdBuffer);
501 TRACE_EXIT("PacketAddIP6Addresses");
502 return FALSE;
505 TRACE_PRINT("PacketAddIP6Addresses, retrieved addresses, scanning the list");
508 // Scan the list of adddresses obtained from the IP helper API
510 for(TmpAddr = AdBuffer; TmpAddr != NULL; TmpAddr = TmpAddr->Next)
513 // Old registry based WinPcap names
515 // RegQueryLen = sizeof(npfDeviceNamesPrefix)/sizeof(npfDeviceNamesPrefix[0]);
517 // if (QueryWinPcapRegistryStringA(NPF_DRIVER_COMPLETE_DEVICE_PREFIX_REG_KEY, npfDeviceNamesPrefix, &RegQueryLen, NPF_DRIVER_COMPLETE_DEVICE_PREFIX) == FALSE && RegQueryLen == 0)
518 // continue;
520 // OrName = AdInfo->Name + RegQueryLen - 1;
522 OrName = AdInfo->Name + strlen(npfDeviceNamesPrefix);
524 TRACE_PRINT("PacketAddIP6Addresses, external loop");
525 if(strcmp(TmpAddr->AdapterName, OrName) == 0)
527 // Found a corresponding adapter, scan its address list
528 for(UnicastAddr = TmpAddr->FirstUnicastAddress; UnicastAddr != NULL; UnicastAddr = UnicastAddr->Next)
530 TRACE_PRINT("PacketAddIP6Addresses, internal loop");
532 AddrLen = UnicastAddr->Address.iSockaddrLength;
533 Addr = (struct sockaddr_storage *)UnicastAddr->Address.lpSockaddr;
534 if(Addr->ss_family == AF_INET6)
536 // Be sure not to overflow the addresses buffer of this adapter
537 if(AdInfo->NNetworkAddresses >= MAX_NETWORK_ADDRESSES)
539 GlobalFreePtr(AdBuffer);
540 TRACE_PRINT("The space in AdInfo->NNetworkAddresses is not large enough, failing");
541 TRACE_EXIT("PacketAddIP6Addresses");
542 return FALSE;
545 memcpy(&(AdInfo->NetworkAddresses[AdInfo->NNetworkAddresses].IPAddress), Addr, AddrLen);
546 memset(&(AdInfo->NetworkAddresses[AdInfo->NNetworkAddresses].SubnetMask), 0, sizeof(struct sockaddr_storage));
547 memset(&(AdInfo->NetworkAddresses[AdInfo->NNetworkAddresses].Broadcast), 0, sizeof(struct sockaddr_storage));
548 AdInfo->NNetworkAddresses ++;
554 TRACE_PRINT("PacketAddIP6Addresses, finished parsing the addresses");
556 GlobalFreePtr(AdBuffer);
558 TRACE_EXIT("PacketAddIP6Addresses");
559 return TRUE;
561 #endif // HAVE_IPHELPER_API
564 \brief Check if a string contains the "1394" substring
566 We prevent opening of firewire adapters since they have non standard behaviors that can cause
567 problems with winpcap
569 \param AdapterDesc NULL-terminated ASCII string with the adapter's description
570 \return TRUE if the input string contains "1394"
572 BOOLEAN IsFireWire(TCHAR *AdapterDesc)
574 TRACE_ENTER("IsFireWire");
575 if(wcsstr(AdapterDesc, FIREWIRE_SUBSTR) != NULL)
577 TRACE_EXIT("IsFireWire");
578 return TRUE;
581 TRACE_EXIT("IsFireWire");
582 return FALSE;
585 #ifdef HAVE_IPHELPER_API
588 \brief Adds an entry to the adapter description list, gathering its values from the IP Helper API.
589 \param IphAd PIP_ADAPTER_INFO IP Helper API structure containing the parameters of the adapter that must be added to the list.
590 \return If the function succeeds, the return value is TRUE.
591 \note we suppose that we are called after having acquired the g_AdaptersInfoMutex mutex
593 static BOOLEAN PacketAddAdapterIPH(PIP_ADAPTER_INFO IphAd)
595 PADAPTER_INFO TmpAdInfo, SAdInfo;
596 PIP_ADDR_STRING TmpAddrStr;
597 UINT i;
598 struct sockaddr_in *TmpAddr;
599 CHAR TName[256];
600 LPADAPTER adapter;
602 // Old registry based WinPcap names
604 // UINT RegQueryLen;
605 // CHAR npfCompleteDriverPrefix[MAX_WINPCAP_KEY_CHARS];
606 CHAR npfCompleteDriverPrefix[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_COMPLETE_DEVICE_PREFIX;
608 TRACE_ENTER("PacketAddAdapterIPH");
610 // Create the NPF device name from the original device name
613 // Old registry based WinPcap names
615 // RegQueryLen = sizeof(npfCompleteDriverPrefix)/sizeof(npfCompleteDriverPrefix[0]);
617 // if (QueryWinPcapRegistryStringA(NPF_DRIVER_COMPLETE_DEVICE_PREFIX_REG_KEY, npfCompleteDriverPrefix, &RegQueryLen, NPF_DRIVER_COMPLETE_DEVICE_PREFIX) == FALSE && RegQueryLen == 0)
618 // return FALSE;
620 // // Create the NPF device name from the original device name
621 // _snprintf(TName,
622 // sizeof(TName) - 1 - RegQueryLen - 1,
623 // "%s%s",
624 // npfCompleteDriverPrefix,
625 // IphAd->AdapterName);
627 // Create the NPF device name from the original device name
628 StringCchPrintfA(TName,
629 sizeof(TName) - strlen(npfCompleteDriverPrefix),
630 "%s%s",
631 npfCompleteDriverPrefix,
632 IphAd->AdapterName);
634 // Scan the adapters list to see if this one is already present
635 for(SAdInfo = g_AdaptersInfoList; SAdInfo != NULL; SAdInfo = SAdInfo->Next)
637 if(strcmp(TName, SAdInfo->Name) == 0)
639 TRACE_PRINT1("PacketAddAdapterIPH: Adapter %s already present in the list", TName);
640 goto SkipAd;
644 if(IphAd->Type == IF_TYPE_PPP || IphAd->Type == IF_TYPE_SLIP)
646 #ifdef HAVE_WANPACKET_API
647 if (!WanPacketTestAdapter())
648 goto SkipAd;
649 #else
650 goto SkipAd;
651 #endif
654 else
657 TRACE_PRINT1("Trying to open adapter %s to see if it's available...", TName);
658 adapter = PacketOpenAdapterNPF(TName);
660 if(adapter == NULL)
662 // We are not able to open this adapter. Skip to the next one.
663 TRACE_PRINT1("PacketAddAdapterIPH: unable to open the adapter %s", TName);
664 goto SkipAd;
666 else
668 TRACE_PRINT1("PacketAddAdapterIPH: adapter %s is available", TName);
669 PacketCloseAdapter(adapter);
674 // Adapter valid and not yet present in the list. Allocate the ADAPTER_INFO structure
676 TRACE_PRINT1("Adapter %s is available and should be added to the global list...", TName);
678 TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO));
679 if (TmpAdInfo == NULL)
681 TRACE_PRINT("PacketAddAdapterIPH: GlobalAlloc Failed allocating memory for the AdInfo");
682 TRACE_EXIT("PacketAddAdapterIPH");
683 return FALSE;
686 // Copy the device name
687 StringCchCopyA(TmpAdInfo->Name,ADAPTER_NAME_LENGTH, TName);
689 // Copy the description
690 StringCchCopyA(TmpAdInfo->Description, ADAPTER_DESC_LENGTH, IphAd->Description);
692 // Copy the MAC address
693 TmpAdInfo->MacAddressLen = IphAd->AddressLength;
695 memcpy(TmpAdInfo->MacAddress,
696 IphAd->Address,
697 (MAX_MAC_ADDR_LENGTH<MAX_ADAPTER_ADDRESS_LENGTH)? MAX_MAC_ADDR_LENGTH:MAX_ADAPTER_ADDRESS_LENGTH);
699 // Calculate the number of IP addresses of this interface
700 for(TmpAddrStr = &IphAd->IpAddressList, i = 0; TmpAddrStr != NULL; TmpAddrStr = TmpAddrStr->Next, i++)
705 TmpAdInfo->NetworkAddresses = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, MAX_NETWORK_ADDRESSES * sizeof(npf_if_addr));
706 if (TmpAdInfo->NetworkAddresses == NULL) {
707 TRACE_PRINT("PacketAddAdapterIPH: GlobalAlloc Failed allocating the memory for the IP addresses in AdInfo.");
708 GlobalFreePtr(TmpAdInfo);
709 TRACE_EXIT("PacketAddAdapterIPH");
710 return FALSE;
713 TRACE_PRINT1("Adding the IPv4 addresses to the adapter %s...", TName);
714 // Scan the addresses, convert them to addrinfo structures and put each of them in the list
715 for(TmpAddrStr = &IphAd->IpAddressList, i = 0; TmpAddrStr != NULL; TmpAddrStr = TmpAddrStr->Next)
717 TmpAddr = (struct sockaddr_in *)&(TmpAdInfo->NetworkAddresses[i].IPAddress);
718 if((TmpAddr->sin_addr.S_un.S_addr = inet_addr(TmpAddrStr->IpAddress.String))!= INADDR_NONE)
720 TmpAddr->sin_family = AF_INET;
721 TmpAddr = (struct sockaddr_in *)&(TmpAdInfo->NetworkAddresses[i].SubnetMask);
722 TmpAddr->sin_addr.S_un.S_addr = inet_addr(TmpAddrStr->IpMask.String);
723 TmpAddr->sin_family = AF_INET;
724 TmpAddr = (struct sockaddr_in *)&(TmpAdInfo->NetworkAddresses[i].Broadcast);
725 TmpAddr->sin_addr.S_un.S_addr = 0xffffffff; // Consider 255.255.255.255 as broadcast address since IP Helper API doesn't provide information about it
726 TmpAddr->sin_family = AF_INET;
727 i++;
731 TmpAdInfo->NNetworkAddresses = i;
734 TRACE_PRINT1("Adding the IPv6 addresses to the adapter %s...", TName);
735 // Now Add IPv6 Addresses
736 PacketAddIP6Addresses(TmpAdInfo);
738 if(IphAd->Type == IF_TYPE_PPP || IphAd->Type == IF_TYPE_SLIP)
740 TRACE_PRINT("Flagging the adapter as NDISWAN.");
741 // NdisWan adapter
742 TmpAdInfo->Flags = INFO_FLAG_NDISWAN_ADAPTER;
745 // Update the AdaptersInfo list
746 TmpAdInfo->Next = g_AdaptersInfoList;
747 g_AdaptersInfoList = TmpAdInfo;
749 SkipAd:
751 TRACE_EXIT("PacketAddAdapterIPH");
752 return TRUE;
756 \brief Updates the list of the adapters querying the IP Helper API.
757 \return If the function succeeds, the return value is nonzero.
759 This function populates the list of adapter descriptions, retrieving the information from a query to
760 the IP Helper API. The IP Helper API is used as a support of the standard registry query method to obtain
761 adapter information, so PacketGetAdaptersIPH() add only information about the adapters that were not
762 found by PacketGetAdapters().
764 static BOOLEAN PacketGetAdaptersIPH()
766 PIP_ADAPTER_INFO AdList = NULL;
767 PIP_ADAPTER_INFO TmpAd;
768 ULONG OutBufLen=0;
770 TRACE_ENTER("PacketGetAdaptersIPH");
772 // Find the size of the buffer filled by GetAdaptersInfo
773 if(GetAdaptersInfo(AdList, &OutBufLen) == ERROR_NOT_SUPPORTED)
775 TRACE_PRINT("IP Helper API not supported on this system!");
776 TRACE_EXIT("PacketGetAdaptersIPH");
777 return FALSE;
780 TRACE_PRINT("PacketGetAdaptersIPH: retrieved needed bytes for IPH");
782 // Allocate the buffer
783 AdList = GlobalAllocPtr(GMEM_MOVEABLE, OutBufLen);
784 if (AdList == NULL)
786 TRACE_PRINT("PacketGetAdaptersIPH: GlobalAlloc Failed allocating the buffer for GetAdaptersInfo");
787 TRACE_EXIT("PacketGetAdaptersIPH");
788 return FALSE;
791 // Retrieve the adapters information using the IP helper API
792 GetAdaptersInfo(AdList, &OutBufLen);
794 TRACE_PRINT("PacketGetAdaptersIPH: retrieved list from IPH. Adding adapters to the global list.");
796 // Scan the list of adapters obtained from the IP helper API, create a new ADAPTER_INFO
797 // structure for every new adapter and put it in our global list
798 for(TmpAd = AdList; TmpAd != NULL; TmpAd = TmpAd->Next)
800 PacketAddAdapterIPH(TmpAd);
803 GlobalFreePtr(AdList);
805 TRACE_EXIT("PacketGetAdaptersIPH");
806 return TRUE;
809 #endif // HAVE_IPHELPER_API
813 \brief Adds an entry to the adapter description list.
814 \param AdName Name of the adapter to add
815 \return If the function succeeds, the return value is nonzero.
817 Used by PacketGetAdapters(). Queries the registry to fill the PADAPTER_INFO describing the new adapter.
819 static BOOLEAN PacketAddAdapterNPF(PCHAR AdName, UINT flags)
821 //this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter
822 LONG Status;
823 LPADAPTER adapter = NULL;
824 PPACKET_OID_DATA OidData = NULL;
825 PADAPTER_INFO TmpAdInfo;
826 PADAPTER_INFO TAdInfo;
828 TRACE_ENTER("PacketAddAdapterNPF");
829 TRACE_PRINT1("Trying to add adapter %s", AdName);
832 // let's check that the adapter name will fit in the space available within ADAPTER_INFO::Name
833 // If not, simply fail, since we cannot properly save the adapter name
835 if (strlen(AdName) + 1 > sizeof(TmpAdInfo->Name))
837 TRACE_PRINT("PacketAddAdapterNPF: adapter name is too long to be stored into ADAPTER_INFO::Name, simply skip it");
838 return FALSE;
841 WaitForSingleObject(g_AdaptersInfoMutex, INFINITE);
843 for(TAdInfo = g_AdaptersInfoList; TAdInfo != NULL; TAdInfo = TAdInfo->Next)
845 if(strcmp(AdName, TAdInfo->Name) == 0)
847 TRACE_PRINT("PacketAddAdapterNPF: Adapter already present in the list");
848 ReleaseMutex(g_AdaptersInfoMutex);
849 TRACE_EXIT("PacketAddAdapterNPF");
850 return TRUE;
854 //here we could have released the mutex, but what happens if two threads try to add the same adapter?
855 //The adapter would be duplicated on the linked list
857 if(flags != INFO_FLAG_DONT_EXPORT)
859 TRACE_PRINT("Trying to open the NPF adapter and see if it's available...");
861 // Try to Open the adapter
862 adapter = PacketOpenAdapterNPF(AdName);
864 if(adapter != NULL)
867 // Allocate a buffer to get the vendor description from the driver
868 OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,512);
869 if (OidData == NULL)
871 TRACE_PRINT("PacketAddAdapterNPF: GlobalAlloc Failed allocating the buffer for the OID request to obtain the NIC description. Returning.");
872 PacketCloseAdapter(adapter);
873 ReleaseMutex(g_AdaptersInfoMutex);
874 TRACE_EXIT("PacketAddAdapterNPF");
875 return FALSE;
878 else
880 TRACE_PRINT("NPF Adapter not available, do not add it to the global list");
881 // We are not able to open this adapter. Skip to the next one.
882 ReleaseMutex(g_AdaptersInfoMutex);
883 TRACE_EXIT("AddAdapter");
884 return FALSE;
890 // PacketOpenAdapter was succesful. Consider this a valid adapter and allocate an entry for it
891 // In the adapter list
894 TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO));
895 if (TmpAdInfo == NULL)
897 TRACE_PRINT("AddAdapter: GlobalAlloc Failed");
899 if(flags != INFO_FLAG_DONT_EXPORT)
901 TRACE_PRINT("AddAdapter: GlobalAlloc Failed allocating the buffer for the AdInfo to be added to the global list. Returning.");
902 if (OidData != NULL) GlobalFreePtr(OidData);
903 PacketCloseAdapter(adapter);
906 ReleaseMutex(g_AdaptersInfoMutex);
907 TRACE_EXIT("AddAdapter");
908 return FALSE;
911 // Copy the device name
912 strncpy(TmpAdInfo->Name, AdName, sizeof(TmpAdInfo->Name)/ sizeof(TmpAdInfo->Name[0]) - 1);
914 //we do not need to terminate the string TmpAdInfo->Name, since we have left a char at the end, and
915 //the memory for TmpAdInfo was zeroed upon allocation
917 if(flags != INFO_FLAG_DONT_EXPORT)
919 // Retrieve the adapter description querying the NIC driver
920 OidData->Oid = OID_GEN_VENDOR_DESCRIPTION;
921 OidData->Length = 256;
922 ZeroMemory(OidData->Data, 256);
924 Status = PacketRequest(adapter, FALSE, OidData);
926 if(Status==0 || ((char*)OidData->Data)[0]==0)
928 TRACE_PRINT("AddAdapter: unable to get a valid adapter description from the NIC driver");
931 TRACE_PRINT1("Adapter Description = %s",OidData->Data);
933 // Copy the description
934 strncpy(TmpAdInfo->Description, (PCHAR)OidData->Data, sizeof(TmpAdInfo->Description)/ sizeof(TmpAdInfo->Description[0]) - 1);
935 //we do not need to terminate the string TmpAdInfo->Description, since we have left a char at the end, and
936 //the memory for TmpAdInfo was zeroed upon allocation
938 Status = PacketGetLinkLayerFromRegistry(adapter, &(TmpAdInfo->LinkLayer));
940 if (Status == FALSE)
942 TRACE_PRINT("AddAdapter: PacketGetLinkLayerFromRegistry failed. Returning.");
943 PacketCloseAdapter(adapter);
944 GlobalFreePtr(OidData);
945 GlobalFreePtr(TmpAdInfo);
946 ReleaseMutex(g_AdaptersInfoMutex);
947 TRACE_EXIT("AddAdapter");
948 return FALSE;
951 // Retrieve the adapter MAC address querying the NIC driver
952 OidData->Oid = OID_802_3_CURRENT_ADDRESS; // XXX At the moment only Ethernet is supported.
953 // Waiting a patch to support other Link Layers
954 OidData->Length = 256;
955 ZeroMemory(OidData->Data, 256);
957 TRACE_PRINT("Trying to obtain the MAC address for the NIC...");
958 Status = PacketRequest(adapter, FALSE, OidData);
959 if(Status)
961 memcpy(TmpAdInfo->MacAddress, OidData->Data, 6);
962 TmpAdInfo->MacAddressLen = 6;
964 TRACE_PRINT6("Successfully obtained the MAC address, it's "
965 "%.02x:%.02x:%.02x:%.02x:%.02x:%.02x",
966 TmpAdInfo->MacAddress[0],
967 TmpAdInfo->MacAddress[1],
968 TmpAdInfo->MacAddress[2],
969 TmpAdInfo->MacAddress[3],
970 TmpAdInfo->MacAddress[4],
971 TmpAdInfo->MacAddress[5]);
975 else
977 TRACE_PRINT("Failed obtaining the MAC address, put a fake 00:00:00:00:00:00");
978 memset(TmpAdInfo->MacAddress, 0, 6);
979 TmpAdInfo->MacAddressLen = 0;
982 // Retrieve IP addresses
983 TmpAdInfo->NetworkAddresses = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, MAX_NETWORK_ADDRESSES * sizeof(npf_if_addr));
984 if (TmpAdInfo->NetworkAddresses == NULL) {
985 TRACE_PRINT("AddAdapter: GlobalAlloc Failed to allocate the buffer for the IP addresses in the AdInfo structure. Returning.");
986 PacketCloseAdapter(adapter);
987 GlobalFreePtr(OidData);
988 GlobalFreePtr(TmpAdInfo);
989 ReleaseMutex(g_AdaptersInfoMutex);
990 TRACE_EXIT("AddAdapter");
991 return FALSE;
994 TmpAdInfo->NNetworkAddresses = MAX_NETWORK_ADDRESSES;
995 if(!PacketGetAddressesFromRegistry(TmpAdInfo->Name, TmpAdInfo->NetworkAddresses, (long*)&TmpAdInfo->NNetworkAddresses))
997 #ifdef HAVE_IPHELPER_API
998 // Try to see if the interface has some IPv6 addresses
999 TmpAdInfo->NNetworkAddresses = 0; // We have no addresses because PacketGetAddressesFromRegistry() failed
1001 if(!PacketAddIP6Addresses(TmpAdInfo))
1003 #endif // HAVE_IPHELPER_API
1004 GlobalFreePtr(TmpAdInfo->NetworkAddresses);
1005 TmpAdInfo->NetworkAddresses = NULL;
1006 TmpAdInfo->NNetworkAddresses = 0;
1007 #ifdef HAVE_IPHELPER_API
1009 #endif // HAVE_IPHELPER_API
1012 #ifdef HAVE_IPHELPER_API
1013 // Now Add IPv6 Addresses
1014 PacketAddIP6Addresses(TmpAdInfo);
1015 #endif // HAVE_IPHELPER_API
1017 TmpAdInfo->Flags = INFO_FLAG_NDIS_ADAPTER; // NdisWan adapters are not exported by the NPF driver,
1018 // therefore it's impossible to see them here
1020 // Free storage
1021 PacketCloseAdapter(adapter);
1022 GlobalFreePtr(OidData);
1024 else
1026 // Write in the flags that this adapter is firewire
1027 // This will block it in all successive calls
1028 TmpAdInfo->Flags = INFO_FLAG_DONT_EXPORT;
1031 // Update the AdaptersInfo list
1032 TmpAdInfo->Next = g_AdaptersInfoList;
1033 g_AdaptersInfoList = TmpAdInfo;
1035 ReleaseMutex(g_AdaptersInfoMutex);
1037 TRACE_EXIT("AddAdapter");
1038 return TRUE;
1043 \brief Updates the list of the adapters querying the registry.
1044 \return If the function succeeds, the return value is nonzero.
1046 This function populates the list of adapter descriptions, retrieving the information from the registry.
1048 static BOOLEAN PacketGetAdaptersNPF()
1050 HKEY LinkageKey,AdapKey, OneAdapKey;
1051 DWORD RegKeySize=0;
1052 LONG Status;
1053 ULONG Result;
1054 INT i;
1055 DWORD dim;
1056 DWORD RegType;
1057 WCHAR TName[256];
1058 CHAR TAName[256];
1059 TCHAR AdapName[256];
1060 CHAR *TcpBindingsMultiString;
1061 UINT FireWireFlag;
1063 // Old registry based WinPcap names
1065 // CHAR npfCompleteDriverPrefix[MAX_WINPCAP_KEY_CHARS];
1066 // UINT RegQueryLen;
1068 CHAR npfCompleteDriverPrefix[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_COMPLETE_DEVICE_PREFIX;
1069 CHAR DeviceGuidName[256];
1071 TRACE_ENTER("PacketGetAdaptersNPF");
1074 // Old registry based WinPcap names
1076 // // Get device prefixes from the registry
1077 // RegQueryLen = sizeof(npfCompleteDriverPrefix)/sizeof(npfCompleteDriverPrefix[0]);
1079 // if (QueryWinPcapRegistryStringA(NPF_DRIVER_COMPLETE_DEVICE_PREFIX_REG_KEY, npfCompleteDriverPrefix, &RegQueryLen, NPF_DRIVER_COMPLETE_DEVICE_PREFIX) == FALSE && RegQueryLen == 0)
1080 // return FALSE;
1082 Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
1083 TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"),
1085 KEY_READ,
1086 &AdapKey);
1088 if ( Status != ERROR_SUCCESS ){
1089 TRACE_PRINT("PacketGetAdaptersNPF: RegOpenKeyEx ( Class\\{networkclassguid} ) Failed");
1090 goto tcpip_linkage;
1093 i = 0;
1095 TRACE_PRINT("PacketGetAdaptersNPF: RegOpenKeyEx ( Class\\{networkclassguid} ) was successful");
1096 TRACE_PRINT("PacketGetAdaptersNPF: Cycling through the adapters in the registry:");
1099 // Cycle through the entries inside the {4D36E972-E325-11CE-BFC1-08002BE10318} key
1100 // To get the names of the adapters
1102 while((Result = RegEnumKey(AdapKey, i, AdapName, sizeof(AdapName)/2)) == ERROR_SUCCESS)
1104 i++;
1105 FireWireFlag = 0;
1108 // Get the adapter name from the registry key
1110 Status=RegOpenKeyEx(AdapKey, AdapName, 0, KEY_READ, &OneAdapKey);
1111 if ( Status != ERROR_SUCCESS )
1113 TRACE_PRINT1("%d) RegOpenKey( OneAdapKey ) Failed, skipping the adapter.",i);
1114 continue;
1119 // Check if this is a FireWire adapter, looking for "1394" in its ComponentId string.
1120 // We prevent listing FireWire adapters because winpcap can open them, but their interface
1121 // with the OS is broken and they can cause blue screens.
1123 dim = sizeof(TName);
1124 Status = RegQueryValueEx(OneAdapKey,
1125 TEXT("ComponentId"),
1126 NULL,
1127 NULL,
1128 (PBYTE)TName,
1129 &dim);
1131 if(Status == ERROR_SUCCESS)
1133 if(IsFireWire(TName))
1135 FireWireFlag = INFO_FLAG_DONT_EXPORT;
1139 Status=RegOpenKeyEx(OneAdapKey, TEXT("Linkage"), 0, KEY_READ, &LinkageKey);
1140 if (Status != ERROR_SUCCESS)
1142 RegCloseKey(OneAdapKey);
1143 TRACE_PRINT1("%d) RegOpenKeyEx ( LinkageKey ) Failed, skipping the adapter",i);
1144 continue;
1147 dim = sizeof(DeviceGuidName);
1148 Status=RegQueryValueExA(LinkageKey,
1149 "Export",
1150 NULL,
1151 NULL,
1152 (PBYTE)DeviceGuidName,
1153 &dim);
1155 if(Status != ERROR_SUCCESS)
1157 RegCloseKey(OneAdapKey);
1158 RegCloseKey(LinkageKey);
1159 TRACE_PRINT1("%d) Name = SKIPPED (error reading the key)", i);
1160 continue;
1163 if (strlen(DeviceGuidName) >= strlen("\\Device\\"))
1165 // Put the \Device\NPF_ string at the beginning of the name
1166 StringCchPrintfA(TAName, sizeof(TAName), "%s%s",
1167 npfCompleteDriverPrefix,
1168 DeviceGuidName + strlen("\\Device\\"));
1170 else
1171 continue;
1173 //terminate the string, just in case
1174 TAName[sizeof(TAName) - 1] = '\0';
1176 TRACE_PRINT2("%d) Successfully retrieved info for adapter %s, trying to add it to the global list...", i, TAName);
1177 // If the adapter is valid, add it to the list.
1178 PacketAddAdapterNPF(TAName, FireWireFlag);
1180 RegCloseKey(OneAdapKey);
1181 RegCloseKey(LinkageKey);
1183 } // while enum reg keys
1185 RegCloseKey(AdapKey);
1187 tcpip_linkage:
1189 // no adapters were found under {4D36E972-E325-11CE-BFC1-08002BE10318}. This means with great probability
1190 // that we are under Windows NT 4, so we try to look under the tcpip bindings.
1193 TRACE_PRINT("Adapters not found under SYSTEM\\CurrentControlSet\\Control\\Class. Using the TCP/IP bindings.");
1195 Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
1196 TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage"),
1198 KEY_READ,
1199 &LinkageKey);
1201 if (Status == ERROR_SUCCESS)
1203 // Retrieve the length of th binde key
1204 // This key contains the name of the devices as \device\foo
1205 //in ASCII, separated by a single '\0'. The list is terminated
1206 //by another '\0'
1207 Status=RegQueryValueExA(LinkageKey,
1208 "bind",
1209 NULL,
1210 &RegType,
1211 NULL,
1212 &RegKeySize);
1214 // Allocate the buffer
1215 TcpBindingsMultiString = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, RegKeySize + 2);
1217 if (TcpBindingsMultiString == NULL)
1219 TRACE_PRINT("GlobalAlloc failed allocating memory for the registry key, returning.");
1220 TRACE_EXIT("PacketGetAdaptersNPF");
1221 return FALSE;
1224 // Query the key again to get its content
1225 Status = RegQueryValueExA(LinkageKey,
1226 "bind",
1227 NULL,
1228 &RegType,
1229 (LPBYTE)TcpBindingsMultiString,
1230 &RegKeySize);
1232 RegCloseKey(LinkageKey);
1234 // Scan the buffer with the device names
1235 for(i = 0;;)
1237 if (TcpBindingsMultiString[i] == '\0')
1238 break;
1240 StringCchPrintfA(TAName, sizeof(TAName), "%s%s",
1241 npfCompleteDriverPrefix,
1242 TcpBindingsMultiString + i + strlen("\\Device\\"));
1245 // TODO GV: this cast to avoid a compilation warning is
1246 // actually stupid. We shouls check not to go over the buffer boundary!
1248 i += (INT)strlen(&TcpBindingsMultiString[i]) + 1;
1250 TRACE_PRINT1("Successfully retrieved info for adapter %s, trying to add it to the global list...", TAName);
1253 // If the adapter is valid, add it to the list.
1254 PacketAddAdapterNPF(TAName, 0);
1257 GlobalFreePtr(TcpBindingsMultiString);
1260 else{
1261 #ifdef _WINNT4
1262 MessageBox(NULL,TEXT("Can not find TCP/IP bindings.\nIn order to run the packet capture driver you must install TCP/IP."),szWindowTitle,MB_OK);
1263 TRACE_PRINT("Cannot find the TCP/IP bindings on NT4, no adapters.");
1264 TRACE_EXIT("PacketGetAdaptersNPF");
1265 return FALSE;
1266 #endif
1269 TRACE_EXIT("PacketGetAdaptersNPF");
1270 return TRUE;
1273 #ifdef HAVE_AIRPCAP_API
1275 \brief Add an airpcap adapter to the adapters info list, gathering information from the airpcap dll
1276 \param name Name of the adapter.
1277 \param description description of the adapter.
1278 \return If the function succeeds, the return value is nonzero.
1280 static BOOLEAN PacketAddAdapterAirpcap(PCHAR name, PCHAR description)
1282 //this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter
1283 CHAR ebuf[AIRPCAP_ERRBUF_SIZE];
1284 PADAPTER_INFO TmpAdInfo;
1285 PAirpcapHandle AirpcapAdapter;
1286 BOOL GllRes;
1287 AirpcapLinkType AirpcapLinkLayer;
1288 BOOLEAN Result = TRUE;
1290 TRACE_ENTER("PacketAddAdapterAirpcap");
1291 //XXX what about checking if the adapter already exists???
1293 WaitForSingleObject(g_AdaptersInfoMutex, INFINITE);
1299 // check if the adapter is already there, and remove it
1301 for (TmpAdInfo = g_AdaptersInfoList; TmpAdInfo != NULL; TmpAdInfo = TmpAdInfo->Next)
1303 if (TmpAdInfo->Flags == INFO_FLAG_AIRPCAP_CARD)
1305 if (strcmp(TmpAdInfo->Name, name) == 0)
1306 break;
1310 if (TmpAdInfo != NULL)
1313 // we already have it in the list. Just return
1315 Result = TRUE;
1316 break;
1320 // Allocate a descriptor for this adapter
1322 //here we do not acquire the mutex, since we are not touching the list, yet.
1323 TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO));
1324 if (TmpAdInfo == NULL)
1326 TRACE_PRINT("PacketAddAdapterDag: GlobalAlloc Failed");
1327 Result = FALSE;
1328 break;
1331 // Copy the device name and description
1332 StringCchCopyA(TmpAdInfo->Name,
1333 sizeof(TmpAdInfo->Name),
1334 name);
1336 StringCchCopyA(TmpAdInfo->Description,
1337 sizeof(TmpAdInfo->Description),
1338 description);
1340 TmpAdInfo->Flags = INFO_FLAG_AIRPCAP_CARD;
1342 if(g_PAirpcapOpen)
1344 AirpcapAdapter = g_PAirpcapOpen(name, ebuf);
1346 else
1348 AirpcapAdapter = NULL;
1351 if(!AirpcapAdapter)
1353 GlobalFreePtr(TmpAdInfo);
1354 Result = FALSE;
1355 break;
1358 GllRes = g_PAirpcapGetLinkType(AirpcapAdapter, &AirpcapLinkLayer);
1359 if(!GllRes)
1361 g_PAirpcapClose(AirpcapAdapter);
1362 GlobalFreePtr(TmpAdInfo);
1363 Result = FALSE;
1364 break;
1367 switch(AirpcapLinkLayer)
1369 case AIRPCAP_LT_802_11:
1370 TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMediumBare80211;
1371 break;
1372 case AIRPCAP_LT_802_11_PLUS_RADIO:
1373 TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMediumRadio80211;
1374 break;
1375 default:
1376 TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMediumNull; // Note: custom linktype, NDIS doesn't provide an equivalent
1377 break;
1381 // For the moment, we always set the speed to 54Mbps, since the speed is not channel-specific,
1382 // but per packet
1384 TmpAdInfo->LinkLayer.LinkSpeed = 54000000;
1386 g_PAirpcapClose(AirpcapAdapter);
1388 // Update the AdaptersInfo list
1389 TmpAdInfo->Next = g_AdaptersInfoList;
1390 g_AdaptersInfoList = TmpAdInfo;
1392 while(FALSE);
1394 ReleaseMutex(g_AdaptersInfoMutex);
1396 TRACE_EXIT("PacketAddAdapterAirpcap");
1397 return Result;
1401 \brief Updates the list of the adapters using the airpcap dll.
1402 \return If the function succeeds, the return value is nonzero.
1404 This function populates the list of adapter descriptions, looking for DAG cards on the system.
1406 static BOOLEAN PacketGetAdaptersAirpcap()
1408 CHAR Ebuf[AIRPCAP_ERRBUF_SIZE];
1409 AirpcapDeviceDescription *Devs = NULL, *TmpDevs;
1410 UINT i;
1412 TRACE_ENTER("PacketGetAdaptersAirpcap");
1414 if(!g_PAirpcapGetDeviceList(&Devs, Ebuf))
1416 // No airpcap cards found on this system
1417 TRACE_PRINT("No AirPcap adapters found");
1418 TRACE_EXIT("PacketGetAdaptersAirpcap");
1419 return FALSE;
1421 else
1423 for(TmpDevs = Devs, i = 0; TmpDevs != NULL; TmpDevs = TmpDevs->next)
1425 PacketAddAdapterAirpcap(TmpDevs->Name, TmpDevs->Description);
1429 g_PAirpcapFreeDeviceList(Devs);
1431 TRACE_EXIT("PacketGetAdaptersAirpcap");
1432 return TRUE;
1434 #endif // HAVE_AIRPCAP_API
1436 #ifdef HAVE_NPFIM_API
1438 static BOOLEAN PacketAddAdapterNpfIm(PNPF_IM_DEVICE pDevice)
1440 //this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter
1441 PADAPTER_INFO TmpAdInfo;
1442 NPF_IM_DEV_HANDLE handle = NULL;
1443 BYTE mac[6];
1444 DWORD macSize = 0;
1445 NDIS_MEDIUM medium = NdisMediumNull;
1446 ULONGLONG linkSpeed = 0;
1447 BOOL bResult = TRUE;
1448 PNPF_IM_ADDRESS pAddresses = NULL;
1449 DWORD addressesSize = 0;
1450 DWORD returnedBytes = 0;
1451 npf_if_addr *pnpf_if_addresses = NULL;
1452 DWORD numAddresses;
1453 DWORD i;
1455 TRACE_ENTER("PacketAddAdapterNpfIm");
1457 WaitForSingleObject(g_AdaptersInfoMutex, INFINITE);
1462 // check if the adapter is already there, and remove it
1464 for (TmpAdInfo = g_AdaptersInfoList; TmpAdInfo != NULL; TmpAdInfo = TmpAdInfo->Next)
1466 if (TmpAdInfo->Flags == INFO_FLAG_NPFIM_DEVICE)
1468 if (strcmp(TmpAdInfo->Name, pDevice->Name) == 0)
1469 break;
1473 if (TmpAdInfo != NULL)
1476 // we already have it in the list. Just return
1480 // NOTE in this case we do not refresh the IP list
1482 bResult = TRUE;
1483 break;
1489 // We suppose that the DLL has been loaded successfully
1491 bResult = g_NpfImHandlers.NpfImOpenDevice(pDevice->Name, &handle);
1492 if (bResult == FALSE) break;
1494 bResult = g_NpfImHandlers.NpfImGetMedium(handle, &medium);
1495 if (bResult == FALSE) break;
1497 if (medium == NdisMedium802_3 || medium == NdisMediumWan)
1499 DWORD bufferSize = sizeof(mac);
1501 if (g_NpfImHandlers.NpfImIssueQueryOid(handle, OID_802_3_CURRENT_ADDRESS, mac, &bufferSize) == FALSE)
1503 macSize = 0;
1507 bResult = g_NpfImHandlers.NpfImGetLinkSpeed(handle, &linkSpeed);
1509 if (bResult == FALSE)
1511 break;
1514 bResult = g_NpfImHandlers.NpfImGetIpAddresses(handle, NULL, 0, &returnedBytes);
1516 if (bResult == TRUE)
1519 // no ip addresses, return
1521 break;
1524 if (GetLastError() == ERROR_MORE_DATA)
1526 pAddresses = (PNPF_IM_ADDRESS)LocalAlloc(LPTR, returnedBytes);
1527 if (pAddresses == NULL)
1529 bResult = FALSE;
1530 break;
1533 addressesSize = returnedBytes;
1535 bResult = g_NpfImHandlers.NpfImGetIpAddresses(handle, pAddresses, addressesSize, &returnedBytes);
1537 else
1540 //unknown error listing the IP addresses
1542 break;
1546 while (FALSE);
1548 if (handle != NULL)
1549 g_NpfImHandlers.NpfImCloseDevice(handle);
1551 if (bResult == FALSE)
1553 break;
1556 numAddresses = returnedBytes / sizeof(NPF_IM_ADDRESS);
1559 // Allocate a descriptor for this adapter
1561 //here we do not acquire the mutex, since we are not touching the list, yet.
1562 TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO));
1563 if (TmpAdInfo == NULL)
1565 TRACE_PRINT("PacketAddAdapterNpfIm: GlobalAlloc Failed");
1566 bResult = FALSE;
1567 break;
1570 if (numAddresses > 0)
1572 pnpf_if_addresses = (npf_if_addr*)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(npf_if_addr) * numAddresses);
1574 if (pnpf_if_addresses == NULL)
1576 GlobalFreePtr(TmpAdInfo);
1577 TRACE_PRINT("PacketAddAdapteNpfIm: GlobalAlloc failed");
1578 bResult = FALSE;
1579 break;
1582 for (i = 0; i < numAddresses; i++)
1584 DWORD ipAddr, netMask, broadCast;
1586 CopyMemory(&(pnpf_if_addresses[i].IPAddress), &(pAddresses[i].IPAddress), sizeof(struct sockaddr_storage));
1589 // generate the broadcast addr
1590 switch(pAddresses[i].IPAddress.ss_family)
1592 case AF_INET:
1593 CopyMemory(&(pnpf_if_addresses[i].SubnetMask), &(pAddresses[i].SubnetMask), sizeof(struct sockaddr_storage));
1594 CopyMemory(&(pnpf_if_addresses[i].Broadcast), &(pAddresses[i].SubnetMask), sizeof(struct sockaddr_storage));
1595 ipAddr = ((struct sockaddr_in*)(&pnpf_if_addresses[i].IPAddress))->sin_addr.S_un.S_addr;
1596 netMask = ((struct sockaddr_in*)(&pnpf_if_addresses[i].SubnetMask))->sin_addr.S_un.S_addr;
1597 broadCast = ipAddr | (~netMask);
1598 ((struct sockaddr_in*)(&pnpf_if_addresses[i].Broadcast))->sin_addr.S_un.S_addr = broadCast;
1599 break;
1601 case AF_INET6:
1602 default:
1603 ZeroMemory(&(pnpf_if_addresses[i].SubnetMask), sizeof(struct sockaddr_storage));
1604 ZeroMemory(&(pnpf_if_addresses[i].Broadcast), sizeof(struct sockaddr_storage));
1605 break;
1610 // put the ip addresses
1612 TmpAdInfo->NetworkAddresses = pnpf_if_addresses;
1613 TmpAdInfo->NNetworkAddresses = numAddresses;
1619 // Copy the device name and description
1620 StringCchCopyA(TmpAdInfo->Name,
1621 sizeof(TmpAdInfo->Name),
1622 pDevice->Name);
1624 StringCchCopyA(TmpAdInfo->Description,
1625 sizeof(TmpAdInfo->Description),
1626 pDevice->Description);
1628 CopyMemory(TmpAdInfo->MacAddress, mac, macSize);
1629 TmpAdInfo->LinkLayer.LinkType = medium;
1631 TmpAdInfo->Flags = INFO_FLAG_NPFIM_DEVICE;
1633 TmpAdInfo->LinkLayer.LinkSpeed = linkSpeed;
1635 // Update the AdaptersInfo list
1636 TmpAdInfo->Next = g_AdaptersInfoList;
1637 g_AdaptersInfoList = TmpAdInfo;
1639 while(FALSE);
1641 if (pAddresses != NULL) LocalFree(pAddresses);
1643 ReleaseMutex(g_AdaptersInfoMutex);
1645 TRACE_EXIT("PacketAddAdapterNpfIm");
1646 return (BOOLEAN)bResult;
1651 \brief Updates the list of the adapters using the NpfIm dll.
1652 \return If the function succeeds, the return value is nonzero.
1654 This function populates the list of adapter descriptions, looking for NpfIm adapters on the system.
1656 static BOOLEAN PacketGetAdaptersNpfIm()
1658 PNPF_IM_DEVICE pDevices = NULL, pDevCursor;
1660 TRACE_ENTER("PacketGetAdaptersNpfIm");
1662 // We suppose that the DLL has been loaded successfully
1664 if (g_NpfImHandlers.NpfImGetDeviceList(&pDevices) == FALSE)
1666 TRACE_EXIT("PacketGetAdaptersNpfIm");
1667 return FALSE;
1670 for (pDevCursor = pDevices; pDevCursor != NULL; pDevCursor = pDevCursor->pNext)
1672 PacketAddAdapterNpfIm(pDevCursor);
1675 g_NpfImHandlers.NpfImFreeDeviceList(pDevices);
1677 TRACE_EXIT("PacketGetAdaptersNpfIm");
1678 return TRUE;
1682 \brief Add an npfim adapter to the adapters info list, gathering information from the npfim dll
1683 \param
1684 \param description description of the adapter.
1685 \return If the function succeeds, the return value is nonzero.
1687 #endif // HAVE_NPFIM_API
1691 #ifdef HAVE_DAG_API
1693 \brief Add a dag adapter to the adapters info list, gathering information from the dagc API
1694 \param name Name of the adapter.
1695 \param description description of the adapter.
1696 \return If the function succeeds, the return value is nonzero.
1698 BOOLEAN PacketAddAdapterDag(PCHAR name, PCHAR description, BOOLEAN IsAFile)
1700 //this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter
1701 CHAR ebuf[DAGC_ERRBUF_SIZE];
1702 PADAPTER_INFO TmpAdInfo;
1703 dagc_t *dagfd;
1705 TRACE_ENTER("PacketAddAdapterDag");
1707 //XXX what about checking if the adapter already exists???
1710 // Allocate a descriptor for this adapter
1712 //here we do not acquire the mutex, since we are not touching the list, yet.
1713 TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO));
1714 if (TmpAdInfo == NULL)
1716 TRACE_PRINT("PacketAddAdapterDag: GlobalAlloc Failed allocating memory for the AdInfo structure.");
1717 TRACE_EXIT("PacketAddAdapterDag");
1718 return FALSE;
1721 // Copy the device name and description
1722 StringCchCopyA(TmpAdInfo->Name,
1723 sizeof(TmpAdInfo->Name),
1724 name);
1726 StringCchCopyA(TmpAdInfo->Description,
1727 sizeof(TmpAdInfo->Description),
1728 description);
1730 if(IsAFile)
1731 TmpAdInfo->Flags = INFO_FLAG_DAG_FILE;
1732 else
1733 TmpAdInfo->Flags = INFO_FLAG_DAG_CARD;
1735 if(g_p_dagc_open)
1736 dagfd = g_p_dagc_open(name, 0, ebuf);
1737 else
1738 dagfd = NULL;
1740 if(!dagfd)
1742 GlobalFreePtr(TmpAdInfo);
1743 TRACE_EXIT("PacketAddAdapterDag");
1744 return FALSE;
1747 TmpAdInfo->LinkLayer.LinkType = g_p_dagc_getlinktype(dagfd);
1749 switch(g_p_dagc_getlinktype(dagfd))
1751 case TYPE_HDLC_POS:
1752 TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMediumCHDLC; // Note: custom linktype, NDIS doesn't provide an equivalent
1753 break;
1754 case -TYPE_HDLC_POS:
1755 TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMediumPPPSerial; // Note: custom linktype, NDIS doesn't provide an equivalent
1756 break;
1757 case TYPE_ETH:
1758 TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMedium802_3;
1759 break;
1760 case TYPE_ATM:
1761 TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMediumAtm;
1762 break;
1763 default:
1764 TmpAdInfo->LinkLayer.LinkType = (UINT)NdisMediumNull; // Note: custom linktype, NDIS doesn't provide an equivalent
1765 break;
1768 TmpAdInfo->LinkLayer.LinkSpeed = (g_p_dagc_getlinkspeed(dagfd) == -1)?
1769 100000000: // Unknown speed, default to 100Mbit
1770 g_p_dagc_getlinkspeed(dagfd) * 1000000;
1772 g_p_dagc_close(dagfd);
1774 WaitForSingleObject(g_AdaptersInfoMutex, INFINITE);
1776 // Update the AdaptersInfo list
1777 TmpAdInfo->Next = g_AdaptersInfoList;
1778 g_AdaptersInfoList = TmpAdInfo;
1780 ReleaseMutex(g_AdaptersInfoMutex);
1782 TRACE_EXIT("PacketAddAdapterDag");
1783 return TRUE;
1787 \brief Updates the list of the adapters using the DAGC API.
1788 \return If the function succeeds, the return value is nonzero.
1790 This function populates the list of adapter descriptions, looking for DAG cards on the system.
1792 BOOLEAN PacketGetAdaptersDag()
1794 CHAR ebuf[DAGC_ERRBUF_SIZE];
1795 dagc_if_t *devs = NULL, *tmpdevs;
1796 UINT i;
1798 if(g_p_dagc_finddevs(&devs, ebuf))
1799 // No dag cards found on this system
1800 return FALSE;
1801 else
1803 for(tmpdevs = devs, i=0; tmpdevs != NULL; tmpdevs = tmpdevs->next)
1805 PacketAddAdapterDag(tmpdevs->name, tmpdevs->description, FALSE);
1809 g_p_dagc_freedevs(devs);
1811 return TRUE;
1813 #endif // HAVE_DAG_API
1816 \brief Find the information about an adapter scanning the global ADAPTER_INFO list.
1817 \param AdapterName Name of the adapter whose information has to be retrieved.
1818 \return If the function succeeds, the return value is non-null.
1820 PADAPTER_INFO PacketFindAdInfo(PCHAR AdapterName)
1822 //this function should NOT acquire the g_AdaptersInfoMutex, since it does return an ADAPTER_INFO structure
1823 PADAPTER_INFO TAdInfo;
1825 TRACE_ENTER("PacketFindAdInfo");
1827 if (g_AdaptersInfoList == NULL)
1829 TRACE_PRINT("Repopulating the adapters info list...");
1830 PacketPopulateAdaptersInfoList();
1833 TAdInfo = g_AdaptersInfoList;
1835 while(TAdInfo != NULL)
1837 if(strcmp(TAdInfo->Name, AdapterName) == 0)
1839 TRACE_PRINT1("Found AdInfo for adapter %s", AdapterName);
1840 break;
1843 TAdInfo = TAdInfo->Next;
1846 if (TAdInfo == NULL)
1848 TRACE_PRINT1("NOT found AdInfo for adapter %s", AdapterName);
1851 TRACE_EXIT("PacketFindAdInfo");
1852 return TAdInfo;
1858 \brief Updates information about an adapter in the global ADAPTER_INFO list.
1859 \param AdapterName Name of the adapter whose information has to be retrieved.
1860 \return If the function succeeds, the return value is TRUE. A false value means that the adapter is no
1861 more valid or that it is disconnected.
1863 BOOLEAN PacketUpdateAdInfo(PCHAR AdapterName)
1865 //this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter
1866 PADAPTER_INFO TAdInfo, PrevAdInfo;
1868 #ifdef HAVE_WANPACKET_API
1869 CHAR FakeNdisWanAdapterName[MAX_WINPCAP_KEY_CHARS] = FAKE_NDISWAN_ADAPTER_NAME;
1870 #endif
1873 // Old registry based WinPcap names
1875 // UINT RegQueryLen;
1876 // CHAR FakeNdisWanAdapterName[MAX_WINPCAP_KEY_CHARS];
1878 // // retrieve the name for the fake ndis wan adapter
1879 // RegQueryLen = sizeof(FakeNdisWanAdapterName)/sizeof(FakeNdisWanAdapterName[0]);
1880 // if (QueryWinPcapRegistryStringA(NPF_FAKE_NDISWAN_ADAPTER_NAME_REG_KEY, FakeNdisWanAdapterName, &RegQueryLen, FAKE_NDISWAN_ADAPTER_NAME) == FALSE && RegQueryLen == 0)
1881 // return FALSE;
1883 TRACE_ENTER("PacketUpdateAdInfo");
1885 TRACE_PRINT1("Updating adapter info for adapter %s", AdapterName);
1887 WaitForSingleObject(g_AdaptersInfoMutex, INFINITE);
1889 PrevAdInfo = TAdInfo = g_AdaptersInfoList;
1892 // If an entry for this adapter is present in the list, we destroy it
1894 while(TAdInfo != NULL)
1896 if(strcmp(TAdInfo->Name, AdapterName) == 0)
1898 #ifdef HAVE_WANPACKET_API
1899 if (strcmp(AdapterName, FakeNdisWanAdapterName) == 0)
1901 ReleaseMutex(g_AdaptersInfoMutex);
1902 TRACE_EXIT("PacketUpdateAdInfo");
1903 return TRUE;
1905 #endif
1906 if(TAdInfo == g_AdaptersInfoList)
1908 g_AdaptersInfoList = TAdInfo->Next;
1910 else
1912 PrevAdInfo->Next = TAdInfo->Next;
1915 if (TAdInfo->NetworkAddresses != NULL)
1916 GlobalFreePtr(TAdInfo->NetworkAddresses);
1917 GlobalFreePtr(TAdInfo);
1919 break;
1922 PrevAdInfo = TAdInfo;
1924 TAdInfo = TAdInfo->Next;
1927 ReleaseMutex(g_AdaptersInfoMutex);
1930 // Now obtain the information about this adapter
1932 if(PacketAddAdapterNPF(AdapterName, 0) == TRUE)
1934 TRACE_EXIT("PacketUpdateAdInfo");
1935 return TRUE;
1938 #ifdef HAVE_IPHELPER_API
1939 PacketGetAdaptersIPH();
1940 #endif //HAVE_IPHELPER_API
1942 #ifdef HAVE_NPFIM_API
1943 if (g_hNpfImDll != NULL)
1945 PacketGetAdaptersNpfIm();
1947 else
1949 TRACE_PRINT("NpfIm extension not available");
1951 #endif //HAVE_NPFIM_API
1953 #ifdef HAVE_AIRPCAP_API
1954 if (g_PAirpcapGetDeviceList != NULL)
1956 PacketGetAdaptersAirpcap();
1958 else
1960 TRACE_PRINT("AirPcap extension not available");
1962 #endif
1964 #ifdef HAVE_WANPACKET_API
1965 PacketAddFakeNdisWanAdapter();
1966 #endif //HAVE_WANPACKET_API
1968 #ifdef HAVE_DAG_API
1969 if(g_p_dagc_open != NULL)
1971 PacketGetAdaptersDag();
1973 else
1975 TRACE_PRINT("Dag extension not available");
1977 #endif // HAVE_DAG_API
1979 TRACE_EXIT("PacketUpdateAdInfo");
1980 return TRUE;
1984 \brief Populates the list of the adapters.
1986 This function populates the list of adapter descriptions, invoking first PacketGetAdapters() and then
1987 PacketGetAdaptersIPH().
1989 void PacketPopulateAdaptersInfoList()
1991 //this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter
1992 PADAPTER_INFO TAdInfo;
1993 PVOID Mem1, Mem2;
1995 TRACE_ENTER("PacketPopulateAdaptersInfoList");
1997 WaitForSingleObject(g_AdaptersInfoMutex, INFINITE);
1999 if(g_AdaptersInfoList)
2001 // Free the old list
2002 TAdInfo = g_AdaptersInfoList;
2003 while(TAdInfo != NULL)
2005 Mem1 = TAdInfo->NetworkAddresses;
2006 Mem2 = TAdInfo;
2008 TAdInfo = TAdInfo->Next;
2010 if (Mem1 != NULL)
2011 GlobalFreePtr(Mem1);
2012 GlobalFreePtr(Mem2);
2015 g_AdaptersInfoList = NULL;
2019 // Fill the new list
2021 if(!PacketGetAdaptersNPF())
2023 // No info about adapters in the registry. (NDIS adapters, i.e. exported by NPF)
2024 TRACE_PRINT("PacketPopulateAdaptersInfoList: registry scan for adapters failed!");
2027 #ifdef HAVE_IPHELPER_API
2028 if(!PacketGetAdaptersIPH())
2030 // IP Helper API not present. We are under WinNT 4 or TCP/IP is not installed
2031 TRACE_PRINT("PacketPopulateAdaptersInfoList: failed to get adapters from the IP Helper API!");
2033 #endif //HAVE_IPHELPER_API
2035 #ifdef HAVE_WANPACKET_API
2036 if (!PacketAddFakeNdisWanAdapter())
2038 TRACE_PRINT("PacketPopulateAdaptersInfoList: adding fake NdisWan adapter failed.");
2040 #endif // HAVE_WANPACKET_API
2042 #ifdef HAVE_AIRPCAP_API
2043 if(g_PAirpcapGetDeviceList) // Ensure that the airpcap dll is present
2045 if(!PacketGetAdaptersAirpcap())
2047 TRACE_PRINT("PacketPopulateAdaptersInfoList: lookup of airpcap adapters failed!");
2050 #endif // HAVE_AIRPCAP_API
2052 #ifdef HAVE_NPFIM_API
2053 if (g_hNpfImDll != NULL)
2055 if (!PacketGetAdaptersNpfIm()) // Ensure that the npfim dll is present
2057 TRACE_PRINT("PacketPopulateAdaptersInfoList: lookup of NpfIm adapters failed!");
2060 #endif //HAVE_NPFIM_API
2062 #ifdef HAVE_DAG_API
2063 if(g_p_dagc_open != NULL)
2065 if(!PacketGetAdaptersDag())
2067 // No info about adapters in the registry.
2068 TRACE_PRINT("PacketPopulateAdaptersInfoList: lookup of dag cards failed!");
2071 #endif // HAVE_DAG_API
2073 ReleaseMutex(g_AdaptersInfoMutex);
2074 TRACE_EXIT("PacketPopulateAdaptersInfoList");
2077 #ifdef HAVE_WANPACKET_API
2079 static BOOLEAN PacketAddFakeNdisWanAdapter()
2081 //this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter
2082 PADAPTER_INFO TmpAdInfo, SAdInfo;
2084 // Old registry based WinPcap names
2086 // CHAR DialupName[MAX_WINPCAP_KEY_CHARS];
2087 // CHAR DialupDesc[MAX_WINPCAP_KEY_CHARS];
2088 // UINT RegQueryLen;
2089 CHAR DialupName[MAX_WINPCAP_KEY_CHARS] = FAKE_NDISWAN_ADAPTER_NAME;
2090 CHAR DialupDesc[MAX_WINPCAP_KEY_CHARS] = FAKE_NDISWAN_ADAPTER_DESCRIPTION;
2092 TRACE_ENTER("PacketAddFakeNdisWanAdapter");
2095 // Old registry based WinPcap names
2097 // //
2098 // // Get name and description of the wan adapter from the registry
2099 // //
2100 // RegQueryLen = sizeof(DialupName)/sizeof(DialupName[0]);
2101 // if (QueryWinPcapRegistryStringA(NPF_FAKE_NDISWAN_ADAPTER_NAME_REG_KEY, DialupName, &RegQueryLen, FAKE_NDISWAN_ADAPTER_NAME) == FALSE && RegQueryLen == 0)
2102 // return FALSE;
2104 // RegQueryLen = sizeof(DialupDesc)/sizeof(DialupDesc[0]);
2105 // if (QueryWinPcapRegistryStringA(NPF_FAKE_NDISWAN_ADAPTER_DESC_REG_KEY, DialupDesc, &RegQueryLen, FAKE_NDISWAN_ADAPTER_DESCRIPTION) == FALSE && RegQueryLen == 0)
2106 // return FALSE;
2108 // Scan the adapters list to see if this one is already present
2109 if (!WanPacketTestAdapter())
2111 TRACE_PRINT("Cannot add the wan adapter, since it cannot be opened.");
2112 //the adapter cannot be opened, we do not list it, but we return t
2113 TRACE_EXIT("PacketAddFakeNdisWanAdapter");
2114 return FALSE;
2117 WaitForSingleObject(g_AdaptersInfoMutex, INFINITE);
2119 for(SAdInfo = g_AdaptersInfoList; SAdInfo != NULL; SAdInfo = SAdInfo->Next)
2121 if(strcmp(DialupName, SAdInfo->Name) == 0)
2123 TRACE_PRINT("PacketAddFakeNdisWanAdapter: Adapter already present in the list");
2124 ReleaseMutex(g_AdaptersInfoMutex);
2125 TRACE_EXIT("PacketAddFakeNdisWanAdapter");
2126 return TRUE;
2130 TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO));
2131 if (TmpAdInfo == NULL)
2133 TRACE_PRINT("PacketAddFakeNdisWanAdapter: GlobalAlloc Failed allocating memory for the AdInfo structure");
2134 ReleaseMutex(g_AdaptersInfoMutex);
2135 TRACE_EXIT("PacketAddFakeNdisWanAdapter");
2136 return FALSE;
2139 strncpy(TmpAdInfo->Name, DialupName, sizeof(TmpAdInfo->Name) - 1);
2140 strncpy(TmpAdInfo->Description, DialupDesc, sizeof(TmpAdInfo->Description) - 1);
2141 TmpAdInfo->LinkLayer.LinkType = NdisMedium802_3;
2142 TmpAdInfo->LinkLayer.LinkSpeed = 10 * 1000 * 1000; //we emulate a fake 10MBit Ethernet
2143 TmpAdInfo->Flags = INFO_FLAG_NDISWAN_ADAPTER;
2144 memset(TmpAdInfo->MacAddress,'0',6);
2145 TmpAdInfo->MacAddressLen = 6;
2146 TmpAdInfo->NetworkAddresses = NULL;
2147 TmpAdInfo->NNetworkAddresses = 0;
2149 TmpAdInfo->Next = g_AdaptersInfoList;
2150 g_AdaptersInfoList = TmpAdInfo;
2151 ReleaseMutex(g_AdaptersInfoMutex);
2153 TRACE_EXIT("PacketAddFakeNdisWanAdapter");
2154 return TRUE;
2157 #endif //HAVE_WANPACKET_API