diff options
Diffstat (limited to 'lib/libUPnP/Platinum/Source/Core/PltUtilities.h')
-rw-r--r-- | lib/libUPnP/Platinum/Source/Core/PltUtilities.h | 766 |
1 files changed, 766 insertions, 0 deletions
diff --git a/lib/libUPnP/Platinum/Source/Core/PltUtilities.h b/lib/libUPnP/Platinum/Source/Core/PltUtilities.h new file mode 100644 index 0000000..4677f5b --- /dev/null +++ b/lib/libUPnP/Platinum/Source/Core/PltUtilities.h @@ -0,0 +1,766 @@ +/***************************************************************** +| +| Platinum - Utilities +| +| Copyright (c) 2004-2010, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| licensing@plutinosoft.com +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_UTILITIES_H_ +#define _PLT_UTILITIES_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" + +/*---------------------------------------------------------------------- +| PLT_XmlAttributeFinder ++---------------------------------------------------------------------*/ +/** + The PLT_XmlAttributeFinder class is used to determine if an attribute + exists given an xml element node, an attribute name and namespace. + */ +class PLT_XmlAttributeFinder +{ +public: + // if 'namespc' is NULL, we're looking for ANY namespace + // if 'namespc' is '\0', we're looking for NO namespace + // if 'namespc' is non-empty, look for that SPECIFIC namespace + PLT_XmlAttributeFinder(const NPT_XmlElementNode& element, + const char* name, + const char* namespc) : + m_Element(element), m_Name(name), m_Namespace(namespc) {} + + bool operator()(const NPT_XmlAttribute* const & attribute) const { + if (attribute->GetName() == m_Name) { + if (m_Namespace) { + const NPT_String& prefix = attribute->GetPrefix(); + if (m_Namespace[0] == '\0') { + // match if the attribute has NO namespace + return prefix.IsEmpty(); + } else { + // match if the attribute has the SPECIFIC namespace + // we're looking for + const NPT_String* namespc = m_Element.GetNamespaceUri(prefix); + return namespc && *namespc == m_Namespace; + } + } else { + // ANY namespace will match + return true; + } + } else { + return false; + } + } + +private: + const NPT_XmlElementNode& m_Element; + const char* m_Name; + const char* m_Namespace; +}; + +/*---------------------------------------------------------------------- +| PLT_XmlHelper ++---------------------------------------------------------------------*/ +/** + The PLT_XmlHelper class is a set of utility functions for manipulating + xml documents and DOM trees. + */ +class PLT_XmlHelper +{ +public: + + // static methods + + static NPT_Result Parse(const NPT_String& xml, NPT_XmlElementNode*& tree) { + // reset tree + tree = NULL; + + // parse body + NPT_XmlParser parser; + NPT_XmlNode* node; + NPT_Result result = parser.Parse(xml, node); + if (NPT_FAILED(result)) { + //NPT_LOG_FINEST_1("Failed to parse %s", xml.IsEmpty()?"(empty string)":xml.GetChars()); + NPT_CHECK(result); + } + + tree = node->AsElementNode(); + if (!tree) { + delete node; + return NPT_FAILURE; + } + + return NPT_SUCCESS; + } + + static NPT_Result GetChildText(NPT_XmlElementNode* node, + const char* tag, + NPT_String& value, + const char* namespc = "", + NPT_Cardinal max_size = 1024) { + value = ""; + + if (!node) return NPT_FAILURE; + + // special case "" means we look for the same namespace as the parent + if (namespc && namespc[0] == '\0') { + namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE; + } + + NPT_XmlElementNode* child = node->GetChild(tag, namespc); + if (!child) return NPT_FAILURE; + + const NPT_String* text = child->GetText(); + // DLNA 7.3.17 + if (text) + value = text->SubString(0, max_size); + return NPT_SUCCESS; + } + + static NPT_Result RemoveAttribute(NPT_XmlElementNode* node, + const char* name, + const char* namespc = "") { + if (!node) return NPT_FAILURE; + + // special case "" means we look for the same namespace as the parent + if (namespc && namespc[0] == '\0') { + namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE; + } + + NPT_List<NPT_XmlAttribute*>::Iterator attribute; + attribute = node->GetAttributes().Find(PLT_XmlAttributeFinder(*node, name, namespc)); + if (!attribute) return NPT_FAILURE; + + delete *attribute; + NPT_CHECK(node->GetAttributes().Erase(attribute)); + + return NPT_SUCCESS; + } + + static NPT_Result GetAttribute(NPT_XmlElementNode* node, + const char* name, + NPT_XmlAttribute*& attr, + const char* namespc = "") { + attr = NULL; + + if (!node) return NPT_FAILURE; + + // special case "" means we look for the same namespace as the parent + if (namespc && namespc[0] == '\0') { + namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE; + } + + NPT_List<NPT_XmlAttribute*>::Iterator attribute; + attribute = node->GetAttributes().Find(PLT_XmlAttributeFinder(*node, name, namespc)); + if (!attribute) { + //NPT_Debug("Failed to find attribute [%s]:%s", namespc, name); + return NPT_FAILURE; + } + + attr = (*attribute); + return NPT_SUCCESS; + } + + static NPT_Result GetAttribute(NPT_XmlElementNode* node, + const char* name, + NPT_String& value, + const char* namespc = "", + NPT_Cardinal max_size = 1024) { + value = ""; + + NPT_XmlAttribute* attribute = NULL; + NPT_Result result = GetAttribute(node, name, attribute, namespc); + if (NPT_FAILED(result)) return result; + + if (!attribute) return NPT_FAILURE; + // DLNA 7.3.17 truncate to 1024 bytes + value = attribute->GetValue().SubString(0, max_size); + return NPT_SUCCESS; + } + + static NPT_Result SetAttribute(NPT_XmlElementNode* node, + const char* name, + const char* value, + const char* namespc = "") { + NPT_XmlAttribute* attribute = NULL; + NPT_CHECK(GetAttribute(node, name, attribute, namespc)); + if (!attribute) return NPT_FAILURE; + + attribute->SetValue(value); + return NPT_SUCCESS; + } + + static NPT_Result AddChildText(NPT_XmlElementNode* node, + const char* tag, + const char* text, + const char* prefix = NULL) { + if (!node) return NPT_FAILURE; + NPT_XmlElementNode* child = new NPT_XmlElementNode(prefix, tag); + child->AddText(text); + return node->AddChild(child); + } + + static bool IsMatch(const NPT_XmlNode* const & node, const char* tag, const char* namespc_mapped) { + // if m_Namespace is NULL, we're looking for ANY namespace + // if m_Namespace is '\0', we're looking for NO namespace + // if m_Namespace is non-empty, look for that SPECIFIC namespace + + const NPT_XmlElementNode* element = node->AsElementNode(); + // is tag the same (case sensitive)? + if (element && element->GetTag() == tag) { + if (namespc_mapped) { + // look for a SPECIFIC namespace or NO namespace + const NPT_String* namespc = element->GetNamespace(); + if (namespc) { + // the element has a namespace, match if it is equal to + // what we're looking for + return *namespc == namespc_mapped; + } else { + // the element does not have a namespace, match if we're + // looking for NO namespace + return namespc_mapped[0] == '\0'; + } + } else { + // ANY namespace will match + return true; + } + } + return false; + } + + static NPT_Result GetChildren(NPT_XmlElementNode* node, + NPT_Array<NPT_XmlElementNode*>& children, + const char* tag, + const char* namespc = "") { + if (!node) return NPT_FAILURE; + + // special case "" means we look for the same namespace as the parent + if (namespc && namespc[0] == '\0') { + namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE; + } + + const char* namespc_mapped = (namespc==NULL)?"":(namespc[0]=='*' && namespc[1]=='\0')?NULL:namespc; + + // get all children first + NPT_List<NPT_XmlNode*>& allchildren = node->GetChildren(); + + // iterate through children and add only elements with matching tag + NPT_List<NPT_XmlNode*>::Iterator child = allchildren.GetFirstItem(); + while (child) { + if (IsMatch(*child, tag, namespc_mapped)) { + children.Add((*child)->AsElementNode()); + } + ++child; + } + return NPT_SUCCESS; + } + + static NPT_XmlElementNode* GetChild(NPT_XmlElementNode* node, + const char* tag, + const char* namespc = "") { + if (!node) return NULL; + + // special case "" means we look for the same namespace as the parent + if (namespc && namespc[0] == '\0') { + namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE; + } + + return node->GetChild(tag, namespc); + } + + static NPT_Result GetChild(NPT_XmlElementNode* parent, + NPT_XmlElementNode*& child, + NPT_Ordinal n = 0) { + if (!parent) return NPT_FAILURE; + + // reset child + child = NULL; + + // get all children first + NPT_List<NPT_XmlNode*>::Iterator children = parent->GetChildren().GetFirstItem(); + while (children) { + if ((*children)->AsElementNode() && n-- == 0) { + child = (*children)->AsElementNode(); + return NPT_SUCCESS; + } + children++; + } + + return NPT_FAILURE; + } + + static NPT_Result Serialize(NPT_XmlNode& node, NPT_String& xml, bool add_header = true, NPT_Int8 indentation = 0) { + NPT_XmlWriter writer(indentation); + NPT_StringOutputStreamReference stream(new NPT_StringOutputStream(&xml)); + NPT_CHECK(writer.Serialize(node, *stream, add_header)); + return NPT_SUCCESS; + } + + static NPT_String Serialize(NPT_XmlNode& node, bool add_header = true, NPT_Int8 indentation = 0) { + NPT_XmlWriter writer(indentation); + NPT_String xml; + NPT_StringOutputStreamReference stream(new NPT_StringOutputStream(&xml)); + if (NPT_FAILED(writer.Serialize(node, *stream, add_header))) { + NPT_Debug("Failed to serialize xml node"); + return ""; + } + + return xml; + } +private: + // members +}; + +/*---------------------------------------------------------------------- +| NPT_StringFinder ++---------------------------------------------------------------------*/ +/** + The NPT_StringFinder class is used to determine if a string is found + as part of a list of strings. + */ +class NPT_StringFinder +{ +public: + // methods + explicit NPT_StringFinder(NPT_String& value, bool ignore_case = false) : + m_Value(value.GetChars()), m_IgnoreCase(ignore_case) {} + + explicit NPT_StringFinder(const char* value, bool ignore_case = false) : + m_Value(value), m_IgnoreCase(ignore_case) {} + + virtual ~NPT_StringFinder() {} + + bool operator()(const NPT_String* const & value) const { + return value->Compare(m_Value, m_IgnoreCase) ? false : true; + } + bool operator()(const NPT_String& value) const { + return value.Compare(m_Value, m_IgnoreCase) ? false : true; + } + +private: + // members + const char* m_Value; + bool m_IgnoreCase; +}; + +/*---------------------------------------------------------------------- +| NPT_IpAddressFinder ++---------------------------------------------------------------------*/ +/** + The NPT_IpAddressFinder class is used to determine if a IP Address is found + as part of a list of IP Addresses. + */ +class NPT_IpAddressFinder +{ +public: + // methods + NPT_IpAddressFinder(NPT_IpAddress ip) : m_Value(ip) {} + virtual ~NPT_IpAddressFinder() {} + + bool operator()(const NPT_IpAddress* const & value) const { + return *value == m_Value; + } + bool operator()(const NPT_IpAddress& value) const { + return value == m_Value; + } + +private: + // members + NPT_IpAddress m_Value; +}; + + +/*---------------------------------------------------------------------- +| PLT_UPnPMessageHelper class ++---------------------------------------------------------------------*/ +/** + The PLT_UPnPMessageHelper class is a set of utility functions for manipulating + specific UPnP HTTP headers. + */ +class PLT_UPnPMessageHelper +{ +public: + // methods + static const NPT_String* GetST(const NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("ST"); + } + static NPT_Result SetST(NPT_HttpMessage& message, + const char* st) { + return message.GetHeaders().SetHeader("ST", st); + } + + static const NPT_String* GetNT(const NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("NT"); + } + static NPT_Result SetNT(NPT_HttpMessage& message, + const char* nt) { + return message.GetHeaders().SetHeader("NT", nt); + } + + static const NPT_String* GetNTS(const NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("NTS"); + } + static NPT_Result SetNTS(NPT_HttpMessage& message, + const char* nts) { + return message.GetHeaders().SetHeader("NTS", nts); + } + + static const NPT_String* GetMAN(const NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("MAN"); + } + static NPT_Result SetMAN(NPT_HttpMessage& message, + const char* man) { + return message.GetHeaders().SetHeader("MAN", man); + } + + static const NPT_String* GetLocation(const NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("Location"); + } + static NPT_Result SetLocation(NPT_HttpMessage& message, + const char* location) { + return message.GetHeaders().SetHeader("Location", location); + } + + static const NPT_String* GetServer(const NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue(NPT_HTTP_HEADER_SERVER); + } + static NPT_Result SetServer(NPT_HttpMessage& message, + const char* server, + bool replace = true) { + return message.GetHeaders().SetHeader( + NPT_HTTP_HEADER_SERVER, + server, + replace); + } + + static const NPT_String* GetUSN(const NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("USN"); + } + static NPT_Result SetUSN(NPT_HttpMessage& message, + const char* usn) { + return message.GetHeaders().SetHeader("USN", usn); + } + + static const NPT_String* GetCallbacks(const NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("CALLBACK"); + } + static NPT_Result SetCallbacks(NPT_HttpMessage& message, const char* callbacks) { + return message.GetHeaders().SetHeader("CALLBACK", callbacks); + } + + static const NPT_String* GetSID(const NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("SID"); + } + static NPT_Result SetSID(NPT_HttpMessage& message, + const char* sid) { + return message.GetHeaders().SetHeader("SID", sid); + } + + static NPT_Result GetLeaseTime(const NPT_HttpMessage& message, NPT_TimeInterval& lease) { + const NPT_String* cc = + message.GetHeaders().GetHeaderValue("Cache-Control"); + NPT_CHECK_POINTER(cc); + return ExtractLeaseTime(*cc, lease); + } + static NPT_Result SetLeaseTime(NPT_HttpMessage& message, const NPT_TimeInterval& lease) { + return message.GetHeaders().SetHeader("Cache-Control", + "max-age="+NPT_String::FromInteger(lease.ToSeconds())); + } + + static NPT_Result GetBootId(const NPT_HttpMessage& message, NPT_UInt32& bootId) { + bootId = 0; + const NPT_String* bid = message.GetHeaders().GetHeaderValue("BOOTID.UPNP.ORG"); + NPT_CHECK_POINTER(bid); + return NPT_ParseInteger32(*bid, bootId, false); + } + static NPT_Result SetBootId(NPT_HttpMessage& message, const NPT_UInt32& bootId) { + return message.GetHeaders().SetHeader("BOOTID.UPNP.ORG", + NPT_String::FromInteger(bootId)); + } + + static NPT_Result GetNextBootId(const NPT_HttpMessage& message, NPT_UInt32& nextBootId) { + nextBootId = 0; + const NPT_String* nbid = message.GetHeaders().GetHeaderValue("NEXTBOOTID.UPNP.ORG"); + NPT_CHECK_POINTER(nbid); + return NPT_ParseInteger32(*nbid, nextBootId, false); + } + static NPT_Result SetNextBootId(NPT_HttpMessage& message, const NPT_UInt32& nextBootId) { + return message.GetHeaders().SetHeader("NEXTBOOTID.UPNP.ORG", + NPT_String::FromInteger(nextBootId)); + } + + static NPT_Result GetConfigId(const NPT_HttpMessage& message, NPT_UInt32& configId) { + configId = 0; + const NPT_String* cid = message.GetHeaders().GetHeaderValue("CONFIGID.UPNP.ORG"); + NPT_CHECK_POINTER(cid); + return NPT_ParseInteger32(*cid, configId, false); + } + static NPT_Result SetConfigId(NPT_HttpMessage& message, const NPT_UInt32& configId) { + return message.GetHeaders().SetHeader("CONFIGID.UPNP.ORG", NPT_String::FromInteger(configId)); + } + + static NPT_Result GetTimeOut(const NPT_HttpMessage& message, NPT_Int32& seconds) { + seconds = 0; + const NPT_String* timeout = + message.GetHeaders().GetHeaderValue("TIMEOUT"); + NPT_CHECK_POINTER(timeout); + return ExtractTimeOut(*timeout, seconds); + } + static NPT_Result SetTimeOut(NPT_HttpMessage& message, const NPT_Int32 seconds) { + if (seconds >= 0) { + return message.GetHeaders().SetHeader("TIMEOUT", "Second-"+NPT_String::FromInteger(seconds)); + } else { + return message.GetHeaders().SetHeader("TIMEOUT", "Second-infinite"); + } + } + + static NPT_Result SetDate(NPT_HttpMessage& message) { + NPT_TimeStamp now; + NPT_System::GetCurrentTimeStamp(now); + NPT_DateTime date(now); + + return message.GetHeaders().SetHeader("Date", date.ToString(NPT_DateTime::FORMAT_RFC_1123)); + } + + static NPT_Result GetIfModifiedSince(const NPT_HttpMessage& message, NPT_DateTime& date) { + const NPT_String* value = message.GetHeaders().GetHeaderValue("If-Modified-Since"); + if (!value) return NPT_FAILURE; + + // Try RFC 1123, RFC 1036, then ANSI + if (NPT_SUCCEEDED(date.FromString(*value, NPT_DateTime::FORMAT_RFC_1123))) + return NPT_SUCCESS; + + if (NPT_SUCCEEDED(date.FromString(*value, NPT_DateTime::FORMAT_RFC_1036))) + return NPT_SUCCESS; + + return date.FromString(*value, NPT_DateTime::FORMAT_ANSI); + } + static NPT_Result SetIfModifiedSince(NPT_HttpMessage& message, const NPT_DateTime& date) { + return message.GetHeaders().SetHeader("If-Modified-Since", + date.ToString(NPT_DateTime::FORMAT_RFC_1123)); + } + + static NPT_Result GetMX(const NPT_HttpMessage& message, NPT_UInt32& value) { + value = 0; + const NPT_String* mx = + message.GetHeaders().GetHeaderValue("MX"); + NPT_CHECK_POINTER(mx); + return NPT_ParseInteger32(*mx, value, false); // no relax to be UPnP compliant + } + static NPT_Result SetMX(NPT_HttpMessage& message, const NPT_UInt32 mx) { + return message.GetHeaders().SetHeader("MX", + NPT_String::FromInteger(mx)); + } + + static NPT_Result GetSeq(const NPT_HttpMessage& message, NPT_UInt32& value) { + value = 0; + const NPT_String* seq = + message.GetHeaders().GetHeaderValue("SEQ"); + NPT_CHECK_POINTER(seq); + return NPT_ParseInteger32(*seq, value); + } + static NPT_Result SetSeq(NPT_HttpMessage& message, const NPT_UInt32 seq) { + return message.GetHeaders().SetHeader("SEQ", + NPT_String::FromInteger(seq)); + } + + static const char* GenerateUUID(int count, NPT_String& uuid) { + uuid = ""; + for (int i=0;i<(count<100?count:100);i++) { + int random = NPT_System::GetRandomInteger(); + uuid += (char)((random % 25) + 66); + } + return uuid; + } + + static const char* GenerateSerialNumber(NPT_String& sn, int count = 40) { + sn = "{"; + for (int i=0;i<count;i++) { + char nibble = (char)(NPT_System::GetRandomInteger() % 16); + sn += (nibble < 10) ? ('0' + nibble) : ('a' + (nibble-10)); + } + sn += "}"; + return sn; + } + + static const char* GenerateGUID(NPT_String& guid) { + guid = ""; + for (int i=0;i<32;i++) { + char nibble = (char)(NPT_System::GetRandomInteger() % 16); + guid += (nibble < 10) ? ('0' + nibble) : ('a' + (nibble-10)); + if (i == 7 || i == 11 || i == 15 || i == 19) { + guid += '-'; + } + } + return guid; + } + + static NPT_Result ExtractLeaseTime(const NPT_String& cache_control, NPT_TimeInterval& lease) { + NPT_Int32 value; + if (cache_control.StartsWith("max-age=", true) && + NPT_SUCCEEDED(NPT_ParseInteger32(cache_control.GetChars()+8, value))) { + lease.SetSeconds(value); + return NPT_SUCCESS; + } + return NPT_FAILURE; + } + + static NPT_Result ExtractTimeOut(const char* timeout, NPT_Int32& len) { + NPT_String temp = timeout; + if (temp.CompareN("Second-", 7, true)) { + return NPT_ERROR_INVALID_FORMAT; + } + + if (temp.Compare("Second-infinite", true) == 0) { + len = NPT_TIMEOUT_INFINITE; + return NPT_SUCCESS; + } + return temp.SubString(7).ToInteger(len); + } + + static NPT_Result GetIPAddresses(NPT_List<NPT_IpAddress>& ips, bool with_localhost = false) { + NPT_List<NPT_NetworkInterface*> if_list; + NPT_CHECK(GetNetworkInterfaces(if_list, with_localhost)); + + NPT_List<NPT_NetworkInterface*>::Iterator iface = if_list.GetFirstItem(); + while (iface) { + NPT_IpAddress ip = (*(*iface)->GetAddresses().GetFirstItem()).GetPrimaryAddress(); + if (ip.ToString().Compare("0.0.0.0") && + (with_localhost || ip.ToString().Compare("127.0.0.1"))) { + ips.Add(ip); + } + ++iface; + } + + if (with_localhost && !ips.Find(NPT_IpAddressFinder(NPT_IpAddress(127, 0, 0, 1)))) { + NPT_IpAddress localhost; + localhost.Parse("127.0.0.1"); + ips.Add(localhost); + } + + if_list.Apply(NPT_ObjectDeleter<NPT_NetworkInterface>()); + return NPT_SUCCESS; + } + + static NPT_Result GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& if_list, + bool with_localhost = false) { + NPT_CHECK(_GetNetworkInterfaces(if_list, with_localhost, false)); + + // if no valid interfaces or if requested, add localhost interface + if (if_list.GetItemCount() == 0) { + NPT_CHECK(_GetNetworkInterfaces(if_list, true, true)); + } + return NPT_SUCCESS; + } + + static NPT_Result GetMACAddresses(NPT_List<NPT_String>& addresses) { + NPT_List<NPT_NetworkInterface*> if_list; + NPT_CHECK(GetNetworkInterfaces(if_list)); + + NPT_List<NPT_NetworkInterface*>::Iterator iface = if_list.GetFirstItem(); + while (iface) { + NPT_String ip = (*(*iface)->GetAddresses().GetFirstItem()).GetPrimaryAddress().ToString(); + if (ip.Compare("0.0.0.0") && ip.Compare("127.0.0.1")) { + addresses.Add((*iface)->GetMacAddress().ToString()); + } + ++iface; + } + + if_list.Apply(NPT_ObjectDeleter<NPT_NetworkInterface>()); + return NPT_SUCCESS; + } + + + static bool IsLocalNetworkAddress(const NPT_IpAddress& address) { + if (address.ToString() == "127.0.0.1") return true; + + NPT_List<NPT_NetworkInterface*> if_list; + NPT_NetworkInterface::GetNetworkInterfaces(if_list); + + NPT_List<NPT_NetworkInterface*>::Iterator iface = if_list.GetFirstItem(); + while (iface) { + if((*iface)->IsAddressInNetwork(address)) return true; + ++iface; + } + + if_list.Apply(NPT_ObjectDeleter<NPT_NetworkInterface>()); + return false; + } + +private: + + static NPT_Result _GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& if_list, + bool include_localhost = false, + bool only_localhost = false) { + NPT_List<NPT_NetworkInterface*> _if_list; + NPT_CHECK(NPT_NetworkInterface::GetNetworkInterfaces(_if_list)); + + NPT_NetworkInterface* iface; + while (NPT_SUCCEEDED(_if_list.PopHead(iface))) { + // only interested in non PTP & multicast capable interfaces + if ((iface->GetAddresses().GetItemCount() == 0) || + !(iface->GetFlags() & NPT_NETWORK_INTERFACE_FLAG_MULTICAST) || + (iface->GetFlags() & NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT)) { + delete iface; + continue; + } + + NPT_String ip = iface->GetAddresses().GetFirstItem()->GetPrimaryAddress().ToString(); + + if (iface->GetFlags() & NPT_NETWORK_INTERFACE_FLAG_LOOPBACK) { + if (include_localhost || only_localhost) { + if_list.Add(iface); + continue; + } + } else if (ip.Compare("0.0.0.0") && !only_localhost) { + if_list.Add(iface); + continue; + } + + delete iface; + } + + // cleanup any remaining items in list if we breaked early + _if_list.Apply(NPT_ObjectDeleter<NPT_NetworkInterface>()); + return NPT_SUCCESS; + } +}; + +#endif // _PLT_UTILITIES_H_ + + + + + + + + + |