⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adinfo.c

📁 Windows XP下的抓包程序实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 + -