API for enumerating IP addresses of local network interfaces.

git-svn-id: svn://10.0.0.236/branches/ZAP_20050610_BRANCH@252386 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
alex%croczilla.com
2008-06-16 22:05:08 +00:00
parent 06312a1551
commit fbb5c4ff09
8 changed files with 703 additions and 21 deletions

View File

@@ -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 = \

View File

@@ -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 <alex@croczilla.com> (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;
};

View File

@@ -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<zapINetItfAddress>);
/**
* \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++

View File

@@ -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 <alex@croczilla.com> (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 <iphlpapi.h>
#include "prlink.h"
#include "nsDebug.h"
#include <stdlib.h>
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);
}
}

View File

@@ -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 <alex@croczilla.com> (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 <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
//----------------------------------------------------------------------
// 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__

View File

@@ -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 <alex@croczilla.com> (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 <ws2tcpip.h>
#else
#include <net/if.h>
#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;
}

View File

@@ -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 <alex@croczilla.com> (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__

View File

@@ -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 <sys/ioctl.h>
#include <net/if.h>
#include <netdb.h>
#include <ifaddrs.h>
#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 <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <net/if.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#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<zapINetItfAddress> addrs;
nsresult rv = GetNetItfAddressesCOMArray(&addrs);
NS_ENSURE_SUCCESS(rv, rv);
if (addrs.Count() == 0) return NS_OK;
*results = static_cast<zapINetItfAddress**>(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<zapINetItfAddress> * 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<zapNetItfAddress> 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<zapINetItfAddress*>(nia))) goto bail;
}
// success!
rv = NS_OK;
// fall through to clean up addrs
bail:
freeifaddrs(addrs);
return rv;
}