2 * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
3 * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
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
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 */
45 #pragma warning (disable : 4127) //conditional expression is constant. Used for do{}while(FALSE) loops.
48 #pragma warning (disable : 4710) // inline function not expanded. used for strsafe functions
52 #include "Packet32-Int.h"
55 #ifdef HAVE_WANPACKET_API
56 #include "wanpacket/wanpacket.h"
57 #endif //HAVE_WANPACKET_API
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 */
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
;
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)
124 - NdisMedium802_5: Token Ring (802.5)
125 - NdisMediumFddi: FDDI
127 - NdisMediumArcnet878_2: ARCNET (878.2)
129 static BOOLEAN
PacketGetLinkLayerFromRegistry(LPADAPTER AdapterObject
, NetType
*type
)
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");
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
);
156 type
->LinkSpeed
=*((UINT
*)OidData
->Data
)*100;
159 GlobalFreePtr (OidData
);
161 TRACE_PRINT2("Media:%.010d" "\t" "Speed=%0.10I64u",
165 TRACE_EXIT("PacketGetLinkLayerFromRegistry");
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
)
186 WCHAR AdapterNameW
[ADAPTER_NAME_LENGTH
];
193 WCHAR String
[1024+1];
197 struct sockaddr_in
*TmpAddr
, *TmpBroad
;
198 LONG naddrs
,nmasks
,StringPos
;
201 // Old registry based WinPcap names
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
'\\');
213 IfNameW
= AdapterNameW
;
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)
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
);
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
)
245 status
= RegOpenKeyEx(SystemKey
,IfNameW
,0,KEY_READ
,&InterfaceKey
);
246 if (status
!= ERROR_SUCCESS
) {
247 RegCloseKey(SystemKey
);
248 RegCloseKey(UnderTcpKey
);
251 RegCloseKey(SystemKey
);
252 status
= RegOpenKeyEx(InterfaceKey
,TEXT("Parameters"),0,KEY_READ
,&ParametersKey
);
253 if (status
!= ERROR_SUCCESS
) {
254 RegCloseKey(InterfaceKey
);
255 RegCloseKey(UnderTcpKey
);
258 RegCloseKey(InterfaceKey
);
259 status
= RegOpenKeyEx(ParametersKey
,TEXT("TcpIp"),0,KEY_READ
,&TcpIpKey
);
260 if (status
!= ERROR_SUCCESS
) {
261 RegCloseKey(ParametersKey
);
262 RegCloseKey(UnderTcpKey
);
265 RegCloseKey(ParametersKey
);
266 BufLen
= sizeof String
;
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
)
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
)
282 /* Retrieve the adrresses */
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
);
294 // scan the key to obtain the addresses
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
;
305 TmpBroad
->sin_addr
.S_un
.S_addr
= 0xffffffff; // 255.255.255.255
307 TmpBroad
->sin_addr
.S_un
.S_addr
= 0; // 0.0.0.0
309 while(*(String
+ StringPos
) != 0)StringPos
++;
312 if(*(String
+ StringPos
) == 0 || (StringPos
* sizeof (WCHAR
)) >= BufLen
)
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
);
327 // scan the key to obtain the masks
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
++;
338 if(*(String
+ StringPos
) == 0 || (StringPos
* sizeof (WCHAR
)) >= BufLen
)
344 // The number of masks MUST be equal to the number of adresses
345 if(nmasks
!= naddrs
){
346 RegCloseKey(TcpIpKey
);
347 RegCloseKey(UnderTcpKey
);
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
);
363 // scan the key to obtain the addresses
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
;
374 TmpBroad
->sin_addr
.S_un
.S_addr
= 0xffffffff; // 255.255.255.255
376 TmpBroad
->sin_addr
.S_un
.S_addr
= 0; // 0.0.0.0
378 while(*(String
+ StringPos
) != 0)StringPos
++;
381 if(*(String
+ StringPos
) == 0 || (StringPos
* sizeof (WCHAR
)) >= BufLen
)
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
);
396 // scan the key to obtain the masks
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
++;
407 if(*(String
+ StringPos
) == 0 || (StringPos
* sizeof (WCHAR
)) >= BufLen
)
413 // The number of masks MUST be equal to the number of adresses
414 if(nmasks
!= naddrs
){
415 RegCloseKey(TcpIpKey
);
416 RegCloseKey(UnderTcpKey
);
422 *NEntries
= naddrs
+ 1;
424 RegCloseKey(TcpIpKey
);
425 RegCloseKey(UnderTcpKey
);
427 if (status
!= ERROR_SUCCESS
) {
431 TRACE_PRINT("Successfully retrieved the addresses from the registry.");
432 TRACE_EXIT("PacketGetAddressesFromRegistry");
437 TRACE_PRINT("Failed retrieving the addresses from the registry.");
438 TRACE_EXIT("PacketGetAddressesFromRegistry");
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
)
457 PIP_ADAPTER_ADDRESSES AdBuffer
, TmpAddr
;
459 PIP_ADAPTER_UNICAST_ADDRESS UnicastAddr
;
460 struct sockaddr_storage
*Addr
;
463 // Old registry based WinPcap names
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");
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");
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");
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)
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");
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");
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");
581 TRACE_EXIT("IsFireWire");
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
;
598 struct sockaddr_in
*TmpAddr
;
602 // Old registry based WinPcap names
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)
620 // // Create the NPF device name from the original device name
622 // sizeof(TName) - 1 - RegQueryLen - 1,
624 // npfCompleteDriverPrefix,
625 // IphAd->AdapterName);
627 // Create the NPF device name from the original device name
628 StringCchPrintfA(TName
,
629 sizeof(TName
) - strlen(npfCompleteDriverPrefix
),
631 npfCompleteDriverPrefix
,
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
);
644 if(IphAd
->Type
== IF_TYPE_PPP
|| IphAd
->Type
== IF_TYPE_SLIP
)
646 #ifdef HAVE_WANPACKET_API
647 if (!WanPacketTestAdapter())
657 TRACE_PRINT1("Trying to open adapter %s to see if it's available...", TName
);
658 adapter
= PacketOpenAdapterNPF(TName
);
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
);
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");
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
,
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");
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
;
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.");
742 TmpAdInfo
->Flags
= INFO_FLAG_NDISWAN_ADAPTER
;
745 // Update the AdaptersInfo list
746 TmpAdInfo
->Next
= g_AdaptersInfoList
;
747 g_AdaptersInfoList
= TmpAdInfo
;
751 TRACE_EXIT("PacketAddAdapterIPH");
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
;
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");
780 TRACE_PRINT("PacketGetAdaptersIPH: retrieved needed bytes for IPH");
782 // Allocate the buffer
783 AdList
= GlobalAllocPtr(GMEM_MOVEABLE
, OutBufLen
);
786 TRACE_PRINT("PacketGetAdaptersIPH: GlobalAlloc Failed allocating the buffer for GetAdaptersInfo");
787 TRACE_EXIT("PacketGetAdaptersIPH");
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");
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
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");
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");
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
);
867 // Allocate a buffer to get the vendor description from the driver
868 OidData
= GlobalAllocPtr(GMEM_MOVEABLE
| GMEM_ZEROINIT
,512);
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");
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");
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");
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
));
942 TRACE_PRINT("AddAdapter: PacketGetLinkLayerFromRegistry failed. Returning.");
943 PacketCloseAdapter(adapter
);
944 GlobalFreePtr(OidData
);
945 GlobalFreePtr(TmpAdInfo
);
946 ReleaseMutex(g_AdaptersInfoMutex
);
947 TRACE_EXIT("AddAdapter");
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
);
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]);
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");
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
1021 PacketCloseAdapter(adapter
);
1022 GlobalFreePtr(OidData
);
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");
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
;
1059 TCHAR AdapName
[256];
1060 CHAR
*TcpBindingsMultiString
;
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)
1082 Status
=RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
1083 TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"),
1088 if ( Status
!= ERROR_SUCCESS
){
1089 TRACE_PRINT("PacketGetAdaptersNPF: RegOpenKeyEx ( Class\\{networkclassguid} ) Failed");
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
)
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
);
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"),
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
);
1147 dim
= sizeof(DeviceGuidName
);
1148 Status
=RegQueryValueExA(LinkageKey
,
1152 (PBYTE
)DeviceGuidName
,
1155 if(Status
!= ERROR_SUCCESS
)
1157 RegCloseKey(OneAdapKey
);
1158 RegCloseKey(LinkageKey
);
1159 TRACE_PRINT1("%d) Name = SKIPPED (error reading the key)", i
);
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\\"));
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
);
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"),
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
1207 Status
=RegQueryValueExA(LinkageKey
,
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");
1224 // Query the key again to get its content
1225 Status
= RegQueryValueExA(LinkageKey
,
1229 (LPBYTE
)TcpBindingsMultiString
,
1232 RegCloseKey(LinkageKey
);
1234 // Scan the buffer with the device names
1237 if (TcpBindingsMultiString
[i
] == '\0')
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
);
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");
1269 TRACE_EXIT("PacketGetAdaptersNPF");
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
;
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)
1310 if (TmpAdInfo
!= NULL
)
1313 // we already have it in the list. Just return
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");
1331 // Copy the device name and description
1332 StringCchCopyA(TmpAdInfo
->Name
,
1333 sizeof(TmpAdInfo
->Name
),
1336 StringCchCopyA(TmpAdInfo
->Description
,
1337 sizeof(TmpAdInfo
->Description
),
1340 TmpAdInfo
->Flags
= INFO_FLAG_AIRPCAP_CARD
;
1344 AirpcapAdapter
= g_PAirpcapOpen(name
, ebuf
);
1348 AirpcapAdapter
= NULL
;
1353 GlobalFreePtr(TmpAdInfo
);
1358 GllRes
= g_PAirpcapGetLinkType(AirpcapAdapter
, &AirpcapLinkLayer
);
1361 g_PAirpcapClose(AirpcapAdapter
);
1362 GlobalFreePtr(TmpAdInfo
);
1367 switch(AirpcapLinkLayer
)
1369 case AIRPCAP_LT_802_11
:
1370 TmpAdInfo
->LinkLayer
.LinkType
= (UINT
)NdisMediumBare80211
;
1372 case AIRPCAP_LT_802_11_PLUS_RADIO
:
1373 TmpAdInfo
->LinkLayer
.LinkType
= (UINT
)NdisMediumRadio80211
;
1376 TmpAdInfo
->LinkLayer
.LinkType
= (UINT
)NdisMediumNull
; // Note: custom linktype, NDIS doesn't provide an equivalent
1381 // For the moment, we always set the speed to 54Mbps, since the speed is not channel-specific,
1384 TmpAdInfo
->LinkLayer
.LinkSpeed
= 54000000;
1386 g_PAirpcapClose(AirpcapAdapter
);
1388 // Update the AdaptersInfo list
1389 TmpAdInfo
->Next
= g_AdaptersInfoList
;
1390 g_AdaptersInfoList
= TmpAdInfo
;
1394 ReleaseMutex(g_AdaptersInfoMutex
);
1396 TRACE_EXIT("PacketAddAdapterAirpcap");
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
;
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");
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");
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
;
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
;
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)
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
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
)
1507 bResult
= g_NpfImHandlers
.NpfImGetLinkSpeed(handle
, &linkSpeed
);
1509 if (bResult
== FALSE
)
1514 bResult
= g_NpfImHandlers
.NpfImGetIpAddresses(handle
, NULL
, 0, &returnedBytes
);
1516 if (bResult
== TRUE
)
1519 // no ip addresses, return
1524 if (GetLastError() == ERROR_MORE_DATA
)
1526 pAddresses
= (PNPF_IM_ADDRESS
)LocalAlloc(LPTR
, returnedBytes
);
1527 if (pAddresses
== NULL
)
1533 addressesSize
= returnedBytes
;
1535 bResult
= g_NpfImHandlers
.NpfImGetIpAddresses(handle
, pAddresses
, addressesSize
, &returnedBytes
);
1540 //unknown error listing the IP addresses
1549 g_NpfImHandlers
.NpfImCloseDevice(handle
);
1551 if (bResult
== FALSE
)
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");
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");
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
)
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
;
1603 ZeroMemory(&(pnpf_if_addresses
[i
].SubnetMask
), sizeof(struct sockaddr_storage
));
1604 ZeroMemory(&(pnpf_if_addresses
[i
].Broadcast
), sizeof(struct sockaddr_storage
));
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
),
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
;
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");
1670 for (pDevCursor
= pDevices
; pDevCursor
!= NULL
; pDevCursor
= pDevCursor
->pNext
)
1672 PacketAddAdapterNpfIm(pDevCursor
);
1675 g_NpfImHandlers
.NpfImFreeDeviceList(pDevices
);
1677 TRACE_EXIT("PacketGetAdaptersNpfIm");
1682 \brief Add an npfim adapter to the adapters info list, gathering information from the npfim dll
1684 \param description description of the adapter.
1685 \return If the function succeeds, the return value is nonzero.
1687 #endif // HAVE_NPFIM_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
;
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");
1721 // Copy the device name and description
1722 StringCchCopyA(TmpAdInfo
->Name
,
1723 sizeof(TmpAdInfo
->Name
),
1726 StringCchCopyA(TmpAdInfo
->Description
,
1727 sizeof(TmpAdInfo
->Description
),
1731 TmpAdInfo
->Flags
= INFO_FLAG_DAG_FILE
;
1733 TmpAdInfo
->Flags
= INFO_FLAG_DAG_CARD
;
1736 dagfd
= g_p_dagc_open(name
, 0, ebuf
);
1742 GlobalFreePtr(TmpAdInfo
);
1743 TRACE_EXIT("PacketAddAdapterDag");
1747 TmpAdInfo
->LinkLayer
.LinkType
= g_p_dagc_getlinktype(dagfd
);
1749 switch(g_p_dagc_getlinktype(dagfd
))
1752 TmpAdInfo
->LinkLayer
.LinkType
= (UINT
)NdisMediumCHDLC
; // Note: custom linktype, NDIS doesn't provide an equivalent
1754 case -TYPE_HDLC_POS
:
1755 TmpAdInfo
->LinkLayer
.LinkType
= (UINT
)NdisMediumPPPSerial
; // Note: custom linktype, NDIS doesn't provide an equivalent
1758 TmpAdInfo
->LinkLayer
.LinkType
= (UINT
)NdisMedium802_3
;
1761 TmpAdInfo
->LinkLayer
.LinkType
= (UINT
)NdisMediumAtm
;
1764 TmpAdInfo
->LinkLayer
.LinkType
= (UINT
)NdisMediumNull
; // Note: custom linktype, NDIS doesn't provide an equivalent
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");
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
;
1798 if(g_p_dagc_finddevs(&devs
, ebuf
))
1799 // No dag cards found on this system
1803 for(tmpdevs
= devs
, i
=0; tmpdevs
!= NULL
; tmpdevs
= tmpdevs
->next
)
1805 PacketAddAdapterDag(tmpdevs
->name
, tmpdevs
->description
, FALSE
);
1809 g_p_dagc_freedevs(devs
);
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
);
1843 TAdInfo
= TAdInfo
->Next
;
1846 if (TAdInfo
== NULL
)
1848 TRACE_PRINT1("NOT found AdInfo for adapter %s", AdapterName
);
1851 TRACE_EXIT("PacketFindAdInfo");
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
;
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)
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");
1906 if(TAdInfo
== g_AdaptersInfoList
)
1908 g_AdaptersInfoList
= TAdInfo
->Next
;
1912 PrevAdInfo
->Next
= TAdInfo
->Next
;
1915 if (TAdInfo
->NetworkAddresses
!= NULL
)
1916 GlobalFreePtr(TAdInfo
->NetworkAddresses
);
1917 GlobalFreePtr(TAdInfo
);
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");
1938 #ifdef HAVE_IPHELPER_API
1939 PacketGetAdaptersIPH();
1940 #endif //HAVE_IPHELPER_API
1942 #ifdef HAVE_NPFIM_API
1943 if (g_hNpfImDll
!= NULL
)
1945 PacketGetAdaptersNpfIm();
1949 TRACE_PRINT("NpfIm extension not available");
1951 #endif //HAVE_NPFIM_API
1953 #ifdef HAVE_AIRPCAP_API
1954 if (g_PAirpcapGetDeviceList
!= NULL
)
1956 PacketGetAdaptersAirpcap();
1960 TRACE_PRINT("AirPcap extension not available");
1964 #ifdef HAVE_WANPACKET_API
1965 PacketAddFakeNdisWanAdapter();
1966 #endif //HAVE_WANPACKET_API
1969 if(g_p_dagc_open
!= NULL
)
1971 PacketGetAdaptersDag();
1975 TRACE_PRINT("Dag extension not available");
1977 #endif // HAVE_DAG_API
1979 TRACE_EXIT("PacketUpdateAdInfo");
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
;
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
;
2008 TAdInfo
= TAdInfo
->Next
;
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
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
2098 // // Get name and description of the wan adapter from the registry
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)
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)
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");
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");
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");
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");
2157 #endif //HAVE_WANPACKET_API