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

📄 iphelper.h

📁 软件源代码,共享。有2个文件
💻 H
字号:
#pragma once

#include <Winsock.h>
#pragma comment(lib, "Ws2_32.lib")
#include <IPHlpApi.h>
#pragma comment(lib, "Iphlpapi.lib")
#pragma comment(lib, "Netapi32.lib")

#include <Nb30.h>

#include <string>
#include <sstream>
//#include <atlbase.h>



#define _IPHELPER_BEGIN		namespace iphelper {
#define _IPHELPER_END		}
#define _USING_IPHELPER		using namespace iphelper;




_IPHELPER_BEGIN


//type
struct MAC
	{ UCHAR v[6]; };
const MAC MAC_NONE = {0, 0, 0, 0, 0, 0};




namespace basic
{
	inline 
	ULONG Addr2IP(LPCWSTR addr)
	{
		ULONG ip = inet_addr(ATL::CW2A(addr));
		return ntohl(ip);
	}
	inline 
	std::wstring IP2Addr(ULONG ip)
	{
		in_addr inaddr;
		inaddr.s_addr = htonl(ip);
		return std::wstring(ATL::CA2W(inet_ntoa(inaddr)));
	}


	inline 
	MAC Str2Mac(LPCWSTR sz)
	{
		UINT fields[6];
		if (swscanf(sz, L"%x-%x-%x-%x-%x-%x", &fields[0], &fields[1], &fields[2], &fields[3], &fields[4], &fields[5]) != 6)
			return MAC_NONE;
		MAC mac;
		for (int i = 0; i < 6; ++i)
		{
			if (fields[i] > 0x00FF)
				return MAC_NONE;
			mac.v[i] = (UCHAR)fields[i];
		}
		return mac;
	}
	inline 
	std::wstring Mac2Str(const MAC& mac)
	{
		WCHAR buff[18];
		swprintf(buff, L"%02X-%02X-%02X-%02X-%02X-%02X", (UINT)mac.v[0], (UINT)mac.v[1], (UINT)mac.v[2], (UINT)mac.v[3], (UINT)mac.v[4], (UINT)mac.v[5]);
		return buff;
	}

} //namespace basic



namespace dns
{
	inline 
	ULONG Name2IP(LPCWSTR name)
	{
		hostent* pHE = gethostbyname(ATL::CW2A(name));
		if (pHE == NULL)
			return INADDR_NONE;
		if (pHE->h_addrtype != AF_INET)
			return INADDR_NONE;
		if (pHE->h_length < sizeof(in_addr))
			return INADDR_NONE;
		in_addr* pInAddr = (in_addr*)pHE->h_addr;
		if (pInAddr == NULL)
			return INADDR_NONE;
		return ntohl(pInAddr->s_addr);
	}

	inline 
	std::wstring IP2Name(ULONG ip)
	{
		ULONG ipN = htonl(ip);
		hostent* pHE = gethostbyaddr((const char*)&ipN, sizeof(ipN), AF_INET);
		if (pHE == NULL)
			return L"";
		if (pHE->h_addrtype != AF_INET)
			return L"";
		return std::wstring(ATL::CA2W(pHE->h_name));
	}

} //namespace dns




//支持Addr和Name两种格式
namespace advance
{
	inline 
	ULONG RetrieveIP(LPCWSTR AddrOrName)
	{
		ULONG ip = iphelper::basic::Addr2IP(AddrOrName);
		if (ip == INADDR_NONE)
			ip = iphelper::dns::Name2IP(AddrOrName);
		return ip;
	}

} //namespace adv




namespace adapter
{
	namespace
	{
		inline 
		bool _IsLoopbackIp(ULONG ip)
		{
			return (ip & 0xFF000000) == 0x7F000000;
		}

		inline 
		bool _IsValidIpAddrRow(const MIB_IPADDRROW& row, bool fIncludeLoopback)
		{
			if (row.dwMask == 0
					|| (row.dwAddr & 0xFF000000) == 0x00000000 || (row.dwAddr  & 0xFF000000) == 0xFF000000)
				return false;	//? Windows server 2003 中会有此情况
			if (!fIncludeLoopback)
			{
				if (_IsLoopbackIp(row.dwAddr))
					return false;
			}
			return true;
		}

		inline 
		void _TidyIpAddrTable(MIB_IPADDRTABLE* pIpAddrTable, bool fIncludeLoopback)
		{
			DWORD dwNumEntries = pIpAddrTable->dwNumEntries;
			pIpAddrTable->dwNumEntries = 0;

			for (DWORD i = 0; i < dwNumEntries; ++i)
			{
				pIpAddrTable->table[i].dwAddr = ntohl(pIpAddrTable->table[i].dwAddr);
				pIpAddrTable->table[i].dwMask = ntohl(pIpAddrTable->table[i].dwMask);

				if (!_IsValidIpAddrRow(pIpAddrTable->table[i], fIncludeLoopback))
					continue;

				if (pIpAddrTable->dwNumEntries < i)
					pIpAddrTable->table[pIpAddrTable->dwNumEntries] = pIpAddrTable->table[i];

				++ pIpAddrTable->dwNumEntries;
			}
		}

		inline 
		MIB_IPADDRTABLE* _GetIpAddrTable(bool fIncludeLoopback, bool fSort)
		{
			ULONG cbIpAddrTable = 0;
			if (::GetIpAddrTable(NULL, &cbIpAddrTable, false) != ERROR_INSUFFICIENT_BUFFER)
				return NULL;
			if (cbIpAddrTable == 0)
				return NULL;
			BYTE* pRawMem = new BYTE[cbIpAddrTable];
			MIB_IPADDRTABLE* pIpAddrTable = (MIB_IPADDRTABLE*)pRawMem;

			if (::GetIpAddrTable(pIpAddrTable, &cbIpAddrTable, fSort) != NO_ERROR)
			{
				delete []pRawMem;
				return NULL;
			}

			_TidyIpAddrTable(pIpAddrTable, fIncludeLoopback);

			if (pIpAddrTable->dwNumEntries == 0)
			{
				delete []pRawMem;
				return NULL;
			}

			return pIpAddrTable;
		}

		inline 
		void _FreeIpAddrTable(MIB_IPADDRTABLE* pIpAddrTable)
		{
			if (pIpAddrTable != NULL)
			{
				BYTE* pRawMem = (BYTE*)pIpAddrTable;
				delete []pRawMem;
			}
		}

	} //namespace


	inline 
	ULONG GetSelfAddressCount(bool fIncludeLoopback = false)
	{
		//DWORD InterfaceCount = 0;
		//if (::GetNumberOfInterfaces(&InterfaceCount) != NO_ERROR)
		//	return 0;
		//
		//return InterfaceCount;


		//使用GetNumberOfInterfaces()不够准确,因为有部分Ip需要剔除,改成GetIpAddrTable()
		MIB_IPADDRTABLE* pIpAddrTable = _GetIpAddrTable(fIncludeLoopback, false);
		if (pIpAddrTable == NULL)
			return 0;

		ULONG AddressCountRet = pIpAddrTable->dwNumEntries;

		_FreeIpAddrTable(pIpAddrTable);

		return AddressCountRet;
	}

	inline 
	ULONG GetSelfAddresses(ULONG* pAddresses, ULONG AddressCount, bool fIncludeLoopback = false, bool fSort = false)
	{
		MIB_IPADDRTABLE* pIpAddrTable = _GetIpAddrTable(fIncludeLoopback, fSort);
		if (pIpAddrTable == NULL)
			return 0;

		ULONG AddressCountRet = 0;

		for (DWORD i = 0; i < pIpAddrTable->dwNumEntries; ++i)
		{
			if (AddressCountRet >= AddressCount)
				break;

			pAddresses[AddressCountRet] = pIpAddrTable->table[i].dwAddr;
			++ AddressCountRet;
		}

		_FreeIpAddrTable(pIpAddrTable);

		return AddressCountRet;
	}


	inline 
	bool IsLoopbackIp(ULONG ip)
	{
		return _IsLoopbackIp(ip);
	}

	inline 
	bool IsSelfAddress(ULONG ip)
	{
		if (ip == INADDR_NONE)
			return false;
		if (_IsLoopbackIp(ip))	//127.0.0.1
			return true;

		ULONG nAddrCount = GetSelfAddressCount();
		if (nAddrCount == 0)
			return false;


		MIB_IPADDRTABLE* pIpAddrTable = _GetIpAddrTable(false, false);
		if (pIpAddrTable == NULL)
			return false;

		bool fSelf = false;

		for (ULONG i = 0; i < nAddrCount; ++i)
		{
			if (pIpAddrTable->table[i].dwAddr == ip)
			{
				fSelf = true;
				break;
			}
		}

		_FreeIpAddrTable(pIpAddrTable);

		return fSelf;
	}

	inline 
	ULONG GetBestInterface(ULONG ipTo)
	{
		if (ipTo == INADDR_NONE)
			return INADDR_NONE;
		if (_IsLoopbackIp(ipTo))
			return ipTo;

		MIB_IPADDRTABLE* pIpAddrTable = _GetIpAddrTable(false, false);
		if (pIpAddrTable == NULL)
			return INADDR_NONE;


		ULONG ipBest = INADDR_NONE;

		//check self
		for (DWORD i = 0; i < pIpAddrTable->dwNumEntries; ++i)
		{
			if (pIpAddrTable->table[i].dwAddr == ipTo)
			{
				ipBest = ipTo;	//self
				goto over_check;
			}
		}

		//check mask
		for (DWORD i = 0; i < pIpAddrTable->dwNumEntries; ++i)
		{
			if (pIpAddrTable->table[i].dwAddr == 0 || pIpAddrTable->table[i].dwMask == 0)
				continue;	//? Windows server 2003 中会有此情况
			if ((pIpAddrTable->table[i].dwAddr & pIpAddrTable->table[i].dwMask)
					== (ipTo & pIpAddrTable->table[i].dwMask))
			{
				ipBest = pIpAddrTable->table[i].dwAddr;
				goto over_check;
			}
		}

		//best interface
		DWORD BestInterfaceIndex = 0;
		if (::GetBestInterface(ipTo, &BestInterfaceIndex) == NO_ERROR)
		{
			for (DWORD i = 0; i < pIpAddrTable->dwNumEntries; ++i)
			{
				if (pIpAddrTable->table[i].dwIndex == BestInterfaceIndex)
				{
					ipBest = pIpAddrTable->table[i].dwAddr;
					goto over_check;
				}
			}
		}

	over_check:
		_FreeIpAddrTable(pIpAddrTable);

		return ipBest;
	}



	inline 
	ULONG GetLanAdapterCount()
	{
		LANA_ENUM lana_enum;

		NCB ncbEnum = {0};
		ncbEnum.ncb_command = NCBENUM;
		ncbEnum.ncb_buffer = (PUCHAR)&lana_enum;
		ncbEnum.ncb_length = sizeof(lana_enum);
		if (::Netbios(&ncbEnum) != NRC_GOODRET)
			return 0;

		return lana_enum.length;
	}


	inline 
	ULONG GetLanAdapterMACs(MAC* pMacAddresses, ULONG MacAddressCount)
	{
#pragma pack(push, 1)
		struct _ASTAT
		{
			ADAPTER_STATUS status;
			NAME_BUFFER name[30];
		};
#pragma pack(pop)


		LANA_ENUM lana_enum;
		{{
			NCB ncbEnum = {0};
			ncbEnum.ncb_command = NCBENUM;
			ncbEnum.ncb_buffer = (PUCHAR)&lana_enum;
			ncbEnum.ncb_length = sizeof(lana_enum);
			if (::Netbios(&ncbEnum) != NRC_GOODRET)
				return 0;
		}}


		ULONG MacAddressCountRet = 0;

		for (UCHAR i = 0; i < lana_enum.length; ++i)
		{
			if (MacAddressCountRet >= MacAddressCount)
				break;

			{{
				NCB ncbReset = {0};
				ncbReset.ncb_command = NCBRESET;
				ncbReset.ncb_lana_num = lana_enum.lana[i];    
				if (::Netbios(&ncbReset) != NRC_GOODRET)
					break;
			}}

			_ASTAT astat;
			{{
				NCB ncbAStat = {0};
				ncbAStat.ncb_command = NCBASTAT;
				ncbAStat.ncb_lana_num = lana_enum.lana[i];
				strcpy((char*)ncbAStat.ncb_callname, "*");
				ncbAStat.ncb_buffer = (PUCHAR)&astat;
				ncbAStat.ncb_length = sizeof(astat);
				if (::Netbios( &ncbAStat) != NRC_GOODRET)
					break;
			}}

			memcpy(pMacAddresses[MacAddressCountRet].v, astat.status.adapter_address, 6);
			++ MacAddressCountRet;
		}

		return MacAddressCountRet;
	}


} //namespace adapter




_IPHELPER_END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -