NetworkInterface fixes/improvement

This commit is contained in:
Aleksandar Fabijanic 2012-08-14 00:34:38 +00:00
Родитель e8931a928c
Коммит 676675edc7
5 изменённых файлов: 155 добавлений и 127 удалений

Просмотреть файл

@ -73,7 +73,7 @@ public:
typedef std::vector<AddressTuple> AddressList; typedef std::vector<AddressTuple> AddressList;
typedef AddressList::iterator AddressIterator; typedef AddressList::iterator AddressIterator;
typedef AddressList::const_iterator ConstAddressIterator; typedef AddressList::const_iterator ConstAddressIterator;
typedef std::vector<unsigned char> MacAddress; typedef std::vector<unsigned char> MACAddress;
enum AddressType enum AddressType
{ {
@ -82,6 +82,20 @@ public:
BROADCAST_ADDRESS BROADCAST_ADDRESS
}; };
enum Type
{
NI_TYPE_ETHERNET_CSMACD,
NI_TYPE_ISO88025_TOKENRING,
NI_TYPE_FRAMERELAY,
NI_TYPE_PPP,
NI_TYPE_SOFTWARE_LOOPBACK,
NI_TYPE_ATM,
NI_TYPE_IEEE80211,
NI_TYPE_TUNNEL,
NI_TYPE_IEEE1394,
NI_TYPE_OTHER
};
enum IPVersion enum IPVersion
{ {
IPv4_ONLY, /// Return interfaces with IPv4 address only IPv4_ONLY, /// Return interfaces with IPv4 address only
@ -131,7 +145,7 @@ public:
/// ///
/// On other platforms this is the same as name(). /// On other platforms this is the same as name().
const IPAddress& findFirstAddress(IPAddress::Family family) const; const IPAddress& firstAddress(IPAddress::Family family) const;
/// Returns the first IP address bound to the interface. /// Returns the first IP address bound to the interface.
const IPAddress& address(unsigned index) const; const IPAddress& address(unsigned index) const;
@ -155,12 +169,13 @@ public:
const IPAddress& destAddress(unsigned index) 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;
/// Returns MAC (Media Access Control) address for the interface.
unsigned mtu() const; unsigned mtu() const;
/// Returns the MTU for this interface. /// Returns the MTU for this interface.
unsigned hwType() const; NetworkInterface::Type type() const;
/// returns the MIB IfType of the interface. /// returns the MIB IfType of the interface.
bool supportsIP() const; bool supportsIP() 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.findFirstAddress(IPAddress::IPv4)); impl()->setOption(IPPROTO_IP, IP_MULTICAST_IF, interfc.firstAddress(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.findFirstAddress(IPAddress::IPv4).addr(), interfc.findFirstAddress(IPAddress::IPv4).length()); std::memcpy(&mr.imr_interface, interfc.firstAddress(IPAddress::IPv4).addr(), interfc.firstAddress(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.findFirstAddress(IPAddress::IPv4).addr(), interfc.findFirstAddress(IPAddress::IPv4).length()); std::memcpy(&mr.imr_interface, interfc.firstAddress(IPAddress::IPv4).addr(), interfc.firstAddress(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

Просмотреть файл

@ -69,6 +69,7 @@ class NetworkInterfaceImpl: public Poco::RefCountedObject
public: public:
typedef NetworkInterface::AddressTuple AddressTuple; typedef NetworkInterface::AddressTuple AddressTuple;
typedef NetworkInterface::AddressList AddressList; typedef NetworkInterface::AddressList AddressList;
typedef NetworkInterface::Type Type;
NetworkInterfaceImpl(unsigned index); 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, const IPAddress& address, unsigned index);
@ -78,7 +79,7 @@ public:
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; const IPAddress& firstAddress(IPAddress::Family family) const;
void addAddress(const AddressTuple& address); void addAddress(const AddressTuple& address);
const IPAddress& address(unsigned index) const; const IPAddress& address(unsigned index) const;
const NetworkInterface::AddressList& addressList() const; const NetworkInterface::AddressList& addressList() const;
@ -86,19 +87,19 @@ public:
const IPAddress& subnetMask(unsigned index) const; const IPAddress& subnetMask(unsigned index) const;
const IPAddress& broadcastAddress(unsigned index) const; const IPAddress& broadcastAddress(unsigned index) const;
const IPAddress& destAddress(unsigned index) 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;
void setName(const std::string& name); void setName(const std::string& name);
void setDisplayName(const std::string& name); void setDisplayName(const std::string& name);
void addAddress(const IPAddress& addr); void addAddress(const IPAddress& addr);
void setMacAddress(const NetworkInterface::MacAddress& addr); void setMACAddress(const NetworkInterface::MACAddress& addr);
void setMacAddress(const void *addr, std::size_t len); void setMACAddress(const void *addr, std::size_t len);
unsigned mtu() const; unsigned mtu() const;
unsigned ifindex() const; unsigned ifindex() const;
unsigned hwType() const; Type type() const;
bool broadcast() const; bool broadcast() const;
bool loopback() const; bool loopback() const;
@ -118,7 +119,7 @@ protected:
void setUp(bool up); void setUp(bool up);
void setMtu(unsigned mtu); void setMtu(unsigned mtu);
void setHWType(unsigned hwType); void setType(Type type);
void setIndex(unsigned index); void setIndex(unsigned index);
void getPhyParams(); void getPhyParams();
void getPeerAddress(); void getPeerAddress();
@ -135,9 +136,9 @@ private:
bool _up; bool _up;
bool _running; bool _running;
unsigned _mtu; unsigned _mtu;
unsigned _hwType; Type _type;
NetworkInterface::MacAddress _macAddress; NetworkInterface::MACAddress _macAddress;
friend NetworkInterface::Map NetworkInterface::map(bool, bool); friend NetworkInterface::Map NetworkInterface::map(bool, bool);
}; };
@ -294,11 +295,8 @@ inline const std::string& NetworkInterfaceImpl::displayName() const
} }
const IPAddress& NetworkInterfaceImpl::findFirstAddress(IPAddress::Family family) const const IPAddress& NetworkInterfaceImpl::firstAddress(IPAddress::Family family) const
{ {
if (!supportsIPv4() && !supportsIPv6())
throw NotImplementedException("Unknown or unsupported family.");
AddressList::const_iterator it = _addressList.begin(); AddressList::const_iterator it = _addressList.begin();
AddressList::const_iterator end = _addressList.end(); AddressList::const_iterator end = _addressList.end();
for (;it != end; ++it) for (;it != end; ++it)
@ -372,7 +370,7 @@ const IPAddress& NetworkInterfaceImpl::destAddress(unsigned index) const
} }
const NetworkInterface::MacAddress& NetworkInterfaceImpl::macAddress() const const NetworkInterface::MACAddress& NetworkInterfaceImpl::macAddress() const
{ {
return _macAddress; return _macAddress;
} }
@ -384,9 +382,9 @@ inline unsigned NetworkInterfaceImpl::mtu() const
} }
inline unsigned NetworkInterfaceImpl::hwType() const inline NetworkInterface::Type NetworkInterfaceImpl::type() const
{ {
return _hwType; return _type;
} }
@ -480,9 +478,9 @@ inline void NetworkInterfaceImpl::setMtu(unsigned mtu)
} }
inline void NetworkInterfaceImpl::setHWType(unsigned hwType) inline void NetworkInterfaceImpl::setType(Type type)
{ {
_hwType = hwType; _type = type;
} }
@ -509,13 +507,13 @@ inline void NetworkInterfaceImpl::addAddress(const IPAddress& addr)
_addressList.push_back(addr); _addressList.push_back(addr);
} }
inline void NetworkInterfaceImpl::setMacAddress(const NetworkInterface::MacAddress& addr) inline void NetworkInterfaceImpl::setMACAddress(const NetworkInterface::MACAddress& addr)
{ {
_macAddress = addr; _macAddress = addr;
} }
inline void NetworkInterfaceImpl::setMacAddress(const void *addr, std::size_t len) inline void NetworkInterfaceImpl::setMACAddress(const void *addr, std::size_t len)
{ {
_macAddress.clear(); _macAddress.clear();
for (unsigned i = 0; i < len; ++i) for (unsigned i = 0; i < len; ++i)
@ -613,9 +611,9 @@ const std::string& NetworkInterface::displayName() const
} }
const IPAddress& NetworkInterface::findFirstAddress(IPAddress::Family family) const const IPAddress& NetworkInterface::firstAddress(IPAddress::Family family) const
{ {
return _pImpl->findFirstAddress(family); return _pImpl->firstAddress(family);
} }
@ -655,7 +653,7 @@ const IPAddress& NetworkInterface::broadcastAddress(unsigned index) const
} }
const NetworkInterface::MacAddress& NetworkInterface::macAddress() const const NetworkInterface::MACAddress& NetworkInterface::macAddress() const
{ {
return _pImpl->macAddress(); return _pImpl->macAddress();
} }
@ -672,9 +670,9 @@ unsigned NetworkInterface::mtu() const
return _pImpl->mtu(); return _pImpl->mtu();
} }
unsigned NetworkInterface::hwType() const NetworkInterface::Type NetworkInterface::type() const
{ {
return _pImpl->hwType(); return _pImpl->type();
} }
bool NetworkInterface::supportsIP() const bool NetworkInterface::supportsIP() const
@ -713,6 +711,7 @@ bool NetworkInterface::isLoopback() const
} }
bool NetworkInterface::isPointToPoint() const bool NetworkInterface::isPointToPoint() const
{ {
return _pImpl->pointToPoint(); return _pImpl->pointToPoint();
@ -912,6 +911,23 @@ std::string getErrorMessage(DWORD errorCode)
} }
NetworkInterface::Type fromNative(DWORD type)
{
switch (type)
{
case IF_TYPE_ETHERNET_CSMACD: return NetworkInterface::NI_TYPE_ETHERNET_CSMACD;
case IF_TYPE_ISO88025_TOKENRING: return NetworkInterface::NI_TYPE_ISO88025_TOKENRING;
case IF_TYPE_FRAMERELAY: return NetworkInterface::NI_TYPE_FRAMERELAY;
case IF_TYPE_PPP: return NetworkInterface::NI_TYPE_PPP;
case IF_TYPE_SOFTWARE_LOOPBACK: return NetworkInterface::NI_TYPE_SOFTWARE_LOOPBACK;
case IF_TYPE_ATM: return NetworkInterface::NI_TYPE_ATM;
case IF_TYPE_IEEE80211: return NetworkInterface::NI_TYPE_IEEE80211;
case IF_TYPE_TUNNEL: return NetworkInterface::NI_TYPE_TUNNEL;
case IF_TYPE_IEEE1394: return NetworkInterface::NI_TYPE_IEEE1394;
default: return NetworkInterface::NI_TYPE_OTHER;
}
}
} /// namespace } /// namespace
@ -935,6 +951,7 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
PIP_ADAPTER_ADDRESSES pAddress = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(memory.begin()); PIP_ADAPTER_ADDRESSES pAddress = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(memory.begin());
do do
{ {
poco_assert (memory.capacity() >= outBufLen);
if (ERROR_BUFFER_OVERFLOW == (dwRetVal = GetAdaptersAddresses(family, flags, 0, pAddress, &outBufLen))) if (ERROR_BUFFER_OVERFLOW == (dwRetVal = GetAdaptersAddresses(family, flags, 0, pAddress, &outBufLen)))
memory.resize(outBufLen); // adjust size and try again memory.resize(outBufLen); // adjust size and try again
else if (ERROR_NO_DATA == dwRetVal) // no network interfaces found else if (ERROR_NO_DATA == dwRetVal) // no network interfaces found
@ -942,7 +959,7 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
else if (NO_ERROR != dwRetVal) // error occurred else if (NO_ERROR != dwRetVal) // error occurred
throw SystemException(format("An error occurred while trying to obtain list of network interfaces: [%s]", getErrorMessage(dwRetVal))); throw SystemException(format("An error occurred while trying to obtain list of network interfaces: [%s]", getErrorMessage(dwRetVal)));
else else
break; // all good break;
} while ((ERROR_BUFFER_OVERFLOW == dwRetVal) && (++iterations <= 2)); } while ((ERROR_BUFFER_OVERFLOW == dwRetVal) && (++iterations <= 2));
poco_assert (NO_ERROR == dwRetVal); poco_assert (NO_ERROR == dwRetVal);
@ -984,9 +1001,9 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
ifIt->second.impl().setFlags(pAddress->Flags, pAddress->IfType); ifIt->second.impl().setFlags(pAddress->Flags, pAddress->IfType);
ifIt->second.impl().setMtu(pAddress->Mtu); ifIt->second.impl().setMtu(pAddress->Mtu);
ifIt->second.impl().setUp(pAddress->OperStatus == IfOperStatusUp); ifIt->second.impl().setUp(pAddress->OperStatus == IfOperStatusUp);
ifIt->second.impl().setHWType(pAddress->IfType); ifIt->second.impl().setType(fromNative(pAddress->IfType));
if (pAddress->PhysicalAddressLength) if (pAddress->PhysicalAddressLength)
ifIt->second.impl().setMacAddress(pAddress->PhysicalAddress, pAddress->PhysicalAddressLength); ifIt->second.impl().setMACAddress(pAddress->PhysicalAddress, pAddress->PhysicalAddressLength);
for (PIP_ADAPTER_UNICAST_ADDRESS pUniAddr = pAddress->FirstUnicastAddress; for (PIP_ADAPTER_UNICAST_ADDRESS pUniAddr = pAddress->FirstUnicastAddress;
pUniAddr; pUniAddr;
@ -997,24 +1014,24 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
ADDRESS_FAMILY family = pUniAddr->Address.lpSockaddr->sa_family; ADDRESS_FAMILY family = pUniAddr->Address.lpSockaddr->sa_family;
switch (family) switch (family)
{ {
case AF_INET: case AF_INET:
{ {
// Windows lists broadcast address on localhost // Windows lists broadcast address on localhost
bool hasBroadcast = (pAddress->IfType == IF_TYPE_ETHERNET_CSMACD) || (pAddress->IfType == IF_TYPE_SOFTWARE_LOOPBACK); 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 // 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) // 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); broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address);
subnetMask = prefixLength ? IPAddress(prefixLength, IPAddress::IPv4) : IPAddress(); subnetMask = prefixLength ? IPAddress(prefixLength, IPAddress::IPv4) : IPAddress();
if (hasBroadcast) if (hasBroadcast)
ifIt->second.addAddress(address, subnetMask, broadcastAddress); ifIt->second.addAddress(address, subnetMask, broadcastAddress);
else else
ifIt->second.addAddress(address);
} break;
#if defined(POCO_HAVE_IPv6)
case AF_INET6:
ifIt->second.addAddress(address); ifIt->second.addAddress(address);
break; } break;
#endif #if defined(POCO_HAVE_IPv6)
case AF_INET6:
ifIt->second.addAddress(address);
break;
#endif
} // switch family } // switch family
} // for addresses } // for addresses
} // if ipOnly/upOnly } // if ipOnly/upOnly
@ -1126,8 +1143,8 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
intf.impl().setDisplayName(currIface->ifa_name); intf.impl().setDisplayName(currIface->ifa_name);
intf.impl().getPhyParams(); intf.impl().getPhyParams();
intf.impl().setMacAddress(LLADDR(sdl), sdl->sdl_alen); intf.impl().setMACAddress(LLADDR(sdl), sdl->sdl_alen);
intf.impl().setHWType(sdl->sdl_type); intf.impl().setType(sdl->sdl_type);
ifIt = result.insert(Map::value_type(ifIndex, intf)).first; ifIt = result.insert(Map::value_type(ifIndex, intf)).first;
break; break;
@ -1195,7 +1212,7 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
#include <linux/if.h> #include <linux/if.h>
#include <linux/if_packet.h> #include <linux/if_packet.h>
#include <net/if_arp.h> #include <net/if_arp.h>
#include <iostream>
namespace Poco { namespace Poco {
namespace Net { namespace Net {
@ -1203,30 +1220,21 @@ namespace Net {
namespace { namespace {
static unsigned arphrdToIfType(unsigned arphrd) static NetworkInterface::Type fromNative(unsigned arphrd)
{ {
switch (arphrd) { switch (arphrd)
case ARPHRD_ETHER: {
return 6; // IF_TYPE_ETHERNET_CSMACD case ARPHRD_ETHER: return NetworkInterface::NI_TYPE_ETHERNET_CSMACD;
case ARPHRD_IEEE802: case ARPHRD_IEEE802: return NetworkInterface::NI_TYPE_ISO88025_TOKENRING;
return 9; // IF_TYPE_ISO88025_TOKENRING case ARPHRD_DLCI: return NetworkInterface::NI_TYPE_FRAMERELAY;
case ARPHRD_DLCI: case ARPHRD_PPP: return NetworkInterface::NI_TYPE_PPP;
return 32; // IF_TYPE_FRAMERELAY case ARPHRD_LOOPBACK: return NetworkInterface::NI_TYPE_SOFTWARE_LOOPBACK;
case ARPHRD_PPP: case ARPHRD_ATM: return NetworkInterface::NI_TYPE_ATM;
return 512; // IF_TYPE_PPP case ARPHRD_IEEE80211: return NetworkInterface::NI_TYPE_IEEE80211;
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_TUNNEL:
case ARPHRD_TUNNEL6: case ARPHRD_TUNNEL6: return NetworkInterface::NI_TYPE_TUNNEL;
return 131; // IF_TYPE_TUNNEL case ARPHRD_IEEE1394: return NetworkInterface::NI_TYPE_IEEE1394;
case ARPHRD_IEEE1394: default: return NetworkInterface::NI_TYPE_OTHER;
return 144; // IF_TYPE_IEEE1394
default:
return 1; // IF_TYPE_OTHER
} }
} }
@ -1242,77 +1250,81 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
Map::iterator ifIt; Map::iterator ifIt;
struct ifaddrs* ifaces = 0; struct ifaddrs* ifaces = 0;
struct ifaddrs* currIface = 0; struct ifaddrs* iface = 0;
if (getifaddrs(&ifaces) < 0) if (getifaddrs(&ifaces) < 0)
throw NetException("cannot get network adapter list"); throw NetException("cannot get network adapter list");
try try
{ {
for (currIface = ifaces; currIface != 0; currIface = currIface->ifa_next) for (iface = ifaces; iface; iface = iface->ifa_next)
{ {
IPAddress address, subnetMask, broadcastAddress; if (!iface->ifa_addr) continue;
struct sockaddr_ll* sll;
switch (currIface->ifa_addr->sa_family) IPAddress address, subnetMask, broadcastAddress;
unsigned family = iface->ifa_addr->sa_family;
switch (family)
{ {
case AF_PACKET: case AF_PACKET:
sll = (struct sockaddr_ll*)currIface->ifa_addr; {
struct sockaddr_ll* sll = (struct sockaddr_ll*)iface->ifa_addr;
ifIndex = sll->sll_ifindex; ifIndex = sll->sll_ifindex;
intf = NetworkInterface(ifIndex); intf = NetworkInterface(ifIndex);
intf.impl().setName(currIface->ifa_name); intf.impl().setName(iface->ifa_name);
intf.impl().setDisplayName(currIface->ifa_name); intf.impl().setDisplayName(iface->ifa_name);
intf.impl().getPhyParams(); intf.impl().getPhyParams();
intf.impl().setMacAddress(sll->sll_addr, sll->sll_halen); intf.impl().setMACAddress(sll->sll_addr, sll->sll_halen);
intf.impl().setHWType(arphrdToIfType(sll->sll_hatype)); intf.impl().setType(fromNative(sll->sll_hatype));
ifIt = result.insert(Map::value_type(ifIndex, intf)).first; if ((upOnly && intf.isUp()) || !upOnly)
ifIt = result.insert(Map::value_type(ifIndex, intf)).first;
break; break;
}
case AF_INET: case AF_INET:
// need to use Map to search by name, i.e. result.find(name) {
ifIndex = if_nametoindex(currIface->ifa_name); ifIndex = if_nametoindex(iface->ifa_name);
ifIt = result.find(ifIndex); address = IPAddress(*(iface->ifa_addr));
subnetMask = IPAddress(*(iface->ifa_netmask));
address = IPAddress(*(currIface->ifa_addr)); if (iface->ifa_flags & IFF_BROADCAST && iface->ifa_broadaddr)
subnetMask = IPAddress(*(currIface->ifa_netmask)); broadcastAddress = IPAddress(*(iface->ifa_broadaddr));
else if (iface->ifa_flags & IFF_POINTOPOINT && iface->ifa_dstaddr)
if (currIface->ifa_flags & IFF_BROADCAST && currIface->ifa_broadaddr) broadcastAddress = IPAddress(*(iface->ifa_dstaddr));
broadcastAddress = IPAddress(*(currIface->ifa_broadaddr));
else if (currIface->ifa_flags & IFF_POINTOPOINT && currIface->ifa_dstaddr)
broadcastAddress = IPAddress(*(currIface->ifa_dstaddr));
else else
broadcastAddress = IPAddress(); broadcastAddress = IPAddress();
ifIt->second.addAddress(address, subnetMask, broadcastAddress);
break; break;
}
#if defined(POCO_HAVE_IPv6) #if defined(POCO_HAVE_IPv6)
case AF_INET6: case AF_INET6:
// need to use Map to search by name, i.e. result.find(name) ifIndex = if_nametoindex(iface->ifa_name);
ifIndex = if_nametoindex(currIface->ifa_name); address = IPAddress(&reinterpret_cast<const struct sockaddr_in6*>(iface->ifa_addr)->sin6_addr, sizeof(struct in6_addr), ifIndex);
ifIt = result.find(ifIndex); subnetMask = IPAddress(*(iface->ifa_netmask));
broadcastAddress = IPAddress();
address = IPAddress(&reinterpret_cast<const struct sockaddr_in6*>(currIface->ifa_addr)->sin6_addr, sizeof(struct in6_addr), ifIndex);
subnetMask = IPAddress(*(currIface->ifa_netmask));
if (currIface->ifa_flags & IFF_BROADCAST && currIface->ifa_broadaddr)
broadcastAddress = IPAddress(*(currIface->ifa_broadaddr));
else if (currIface->ifa_flags & IFF_POINTOPOINT && currIface->ifa_dstaddr)
broadcastAddress = IPAddress(*(currIface->ifa_dstaddr));
else
broadcastAddress = IPAddress();
ifIt->second.addAddress(address, subnetMask, broadcastAddress);
break; break;
#endif #endif
default: default:
continue; continue;
} }
}
if (family == AF_INET || family == AF_INET6)
{
intf = NetworkInterface(std::string(iface->ifa_name), address, subnetMask, broadcastAddress, ifIndex);
if ((upOnly && intf.isUp()) || !upOnly)
{
if ((ifIt = result.find(ifIndex)) != result.end())
ifIt->second.addAddress(address, subnetMask, broadcastAddress);
}
}
} // for interface
} }
catch (...) catch (...)
{ {
if (ifaces) freeifaddrs(ifaces);
throw;
} }
if (ifaces) freeifaddrs(ifaces); if (ifaces) freeifaddrs(ifaces);
return result; return result;

Просмотреть файл

@ -111,7 +111,7 @@ Poco::Net::NetworkInterface MulticastEchoServer::findInterface()
for (NetworkInterface::Map::const_iterator it = m.begin(); it != m.end(); ++it) for (NetworkInterface::Map::const_iterator it = m.begin(); it != m.end(); ++it)
{ {
if (it->second.supportsIPv4() && if (it->second.supportsIPv4() &&
it->second.findFirstAddress(IPAddress::IPv4).isUnicast() && it->second.firstAddress(IPAddress::IPv4).isUnicast() &&
!it->second.isLoopback() && !it->second.isLoopback() &&
!it->second.isPointToPoint()) !it->second.isPointToPoint())
{ {

Просмотреть файл

@ -67,11 +67,12 @@ void NetworkInterfaceTest::testMap()
std::cout << "DisplayName: " << it->second.displayName() << std::endl; std::cout << "DisplayName: " << it->second.displayName() << std::endl;
std::cout << "Status: " << (it->second.isUp() ? "Up" : "Down") << std::endl; std::cout << "Status: " << (it->second.isUp() ? "Up" : "Down") << std::endl;
NetworkInterface::MacAddress mac(it->second.macAddress()); NetworkInterface::MACAddress mac(it->second.macAddress());
if (!mac.empty()) { if (!mac.empty() && (it->second.type() != NetworkInterface::NI_TYPE_SOFTWARE_LOOPBACK))
std::cout << "Mac Address: (" << it->second.hwType() << ")"; {
std::cout << "MAC Address: ";
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::dec << std::endl; std::cout << std::dec << std::endl;
} }
@ -102,7 +103,7 @@ void NetworkInterfaceTest::testList()
assert (!list.empty()); assert (!list.empty());
for (NetworkInterface::NetworkInterfaceList::const_iterator it = list.begin(); it != list.end(); ++it) for (NetworkInterface::NetworkInterfaceList::const_iterator it = list.begin(); it != list.end(); ++it)
{ {
std::cout << "==============" << std::endl; std::cout << std::endl << "==============" << std::endl;
std::cout << "Index: " << it->index() << std::endl; std::cout << "Index: " << it->index() << std::endl;
std::cout << "Name: " << it->name() << std::endl; std::cout << "Name: " << it->name() << std::endl;
@ -147,14 +148,14 @@ void NetworkInterfaceTest::testForAddress()
if (it->second.supportsIPv4()) if (it->second.supportsIPv4())
{ {
NetworkInterface ifc = NetworkInterface::forAddress(it->second.findFirstAddress(IPAddress::IPv4)); NetworkInterface ifc = NetworkInterface::forAddress(it->second.firstAddress(IPAddress::IPv4));
assert (ifc.findFirstAddress(IPAddress::IPv4) == it->second.findFirstAddress(IPAddress::IPv4)); assert (ifc.firstAddress(IPAddress::IPv4) == it->second.firstAddress(IPAddress::IPv4));
} }
else else
{ {
try try
{ {
it->second.findFirstAddress(IPAddress::IPv4); it->second.firstAddress(IPAddress::IPv4);
fail ("must throw"); fail ("must throw");
} }
catch (NotFoundException&) { } catch (NotFoundException&) { }