more improvements/redesign, mostly Windows related
This commit is contained in:
Родитель
20d5b2d2fb
Коммит
273b9c92f8
|
@ -89,7 +89,9 @@ public:
|
||||||
IPv4_OR_IPv6 /// Return interfaces with IPv4 or IPv6 address
|
IPv4_OR_IPv6 /// Return interfaces with IPv4 or IPv6 address
|
||||||
};
|
};
|
||||||
|
|
||||||
NetworkInterface(unsigned index = 0);
|
static const unsigned NO_INDEX = ~0;
|
||||||
|
|
||||||
|
NetworkInterface(unsigned index = NO_INDEX);
|
||||||
/// Creates a NetworkInterface representing the
|
/// Creates a NetworkInterface representing the
|
||||||
/// default interface.
|
/// default interface.
|
||||||
///
|
///
|
||||||
|
@ -129,8 +131,11 @@ public:
|
||||||
///
|
///
|
||||||
/// On other platforms this is the same as name().
|
/// On other platforms this is the same as name().
|
||||||
|
|
||||||
const IPAddress& address(unsigned index = 0) const;
|
const IPAddress& findFirstAddress(IPAddress::Family family) const;
|
||||||
/// Returns the IP address bound to the interface.
|
/// Returns the first IP address bound to the interface.
|
||||||
|
|
||||||
|
const IPAddress& address(unsigned index) const;
|
||||||
|
/// Returns the IP address bound to the interface at index position.
|
||||||
|
|
||||||
void addAddress(const IPAddress& address);
|
void addAddress(const IPAddress& address);
|
||||||
/// Adds address to the interface.
|
/// Adds address to the interface.
|
||||||
|
@ -141,13 +146,13 @@ public:
|
||||||
const AddressList& addressList() const;
|
const AddressList& addressList() const;
|
||||||
/// Returns the list of IP addresses bound to the interface.
|
/// Returns the list of IP addresses bound to the interface.
|
||||||
|
|
||||||
const IPAddress& subnetMask(unsigned index = 0) const;
|
const IPAddress& subnetMask(unsigned index) const;
|
||||||
/// Returns the subnet mask for this network interface.
|
/// Returns the subnet mask for this network interface.
|
||||||
|
|
||||||
const IPAddress& broadcastAddress(unsigned index = 0) const;
|
const IPAddress& broadcastAddress(unsigned index) const;
|
||||||
/// Returns the broadcast address for this network interface.
|
/// Returns the broadcast address for this network interface.
|
||||||
|
|
||||||
const IPAddress& destAddress(unsigned index = 0) const;
|
const IPAddress& destAddress(unsigned index) const;
|
||||||
/// Returns the IPv4 point-to-point destiation address for this network interface.
|
/// Returns the IPv4 point-to-point destiation address for this network interface.
|
||||||
|
|
||||||
const MacAddress& macAddress() const;
|
const MacAddress& macAddress() const;
|
||||||
|
@ -217,26 +222,50 @@ public:
|
||||||
/// with the given index does not exist (or IPv6 is not
|
/// with the given index does not exist (or IPv6 is not
|
||||||
/// available).
|
/// available).
|
||||||
|
|
||||||
static Map map();
|
static List list(bool ipOnly = true, bool upOnly = true);
|
||||||
/// Returns a map with all network interfaces
|
/// Returns a list with all network interfaces
|
||||||
/// on the system. Map is keyed by interface system
|
/// on the system.
|
||||||
/// indices.
|
///
|
||||||
|
/// If ipOnly is true, only interfaces supporting IP
|
||||||
|
/// are returned. Otherwise, all system network interfaces
|
||||||
|
/// are returned.
|
||||||
|
///
|
||||||
|
/// If upOnly is true, only interfaces being up are returned.
|
||||||
|
/// Otherwise, both interfaces being up and down are returned.
|
||||||
|
///
|
||||||
|
/// If there are multiple addresses bound to one interface,
|
||||||
|
/// multiple NetworkInterface entries are listed for
|
||||||
|
/// the same interface.
|
||||||
|
|
||||||
|
static Map map(bool ipOnly = true, bool upOnly = true);
|
||||||
|
/// Returns a map containing system network interfaces
|
||||||
|
/// Map is keyed by interface system indices.
|
||||||
|
///
|
||||||
|
/// If ipOnly is true, only interfaces supporting IP
|
||||||
|
/// are returned. Otherwise, all system network interfaces
|
||||||
|
/// are returned.
|
||||||
|
///
|
||||||
|
/// If upOnly is true, only interfaces being up are returned.
|
||||||
|
/// Otherwise, both interfaces being up and down are returned.
|
||||||
///
|
///
|
||||||
/// If there are multiple addresses bound to one interface,
|
/// If there are multiple addresses bound to one interface,
|
||||||
/// they are contained within the NetworkInterface (second)
|
/// they are contained within the NetworkInterface (second)
|
||||||
/// member of the pair.
|
/// member of the pair.
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
NetworkInterface(const std::string& name, const std::string& displayName, const IPAddress& address, unsigned index = 0);
|
NetworkInterface(const std::string& name, const std::string& displayName, const IPAddress& address, unsigned index);
|
||||||
/// Creates the NetworkInterface.
|
/// Creates the NetworkInterface.
|
||||||
|
|
||||||
NetworkInterface(const std::string& name, const std::string& displayName, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, unsigned index = 0);
|
NetworkInterface(const std::string& name, const std::string& displayName, unsigned index);
|
||||||
/// Creates the NetworkInterface.
|
/// Creates the NetworkInterface.
|
||||||
|
|
||||||
NetworkInterface(const std::string& name, const IPAddress& address, unsigned index = 0);
|
NetworkInterface(const std::string& name, const IPAddress& address, unsigned index);
|
||||||
/// Creates the NetworkInterface.
|
/// Creates the NetworkInterface.
|
||||||
|
|
||||||
NetworkInterface(const std::string& name, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, unsigned index = 0);
|
NetworkInterface(const std::string& name, const std::string& displayName, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, unsigned index);
|
||||||
|
/// Creates the NetworkInterface.
|
||||||
|
|
||||||
|
NetworkInterface(const std::string& name, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, unsigned index);
|
||||||
/// Creates the NetworkInterface.
|
/// Creates the NetworkInterface.
|
||||||
|
|
||||||
IPAddress interfaceNameToAddress(const std::string& interfaceName) const;
|
IPAddress interfaceNameToAddress(const std::string& interfaceName) const;
|
||||||
|
|
|
@ -99,7 +99,7 @@ void MulticastSocket::setInterface(const NetworkInterface& interfc)
|
||||||
{
|
{
|
||||||
if (!interfc.supportsIPv6())
|
if (!interfc.supportsIPv6())
|
||||||
{
|
{
|
||||||
impl()->setOption(IPPROTO_IP, IP_MULTICAST_IF, interfc.address());
|
impl()->setOption(IPPROTO_IP, IP_MULTICAST_IF, interfc.findFirstAddress(IPAddress::IPv4));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -217,7 +217,7 @@ void MulticastSocket::joinGroup(const IPAddress& groupAddress, const NetworkInte
|
||||||
{
|
{
|
||||||
struct ip_mreq mr;
|
struct ip_mreq mr;
|
||||||
std::memcpy(&mr.imr_multiaddr, groupAddress.addr(), groupAddress.length());
|
std::memcpy(&mr.imr_multiaddr, groupAddress.addr(), groupAddress.length());
|
||||||
std::memcpy(&mr.imr_interface, interfc.address().addr(), interfc.address().length());
|
std::memcpy(&mr.imr_interface, interfc.findFirstAddress(IPAddress::IPv4).addr(), interfc.findFirstAddress(IPAddress::IPv4).length());
|
||||||
impl()->setRawOption(IPPROTO_IP, IP_ADD_MEMBERSHIP, &mr, sizeof(mr));
|
impl()->setRawOption(IPPROTO_IP, IP_ADD_MEMBERSHIP, &mr, sizeof(mr));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -245,7 +245,7 @@ void MulticastSocket::leaveGroup(const IPAddress& groupAddress, const NetworkInt
|
||||||
{
|
{
|
||||||
struct ip_mreq mr;
|
struct ip_mreq mr;
|
||||||
std::memcpy(&mr.imr_multiaddr, groupAddress.addr(), groupAddress.length());
|
std::memcpy(&mr.imr_multiaddr, groupAddress.addr(), groupAddress.length());
|
||||||
std::memcpy(&mr.imr_interface, interfc.address().addr(), interfc.address().length());
|
std::memcpy(&mr.imr_interface, interfc.findFirstAddress(IPAddress::IPv4).addr(), interfc.findFirstAddress(IPAddress::IPv4).length());
|
||||||
impl()->setRawOption(IPPROTO_IP, IP_DROP_MEMBERSHIP, &mr, sizeof(mr));
|
impl()->setRawOption(IPPROTO_IP, IP_DROP_MEMBERSHIP, &mr, sizeof(mr));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -70,20 +70,22 @@ public:
|
||||||
typedef NetworkInterface::AddressTuple AddressTuple;
|
typedef NetworkInterface::AddressTuple AddressTuple;
|
||||||
typedef NetworkInterface::AddressList AddressList;
|
typedef NetworkInterface::AddressList AddressList;
|
||||||
|
|
||||||
NetworkInterfaceImpl(unsigned index = 0);
|
NetworkInterfaceImpl(unsigned index);
|
||||||
NetworkInterfaceImpl(const std::string& name, const std::string& displayName, const IPAddress& address, unsigned index = 0);
|
NetworkInterfaceImpl(const std::string& name, const std::string& displayName, const IPAddress& address, unsigned index);
|
||||||
NetworkInterfaceImpl(const std::string& name, const std::string& displayName, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, unsigned index = 0);
|
NetworkInterfaceImpl(const std::string& name, const std::string& displayName, unsigned index = 0);
|
||||||
|
NetworkInterfaceImpl(const std::string& name, const std::string& displayName, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, unsigned index);
|
||||||
|
|
||||||
unsigned index() const;
|
unsigned index() const;
|
||||||
const std::string& name() const;
|
const std::string& name() const;
|
||||||
const std::string& displayName() const;
|
const std::string& displayName() const;
|
||||||
|
const IPAddress& findFirstAddress(IPAddress::Family family) const;
|
||||||
void addAddress(const AddressTuple& address);
|
void addAddress(const AddressTuple& address);
|
||||||
const IPAddress& address(unsigned index = 0) const;
|
const IPAddress& address(unsigned index) const;
|
||||||
const NetworkInterface::AddressList& addressList() const;
|
const NetworkInterface::AddressList& addressList() const;
|
||||||
bool hasAddress(const IPAddress& address) const;
|
bool hasAddress(const IPAddress& address) const;
|
||||||
const IPAddress& subnetMask(unsigned index = 0) const;
|
const IPAddress& subnetMask(unsigned index) const;
|
||||||
const IPAddress& broadcastAddress(unsigned index = 0) const;
|
const IPAddress& broadcastAddress(unsigned index) const;
|
||||||
const IPAddress& destAddress(unsigned index = 0) const;
|
const IPAddress& destAddress(unsigned index) const;
|
||||||
const NetworkInterface::MacAddress& macAddress() const;
|
const NetworkInterface::MacAddress& macAddress() const;
|
||||||
bool supportsIPv4() const;
|
bool supportsIPv4() const;
|
||||||
bool supportsIPv6() const;
|
bool supportsIPv6() const;
|
||||||
|
@ -137,7 +139,7 @@ private:
|
||||||
|
|
||||||
NetworkInterface::MacAddress _macAddress;
|
NetworkInterface::MacAddress _macAddress;
|
||||||
|
|
||||||
friend NetworkInterface::Map NetworkInterface::map();
|
friend NetworkInterface::Map NetworkInterface::map(bool, bool);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -166,6 +168,23 @@ NetworkInterfaceImpl::NetworkInterfaceImpl(const std::string& name, const std::s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NetworkInterfaceImpl::NetworkInterfaceImpl(const std::string& name, const std::string& displayName, unsigned index):
|
||||||
|
_name(name),
|
||||||
|
_displayName(displayName),
|
||||||
|
_index(index),
|
||||||
|
_broadcast(false),
|
||||||
|
_loopback(false),
|
||||||
|
_multicast(false),
|
||||||
|
_pointToPoint(false),
|
||||||
|
_up(false),
|
||||||
|
_running(false),
|
||||||
|
_mtu(0)
|
||||||
|
{
|
||||||
|
getPhyParams();
|
||||||
|
if (_pointToPoint) getPeerAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NetworkInterfaceImpl::NetworkInterfaceImpl(const std::string& name, const std::string& displayName, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, unsigned index):
|
NetworkInterfaceImpl::NetworkInterfaceImpl(const std::string& name, const std::string& displayName, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, unsigned index):
|
||||||
_name(name),
|
_name(name),
|
||||||
_displayName(displayName),
|
_displayName(displayName),
|
||||||
|
@ -275,6 +294,23 @@ inline const std::string& NetworkInterfaceImpl::displayName() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const IPAddress& NetworkInterfaceImpl::findFirstAddress(IPAddress::Family family) const
|
||||||
|
{
|
||||||
|
if (!supportsIPv4() && !supportsIPv6())
|
||||||
|
throw NotImplementedException("Unknown or unsupported family.");
|
||||||
|
|
||||||
|
AddressList::const_iterator it = _addressList.begin();
|
||||||
|
AddressList::const_iterator end = _addressList.end();
|
||||||
|
for (;it != end; ++it)
|
||||||
|
{
|
||||||
|
const IPAddress& addr = it->get<NetworkInterface::IP_ADDRESS>();
|
||||||
|
if (addr.family() == family) return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw NotFoundException(format("%s family address not found.", family == IPAddress::IPv4 ? "IPv4" : "IPv6"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void NetworkInterfaceImpl::addAddress(const AddressTuple& address)
|
inline void NetworkInterfaceImpl::addAddress(const AddressTuple& address)
|
||||||
{
|
{
|
||||||
_addressList.push_back(address);
|
_addressList.push_back(address);
|
||||||
|
@ -514,8 +550,8 @@ NetworkInterface::NetworkInterface(const std::string& name, const std::string& d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NetworkInterface::NetworkInterface(const std::string& name, const std::string& displayName, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, unsigned index):
|
NetworkInterface::NetworkInterface(const std::string& name, const std::string& displayName, unsigned index):
|
||||||
_pImpl(new NetworkInterfaceImpl(name, displayName, address, subnetMask, broadcastAddress, index))
|
_pImpl(new NetworkInterfaceImpl(name, displayName, index))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,6 +562,12 @@ NetworkInterface::NetworkInterface(const std::string& name, const IPAddress& add
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NetworkInterface::NetworkInterface(const std::string& name, const std::string& displayName, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, unsigned index):
|
||||||
|
_pImpl(new NetworkInterfaceImpl(name, displayName, address, subnetMask, broadcastAddress, index))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NetworkInterface::NetworkInterface(const std::string& name, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, unsigned index):
|
NetworkInterface::NetworkInterface(const std::string& name, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, unsigned index):
|
||||||
_pImpl(new NetworkInterfaceImpl(name, name, address, subnetMask, broadcastAddress, index))
|
_pImpl(new NetworkInterfaceImpl(name, name, address, subnetMask, broadcastAddress, index))
|
||||||
{
|
{
|
||||||
|
@ -571,6 +613,12 @@ const std::string& NetworkInterface::displayName() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const IPAddress& NetworkInterface::findFirstAddress(IPAddress::Family family) const
|
||||||
|
{
|
||||||
|
return _pImpl->findFirstAddress(family);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void NetworkInterface::addAddress(const IPAddress& address)
|
void NetworkInterface::addAddress(const IPAddress& address)
|
||||||
{
|
{
|
||||||
_pImpl->addAddress(AddressTuple(address, IPAddress(), IPAddress()));
|
_pImpl->addAddress(AddressTuple(address, IPAddress(), IPAddress()));
|
||||||
|
@ -741,48 +789,55 @@ NetworkInterface NetworkInterface::forAddress(const IPAddress& addr)
|
||||||
|
|
||||||
NetworkInterface NetworkInterface::forIndex(unsigned i)
|
NetworkInterface NetworkInterface::forIndex(unsigned i)
|
||||||
{
|
{
|
||||||
if (i != 0)
|
if (i != NetworkInterface::NO_INDEX)
|
||||||
{
|
{
|
||||||
Map map = NetworkInterface::map();
|
Map map = NetworkInterface::map();
|
||||||
|
|
||||||
Map::const_iterator it = map.find(i);
|
Map::const_iterator it = map.find(i);
|
||||||
if (it != map.end())
|
if (it != map.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
|
else
|
||||||
|
throw InterfaceNotFoundException("#" + NumberFormatter::format(i));
|
||||||
}
|
}
|
||||||
throw InterfaceNotFoundException("#" + NumberFormatter::format(i));
|
throw InterfaceNotFoundException("#" + NumberFormatter::format(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (POCO_OS == POCO_OS_LINUX)
|
|
||||||
|
|
||||||
#include <net/if_arp.h>
|
NetworkInterface::List NetworkInterface::list(bool ipOnly, bool upOnly)
|
||||||
|
|
||||||
static unsigned arphrdToIfType(unsigned arphrd)
|
|
||||||
{
|
{
|
||||||
switch (arphrd) {
|
List list;
|
||||||
case ARPHRD_ETHER:
|
Map m = map(ipOnly, upOnly);
|
||||||
return 6; // IF_TYPE_ETHERNET_CSMACD
|
NetworkInterface::Map::const_iterator it = m.begin();
|
||||||
case ARPHRD_IEEE802:
|
NetworkInterface::Map::const_iterator end = m.end();
|
||||||
return 9; // IF_TYPE_ISO88025_TOKENRING
|
for (; it != end; ++it)
|
||||||
case ARPHRD_DLCI:
|
{
|
||||||
return 32; // IF_TYPE_FRAMERELAY
|
int index = it->second.index();
|
||||||
case ARPHRD_PPP:
|
std::string name = it->second.name();
|
||||||
return 512; // IF_TYPE_PPP
|
std::string displayName = it->second.displayName();
|
||||||
case ARPHRD_LOOPBACK:
|
|
||||||
return 24; // IF_TYPE_SOFTWARE_LOOPBACK
|
typedef NetworkInterface::AddressList List;
|
||||||
case ARPHRD_ATM:
|
const List& ipList = it->second.addressList();
|
||||||
return 37; // IF_TYPE_ATM
|
List::const_iterator ipIt = ipList.begin();
|
||||||
case ARPHRD_IEEE80211:
|
List::const_iterator ipEnd = ipList.end();
|
||||||
return 71; // IF_TYPE_IEEE80211
|
for (int counter = 0; ipIt != ipEnd; ++ipIt, ++counter)
|
||||||
case ARPHRD_TUNNEL:
|
{
|
||||||
case ARPHRD_TUNNEL6:
|
IPAddress addr = ipIt->get<NetworkInterface::IP_ADDRESS>();
|
||||||
return 131; // IF_TYPE_TUNNEL
|
IPAddress mask = ipIt->get<NetworkInterface::SUBNET_MASK>();
|
||||||
case ARPHRD_IEEE1394:
|
NetworkInterface ni;
|
||||||
return 144; // IF_TYPE_IEEE1394
|
if (mask.isWildcard())
|
||||||
default:
|
ni = NetworkInterface(name, displayName, addr, index);
|
||||||
return 1; // IF_TYPE_OTHER
|
else
|
||||||
|
{
|
||||||
|
IPAddress broadcast = ipIt->get<NetworkInterface::BROADCAST_ADDRESS>();
|
||||||
|
ni = NetworkInterface(name, displayName, addr, mask, broadcast, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
list.push_back(ni);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Net
|
} } // namespace Poco::Net
|
||||||
|
@ -860,7 +915,7 @@ std::string getErrorMessage(DWORD errorCode)
|
||||||
} /// namespace
|
} /// namespace
|
||||||
|
|
||||||
|
|
||||||
NetworkInterface::Map NetworkInterface::map()
|
NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
|
||||||
{
|
{
|
||||||
FastMutex::ScopedLock lock(_mutex);
|
FastMutex::ScopedLock lock(_mutex);
|
||||||
Map result;
|
Map result;
|
||||||
|
@ -897,67 +952,72 @@ NetworkInterface::Map NetworkInterface::map()
|
||||||
IPAddress subnetMask;
|
IPAddress subnetMask;
|
||||||
IPAddress broadcastAddress;
|
IPAddress broadcastAddress;
|
||||||
unsigned ifIndex = 0;
|
unsigned ifIndex = 0;
|
||||||
|
|
||||||
//
|
|
||||||
// Create interface even if it has an empty list of addresses; also, set
|
|
||||||
// physical attributes which are protocol independent (name, media type,
|
|
||||||
// MAC address, MTU, operational status, etc).
|
|
||||||
//
|
|
||||||
Map::iterator ifIt = result.insert(Map::value_type(ifInex, NetworkInterface(name, displayName, ifIndex);
|
|
||||||
|
|
||||||
ifIt->second.impl().setFlags(pAddress->Flags, pAddress->IfType);
|
|
||||||
ifIt->second.impl().setMtu(pAddress->Mtu);
|
|
||||||
ifIt->second.impl().setUp(pAddress->OperStatus == IfOperStatusUp);
|
|
||||||
|
|
||||||
ifIt->second.impl().setMacAddress(pAddress->PhysicalAddress, pAddress->PhysicalAddressLength);
|
|
||||||
ifIt->second.impl().setHWType(pAddress->IfType);
|
|
||||||
|
|
||||||
#if defined(POCO_HAVE_IPv6)
|
#if defined(POCO_HAVE_IPv6)
|
||||||
poco_assert (pAddress->Ipv6IfIndex == pAddress->IfIndex);
|
|
||||||
if (pAddress->Flags & IP_ADAPTER_IPV6_ENABLED) ifIndex = pAddress->Ipv6IfIndex;
|
if (pAddress->Flags & IP_ADAPTER_IPV6_ENABLED) ifIndex = pAddress->Ipv6IfIndex;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (pAddress->Flags & IP_ADAPTER_IPV4_ENABLED) ifIndex = pAddress->IfIndex;
|
if (pAddress->Flags & IP_ADAPTER_IPV4_ENABLED) ifIndex = pAddress->IfIndex;
|
||||||
|
|
||||||
for (PIP_ADAPTER_UNICAST_ADDRESS pUniAddr = pAddress->FirstUnicastAddress;
|
std::string name(pAddress->AdapterName);
|
||||||
pUniAddr;
|
std::string displayName;
|
||||||
pUniAddr = pUniAddr->Next)
|
|
||||||
{
|
|
||||||
std::string name(pAddress->AdapterName);
|
|
||||||
std::string displayName;
|
|
||||||
#ifdef POCO_WIN32_UTF8
|
#ifdef POCO_WIN32_UTF8
|
||||||
Poco::UnicodeConverter::toUTF8(pAddress->FriendlyName, displayName);
|
Poco::UnicodeConverter::toUTF8(pAddress->FriendlyName, displayName);
|
||||||
#else
|
#else
|
||||||
char displayNameBuffer[1024];
|
char displayNameBuffer[1024];
|
||||||
int rc = WideCharToMultiByte(CP_ACP, WC_DEFAULTCHAR, pAddress->FriendlyName, -1, displayNameBuffer, sizeof(displayNameBuffer), NULL, NULL);
|
int rc = WideCharToMultiByte(CP_ACP, WC_DEFAULTCHAR, pAddress->FriendlyName, -1, displayNameBuffer, sizeof(displayNameBuffer), NULL, NULL);
|
||||||
if (rc) displayName = displayNameBuffer;
|
if (rc) displayName = displayNameBuffer;
|
||||||
#endif
|
#endif
|
||||||
UINT8 prefixLength = pUniAddr->OnLinkPrefixLength;
|
|
||||||
address = IPAddress(pUniAddr->Address);
|
bool isUp = (pAddress->OperStatus == IfOperStatusUp);
|
||||||
ADDRESS_FAMILY family = pUniAddr->Address.lpSockaddr->sa_family;
|
bool isIP = (0 != pAddress->FirstUnicastAddress);
|
||||||
switch (family)
|
if (((ipOnly && isIP) || !ipOnly) && ((upOnly && isUp) || !upOnly))
|
||||||
|
{
|
||||||
|
NetworkInterface ni(name, displayName, ifIndex);
|
||||||
|
// Create interface even if it has an empty list of addresses; also, set
|
||||||
|
// physical attributes which are protocol independent (name, media type,
|
||||||
|
// MAC address, MTU, operational status, etc).
|
||||||
|
Map::iterator ifIt = result.find(ifIndex);
|
||||||
|
if (ifIt == result.end())
|
||||||
|
ifIt = result.insert(Map::value_type(ifIndex, ni)).first;
|
||||||
|
|
||||||
|
ifIt->second.impl().setFlags(pAddress->Flags, pAddress->IfType);
|
||||||
|
ifIt->second.impl().setMtu(pAddress->Mtu);
|
||||||
|
ifIt->second.impl().setUp(pAddress->OperStatus == IfOperStatusUp);
|
||||||
|
ifIt->second.impl().setHWType(pAddress->IfType);
|
||||||
|
if (pAddress->PhysicalAddressLength)
|
||||||
|
ifIt->second.impl().setMacAddress(pAddress->PhysicalAddress, pAddress->PhysicalAddressLength);
|
||||||
|
|
||||||
|
for (PIP_ADAPTER_UNICAST_ADDRESS pUniAddr = pAddress->FirstUnicastAddress;
|
||||||
|
pUniAddr;
|
||||||
|
pUniAddr = pUniAddr->Next)
|
||||||
{
|
{
|
||||||
case AF_INET:
|
UINT8 prefixLength = pUniAddr->OnLinkPrefixLength;
|
||||||
|
address = IPAddress(pUniAddr->Address);
|
||||||
|
ADDRESS_FAMILY family = pUniAddr->Address.lpSockaddr->sa_family;
|
||||||
|
switch (family)
|
||||||
{
|
{
|
||||||
// Windows lists broadcast address on localhost
|
case AF_INET:
|
||||||
bool hasBroadcast = (pAddress->IfType == IF_TYPE_ETHERNET_CSMACD) || (pAddress->IfType == IF_TYPE_SOFTWARE_LOOPBACK);
|
{
|
||||||
// On Windows, a valid broadcast address will be all 1's (== address | ~subnetMask); we go an extra mile here in order to
|
// Windows lists broadcast address on localhost
|
||||||
// make sure we reflect the actual value held by system and protect against misconfiguration (e.g. bad DHCP config entry)
|
bool hasBroadcast = (pAddress->IfType == IF_TYPE_ETHERNET_CSMACD) || (pAddress->IfType == IF_TYPE_SOFTWARE_LOOPBACK);
|
||||||
broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address);
|
// On Windows, a valid broadcast address will be all 1's (== address | ~subnetMask); we go an extra mile here in order to
|
||||||
subnetMask = prefixLength ? IPAddress(prefixLength, IPAddress::IPv4) : IPAddress();
|
// make sure we reflect the actual value held by system and protect against misconfiguration (e.g. bad DHCP config entry)
|
||||||
if (hasBroadcast)
|
broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address);
|
||||||
ifIt->second.addAddress(address, subnetMask, broadcastAddress);
|
subnetMask = prefixLength ? IPAddress(prefixLength, IPAddress::IPv4) : IPAddress();
|
||||||
else
|
if (hasBroadcast)
|
||||||
|
ifIt->second.addAddress(address, subnetMask, broadcastAddress);
|
||||||
|
else
|
||||||
|
ifIt->second.addAddress(address);
|
||||||
|
} break;
|
||||||
|
#if defined(POCO_HAVE_IPv6)
|
||||||
|
case AF_INET6:
|
||||||
ifIt->second.addAddress(address);
|
ifIt->second.addAddress(address);
|
||||||
} break;
|
break;
|
||||||
#if defined(POCO_HAVE_IPv6)
|
#endif
|
||||||
case AF_INET6:
|
} // switch family
|
||||||
{
|
} // for addresses
|
||||||
ifIt->second.addAddress(address);
|
} // if ipOnly/upOnly
|
||||||
} break;
|
|
||||||
#endif
|
|
||||||
} // switch family
|
|
||||||
} // for addresses
|
|
||||||
} // for adapters
|
} // for adapters
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1035,7 +1095,7 @@ namespace Poco {
|
||||||
namespace Net {
|
namespace Net {
|
||||||
|
|
||||||
|
|
||||||
NetworkInterface::Map NetworkInterface::map()
|
NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
|
||||||
{
|
{
|
||||||
FastMutex::ScopedLock lock(_mutex);
|
FastMutex::ScopedLock lock(_mutex);
|
||||||
Map result;
|
Map result;
|
||||||
|
@ -1134,13 +1194,46 @@ NetworkInterface::Map NetworkInterface::map()
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
#include <linux/if.h>
|
#include <linux/if.h>
|
||||||
#include <linux/if_packet.h>
|
#include <linux/if_packet.h>
|
||||||
|
#include <net/if_arp.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
namespace Net {
|
namespace Net {
|
||||||
|
|
||||||
|
|
||||||
NetworkInterface::Map NetworkInterface::map()
|
namespace {
|
||||||
|
|
||||||
|
static unsigned arphrdToIfType(unsigned arphrd)
|
||||||
|
{
|
||||||
|
switch (arphrd) {
|
||||||
|
case ARPHRD_ETHER:
|
||||||
|
return 6; // IF_TYPE_ETHERNET_CSMACD
|
||||||
|
case ARPHRD_IEEE802:
|
||||||
|
return 9; // IF_TYPE_ISO88025_TOKENRING
|
||||||
|
case ARPHRD_DLCI:
|
||||||
|
return 32; // IF_TYPE_FRAMERELAY
|
||||||
|
case ARPHRD_PPP:
|
||||||
|
return 512; // IF_TYPE_PPP
|
||||||
|
case ARPHRD_LOOPBACK:
|
||||||
|
return 24; // IF_TYPE_SOFTWARE_LOOPBACK
|
||||||
|
case ARPHRD_ATM:
|
||||||
|
return 37; // IF_TYPE_ATM
|
||||||
|
case ARPHRD_IEEE80211:
|
||||||
|
return 71; // IF_TYPE_IEEE80211
|
||||||
|
case ARPHRD_TUNNEL:
|
||||||
|
case ARPHRD_TUNNEL6:
|
||||||
|
return 131; // IF_TYPE_TUNNEL
|
||||||
|
case ARPHRD_IEEE1394:
|
||||||
|
return 144; // IF_TYPE_IEEE1394
|
||||||
|
default:
|
||||||
|
return 1; // IF_TYPE_OTHER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
|
||||||
{
|
{
|
||||||
FastMutex::ScopedLock lock(_mutex);
|
FastMutex::ScopedLock lock(_mutex);
|
||||||
Map result;
|
Map result;
|
||||||
|
|
|
@ -107,11 +107,16 @@ const NetworkInterface& MulticastEchoServer::interfc() const
|
||||||
|
|
||||||
Poco::Net::NetworkInterface MulticastEchoServer::findInterface()
|
Poco::Net::NetworkInterface MulticastEchoServer::findInterface()
|
||||||
{
|
{
|
||||||
NetworkInterface::Map map = NetworkInterface::map();
|
NetworkInterface::Map m = NetworkInterface::map();
|
||||||
for (NetworkInterface::Map::const_iterator it = map.begin(); it != map.end(); ++it)
|
for (NetworkInterface::Map::const_iterator it = m.begin(); it != m.end(); ++it)
|
||||||
{
|
{
|
||||||
if (it->second.supportsIPv4() && it->second.address().isUnicast() && !it->second.isLoopback() && it->second.isPointToPoint())
|
if (it->second.supportsIPv4() &&
|
||||||
|
it->second.findFirstAddress(IPAddress::IPv4).isUnicast() &&
|
||||||
|
!it->second.isLoopback() &&
|
||||||
|
!it->second.isPointToPoint())
|
||||||
|
{
|
||||||
return it->second;
|
return it->second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return NetworkInterface();
|
return NetworkInterface();
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
|
|
||||||
using Poco::Net::NetworkInterface;
|
using Poco::Net::NetworkInterface;
|
||||||
using Poco::Net::IPAddress;
|
using Poco::Net::IPAddress;
|
||||||
|
using Poco::NotFoundException;
|
||||||
|
|
||||||
|
|
||||||
NetworkInterfaceTest::NetworkInterfaceTest(const std::string& name): CppUnit::TestCase(name)
|
NetworkInterfaceTest::NetworkInterfaceTest(const std::string& name): CppUnit::TestCase(name)
|
||||||
|
@ -55,9 +56,9 @@ NetworkInterfaceTest::~NetworkInterfaceTest()
|
||||||
|
|
||||||
void NetworkInterfaceTest::testMap()
|
void NetworkInterfaceTest::testMap()
|
||||||
{
|
{
|
||||||
NetworkInterface::Map map = NetworkInterface::map();
|
NetworkInterface::Map m = NetworkInterface::map(false, false);
|
||||||
assert (!map.empty());
|
assert (!m.empty());
|
||||||
for (NetworkInterface::Map::const_iterator it = map.begin(); it != map.end(); ++it)
|
for (NetworkInterface::Map::const_iterator it = m.begin(); it != m.end(); ++it)
|
||||||
{
|
{
|
||||||
std::cout << std::endl << "=============" << std::endl;
|
std::cout << std::endl << "=============" << std::endl;
|
||||||
|
|
||||||
|
@ -71,7 +72,7 @@ void NetworkInterfaceTest::testMap()
|
||||||
std::cout << "Mac Address: (" << it->second.hwType() << ")";
|
std::cout << "Mac Address: (" << it->second.hwType() << ")";
|
||||||
for (unsigned i = 0; i < mac.size(); ++i)
|
for (unsigned i = 0; i < mac.size(); ++i)
|
||||||
std::cout << ((i == 0) ? ' ' : ':') << std::hex << std::setw(2) << std::setfill('0') << (unsigned)mac[i];
|
std::cout << ((i == 0) ? ' ' : ':') << std::hex << std::setw(2) << std::setfill('0') << (unsigned)mac[i];
|
||||||
std::cout << std::endl;
|
std::cout << std::dec << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef NetworkInterface::AddressList List;
|
typedef NetworkInterface::AddressList List;
|
||||||
|
@ -95,6 +96,36 @@ void NetworkInterfaceTest::testMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NetworkInterfaceTest::testList()
|
||||||
|
{
|
||||||
|
NetworkInterface::List list = NetworkInterface::list();
|
||||||
|
assert (!list.empty());
|
||||||
|
for (NetworkInterface::NetworkInterfaceList::const_iterator it = list.begin(); it != list.end(); ++it)
|
||||||
|
{
|
||||||
|
std::cout << "==============" << std::endl;
|
||||||
|
|
||||||
|
std::cout << "Index: " << it->index() << std::endl;
|
||||||
|
std::cout << "Name: " << it->name() << std::endl;
|
||||||
|
std::cout << "DisplayName: " << it->displayName() << std::endl;
|
||||||
|
|
||||||
|
typedef NetworkInterface::AddressList List;
|
||||||
|
const List& ipList = it->addressList();
|
||||||
|
List::const_iterator ipIt = ipList.begin();
|
||||||
|
List::const_iterator ipEnd = ipList.end();
|
||||||
|
for (int counter = 0; ipIt != ipEnd; ++ipIt, ++counter)
|
||||||
|
{
|
||||||
|
std::cout << "IP Address: " << ipIt->get<NetworkInterface::IP_ADDRESS>().toString() << std::endl;
|
||||||
|
IPAddress addr = ipIt->get<NetworkInterface::SUBNET_MASK>();
|
||||||
|
if (!addr.isWildcard()) std::cout << "Subnet: " << ipIt->get<NetworkInterface::SUBNET_MASK>().toString() << std::endl;
|
||||||
|
addr = ipIt->get<NetworkInterface::BROADCAST_ADDRESS>();
|
||||||
|
if (!addr.isWildcard()) std::cout << "Broadcast: " << ipIt->get<NetworkInterface::BROADCAST_ADDRESS>().toString() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "==============" << std::endl << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void NetworkInterfaceTest::testForName()
|
void NetworkInterfaceTest::testForName()
|
||||||
{
|
{
|
||||||
NetworkInterface::Map map = NetworkInterface::map();
|
NetworkInterface::Map map = NetworkInterface::map();
|
||||||
|
@ -112,11 +143,22 @@ void NetworkInterfaceTest::testForAddress()
|
||||||
for (NetworkInterface::Map::const_iterator it = map.begin(); it != map.end(); ++it)
|
for (NetworkInterface::Map::const_iterator it = map.begin(); it != map.end(); ++it)
|
||||||
{
|
{
|
||||||
// not all interfaces have IP configured
|
// not all interfaces have IP configured
|
||||||
if (it->second.addressList().empty())
|
if (it->second.addressList().empty()) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
NetworkInterface ifc = NetworkInterface::forAddress(it->second.address());
|
if (it->second.supportsIPv4())
|
||||||
assert (ifc.address() == it->second.address());
|
{
|
||||||
|
NetworkInterface ifc = NetworkInterface::forAddress(it->second.findFirstAddress(IPAddress::IPv4));
|
||||||
|
assert (ifc.findFirstAddress(IPAddress::IPv4) == it->second.findFirstAddress(IPAddress::IPv4));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
it->second.findFirstAddress(IPAddress::IPv4);
|
||||||
|
fail ("must throw");
|
||||||
|
}
|
||||||
|
catch (NotFoundException&) { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +188,7 @@ CppUnit::Test* NetworkInterfaceTest::suite()
|
||||||
{
|
{
|
||||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("NetworkInterfaceTest");
|
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("NetworkInterfaceTest");
|
||||||
|
|
||||||
|
CppUnit_addTest(pSuite, NetworkInterfaceTest, testList);
|
||||||
CppUnit_addTest(pSuite, NetworkInterfaceTest, testMap);
|
CppUnit_addTest(pSuite, NetworkInterfaceTest, testMap);
|
||||||
CppUnit_addTest(pSuite, NetworkInterfaceTest, testForName);
|
CppUnit_addTest(pSuite, NetworkInterfaceTest, testForName);
|
||||||
CppUnit_addTest(pSuite, NetworkInterfaceTest, testForAddress);
|
CppUnit_addTest(pSuite, NetworkInterfaceTest, testForAddress);
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
~NetworkInterfaceTest();
|
~NetworkInterfaceTest();
|
||||||
|
|
||||||
void testMap();
|
void testMap();
|
||||||
|
void testList();
|
||||||
void testForName();
|
void testForName();
|
||||||
void testForAddress();
|
void testForAddress();
|
||||||
void testForIndex();
|
void testForIndex();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче