📄 adinfo.c
字号:
return TRUE;
fail:
TRACE_PRINT("Failed retrieving the addresses from the registry.");
TRACE_EXIT("PacketGetAddressesFromRegistry");
return FALSE;
}
#ifdef HAVE_IPHELPER_API
/*!
\brief Adds the IPv6 addresses of an adapter to the ADAPTER_INFO structure that describes it.
\param AdInfo Pointer to the ADAPTER_INFO structure that keeps the information about the adapter.
\return If the function succeeds, the function returns TRUE.
\note the structure pointed by AdInfo must be initialized the an properly filled. In particular, AdInfo->Name
must be a valid capture device name.
\note uses the GetAdaptersAddresses() Ip Helper API function, so it works only on systems where IP Helper API
provides it (WinXP and successive).
\note we suppose that we are called after having acquired the g_AdaptersInfoMutex mutex
*/
static BOOLEAN PacketAddIP6Addresses(PADAPTER_INFO AdInfo)
{
ULONG BufLen;
PIP_ADAPTER_ADDRESSES AdBuffer, TmpAddr;
PCHAR OrName;
PIP_ADAPTER_UNICAST_ADDRESS UnicastAddr;
struct sockaddr_storage *Addr;
INT AddrLen;
//
// Old registry based WinPcap names
//
// UINT RegQueryLen;
// CHAR npfDeviceNamesPrefix[MAX_WINPCAP_KEY_CHARS];
CHAR npfDeviceNamesPrefix[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_COMPLETE_DEVICE_PREFIX;
TRACE_ENTER("PacketAddIP6Addresses");
if(g_GetAdaptersAddressesPointer == NULL)
{
TRACE_PRINT("GetAdaptersAddressesPointer not available on the system, simply returning success...");
TRACE_EXIT("PacketAddIP6Addresses");
return TRUE; // GetAdaptersAddresses() not present on this system,
} // return immediately.
if(g_GetAdaptersAddressesPointer(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST| GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_FRIENDLY_NAME, NULL, NULL, &BufLen) != ERROR_BUFFER_OVERFLOW)
{
TRACE_PRINT("PacketAddIP6Addresses: GetAdaptersAddresses Failed while retrieving the needed buffer size");
TRACE_EXIT("PacketAddIP6Addresses");
return FALSE;
}
TRACE_PRINT("PacketAddIP6Addresses, retrieved needed storage for the call");
AdBuffer = GlobalAllocPtr(GMEM_MOVEABLE, BufLen);
if (AdBuffer == NULL)
{
TRACE_PRINT("PacketAddIP6Addresses: GlobalAlloc Failed");
TRACE_EXIT("PacketAddIP6Addresses");
return FALSE;
}
if(g_GetAdaptersAddressesPointer(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST| GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_FRIENDLY_NAME, NULL, AdBuffer, &BufLen) != ERROR_SUCCESS)
{
TRACE_PRINT("PacketGetIP6Addresses: GetAdaptersAddresses Failed while retrieving the addresses");
GlobalFreePtr(AdBuffer);
TRACE_EXIT("PacketAddIP6Addresses");
return FALSE;
}
TRACE_PRINT("PacketAddIP6Addresses, retrieved addresses, scanning the list");
//
// Scan the list of adddresses obtained from the IP helper API
//
for(TmpAddr = AdBuffer; TmpAddr != NULL; TmpAddr = TmpAddr->Next)
{
//
// Old registry based WinPcap names
//
// RegQueryLen = sizeof(npfDeviceNamesPrefix)/sizeof(npfDeviceNamesPrefix[0]);
//
// if (QueryWinPcapRegistryStringA(NPF_DRIVER_COMPLETE_DEVICE_PREFIX_REG_KEY, npfDeviceNamesPrefix, &RegQueryLen, NPF_DRIVER_COMPLETE_DEVICE_PREFIX) == FALSE && RegQueryLen == 0)
// continue;
//
// OrName = AdInfo->Name + RegQueryLen - 1;
OrName = AdInfo->Name + strlen(npfDeviceNamesPrefix);
TRACE_PRINT("PacketAddIP6Addresses, external loop");
if(strcmp(TmpAddr->AdapterName, OrName) == 0)
{
// Found a corresponding adapter, scan its address list
for(UnicastAddr = TmpAddr->FirstUnicastAddress; UnicastAddr != NULL; UnicastAddr = UnicastAddr->Next)
{
TRACE_PRINT("PacketAddIP6Addresses, internal loop");
AddrLen = UnicastAddr->Address.iSockaddrLength;
Addr = (struct sockaddr_storage *)UnicastAddr->Address.lpSockaddr;
if(Addr->ss_family == AF_INET6)
{
// Be sure not to overflow the addresses buffer of this adapter
if(AdInfo->NNetworkAddresses >= MAX_NETWORK_ADDRESSES)
{
GlobalFreePtr(AdBuffer);
TRACE_PRINT("The space in AdInfo->NNetworkAddresses is not large enough, failing");
TRACE_EXIT("PacketAddIP6Addresses");
return FALSE;
}
memcpy(&(AdInfo->NetworkAddresses[AdInfo->NNetworkAddresses].IPAddress), Addr, AddrLen);
memset(&(AdInfo->NetworkAddresses[AdInfo->NNetworkAddresses].SubnetMask), 0, sizeof(struct sockaddr_storage));
memset(&(AdInfo->NetworkAddresses[AdInfo->NNetworkAddresses].Broadcast), 0, sizeof(struct sockaddr_storage));
AdInfo->NNetworkAddresses ++;
}
}
}
}
TRACE_PRINT("PacketAddIP6Addresses, finished parsing the addresses");
GlobalFreePtr(AdBuffer);
TRACE_EXIT("PacketAddIP6Addresses");
return TRUE;
}
#endif // HAVE_IPHELPER_API
/*!
\brief Check if a string contains the "1394" substring
We prevent opening of firewire adapters since they have non standard behaviors that can cause
problems with winpcap
\param AdapterDesc NULL-terminated ASCII string with the adapter's description
\return TRUE if the input string contains "1394"
*/
BOOLEAN IsFireWire(TCHAR *AdapterDesc)
{
TRACE_ENTER("IsFireWire");
if(wcsstr(AdapterDesc, FIREWIRE_SUBSTR) != NULL)
{
TRACE_EXIT("IsFireWire");
return TRUE;
}
TRACE_EXIT("IsFireWire");
return FALSE;
}
#ifdef HAVE_IPHELPER_API
/*!
\brief Adds an entry to the adapter description list, gathering its values from the IP Helper API.
\param IphAd PIP_ADAPTER_INFO IP Helper API structure containing the parameters of the adapter that must be added to the list.
\return If the function succeeds, the return value is TRUE.
\note we suppose that we are called after having acquired the g_AdaptersInfoMutex mutex
*/
static BOOLEAN PacketAddAdapterIPH(PIP_ADAPTER_INFO IphAd)
{
PADAPTER_INFO TmpAdInfo, SAdInfo;
PIP_ADDR_STRING TmpAddrStr;
UINT i;
struct sockaddr_in *TmpAddr;
CHAR TName[256];
LPADAPTER adapter;
//
// Old registry based WinPcap names
//
// UINT RegQueryLen;
// CHAR npfCompleteDriverPrefix[MAX_WINPCAP_KEY_CHARS];
CHAR npfCompleteDriverPrefix[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_COMPLETE_DEVICE_PREFIX;
TRACE_ENTER("PacketAddAdapterIPH");
// Create the NPF device name from the original device name
//
// Old registry based WinPcap names
//
// RegQueryLen = sizeof(npfCompleteDriverPrefix)/sizeof(npfCompleteDriverPrefix[0]);
//
// if (QueryWinPcapRegistryStringA(NPF_DRIVER_COMPLETE_DEVICE_PREFIX_REG_KEY, npfCompleteDriverPrefix, &RegQueryLen, NPF_DRIVER_COMPLETE_DEVICE_PREFIX) == FALSE && RegQueryLen == 0)
// return FALSE;
//
// // Create the NPF device name from the original device name
// _snprintf(TName,
// sizeof(TName) - 1 - RegQueryLen - 1,
// "%s%s",
// npfCompleteDriverPrefix,
// IphAd->AdapterName);
// Create the NPF device name from the original device name
StringCchPrintfA(TName,
sizeof(TName) - strlen(npfCompleteDriverPrefix),
"%s%s",
npfCompleteDriverPrefix,
IphAd->AdapterName);
// Scan the adapters list to see if this one is already present
for(SAdInfo = g_AdaptersInfoList; SAdInfo != NULL; SAdInfo = SAdInfo->Next)
{
if(strcmp(TName, SAdInfo->Name) == 0)
{
TRACE_PRINT1("PacketAddAdapterIPH: Adapter %s already present in the list", TName);
goto SkipAd;
}
}
if(IphAd->Type == IF_TYPE_PPP || IphAd->Type == IF_TYPE_SLIP)
{
#ifdef HAVE_WANPACKET_API
if (!WanPacketTestAdapter())
goto SkipAd;
#else
goto SkipAd;
#endif
}
else
{
TRACE_PRINT1("Trying to open adapter %s to see if it's available...", TName);
adapter = PacketOpenAdapterNPF(TName);
if(adapter == NULL)
{
// We are not able to open this adapter. Skip to the next one.
TRACE_PRINT1("PacketAddAdapterIPH: unable to open the adapter %s", TName);
goto SkipAd;
}
else
{
TRACE_PRINT1("PacketAddAdapterIPH: adapter %s is available", TName);
PacketCloseAdapter(adapter);
}
}
//
// Adapter valid and not yet present in the list. Allocate the ADAPTER_INFO structure
//
TRACE_PRINT1("Adapter %s is available and should be added to the global list...", TName);
TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO));
if (TmpAdInfo == NULL)
{
TRACE_PRINT("PacketAddAdapterIPH: GlobalAlloc Failed allocating memory for the AdInfo");
TRACE_EXIT("PacketAddAdapterIPH");
return FALSE;
}
// Copy the device name
StringCchCopyA(TmpAdInfo->Name,ADAPTER_NAME_LENGTH, TName);
// Copy the description
StringCchCopyA(TmpAdInfo->Description, ADAPTER_DESC_LENGTH, IphAd->Description);
// Copy the MAC address
TmpAdInfo->MacAddressLen = IphAd->AddressLength;
memcpy(TmpAdInfo->MacAddress,
IphAd->Address,
(MAX_MAC_ADDR_LENGTH<MAX_ADAPTER_ADDRESS_LENGTH)? MAX_MAC_ADDR_LENGTH:MAX_ADAPTER_ADDRESS_LENGTH);
// Calculate the number of IP addresses of this interface
for(TmpAddrStr = &IphAd->IpAddressList, i = 0; TmpAddrStr != NULL; TmpAddrStr = TmpAddrStr->Next, i++)
{
}
TmpAdInfo->NetworkAddresses = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, MAX_NETWORK_ADDRESSES * sizeof(npf_if_addr));
if (TmpAdInfo->NetworkAddresses == NULL) {
TRACE_PRINT("PacketAddAdapterIPH: GlobalAlloc Failed allocating the memory for the IP addresses in AdInfo.");
GlobalFreePtr(TmpAdInfo);
TRACE_EXIT("PacketAddAdapterIPH");
return FALSE;
}
TRACE_PRINT1("Adding the IPv4 addresses to the adapter %s...", TName);
// Scan the addresses, convert them to addrinfo structures and put each of them in the list
for(TmpAddrStr = &IphAd->IpAddressList, i = 0; TmpAddrStr != NULL; TmpAddrStr = TmpAddrStr->Next)
{
TmpAddr = (struct sockaddr_in *)&(TmpAdInfo->NetworkAddresses[i].IPAddress);
if((TmpAddr->sin_addr.S_un.S_addr = inet_addr(TmpAddrStr->IpAddress.String))!= INADDR_NONE)
{
TmpAddr->sin_family = AF_INET;
TmpAddr = (struct sockaddr_in *)&(TmpAdInfo->NetworkAddresses[i].SubnetMask);
TmpAddr->sin_addr.S_un.S_addr = inet_addr(TmpAddrStr->IpMask.String);
TmpAddr->sin_family = AF_INET;
TmpAddr = (struct sockaddr_in *)&(TmpAdInfo->NetworkAddresses[i].Broadcast);
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
TmpAddr->sin_family = AF_INET;
i++;
}
}
TmpAdInfo->NNetworkAddresses = i;
TRACE_PRINT1("Adding the IPv6 addresses to the adapter %s...", TName);
// Now Add IPv6 Addresses
PacketAddIP6Addresses(TmpAdInfo);
if(IphAd->Type == IF_TYPE_PPP || IphAd->Type == IF_TYPE_SLIP)
{
TRACE_PRINT("Flagging the adapter as NDISWAN.");
// NdisWan adapter
TmpAdInfo->Flags = INFO_FLAG_NDISWAN_ADAPTER;
}
// Update the AdaptersInfo list
TmpAdInfo->Next = g_AdaptersInfoList;
g_AdaptersInfoList = TmpAdInfo;
SkipAd:
TRACE_EXIT("PacketAddAdapterIPH");
return TRUE;
}
/*!
\brief Updates the list of the adapters querying the IP Helper API.
\return If the function succeeds, the return value is nonzero.
This function populates the list of adapter descriptions, retrieving the information from a query to
the IP Helper API. The IP Helper API is used as a support of the standard registry query method to obtain
adapter information, so PacketGetAdaptersIPH() add only information about the adapters that were not
found by PacketGetAdapters().
*/
static BOOLEAN PacketGetAdaptersIPH()
{
PIP_ADAPTER_INFO AdList = NULL;
PIP_ADAPTER_INFO TmpAd;
ULONG OutBufLen=0;
TRACE_ENTER("PacketGetAdaptersIPH");
// Find the size of the buffer filled by GetAdaptersInfo
if(GetAdaptersInfo(AdList, &OutBufLen) == ERROR_NOT_SUPPORTED)
{
TRACE_PRINT("IP Helper API not supported on this system!");
TRACE_EXIT("PacketGetAdaptersIPH");
return FALSE;
}
TRACE_PRINT("PacketGetAdaptersIPH: retrieved needed bytes for IPH");
// Allocate the buffer
AdList = GlobalAllocPtr(GMEM_MOVEABLE, OutBufLen);
if (AdList == NULL)
{
TRACE_PRINT("PacketGetAdaptersIPH: GlobalAlloc Failed allocating the buffer for GetAdaptersInfo");
TRACE_EXIT("PacketGetAdaptersIPH");
return FALSE;
}
// Retrieve the adapters information using the IP helper API
GetAdaptersInfo(AdList, &OutBufLen);
TRACE_PRINT("PacketGetAdaptersIPH: retrieved list from IPH. Adding adapters to the global list.");
// Scan the list of adapters obtained from the IP helper API, create a new ADAPTER_INFO
// structure for every new adapter and put it in our global list
for(TmpAd = AdList; TmpAd != NULL; TmpAd = TmpAd->Next)
{
PacketAddAdapterIPH(TmpAd);
}
GlobalFreePtr(AdList);
TRACE_EXIT("PacketGetAdaptersIPH");
return TRUE;
}
#endif // HAVE_IPHELPER_API
/*!
\brief Adds an entry to the adapter description list.
\param AdName Name of the adapter to add
\return If the function succeeds, the return value is nonzero.
Used by PacketGetAdapters(). Queries the registry to fill the PADAPTER_INFO describing the new adapter.
*/
static BOOLEAN PacketAddAdapterNPF(PCHAR AdName, UINT flags)
{
//this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter
LONG Status;
LPADAPTER adapter = NULL;
PPACKET_OID_DATA OidData = NULL;
PADAPTER_INFO TmpAdInfo;
PADAPTER_INFO TAdInfo;
TRACE_ENTER("PacketAddAdapterNPF");
TRACE_PRINT1("Trying to add adapter %s", AdName);
//
// let's check that the adapter name will fit in the space available within ADAPTER_INFO::Name
// If not, simply fail, since we cannot properly save the adapter name
//
if (strlen(AdName) + 1 > sizeof(TmpAdInfo->Name))
{
TRACE_PRINT("PacketAddAdapterNPF: adapter name is too long to be stored into ADAPTER_INFO::Name, simply skip it");
return FALSE;
}
WaitForSingleObject(g_AdaptersInfoMutex, INFINITE);
for(TAdInfo = g_AdaptersInfoList; TAdInfo != NULL; TAdInfo = TAdInfo->Next)
{
if(strcmp(AdName, TAdInfo->Name) == 0)
{
TRACE_PRINT("PacketAddAdapterNPF: Adapter already present in the list");
ReleaseMutex(g_AdaptersInfoMutex);
TRACE_EXIT("PacketAddAdapterNPF");
return TRUE;
}
}
//here we could have released the mutex, but what happens if two threads try to add the same adapter?
//The adapter would be duplicated on the linked list
if(flags != INFO_FLAG_DONT_EXPORT)
{
TRACE_PRINT("Trying to open the NPF adapter and see if it's available...");
// Try to Open the adapter
adapter = PacketOpenAdapterNPF(AdName);
if(adapter != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -