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

📄 networkinterface.cpp

📁 C++ class libraries for network-centric, portable applications, integrated perfectly with the C++ St
💻 CPP
字号:
//// NetworkInterface.cpp//// $Id: //poco/1.2/Net/src/NetworkInterface.cpp#1 $//// Library: Net// Package: Sockets// Module:  NetworkInterface//// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.// and Contributors.//// Permission is hereby granted, free of charge, to any person or organization// obtaining a copy of the software and accompanying documentation covered by// this license (the "Software") to use, reproduce, display, distribute,// execute, and transmit the Software, and to prepare derivative works of the// Software, and to permit third-parties to whom the Software is furnished to// do so, all subject to the following:// // The copyright notices in the Software and this entire statement, including// the above license grant, this restriction and the following disclaimer,// must be included in all copies of the Software, in whole or in part, and// all derivative works of the Software, unless such copies or derivative// works are solely in the form of machine-executable object code generated by// a source language processor.// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER// DEALINGS IN THE SOFTWARE.//#include "Poco/Net/NetworkInterface.h"#include "Poco/Net/DatagramSocket.h"#include "Poco/Net/NetException.h"#include "Poco/NumberFormatter.h"#include <string.h>using Poco::NumberFormatter;using Poco::FastMutex;namespace Poco {namespace Net {FastMutex NetworkInterface::_mutex;NetworkInterface::NetworkInterface():	_index(0){}NetworkInterface::NetworkInterface(const std::string& name, const IPAddress& address, int index):	_name(name),	_address(address),	_index(index){}NetworkInterface::NetworkInterface(const NetworkInterface& interface):	_name(interface._name),	_address(interface._address),	_index(interface._index){}NetworkInterface::~NetworkInterface(){}NetworkInterface& NetworkInterface::operator = (const NetworkInterface& interface){	if (&interface != this)	{		_name    = interface._name;		_address = interface._address;		_index   = interface._index;	}	return *this;}NetworkInterface NetworkInterface::forName(const std::string& name, bool requireIPv6){#if defined(_WIN32)	NetworkInterfaceList ifs = list();	for (NetworkInterfaceList::const_iterator it = ifs.begin(); it != ifs.end(); ++it)	{		if (it->name() == name && it->supportsIPv6() == requireIPv6)			return *it;	}	throw InterfaceNotFoundException(name);#else	FastMutex::ScopedLock lock(_mutex);	struct ifreq ifr;	strncpy(ifr.ifr_name, name.c_str(), IFNAMSIZ);	DatagramSocket ds(requireIPv6 ? IPAddress::IPv6 : IPAddress::IPv4);	ds.impl()->ioctl(SIOCGIFADDR, &ifr);	IPAddress addr;#if defined(POCO_HAVE_IPv6)	if (ifr.ifr_addr.sa_family == AF_INET)		addr = IPAddress(&reinterpret_cast<const struct sockaddr_in*>(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr));	else if (ifr.ifr_addr.sa_family == AF_INET6)		addr = IPAddress(&reinterpret_cast<const struct sockaddr_in6*>(&ifr.ifr_addr)->sin6_addr, sizeof(struct in6_addr));	else throw InterfaceNotFoundException(addr.toString(), "interface has no IP address");	int index = if_nametoindex(name.c_str());#else	if (ifr.ifr_addr.sa_family == AF_INET)		addr = IPAddress(&reinterpret_cast<const struct sockaddr_in*>(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr));	else throw InterfaceNotFoundException(addr.toString(), "interface has no IP address");	int index = 0;#endif	return NetworkInterface(name, addr, index);#endif}	NetworkInterface NetworkInterface::forAddress(const IPAddress& addr){	NetworkInterfaceList ifs = list();	for (NetworkInterfaceList::const_iterator it = ifs.begin(); it != ifs.end(); ++it)	{		if (it->address() == addr)			return *it;	}	throw InterfaceNotFoundException(addr.toString());}NetworkInterface NetworkInterface::forIndex(int i){	if (i != 0)	{		NetworkInterfaceList ifs = list();		for (NetworkInterfaceList::const_iterator it = ifs.begin(); it != ifs.end(); ++it)		{			if (it->index() == i)				return *it;		}		throw InterfaceNotFoundException("#" + NumberFormatter::format(i));	}	else return NetworkInterface();}} } // namespace Poco::Net//// platform-specific code below//#if defined(POCO_OS_FAMILY_WINDOWS)//// Windows//#include <iphlpapi.h>namespace Poco {namespace Net {	NetworkInterface::NetworkInterfaceList NetworkInterface::list(){	FastMutex::ScopedLock lock(_mutex);	NetworkInterfaceList result;	#if defined(POCO_HAVE_IPv6)	// On Windows XP/Server 2003 and later we use GetAdaptersAddresses.	PIP_ADAPTER_ADDRESSES pAdapterAddresses;	PIP_ADAPTER_ADDRESSES pAdapter = 0;	ULONG len         = sizeof(IP_ADAPTER_ADDRESSES);	pAdapterAddresses = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(new char[len]);	// Make an initial call to GetAdaptersAddresses to get	// the necessary size into len	DWORD rc = GetAdaptersAddresses(AF_UNSPEC, 0, 0, pAdapterAddresses, &len);	if (rc == ERROR_BUFFER_OVERFLOW) 	{		delete [] reinterpret_cast<char*>(pAdapterAddresses);		pAdapterAddresses = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(new char[len]);	}	else if (rc != ERROR_SUCCESS)	{		throw NetException("cannot get network adapter list");	}	try	{		if (GetAdaptersAddresses(AF_UNSPEC, 0, 0, pAdapterAddresses, &len) == NO_ERROR) 		{			pAdapter = pAdapterAddresses;			while (pAdapter) 			{				if (pAdapter->FirstUnicastAddress)				{					IPAddress addr(pAdapter->FirstUnicastAddress->Address.lpSockaddr, pAdapter->FirstUnicastAddress->Address.iSockaddrLength);					result.push_back(NetworkInterface(std::string(pAdapter->AdapterName), addr, pAdapter->Ipv6IfIndex));					pAdapter = pAdapter->Next;				}			}		}		else throw NetException("cannot get network adapter list");	}	catch (Poco::Exception&)	{		delete [] reinterpret_cast<char*>(pAdapterAddresses);		throw;	}	delete [] reinterpret_cast<char*>(pAdapterAddresses);#else	// Add loopback interface (not returned by GetAdaptersInfo)	result.push_back(NetworkInterface("Loopback", IPAddress("127.0.0.1"), -1));	// On Windows 2000 we use GetAdaptersInfo.	PIP_ADAPTER_INFO pAdapterInfo;	PIP_ADAPTER_INFO pAdapter = 0;	ULONG len    = sizeof(IP_ADAPTER_INFO);	pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(new char[len]);	// Make an initial call to GetAdaptersInfo to get	// the necessary size into len	DWORD rc = GetAdaptersInfo(pAdapterInfo, &len);	if (rc == ERROR_BUFFER_OVERFLOW) 	{		delete [] reinterpret_cast<char*>(pAdapterInfo);		pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(new char[len]);	}	else if (rc != ERROR_SUCCESS)	{		throw NetException("cannot get network adapter list");	}	try	{		if (GetAdaptersInfo(pAdapterInfo, &len) == NO_ERROR) 		{			pAdapter = pAdapterInfo;			while (pAdapter) 			{				IPAddress addr(std::string(pAdapter->IpAddressList.IpAddress.String));				result.push_back(NetworkInterface(std::string(pAdapter->AdapterName), addr));				pAdapter = pAdapter->Next;			}		}		else throw NetException("cannot get network adapter list");	}	catch (Poco::Exception&)	{		delete [] reinterpret_cast<char*>(pAdapterInfo);		throw;	}	delete [] reinterpret_cast<char*>(pAdapterInfo);#endif	return result;}} } // namespace Poco::Net#elif defined(POCO_OS_FAMILY_BSD) || POCO_OS == POCO_OS_QNX//// BSD variants//#include <sys/types.h>#include <sys/socket.h>#include <ifaddrs.h>#include <net/if_dl.h>namespace Poco {namespace Net {NetworkInterface::NetworkInterfaceList NetworkInterface::list(){	FastMutex::ScopedLock lock(_mutex);	NetworkInterfaceList result;	struct ifaddrs* ifaphead;	int rc = getifaddrs(&ifaphead);	if (rc) throw NetException("cannot get network adapter list");	for (struct ifaddrs* ifap = ifaphead; ifap; ifap = ifap->ifa_next) 	{		if (ifap->ifa_addr)		{			if (ifap->ifa_addr->sa_family == AF_INET)			{				IPAddress addr(&reinterpret_cast<struct sockaddr_in*>(ifap->ifa_addr)->sin_addr, sizeof(struct in_addr));				result.push_back(NetworkInterface(std::string(ifap->ifa_name), addr));			}#if defined(POCO_HAVE_IPv6)			else if (ifap->ifa_addr->sa_family == AF_INET6)			{				IPAddress addr(&reinterpret_cast<struct sockaddr_in6*>(ifap->ifa_addr)->sin6_addr, sizeof(struct in6_addr));				result.push_back(NetworkInterface(std::string(ifap->ifa_name), addr, if_nametoindex(ifap->ifa_name)));			}#endif		}	}	freeifaddrs(ifaphead);	return result;}} } // namespace Poco::Net#elif POCO_OS == POCO_OS_LINUX//// Linux//namespace Poco {namespace Net {NetworkInterface::NetworkInterfaceList NetworkInterface::list(){	FastMutex::ScopedLock lock(_mutex);	NetworkInterfaceList result;	DatagramSocket socket;	// the following code is loosely based	// on W. Richard Stevens, UNIX Network Programming, pp 434ff.	int lastlen = 0;	int len = 100*sizeof(struct ifreq);	char* buf = 0;	try	{		struct ifconf ifc;		for (;;)		{			buf = new char[len];			ifc.ifc_len = len;			ifc.ifc_buf = buf;			if (::ioctl(socket.impl()->sockfd(), SIOCGIFCONF, &ifc) < 0)			{				if (errno != EINVAL || lastlen != 0)					throw NetException("cannot get network adapter list");			}			else			{				if (ifc.ifc_len == lastlen)					break;				lastlen = ifc.ifc_len;			}			len += 10*sizeof(struct ifreq);			delete [] buf;		}		for (const char* ptr = buf; ptr < buf + ifc.ifc_len;)		{			const struct ifreq* ifr = reinterpret_cast<const struct ifreq*>(ptr);			IPAddress addr;			bool haveAddr = false;			switch (ifr->ifr_addr.sa_family)			{#if defined(POCO_HAVE_IPv6)			case AF_INET6:				addr = IPAddress(&reinterpret_cast<const struct sockaddr_in6*>(&ifr->ifr_addr)->sin6_addr, sizeof(struct in6_addr));				haveAddr = true;				break;#endif			case AF_INET:				addr = IPAddress(&reinterpret_cast<const struct sockaddr_in*>(&ifr->ifr_addr)->sin_addr, sizeof(struct in_addr));				haveAddr = true;				break;			default:				break;			}			if (haveAddr)			{#if defined(POCO_HAVE_IPv6)				int index = if_nametoindex(ifr->ifr_name);#else				int index = -1;#endif				result.push_back(NetworkInterface(std::string(ifr->ifr_name), addr, index));			}			ptr += sizeof(struct ifreq);		}	}	catch (...)	{		delete [] buf;		throw;	}	delete [] buf;	return result;}} } // namespace Poco::Net#else//// Non-BSD Unix variants//namespace Poco {namespace Net {NetworkInterface::NetworkInterfaceList NetworkInterface::list(){	FastMutex::ScopedLock lock(_mutex);	NetworkInterfaceList result;	DatagramSocket socket;	// the following code is loosely based	// on W. Richard Stevens, UNIX Network Programming, pp 434ff.	int lastlen = 0;	int len = 100*sizeof(struct ifreq);	char* buf = 0;	try	{		struct ifconf ifc;		for (;;)		{			buf = new char[len];			ifc.ifc_len = len;			ifc.ifc_buf = buf;			if (::ioctl(socket.impl()->sockfd(), SIOCGIFCONF, &ifc) < 0)			{				if (errno != EINVAL || lastlen != 0)					throw NetException("cannot get network adapter list");			}			else			{				if (ifc.ifc_len == lastlen)					break;				lastlen = ifc.ifc_len;			}			len += 10*sizeof(struct ifreq);			delete [] buf;		}		for (const char* ptr = buf; ptr < buf + ifc.ifc_len;)		{			const struct ifreq* ifr = reinterpret_cast<const struct ifreq*>(ptr);#if defined(POCO_HAVE_SALEN)			len = ifr->ifr_addr.sa_len;			if (sizeof(struct sockaddr) > len) len = sizeof(struct sockaddr);#else			len = sizeof(struct sockaddr);#endif			IPAddress addr;			bool haveAddr = false;			switch (ifr->ifr_addr.sa_family)			{#if defined(POCO_HAVE_IPv6)			case AF_INET6:				if (len < sizeof(struct sockaddr_in6)) len = sizeof(struct sockaddr_in6);				addr = IPAddress(&reinterpret_cast<const struct sockaddr_in6*>(&ifr->ifr_addr)->sin6_addr, sizeof(struct in6_addr));				haveAddr = true;				break;#endif			case AF_INET:				if (len < sizeof(struct sockaddr_in)) len = sizeof(struct sockaddr_in);				addr = IPAddress(&reinterpret_cast<const struct sockaddr_in*>(&ifr->ifr_addr)->sin_addr, sizeof(struct in_addr));				haveAddr = true;				break;			default:				break;			}			if (haveAddr)			{#if defined(POCO_HAVE_IPv6)				int index = if_nametoindex(ifr->ifr_name);#else				int index = -1;#endif				result.push_back(NetworkInterface(std::string(ifr->ifr_name), addr, index));			}			len += sizeof(ifr->ifr_name);			ptr += len;		}	}	catch (...)	{		delete [] buf;		throw;	}	delete [] buf;	return result;}} } // namespace Poco::Net#endif

⌨️ 快捷键说明

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