📄 adinfo.c
字号:
/*
* Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
* Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
* nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
This file contains the support functions used by packet.dll to retrieve information about installed
adapters, like
- the adapter list
- the device associated to any adapter and the description of the adapter
- physical parameters like the linkspeed or the link layer type
- the IP and link layer addresses */
#define UNICODE 1
#pragma warning (disable : 4127) //conditional expression is constant. Used for do{}while(FALSE) loops.
#if (MSC_VER < 1300)
#pragma warning (disable : 4710) // inline function not expanded. used for strsafe functions
#endif
#include <packet32.h>
#include "Packet32-Int.h"
#include "debug.h"
#ifdef HAVE_WANPACKET_API
#include "wanpacket/wanpacket.h"
#endif //HAVE_WANPACKET_API
#include <windows.h>
#include <windowsx.h>
#include <Iphlpapi.h>
#include <strsafe.h>
#include <ntddndis.h>
#include <WpcapNames.h>
static BOOLEAN PacketAddFakeNdisWanAdapter();
PADAPTER_INFO g_AdaptersInfoList = NULL; ///< Head of the adapter information list. This list is populated when packet.dll is linked by the application.
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.
extern FARPROC g_GetAdaptersAddressesPointer;
#ifdef HAVE_AIRPCAP_API
extern AirpcapGetLastErrorHandler g_PAirpcapGetLastError;
extern AirpcapGetDeviceListHandler g_PAirpcapGetDeviceList;
extern AirpcapFreeDeviceListHandler g_PAirpcapFreeDeviceList;
extern AirpcapOpenHandler g_PAirpcapOpen;
extern AirpcapCloseHandler g_PAirpcapClose;
extern AirpcapGetLinkTypeHandler g_PAirpcapGetLinkType;
extern AirpcapSetKernelBufferHandler g_PAirpcapSetKernelBuffer;
extern AirpcapSetFilterHandler g_PAirpcapSetFilter;
extern AirpcapGetMacAddressHandler g_PAirpcapGetMacAddress;
extern AirpcapSetMinToCopyHandler g_PAirpcapSetMinToCopy;
extern AirpcapGetReadEventHandler g_PAirpcapGetReadEvent;
extern AirpcapReadHandler g_PAirpcapRead;
extern AirpcapGetStatsHandler g_PAirpcapGetStats;
#endif /* HAVE_AIRPCAP_API */
#ifdef HAVE_DAG_API
extern dagc_open_handler g_p_dagc_open;
extern dagc_close_handler g_p_dagc_close;
extern dagc_getlinktype_handler g_p_dagc_getlinktype;
extern dagc_getlinkspeed_handler g_p_dagc_getlinkspeed;
extern dagc_finddevs_handler g_p_dagc_finddevs;
extern dagc_freedevs_handler g_p_dagc_freedevs;
#endif /* HAVE_DAG_API */
/// Title of error windows
TCHAR szWindowTitle[] = TEXT("PACKET.DLL");
ULONG inet_addrU(const WCHAR *cp);
extern HKEY WinpcapKey;
extern WCHAR *WinPcapKeyBuffer;
/*!
\brief Gets the link layer of an adapter, querying the registry.
\param AdapterObject Handle to an open adapter.
\param type Pointer to a NetType structure that will be filled by the function.
\return If the function succeeds, the return value is nonzero, otherwise the return value is zero.
This function retrieves from the registry the link layer and the speed (in bps) of an opened adapter.
These values are copied in the NetType structure provided by the user.
The LinkType field of the type parameter can have one of the following values:
- NdisMedium802_3: Ethernet (802.3)
- NdisMediumWan: WAN
- NdisMedium802_5: Token Ring (802.5)
- NdisMediumFddi: FDDI
- NdisMediumAtm: ATM
- NdisMediumArcnet878_2: ARCNET (878.2)
*/
static BOOLEAN PacketGetLinkLayerFromRegistry(LPADAPTER AdapterObject, NetType *type)
{
BOOLEAN Status;
ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
PPACKET_OID_DATA OidData;
TRACE_ENTER("PacketGetLinkLayerFromRegistry");
OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
if (OidData == NULL) {
TRACE_PRINT("PacketGetLinkLayerFromRegistry failed");
TRACE_EXIT("PacketGetLinkLayerFromRegistry");
return FALSE;
}
//get the link-layer type
OidData->Oid = OID_GEN_MEDIA_IN_USE;
OidData->Length = sizeof (ULONG);
Status = PacketRequest(AdapterObject,FALSE,OidData);
type->LinkType=*((UINT*)OidData->Data);
//get the link-layer speed
OidData->Oid = OID_GEN_LINK_SPEED;
OidData->Length = sizeof (ULONG);
Status = PacketRequest(AdapterObject,FALSE,OidData);
if (Status == TRUE)
{
type->LinkSpeed=*((UINT*)OidData->Data)*100;
}
GlobalFreePtr (OidData);
TRACE_PRINT2("Media:%.010d" "\t" "Speed=%0.10I64u",
type->LinkType,
type->LinkSpeed);
TRACE_EXIT("PacketGetLinkLayerFromRegistry");
return Status;
}
/*!
\brief Scan the registry to retrieve the IP addresses of an adapter.
\param AdapterName String that contains the name of the adapter.
\param buffer A user allocated array of npf_if_addr that will be filled by the function.
\param NEntries Size of the array (in npf_if_addr).
\return If the function succeeds, the return value is nonzero.
This function grabs from the registry information like the IP addresses, the netmasks
and the broadcast addresses of an interface. The buffer passed by the user is filled with
npf_if_addr structures, each of which contains the data for a single address. If the buffer
is full, the reaming addresses are dropeed, therefore set its dimension to sizeof(npf_if_addr)
if you want only the first address.
*/
static BOOLEAN PacketGetAddressesFromRegistry(LPCSTR AdapterNameA, npf_if_addr* buffer, PLONG NEntries)
{
WCHAR *IfNameW;
WCHAR AdapterNameW[ADAPTER_NAME_LENGTH];
HKEY SystemKey;
HKEY InterfaceKey;
HKEY ParametersKey;
HKEY TcpIpKey;
HKEY UnderTcpKey;
LONG status;
WCHAR String[1024+1];
DWORD RegType;
ULONG BufLen;
DWORD DHCPEnabled;
struct sockaddr_in *TmpAddr, *TmpBroad;
LONG naddrs,nmasks,StringPos;
DWORD ZeroBroadcast;
//
// Old registry based WinPcap names
//
// UINT RegQueryLen;
// WCHAR npfDeviceNamesPrefix[MAX_WINPCAP_KEY_CHARS];
WCHAR npfDeviceNamesPrefix[MAX_WINPCAP_KEY_CHARS] = NPF_DEVICE_NAMES_PREFIX_WIDECHAR;
TRACE_ENTER("PacketGetAddressesFromRegistry");
StringCchPrintfW(AdapterNameW, ADAPTER_NAME_LENGTH, L"%S", AdapterNameA);
IfNameW = wcsrchr(AdapterNameW, L'\\');
if (IfNameW == NULL)
IfNameW = AdapterNameW;
else
IfNameW++;
//
// Old registry based WinPcap names
//
// RegQueryLen = sizeof(npfDeviceNamesPrefix)/sizeof(npfDeviceNamesPrefix[0]);
//
// if (QueryWinPcapRegistryStringW(TEXT(NPF_DEVICES_PREFIX_REG_KEY), npfDeviceNamesPrefix, &RegQueryLen, NPF_DEVICE_NAMES_PREFIX_WIDECHAR) == FALSE && RegQueryLen == 0)
// return FALSE;
//
// if (wcsncmp(ifname, npfDeviceNamesPrefix, RegQueryLen) == 0)
// ifname += RegQueryLen;
if (wcsncmp(IfNameW, npfDeviceNamesPrefix, wcslen(npfDeviceNamesPrefix)) == 0)
IfNameW += wcslen(npfDeviceNamesPrefix);
if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"), 0, KEY_READ, &UnderTcpKey) == ERROR_SUCCESS)
{
status = RegOpenKeyEx(UnderTcpKey,IfNameW,0,KEY_READ,&TcpIpKey);
if (status != ERROR_SUCCESS) {
RegCloseKey(UnderTcpKey);
goto fail;
}
}
else
{
// Query the registry key with the interface's adresses
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&SystemKey);
if (status != ERROR_SUCCESS)
goto fail;
status = RegOpenKeyEx(SystemKey,IfNameW,0,KEY_READ,&InterfaceKey);
if (status != ERROR_SUCCESS) {
RegCloseKey(SystemKey);
RegCloseKey(UnderTcpKey);
goto fail;
}
RegCloseKey(SystemKey);
status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey);
if (status != ERROR_SUCCESS) {
RegCloseKey(InterfaceKey);
RegCloseKey(UnderTcpKey);
goto fail;
}
RegCloseKey(InterfaceKey);
status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey);
if (status != ERROR_SUCCESS) {
RegCloseKey(ParametersKey);
RegCloseKey(UnderTcpKey);
goto fail;
}
RegCloseKey(ParametersKey);
BufLen = sizeof String;
}
BufLen = 4;
/* Try to detect if the interface has a zero broadcast addr */
status=RegQueryValueEx(TcpIpKey,TEXT("UseZeroBroadcast"),NULL,&RegType,(LPBYTE)&ZeroBroadcast,&BufLen);
if (status != ERROR_SUCCESS)
ZeroBroadcast=0;
BufLen = 4;
/* See if DHCP is used by this system */
status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen);
if (status != ERROR_SUCCESS)
DHCPEnabled=0;
/* Retrieve the adrresses */
if(DHCPEnabled){
BufLen = sizeof String;
// Open the key with the addresses
status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
if (status != ERROR_SUCCESS) {
RegCloseKey(TcpIpKey);
RegCloseKey(UnderTcpKey);
goto fail;
}
// scan the key to obtain the addresses
StringPos = 0;
for(naddrs = 0;naddrs <* NEntries;naddrs++){
TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress);
if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
TmpAddr->sin_family = AF_INET;
TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast);
TmpBroad->sin_family = AF_INET;
if(ZeroBroadcast==0)
TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255
else
TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0
while(*(String + StringPos) != 0)StringPos++;
StringPos++;
if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
break;
}
else break;
}
BufLen = sizeof String;
// Open the key with the netmasks
status = RegQueryValueEx(TcpIpKey,TEXT("DhcpSubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen);
if (status != ERROR_SUCCESS) {
RegCloseKey(TcpIpKey);
RegCloseKey(UnderTcpKey);
goto fail;
}
// scan the key to obtain the masks
StringPos = 0;
for(nmasks = 0;nmasks < *NEntries;nmasks++){
TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask);
if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
TmpAddr->sin_family = AF_INET;
while(*(String + StringPos) != 0)StringPos++;
StringPos++;
if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
break;
}
else break;
}
// The number of masks MUST be equal to the number of adresses
if(nmasks != naddrs){
RegCloseKey(TcpIpKey);
RegCloseKey(UnderTcpKey);
goto fail;
}
}
else{
BufLen = sizeof String;
// Open the key with the addresses
status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
if (status != ERROR_SUCCESS) {
RegCloseKey(TcpIpKey);
RegCloseKey(UnderTcpKey);
goto fail;
}
// scan the key to obtain the addresses
StringPos = 0;
for(naddrs = 0;naddrs < *NEntries;naddrs++){
TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress);
if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
TmpAddr->sin_family = AF_INET;
TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast);
TmpBroad->sin_family = AF_INET;
if(ZeroBroadcast==0)
TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255
else
TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0
while(*(String + StringPos) != 0)StringPos++;
StringPos++;
if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
break;
}
else break;
}
BufLen = sizeof String;
// Open the key with the netmasks
status = RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen);
if (status != ERROR_SUCCESS) {
RegCloseKey(TcpIpKey);
RegCloseKey(UnderTcpKey);
goto fail;
}
// scan the key to obtain the masks
StringPos = 0;
for(nmasks = 0;nmasks <* NEntries;nmasks++){
TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask);
if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
TmpAddr->sin_family = AF_INET;
while(*(String + StringPos) != 0)StringPos++;
StringPos++;
if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
break;
}
else break;
}
// The number of masks MUST be equal to the number of adresses
if(nmasks != naddrs){
RegCloseKey(TcpIpKey);
RegCloseKey(UnderTcpKey);
goto fail;
}
}
*NEntries = naddrs + 1;
RegCloseKey(TcpIpKey);
RegCloseKey(UnderTcpKey);
if (status != ERROR_SUCCESS) {
goto fail;
}
TRACE_PRINT("Successfully retrieved the addresses from the registry.");
TRACE_EXIT("PacketGetAddressesFromRegistry");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -