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
|
||||
};
|
||||
|
||||
NetworkInterface(unsigned index = 0);
|
||||
static const unsigned NO_INDEX = ~0;
|
||||
|
||||
NetworkInterface(unsigned index = NO_INDEX);
|
||||
/// Creates a NetworkInterface representing the
|
||||
/// default interface.
|
||||
///
|
||||
|
@ -129,8 +131,11 @@ public:
|
|||
///
|
||||
/// On other platforms this is the same as name().
|
||||
|
||||
const IPAddress& address(unsigned index = 0) const;
|
||||
/// Returns the IP address bound to the interface.
|
||||
const IPAddress& findFirstAddress(IPAddress::Family family) const;
|
||||
/// 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);
|
||||
/// Adds address to the interface.
|
||||
|
@ -141,13 +146,13 @@ public:
|
|||
const AddressList& addressList() const;
|
||||
/// 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.
|
||||
|
||||
const IPAddress& broadcastAddress(unsigned index = 0) const;
|
||||
const IPAddress& broadcastAddress(unsigned index) const;
|
||||
/// 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.
|
||||
|
||||
const MacAddress& macAddress() const;
|
||||
|
@ -217,26 +222,50 @@ public:
|
|||
/// with the given index does not exist (or IPv6 is not
|
||||
/// available).
|
||||
|
||||
static Map map();
|
||||
/// Returns a map with all network interfaces
|
||||
/// on the system. Map is keyed by interface system
|
||||
/// indices.
|
||||
static List list(bool ipOnly = true, bool upOnly = true);
|
||||
/// Returns a list with all network interfaces
|
||||
/// on the system.
|
||||
///
|
||||
/// 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,
|
||||
/// they are contained within the NetworkInterface (second)
|
||||
/// member of the pair.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
NetworkInterface(const std::string& name, const IPAddress& address, unsigned index = 0);
|
||||
NetworkInterface(const std::string& name, const IPAddress& address, unsigned index);
|
||||
/// 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.
|
||||
|
||||
IPAddress interfaceNameToAddress(const std::string& interfaceName) const;
|
||||
|
|
|
@ -99,7 +99,7 @@ void MulticastSocket::setInterface(const NetworkInterface& interfc)
|
|||
{
|
||||
if (!interfc.supportsIPv6())
|
||||
{
|
||||
impl()->setOption(IPPROTO_IP, IP_MULTICAST_IF, interfc.address());
|
||||
impl()->setOption(IPPROTO_IP, IP_MULTICAST_IF, interfc.findFirstAddress(IPAddress::IPv4));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -217,7 +217,7 @@ void MulticastSocket::joinGroup(const IPAddress& groupAddress, const NetworkInte
|
|||
{
|
||||
struct ip_mreq mr;
|
||||
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));
|
||||
}
|
||||
else
|
||||
|
@ -245,7 +245,7 @@ void MulticastSocket::leaveGroup(const IPAddress& groupAddress, const NetworkInt
|
|||
{
|
||||
struct ip_mreq mr;
|
||||
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));
|
||||
}
|
||||
else
|
||||
|
|
|
@ -70,20 +70,22 @@ public:
|
|||
typedef NetworkInterface::AddressTuple AddressTuple;
|
||||
typedef NetworkInterface::AddressList AddressList;
|
||||
|
||||
NetworkInterfaceImpl(unsigned index = 0);
|
||||
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, const IPAddress& subnetMask, const IPAddress& broadcastAddress, unsigned index = 0);
|
||||
NetworkInterfaceImpl(unsigned index);
|
||||
NetworkInterfaceImpl(const std::string& name, const std::string& displayName, const IPAddress& address, unsigned index);
|
||||
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;
|
||||
const std::string& name() const;
|
||||
const std::string& displayName() const;
|
||||
const IPAddress& findFirstAddress(IPAddress::Family family) const;
|
||||
void addAddress(const AddressTuple& address);
|
||||
const IPAddress& address(unsigned index = 0) const;
|
||||
const IPAddress& address(unsigned index) const;
|
||||
const NetworkInterface::AddressList& addressList() const;
|
||||
bool hasAddress(const IPAddress& address) const;
|
||||
const IPAddress& subnetMask(unsigned index = 0) const;
|
||||
const IPAddress& broadcastAddress(unsigned index = 0) const;
|
||||
const IPAddress& destAddress(unsigned index = 0) const;
|
||||
const IPAddress& subnetMask(unsigned index) const;
|
||||
const IPAddress& broadcastAddress(unsigned index) const;
|
||||
const IPAddress& destAddress(unsigned index) const;
|
||||
const NetworkInterface::MacAddress& macAddress() const;
|
||||
bool supportsIPv4() const;
|
||||
bool supportsIPv6() const;
|
||||
|
@ -137,7 +139,7 @@ private:
|
|||
|
||||
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):
|
||||
_name(name),
|
||||
_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)
|
||||
{
|
||||
_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):
|
||||
_pImpl(new NetworkInterfaceImpl(name, displayName, address, subnetMask, broadcastAddress, index))
|
||||
NetworkInterface::NetworkInterface(const std::string& name, const std::string& displayName, unsigned 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):
|
||||
_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)
|
||||
{
|
||||
_pImpl->addAddress(AddressTuple(address, IPAddress(), IPAddress()));
|
||||
|
@ -741,48 +789,55 @@ NetworkInterface NetworkInterface::forAddress(const IPAddress& addr)
|
|||
|
||||
NetworkInterface NetworkInterface::forIndex(unsigned i)
|
||||
{
|
||||
if (i != 0)
|
||||
if (i != NetworkInterface::NO_INDEX)
|
||||
{
|
||||
Map map = NetworkInterface::map();
|
||||
|
||||
Map::const_iterator it = map.find(i);
|
||||
if (it != map.end())
|
||||
return it->second;
|
||||
else
|
||||
throw InterfaceNotFoundException("#" + NumberFormatter::format(i));
|
||||
}
|
||||
throw InterfaceNotFoundException("#" + NumberFormatter::format(i));
|
||||
}
|
||||
|
||||
#if (POCO_OS == POCO_OS_LINUX)
|
||||
|
||||
#include <net/if_arp.h>
|
||||
|
||||
static unsigned arphrdToIfType(unsigned arphrd)
|
||||
NetworkInterface::List NetworkInterface::list(bool ipOnly, bool upOnly)
|
||||
{
|
||||
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
|
||||
List list;
|
||||
Map m = map(ipOnly, upOnly);
|
||||
NetworkInterface::Map::const_iterator it = m.begin();
|
||||
NetworkInterface::Map::const_iterator end = m.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
int index = it->second.index();
|
||||
std::string name = it->second.name();
|
||||
std::string displayName = it->second.displayName();
|
||||
|
||||
typedef NetworkInterface::AddressList List;
|
||||
const List& ipList = it->second.addressList();
|
||||
List::const_iterator ipIt = ipList.begin();
|
||||
List::const_iterator ipEnd = ipList.end();
|
||||
for (int counter = 0; ipIt != ipEnd; ++ipIt, ++counter)
|
||||
{
|
||||
IPAddress addr = ipIt->get<NetworkInterface::IP_ADDRESS>();
|
||||
IPAddress mask = ipIt->get<NetworkInterface::SUBNET_MASK>();
|
||||
NetworkInterface ni;
|
||||
if (mask.isWildcard())
|
||||
ni = NetworkInterface(name, displayName, addr, index);
|
||||
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
|
||||
|
@ -860,7 +915,7 @@ std::string getErrorMessage(DWORD errorCode)
|
|||
} /// namespace
|
||||
|
||||
|
||||
NetworkInterface::Map NetworkInterface::map()
|
||||
NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
Map result;
|
||||
|
@ -897,67 +952,72 @@ NetworkInterface::Map NetworkInterface::map()
|
|||
IPAddress subnetMask;
|
||||
IPAddress broadcastAddress;
|
||||
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)
|
||||
poco_assert (pAddress->Ipv6IfIndex == pAddress->IfIndex);
|
||||
if (pAddress->Flags & IP_ADAPTER_IPV6_ENABLED) ifIndex = pAddress->Ipv6IfIndex;
|
||||
else
|
||||
#endif
|
||||
if (pAddress->Flags & IP_ADAPTER_IPV4_ENABLED) ifIndex = pAddress->IfIndex;
|
||||
|
||||
for (PIP_ADAPTER_UNICAST_ADDRESS pUniAddr = pAddress->FirstUnicastAddress;
|
||||
pUniAddr;
|
||||
pUniAddr = pUniAddr->Next)
|
||||
{
|
||||
std::string name(pAddress->AdapterName);
|
||||
std::string displayName;
|
||||
std::string name(pAddress->AdapterName);
|
||||
std::string displayName;
|
||||
#ifdef POCO_WIN32_UTF8
|
||||
Poco::UnicodeConverter::toUTF8(pAddress->FriendlyName, displayName);
|
||||
Poco::UnicodeConverter::toUTF8(pAddress->FriendlyName, displayName);
|
||||
#else
|
||||
char displayNameBuffer[1024];
|
||||
int rc = WideCharToMultiByte(CP_ACP, WC_DEFAULTCHAR, pAddress->FriendlyName, -1, displayNameBuffer, sizeof(displayNameBuffer), NULL, NULL);
|
||||
if (rc) displayName = displayNameBuffer;
|
||||
char displayNameBuffer[1024];
|
||||
int rc = WideCharToMultiByte(CP_ACP, WC_DEFAULTCHAR, pAddress->FriendlyName, -1, displayNameBuffer, sizeof(displayNameBuffer), NULL, NULL);
|
||||
if (rc) displayName = displayNameBuffer;
|
||||
#endif
|
||||
UINT8 prefixLength = pUniAddr->OnLinkPrefixLength;
|
||||
address = IPAddress(pUniAddr->Address);
|
||||
ADDRESS_FAMILY family = pUniAddr->Address.lpSockaddr->sa_family;
|
||||
switch (family)
|
||||
|
||||
bool isUp = (pAddress->OperStatus == IfOperStatusUp);
|
||||
bool isIP = (0 != pAddress->FirstUnicastAddress);
|
||||
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
|
||||
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
|
||||
// make sure we reflect the actual value held by system and protect against misconfiguration (e.g. bad DHCP config entry)
|
||||
broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address);
|
||||
subnetMask = prefixLength ? IPAddress(prefixLength, IPAddress::IPv4) : IPAddress();
|
||||
if (hasBroadcast)
|
||||
ifIt->second.addAddress(address, subnetMask, broadcastAddress);
|
||||
else
|
||||
case AF_INET:
|
||||
{
|
||||
// Windows lists broadcast address on localhost
|
||||
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
|
||||
// make sure we reflect the actual value held by system and protect against misconfiguration (e.g. bad DHCP config entry)
|
||||
broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address);
|
||||
subnetMask = prefixLength ? IPAddress(prefixLength, IPAddress::IPv4) : IPAddress();
|
||||
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);
|
||||
} break;
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
case AF_INET6:
|
||||
{
|
||||
ifIt->second.addAddress(address);
|
||||
} break;
|
||||
#endif
|
||||
} // switch family
|
||||
} // for addresses
|
||||
break;
|
||||
#endif
|
||||
} // switch family
|
||||
} // for addresses
|
||||
} // if ipOnly/upOnly
|
||||
} // for adapters
|
||||
return result;
|
||||
}
|
||||
|
@ -1035,7 +1095,7 @@ namespace Poco {
|
|||
namespace Net {
|
||||
|
||||
|
||||
NetworkInterface::Map NetworkInterface::map()
|
||||
NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
Map result;
|
||||
|
@ -1134,13 +1194,46 @@ NetworkInterface::Map NetworkInterface::map()
|
|||
#include <ifaddrs.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <net/if_arp.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
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);
|
||||
Map result;
|
||||
|
|
|
@ -107,11 +107,16 @@ const NetworkInterface& MulticastEchoServer::interfc() const
|
|||
|
||||
Poco::Net::NetworkInterface MulticastEchoServer::findInterface()
|
||||
{
|
||||
NetworkInterface::Map map = NetworkInterface::map();
|
||||
for (NetworkInterface::Map::const_iterator it = map.begin(); it != map.end(); ++it)
|
||||
NetworkInterface::Map m = NetworkInterface::map();
|
||||
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 NetworkInterface();
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
using Poco::Net::NetworkInterface;
|
||||
using Poco::Net::IPAddress;
|
||||
using Poco::NotFoundException;
|
||||
|
||||
|
||||
NetworkInterfaceTest::NetworkInterfaceTest(const std::string& name): CppUnit::TestCase(name)
|
||||
|
@ -55,9 +56,9 @@ NetworkInterfaceTest::~NetworkInterfaceTest()
|
|||
|
||||
void NetworkInterfaceTest::testMap()
|
||||
{
|
||||
NetworkInterface::Map map = NetworkInterface::map();
|
||||
assert (!map.empty());
|
||||
for (NetworkInterface::Map::const_iterator it = map.begin(); it != map.end(); ++it)
|
||||
NetworkInterface::Map m = NetworkInterface::map(false, false);
|
||||
assert (!m.empty());
|
||||
for (NetworkInterface::Map::const_iterator it = m.begin(); it != m.end(); ++it)
|
||||
{
|
||||
std::cout << std::endl << "=============" << std::endl;
|
||||
|
||||
|
@ -71,7 +72,7 @@ void NetworkInterfaceTest::testMap()
|
|||
std::cout << "Mac Address: (" << it->second.hwType() << ")";
|
||||
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 << std::endl;
|
||||
std::cout << std::dec << std::endl;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
NetworkInterface::Map map = NetworkInterface::map();
|
||||
|
@ -112,11 +143,22 @@ void NetworkInterfaceTest::testForAddress()
|
|||
for (NetworkInterface::Map::const_iterator it = map.begin(); it != map.end(); ++it)
|
||||
{
|
||||
// not all interfaces have IP configured
|
||||
if (it->second.addressList().empty())
|
||||
continue;
|
||||
if (it->second.addressList().empty()) continue;
|
||||
|
||||
NetworkInterface ifc = NetworkInterface::forAddress(it->second.address());
|
||||
assert (ifc.address() == it->second.address());
|
||||
if (it->second.supportsIPv4())
|
||||
{
|
||||
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_addTest(pSuite, NetworkInterfaceTest, testList);
|
||||
CppUnit_addTest(pSuite, NetworkInterfaceTest, testMap);
|
||||
CppUnit_addTest(pSuite, NetworkInterfaceTest, testForName);
|
||||
CppUnit_addTest(pSuite, NetworkInterfaceTest, testForAddress);
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
~NetworkInterfaceTest();
|
||||
|
||||
void testMap();
|
||||
void testList();
|
||||
void testForName();
|
||||
void testForAddress();
|
||||
void testForIndex();
|
||||
|
|
Загрузка…
Ссылка в новой задаче