diff --git a/mozilla/zap/netutils/src/Makefile.in b/mozilla/zap/netutils/src/Makefile.in index 79290442e6a..48c170b537e 100644 --- a/mozilla/zap/netutils/src/Makefile.in +++ b/mozilla/zap/netutils/src/Makefile.in @@ -22,13 +22,21 @@ CPPSRCS = \ zapNetUtils.cpp \ zapStunMessage.cpp \ zapNetUtilsModule.cpp \ + zapNetItfAddress.cpp \ $(NULL) +ifeq ($(OS_ARCH),WINNT) +CPPSRCS += \ + zapNetHelpersWin.cpp \ + $(NULL) +endif + XPIDLSRCS = \ zapINetUtils.idl \ zapIStunMessage.idl \ zapIStunAddressResolveListener.idl \ zapIStunResolver.idl \ + zapINetItfAddress.idl \ $(NULL) EXTRA_PP_COMPONENTS = \ diff --git a/mozilla/zap/netutils/src/zapINetItfAddress.idl b/mozilla/zap/netutils/src/zapINetItfAddress.idl new file mode 100644 index 00000000000..273c8d94c9d --- /dev/null +++ b/mozilla/zap/netutils/src/zapINetItfAddress.idl @@ -0,0 +1,80 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla SIP client project. + * + * The Initial Developer of the Original Code is 8x8 Inc. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Alexander Fritze (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +native PRNetAddr(PRNetAddr); + +/** + * \defgroup NETUTILS_MODULE ZAP NetUtils module + */ + +/** + * \ingroup NETUTILS_MODULE + */ +[scriptable, uuid(91735c6b-fec4-4f2e-9aec-34824c28b1d0)] +interface zapINetItfAddress : nsISupports +{ + /** + * IP address as a string + */ + readonly attribute ACString address; + + /** + * IP address as a PRNetAddr structure + */ + [noscript] PRNetAddr getPRNetAddress(); + + /** + * Name of network interface associated with this address + */ + readonly attribute ACString itf; + + /** + * true if interface is up + */ + readonly attribute boolean up; + + /** + * true if this is a loopback net + */ + readonly attribute boolean loopback; + + /** + * true if this itf supports multicast. + */ + readonly attribute boolean multicast; +}; diff --git a/mozilla/zap/netutils/src/zapINetUtils.idl b/mozilla/zap/netutils/src/zapINetUtils.idl index 7fbc4c0678c..8a2be79f8bc 100644 --- a/mozilla/zap/netutils/src/zapINetUtils.idl +++ b/mozilla/zap/netutils/src/zapINetUtils.idl @@ -14,7 +14,7 @@ * The Original Code is the Mozilla SIP client project. * * The Initial Developer of the Original Code is 8x8 Inc. - * Portions created by the Initial Developer are Copyright (C) 2005 + * Portions created by the Initial Developer are Copyright (C) 2005-2008 * the Initial Developer. All Rights Reserved. * * Contributor(s): @@ -38,6 +38,13 @@ interface zapIStunMessage; interface zapIStunAddressResolveListener; +interface zapINetItfAddress; + +%{C++ +#include "nsCOMArray.h" +%} + +[ptr] native NetItfAddrArray(nsCOMArray); /** * \defgroup NETUTILS_MODULE ZAP NetUtils module @@ -46,11 +53,13 @@ interface zapIStunAddressResolveListener; /** * \ingroup NETUTILS_MODULE */ -[scriptable, uuid(93fa38d7-aad3-4857-ad1c-b353c79481f1)] +[scriptable, uuid(fca750a3-cbfd-4cb0-a7f3-6707caf42cba)] interface zapINetUtils : nsISupports { /** * Create an empty STUN message + * + * DEPRECATED */ zapIStunMessage createStunMessage(); @@ -60,6 +69,8 @@ interface zapINetUtils : nsISupports * If parsing of the packet succeeds, unknownAttribs will contain * any attributes with values less than or equal to 0x7fff which * were not understood. + * + * DEPRECATED */ zapIStunMessage deserializeStunPacket(in ACString packet, [array, size_is(count)] out @@ -77,6 +88,8 @@ interface zapINetUtils : nsISupports * the header), or n>20 (== the length of the STUN message including * header) if the buffer appears to be a (possibly partial) STUN * message and the length can be determined. + * + * DEPRECATED */ PRInt32 snoopStunPacket(in ACString buffer); @@ -84,6 +97,8 @@ interface zapINetUtils : nsISupports * Asynchronously resolve our mapped NAT address using the given * stun server. 'stunServer' can be a domain name or IP address, * optionally postfixed with ':' and port number. + * + * DEPRECATED */ void resolveMappedAddress(in zapIStunAddressResolveListener listener, in ACString stunServer); @@ -91,14 +106,23 @@ interface zapINetUtils : nsISupports /** * Returns the 'primary' ip address of the local host. This will be * the first ip address returned by the dns resolver for the current - * hostname, or if this fails on Linux, the address of interface - * 'eth0'. If no ip address can be inferred, 127.0.0.1 will be - * returned. - * - * Note: This is a temporary method that will be replaced by a mechanism - * for querying all local ip addresses at some point. + * hostname, or if this fails on Unix-like OSs, the address of + * interface 'eth0'. If no 'primary' ip address can be inferred, + * 127.0.0.1 will be returned. */ ACString getPrimaryHostAddress(); + + /** + * Returns an array of IP addresses of all network interfaces on the + * local machine. + */ + void getNetItfAddresses(out unsigned long count, + [retval, array, size_is(count)] out zapINetItfAddress results); + + /** + * C++-friendly, non-scriptable version of getNetItfAddresses() + */ + [noscript] void getNetItfAddressesCOMArray(in NetItfAddrArray results); }; %{ C++ diff --git a/mozilla/zap/netutils/src/zapNetHelpersWin.cpp b/mozilla/zap/netutils/src/zapNetHelpersWin.cpp new file mode 100644 index 00000000000..f5c6581bff6 --- /dev/null +++ b/mozilla/zap/netutils/src/zapNetHelpersWin.cpp @@ -0,0 +1,214 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla SIP client project. + * + * The Initial Developer of the Original Code is 8x8 Inc. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Alexander Fritze (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "zapNetHelpersWin.h" +#include +#include "prlink.h" +#include "nsDebug.h" +#include + +typedef DWORD +(WINAPI *GetAdaptersAddressesFunc)(ULONG family, + DWORD flags, + PVOID reserved, + PIP_ADAPTER_ADDRESSES aaddrs, + PULONG size); + +static PRLibrary* sPHLPAPI = NULL; +static GetAdaptersAddressesFunc sGetAdaptersAddresses = NULL; + +void InitNetHelpersWin() +{ + sPHLPAPI = PR_LoadLibrary("iphlpapi.dll"); + if (!sPHLPAPI) + return; + + sGetAdaptersAddresses = + (GetAdaptersAddressesFunc)PR_FindSymbol(sPHLPAPI, + "GetAdaptersAddresses"); + + if (!sGetAdaptersAddresses) + FreeNetHelpersWin(); +} + +void FreeNetHelpersWin() +{ + if (!sPHLPAPI) return; + PR_UnloadLibrary(sPHLPAPI); + sPHLPAPI = NULL; + sGetAdaptersAddresses = NULL; +} + +// These implementations of getifaddrs and freeifaddrs are (very +// loosely) adapted from +// http://www.opensource.apple.com/darwinsource/tarballs/other/mDNSResponder-107.6.tar.gz, +// Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved. +// (Apache License, http://www.apache.org/licenses/LICENSE-2.0) + +int getifaddrs(struct ifaddrs **ifap) +{ + if (!sGetAdaptersAddresses) { + NS_WARNING("zapNetHelpersWin lib not init'ed or unsupported version of Windows"); + return -1; + } + + DWORD gaa_flags = /* GAA_FLAG_INCLUDE_PREFIX | */ + GAA_FLAG_SKIP_ANYCAST | + GAA_FLAG_SKIP_MULTICAST | + GAA_FLAG_SKIP_DNS_SERVER | + GAA_FLAG_SKIP_FRIENDLY_NAME; + + ULONG aa_list_size; + IP_ADAPTER_ADDRESSES *aa_list; + + int retries = 0; + while (1) { + aa_list_size = 0; + if (sGetAdaptersAddresses(AF_UNSPEC, gaa_flags, NULL, NULL, &aa_list_size) != + ERROR_BUFFER_OVERFLOW) { + NS_WARNING("Unexpected return value from GetAdaptersAddresses"); + return -1; + } + + aa_list = (IP_ADAPTER_ADDRESSES*)malloc(aa_list_size); + if (!aa_list) { + NS_ERROR("Out of memory"); + return -1; + } + + if (sGetAdaptersAddresses(AF_UNSPEC, gaa_flags, NULL, + aa_list, &aa_list_size) == + ERROR_SUCCESS) + break; + + // There might have been interfaces added/removed between the two + // call to GetAdaptersAddresses, making the second call + // fail. We'll retry up to 10 times. + free(aa_list); + if (++retries >= 10) { + NS_ERROR("Too many retries for GetAdaptersAddresses"); + return -1; + } + } + + // At this point the aa_list datastructure has been filled. Now pick + // it apart and reassemble the information into our output + // datastructure: + int err = -1; + struct ifaddrs *head = NULL; + struct ifaddrs **next = &head; + + // On Windows XP pre-SP1, GetAdaptersAddresses returns an + // incompatible structure, which we can identify based on its size + // being smaller than what we expect. We bail under these + // conditions. + // XXX As long as we don't try to parse the prefix list (which has + // some dodgy semantics anyway), we're safe to continue. + // if (aa_list && aa_list->Length < sizeof(IP_ADAPTER_ADDRESSES)) { + // NS_WARNING("GetAdaptersAddresses returned incompatible struct"); + // goto bail; + // } + + for (IP_ADAPTER_ADDRESSES *aa = aa_list; aa; aa = aa->Next) { + // Skip tunnel interfaces. XXX Do we really want to do that? + if (aa->IfType == IF_TYPE_TUNNEL) + continue; + + // Add each address as a separate interface to emulate the way + // getifaddrs works. + IP_ADAPTER_UNICAST_ADDRESS *addr; + for (addr = aa->FirstUnicastAddress; addr; addr = addr->Next) { + int family = addr->Address.lpSockaddr->sa_family; + if (family != AF_INET && family != AF_INET6) continue; + + struct ifaddrs *ifa = (struct ifaddrs *)calloc(1, sizeof(struct ifaddrs)); + if (!ifa) goto bail; + *next = ifa; + next = &ifa->ifa_next; + + // Interface name + ifa->ifa_name = strdup(aa->AdapterName); + + // Interface flags + ifa->ifa_flags = 0; + if (aa->OperStatus == IfOperStatusUp) + ifa->ifa_flags |= IFF_UP; + if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) + ifa->ifa_flags |= IFF_LOOPBACK; + if (!(aa->Flags & IP_ADAPTER_NO_MULTICAST)) + ifa->ifa_flags |= IFF_MULTICAST; + // XXX IFF_POINTTOPOINT + + // Address + ifa->ifa_addr = (struct sockaddr*)calloc(1, addr->Address.iSockaddrLength); + if (!ifa->ifa_addr) goto bail; + memcpy(ifa->ifa_addr, addr->Address.lpSockaddr, addr->Address.iSockaddrLength); + + // XXX NETMASK + + // XXX BROADCAST ADDRESS + } + } + + // Only if we end up at this line have we been successful. Clear + // error flag and fall through to cleanup code. + *ifap = head; + head = NULL; + err = 0; + + bail: + if (head) + freeifaddrs(head); + if (aa_list) + free(aa_list); + + return err; +} + +void freeifaddrs(struct ifaddrs *ifp) +{ + while (ifp) { + struct ifaddrs *p = ifp; + ifp = p->ifa_next; + + if (p->ifa_name) free(p->ifa_name); + if (p->ifa_addr) free(p->ifa_addr); + if (p->ifa_netmask) free(p->ifa_netmask); + if (p->ifa_dstaddr) free(p->ifa_dstaddr); + if (p->ifa_data) free(p->ifa_data); + free(p); + } +} diff --git a/mozilla/zap/netutils/src/zapNetHelpersWin.h b/mozilla/zap/netutils/src/zapNetHelpersWin.h new file mode 100644 index 00000000000..20daaafa627 --- /dev/null +++ b/mozilla/zap/netutils/src/zapNetHelpersWin.h @@ -0,0 +1,93 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla SIP client project. + * + * The Initial Developer of the Original Code is 8x8 Inc. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Alexander Fritze (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef __ZAP_NETHELPERSWIN__ +#define __ZAP_NETHELPERSWIN__ + +#include "prtypes.h" + +//////////////////////////////////////////////////////////////////////// +// Network compatibility functions for Windows + + +//---------------------------------------------------------------------- +// Windows headers + +// We need to force compilation for Windows XP SP1 or higher to pull +// in the definitions of IP_ADAPTER_UNICAST_ADDRESS and +// IP_ADAPTER_PREFIX. We have a check in getifaddrs() to ascertain +// that the structure returned from GetAdaptersAddresses is in fact +// a version we can process. +#if (_WIN32_WINNT < 0x501) +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x501 +#endif + +#include +#include +#include + +//---------------------------------------------------------------------- +// Initialization + +void InitNetHelpersWin(); +void FreeNetHelpersWin(); + +//---------------------------------------------------------------------- +// getifaddrs/freeifaddrs: +// Emulate the eponymous UNIX function. +// Shortcomings: +// - Only works on Windows XP and later. Fails gracefully on earlier +// versions. +// - Only IPv4 and IPv6 sockets. +// - ifa_netmask/ifa_dstaddr/ifa_data are not filled in. +// - Only flags IFF_UP, IFF_LOOPBACK and IFF_MULTICAST are filled in. + +struct ifaddrs +{ + struct ifaddrs *ifa_next; + char *ifa_name; + PRUint32 ifa_flags; + struct sockaddr *ifa_addr; + struct sockaddr *ifa_netmask; + struct sockaddr *ifa_dstaddr; + void *ifa_data; +}; + +int getifaddrs(struct ifaddrs **ifap); +void freeifaddrs(struct ifaddrs *ifp); + +#endif // __ZAP_NETHELPERSWIN__ diff --git a/mozilla/zap/netutils/src/zapNetItfAddress.cpp b/mozilla/zap/netutils/src/zapNetItfAddress.cpp new file mode 100644 index 00000000000..d48b078e0c8 --- /dev/null +++ b/mozilla/zap/netutils/src/zapNetItfAddress.cpp @@ -0,0 +1,114 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla SIP client project. + * + * The Initial Developer of the Original Code is 8x8 Inc. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Alexander Fritze (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "zapNetItfAddress.h" +#include "prnetdb.h" + +#ifdef XP_WIN +#include +#else +#include +#endif + + +//////////////////////////////////////////////////////////////////////// +// zapNetItfAddress + +//---------------------------------------------------------------------- +// nsISupports methods: + +NS_IMPL_THREADSAFE_ADDREF(zapNetItfAddress) +NS_IMPL_THREADSAFE_RELEASE(zapNetItfAddress) + +NS_INTERFACE_MAP_BEGIN(zapNetItfAddress) + NS_INTERFACE_MAP_ENTRY(nsISupports) + NS_INTERFACE_MAP_ENTRY(zapINetItfAddress) +NS_INTERFACE_MAP_END + +//---------------------------------------------------------------------- +// zapINetItfAddress methods: + +/* readonly attribute ACString address; */ +NS_IMETHODIMP +zapNetItfAddress::GetAddress(nsACString & aAddress) +{ + char buf[NI_MAXHOST]; + if (PR_NetAddrToString(&mNetAddr, buf, NI_MAXHOST) != PR_SUCCESS) + return NS_ERROR_FAILURE; + + aAddress.Assign(buf); + return NS_OK; +} + +/* [noscript] PRNetAddr getPRNetAddress (); */ +NS_IMETHODIMP +zapNetItfAddress::GetPRNetAddress(PRNetAddr *_retval) +{ + memcpy(_retval, &mNetAddr, sizeof(mNetAddr)); + return NS_OK; +} + +/* readonly attribute ACString itf; */ +NS_IMETHODIMP +zapNetItfAddress::GetItf(nsACString & aItf) +{ + aItf = mItfName; + return NS_OK; +} + +/* readonly attribute boolean up; */ +NS_IMETHODIMP +zapNetItfAddress::GetUp(PRBool *aUp) +{ + *aUp = ((mFlags & IFF_UP) == IFF_UP); + return NS_OK; +} + +/* readonly attribute boolean loopback; */ +NS_IMETHODIMP +zapNetItfAddress::GetLoopback(PRBool *aLoopback) +{ + *aLoopback = ((mFlags & IFF_LOOPBACK) == IFF_LOOPBACK); + return NS_OK; +} + +/* readonly attribute boolean multicast; */ +NS_IMETHODIMP +zapNetItfAddress::GetMulticast(PRBool *aMulticast) +{ + *aMulticast = ((mFlags & IFF_MULTICAST) == IFF_MULTICAST); + return NS_OK; +} diff --git a/mozilla/zap/netutils/src/zapNetItfAddress.h b/mozilla/zap/netutils/src/zapNetItfAddress.h new file mode 100644 index 00000000000..b12f645218b --- /dev/null +++ b/mozilla/zap/netutils/src/zapNetItfAddress.h @@ -0,0 +1,54 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla SIP client project. + * + * The Initial Developer of the Original Code is 8x8 Inc. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Alexander Fritze (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef __ZAP_NETITFADDRESS_H__ +#define __ZAP_NETITFADDRESS_H__ + +#include "zapINetItfAddress.h" +#include "nsStringAPI.h" + +class zapNetItfAddress : public zapINetItfAddress +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_ZAPINETITFADDRESS + + PRNetAddr mNetAddr; + nsCString mItfName; + PRUint32 mFlags; // interface flags as defined in net/if.h +}; + +#endif // __ZAP_NETITFADDRESS_H__ diff --git a/mozilla/zap/netutils/src/zapNetUtils.cpp b/mozilla/zap/netutils/src/zapNetUtils.cpp index 23b76823b9f..9ff27114285 100644 --- a/mozilla/zap/netutils/src/zapNetUtils.cpp +++ b/mozilla/zap/netutils/src/zapNetUtils.cpp @@ -14,7 +14,7 @@ * The Original Code is the Mozilla SIP client project. * * The Initial Developer of the Original Code is 8x8 Inc. - * Portions created by the Initial Developer are Copyright (C) 2005 + * Portions created by the Initial Developer are Copyright (C) 2005-2008 * the Initial Developer. All Rights Reserved. * * Contributor(s): @@ -43,16 +43,62 @@ #include "nsComponentManagerUtils.h" #include "nsIDNSService.h" #include "nsIDNSRecord.h" +#include "zapNetItfAddress.h" +#include "nsAutoPtr.h" +#include "nsMemory.h" + +#ifdef XP_WIN +#include "zapNetHelpersWin.h" +#else +#include +#include +#include +#include +#endif + +//////////////////////////////////////////////////////////////////////// +// helpers + +// XXX something like this should be in NSPR +static PRBool sockaddr_to_prnetaddr(const struct sockaddr *sa, PRNetAddr *pa) +{ + if (!sa) { + NS_WARNING("Null socket"); + return PR_FALSE; + } + + switch (sa->sa_family) { + case AF_INET: + memcpy(pa, sa, sizeof(struct sockaddr_in)); + pa->raw.family = PR_AF_INET; + break; + case AF_INET6: + memcpy(pa, sa, sizeof(struct sockaddr_in6)); + pa->raw.family = PR_AF_INET6; + break; + default: + NS_WARNING("Unsupported address family"); + return PR_FALSE; + } + return PR_TRUE; +} + //////////////////////////////////////////////////////////////////////// // zapNetUtils zapNetUtils::zapNetUtils() { +#ifdef XP_WIN + InitNetHelpersWin(); +#endif } zapNetUtils::~zapNetUtils() { +#ifdef XP_WIN + FreeNetHelpersWin(); +#endif } //---------------------------------------------------------------------- @@ -161,18 +207,6 @@ zapNetUtils::ResolveMappedAddress(zapIStunAddressResolveListener *listener, cons } -#ifdef XP_UNIX -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif - /* ACString getPrimaryHostAddress(); */ NS_IMETHODIMP zapNetUtils::GetPrimaryHostAddress(nsACString & retval) @@ -208,3 +242,64 @@ zapNetUtils::GetPrimaryHostAddress(nsACString & retval) return NS_OK; } + +/* void getNetItfAddresses (out unsigned long count, [array, size_is (count), retval] out zapINetItfAddress results); */ +NS_IMETHODIMP +zapNetUtils::GetNetItfAddresses(PRUint32 *count, zapINetItfAddress ***results) +{ + *count = 0; + *results = nsnull; + + nsCOMArray addrs; + nsresult rv = GetNetItfAddressesCOMArray(&addrs); + NS_ENSURE_SUCCESS(rv, rv); + if (addrs.Count() == 0) return NS_OK; + + *results = static_cast(nsMemory::Alloc(sizeof(zapINetItfAddress*) * addrs.Count())); + NS_ENSURE_TRUE(*results, NS_ERROR_OUT_OF_MEMORY); + + *count = addrs.Count(); + for (int i=0; i<*count; ++i) { + NS_ADDREF((*results)[i] = addrs[i]); + } + + return NS_OK; +} + +/* [noscript] void getNetItfAddressesCOMArray (in NetItfAddrArray results); */ +NS_IMETHODIMP +zapNetUtils::GetNetItfAddressesCOMArray(nsCOMArray * results) +{ + results->Clear(); + + struct ifaddrs *addrs; + if (getifaddrs(&addrs) < 0) + return NS_ERROR_FAILURE; + + nsresult rv = NS_ERROR_OUT_OF_MEMORY; + struct ifaddrs *p = addrs; + while (p) { + struct ifaddrs *c = p; + p = c->ifa_next; + + nsRefPtr nia = new zapNetItfAddress(); + if (!nia) goto bail; + if (!sockaddr_to_prnetaddr(c->ifa_addr, &nia->mNetAddr)) { + // unsupported address family -> skip + continue; + } + nia->mItfName = c->ifa_name; + nia->mFlags = c->ifa_flags; + + if (!results->AppendObject(static_cast(nia))) goto bail; + } + + // success! + rv = NS_OK; + // fall through to clean up addrs + + bail: + freeifaddrs(addrs); + + return rv; +}