diff --git a/Net/include/Poco/Net/NetworkInterface.h b/Net/include/Poco/Net/NetworkInterface.h index 9eb9d6cdf..c7f4fbdfb 100644 --- a/Net/include/Poco/Net/NetworkInterface.h +++ b/Net/include/Poco/Net/NetworkInterface.h @@ -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; diff --git a/Net/src/MulticastSocket.cpp b/Net/src/MulticastSocket.cpp index 8da35bd79..f99ae9dc1 100644 --- a/Net/src/MulticastSocket.cpp +++ b/Net/src/MulticastSocket.cpp @@ -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 diff --git a/Net/src/NetworkInterface.cpp b/Net/src/NetworkInterface.cpp index a76d298bc..aaf4cd0b4 100644 --- a/Net/src/NetworkInterface.cpp +++ b/Net/src/NetworkInterface.cpp @@ -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(); + 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 - -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(); + IPAddress mask = ipIt->get(); + NetworkInterface ni; + if (mask.isWildcard()) + ni = NetworkInterface(name, displayName, addr, index); + else + { + IPAddress broadcast = ipIt->get(); + 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 #include #include +#include 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; diff --git a/Net/testsuite/src/MulticastEchoServer.cpp b/Net/testsuite/src/MulticastEchoServer.cpp index c0834755f..8d24341cd 100644 --- a/Net/testsuite/src/MulticastEchoServer.cpp +++ b/Net/testsuite/src/MulticastEchoServer.cpp @@ -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(); } diff --git a/Net/testsuite/src/NetworkInterfaceTest.cpp b/Net/testsuite/src/NetworkInterfaceTest.cpp index f5b145065..a224a06a7 100644 --- a/Net/testsuite/src/NetworkInterfaceTest.cpp +++ b/Net/testsuite/src/NetworkInterfaceTest.cpp @@ -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().toString() << std::endl; + IPAddress addr = ipIt->get(); + if (!addr.isWildcard()) std::cout << "Subnet: " << ipIt->get().toString() << std::endl; + addr = ipIt->get(); + if (!addr.isWildcard()) std::cout << "Broadcast: " << ipIt->get().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); diff --git a/Net/testsuite/src/NetworkInterfaceTest.h b/Net/testsuite/src/NetworkInterfaceTest.h index 60bd60466..ef5a477d0 100644 --- a/Net/testsuite/src/NetworkInterfaceTest.h +++ b/Net/testsuite/src/NetworkInterfaceTest.h @@ -47,6 +47,7 @@ public: ~NetworkInterfaceTest(); void testMap(); + void testList(); void testForName(); void testForAddress(); void testForIndex();