diff --git a/lib/native/freebsd-64/libhwaddressretriever.so b/lib/native/freebsd-64/libhwaddressretriever.so
new file mode 100755
index 000000000..cd1813cf6
Binary files /dev/null and b/lib/native/freebsd-64/libhwaddressretriever.so differ
diff --git a/lib/native/freebsd/libhwaddressretriever.so b/lib/native/freebsd/libhwaddressretriever.so
new file mode 100755
index 000000000..c48366b0f
Binary files /dev/null and b/lib/native/freebsd/libhwaddressretriever.so differ
diff --git a/lib/native/linux-64/libhwaddressretriever.so b/lib/native/linux-64/libhwaddressretriever.so
new file mode 100755
index 000000000..e7882609a
Binary files /dev/null and b/lib/native/linux-64/libhwaddressretriever.so differ
diff --git a/lib/native/linux/libhwaddressretriever.so b/lib/native/linux/libhwaddressretriever.so
new file mode 100755
index 000000000..09574a082
Binary files /dev/null and b/lib/native/linux/libhwaddressretriever.so differ
diff --git a/lib/native/mac/libhwaddressretriever.jnilib b/lib/native/mac/libhwaddressretriever.jnilib
new file mode 100755
index 000000000..bbfba5e1d
Binary files /dev/null and b/lib/native/mac/libhwaddressretriever.jnilib differ
diff --git a/lib/native/windows-64/hwaddressretriever.dll b/lib/native/windows-64/hwaddressretriever.dll
new file mode 100755
index 000000000..8f29f8fea
Binary files /dev/null and b/lib/native/windows-64/hwaddressretriever.dll differ
diff --git a/lib/native/windows/hwaddressretriever.dll b/lib/native/windows/hwaddressretriever.dll
new file mode 100755
index 000000000..35f20b29e
Binary files /dev/null and b/lib/native/windows/hwaddressretriever.dll differ
diff --git a/src/native/build.xml b/src/native/build.xml
index 3b5dff4d7..fe5d08d9f 100644
--- a/src/native/build.xml
+++ b/src/native/build.xml
@@ -468,6 +468,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -654,6 +708,7 @@
+
diff --git a/src/native/hwaddressretriever/HardwareAddressRetriever.h b/src/native/hwaddressretriever/HardwareAddressRetriever.h
new file mode 100644
index 000000000..48a12b166
--- /dev/null
+++ b/src/native/hwaddressretriever/HardwareAddressRetriever.h
@@ -0,0 +1,30 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+/**
+ * \file HardwareAddressRetriever.h
+ * \brief Hardware address retriever.
+ * \author Sebastien Vincent
+ * \date 2010
+ */
+
+#ifndef HARDWARE_ADDRESS_RETRIEVER_H
+#define HARDWARE_ADDRESS_RETRIEVER_H
+
+#include
+
+/**
+ * \brief Returns the hardware address for the specified interface.
+ * \param env JNI environment
+ * \param ifName name of the interface that we want to get the hardware address
+ * \return byte array representing hardware address or NULL if not found or
+ * system related errors happen.
+ */
+jbyteArray getHardwareAddress(JNIEnv* env, jstring ifName);
+
+#endif /* HARDWARE_ADDRESS_RETRIEVER_H */
+
diff --git a/src/native/hwaddressretriever/HardwareAddressRetriever_unix.c b/src/native/hwaddressretriever/HardwareAddressRetriever_unix.c
new file mode 100644
index 000000000..f4a79ea12
--- /dev/null
+++ b/src/native/hwaddressretriever/HardwareAddressRetriever_unix.c
@@ -0,0 +1,124 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+/**
+ * \file HardwareAddressRetriever_unix.c
+ * \brief Hardware address retriever (Unix specific code).
+ * \author Sebastien Vincent
+ * \date 2010
+ */
+
+#if !defined(_WIN32) && !defined(_WIN64)
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+
+#if defined(__FreeBSD__) || defined(__APPLE__)
+#include
+#include
+#include
+#include
+#endif
+
+#include "HardwareAddressRetriever.h"
+
+jbyteArray getHardwareAddress(JNIEnv* env, jstring ifName)
+{
+ int sock = -1;
+ struct ifreq ifr;
+ jbyteArray hwaddr = NULL;
+ char* name = NULL;
+ jbyte* addr = NULL;
+ int hwlen = 6;
+
+ name = (char*)(*env)->GetStringUTFChars(env, ifName, NULL);
+
+ if(!name)
+ {
+ return NULL;
+ }
+
+#ifdef __linux__
+
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+
+ if(sock == -1)
+ {
+ (*env)->ReleaseStringUTFChars(env, ifName, name);
+ return NULL;
+ }
+
+ memset(&ifr, 0x00, sizeof(struct ifreq));
+
+ strncpy(ifr.ifr_name, name, IFNAMSIZ - 1);
+ ifr.ifr_name[IFNAMSIZ - 1] = 0x00;
+
+ if(ioctl(sock, SIOCGIFHWADDR, &ifr) != 0)
+ {
+ (*env)->ReleaseStringUTFChars(env, ifName, name);
+ close(sock);
+ return NULL;
+ }
+
+ close(sock);
+ addr = (const jbyte*)ifr.ifr_hwaddr.sa_data;
+
+#else /* BSD like */
+
+ struct ifaddrs* addrs = NULL;
+ struct ifaddrs* ifa = NULL;
+ jbyte buf[hwlen];
+
+ if(getifaddrs(&addrs) != -1)
+ {
+ for(ifa = addrs ; ifa != NULL ; ifa = ifa->ifa_next)
+ {
+ if(ifa->ifa_addr->sa_family == AF_LINK && !strcmp(ifa->ifa_name, name))
+ {
+ struct sockaddr_dl* sdl = (struct sockaddr_dl*)ifa->ifa_addr;
+
+ if(sdl->sdl_type == IFT_ETHER)
+ {
+ memcpy(buf, LLADDR(sdl), hwlen);
+ addr = buf;
+ break;
+ }
+ }
+ }
+
+ freeifaddrs(addrs);
+ }
+
+#endif
+
+ if(addr)
+ {
+ hwaddr = (*env)->NewByteArray(env, hwlen);
+
+ if(hwaddr)
+ {
+ /* copy the hardware address and return it */
+ (*env)->SetByteArrayRegion(env, hwaddr, 0, hwlen, addr);
+ }
+ }
+
+ /* cleanup */
+ (*env)->ReleaseStringUTFChars(env, ifName, name);
+ return hwaddr;
+}
+
+#endif
+
diff --git a/src/native/hwaddressretriever/HardwareAddressRetriever_win.c b/src/native/hwaddressretriever/HardwareAddressRetriever_win.c
new file mode 100644
index 000000000..384cab090
--- /dev/null
+++ b/src/native/hwaddressretriever/HardwareAddressRetriever_win.c
@@ -0,0 +1,125 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+/**
+ * \file HardwareAddressRetriever_win.c
+ * \brief Hardware address retriever (Windows specific code).
+ * \author Sebastien Vincent
+ * \date 2010
+ */
+
+#if defined(_WIN32) || defined(_WIN64)
+
+/**
+ * \def WIN32_LEAN_AND_MEAN
+ * \brief Exclude not commonly used headers from win32 API.
+ *
+ * It excludes some unused stuff from windows headers and
+ * by the way code compiles faster.
+ */
+#define WIN32_LEAN_AND_MEAN
+
+#include
+#include
+
+#include
+#include
+
+#include "HardwareAddressRetriever.h"
+
+jbyteArray getHardwareAddress(JNIEnv* env, jstring ifName)
+{
+ MIB_IFTABLE* ifTable = NULL;
+ ULONG size = 15000;
+ int found = 0;
+ jbyteArray hwaddr = NULL;
+ DWORD ret = 0;
+ DWORD i = 0;
+ WCHAR* wname = NULL;
+ MIB_IFROW ifi;
+ jclass clazz = (*env)->GetObjectClass(env, ifName);
+ jmethodID method = (*env)->GetMethodID(env, clazz, "compareTo", "(Ljava/lang/String;)I");
+
+ if(method == NULL)
+ {
+ return NULL;
+ }
+
+ memset(&ifi, 0x00, sizeof(MIB_IFROW));
+
+ do
+ {
+ ifTable = malloc(size);
+
+ if(!ifTable)
+ {
+ /* out of memory */
+ return NULL;
+ }
+
+ ret = GetIfTable(ifTable, &size, 1);
+
+ }while(ret == ERROR_INSUFFICIENT_BUFFER);
+
+ if(ret != ERROR_SUCCESS)
+ {
+ free(ifTable);
+ return NULL;
+ }
+
+ for(i = 0 ; i < ifTable->dwNumEntries ; i++)
+ {
+ jstring tmp = NULL;
+ ifi = ifTable->table[i];
+
+ if(ifi.dwType == IF_TYPE_OTHER)
+ {
+ continue;
+ }
+
+ /* jstring created by NewStringUTF will be garbage collected at
+ * the end of the function
+ */
+ tmp = (*env)->NewStringUTF(env, ifi.bDescr);
+
+ if(!tmp)
+ {
+ /* printf("error\n"); */
+ continue;
+ }
+
+ if((*env)->CallIntMethod(env, ifName, method, tmp) == 0)
+ {
+ found = 1;
+ break;
+ }
+ }
+
+ if(found)
+ {
+ DWORD hwlen = ifi.dwPhysAddrLen;
+
+ if(hwlen > 0)
+ {
+ hwaddr = (*env)->NewByteArray(env, hwlen);
+
+ if(hwaddr)
+ {
+ /* copy the hardware address and return it */
+ (*env)->SetByteArrayRegion(env, hwaddr, 0, hwlen, ifi.bPhysAddr);
+ }
+ }
+ }
+
+ /* cleanup */
+ free(ifTable);
+
+ return hwaddr;
+}
+
+#endif
+
diff --git a/src/native/hwaddressretriever/net_java_sip_communicator_impl_netaddr_HardwareAddressRetriever.c b/src/native/hwaddressretriever/net_java_sip_communicator_impl_netaddr_HardwareAddressRetriever.c
new file mode 100644
index 000000000..5e8d94408
--- /dev/null
+++ b/src/native/hwaddressretriever/net_java_sip_communicator_impl_netaddr_HardwareAddressRetriever.c
@@ -0,0 +1,35 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+/**
+ * \file net_java_sip_communicator_impl_netaddr_HardwareAddressRetriever.h
+ * \brief Hardware address retriever.
+ * \author Sebastien Vincent
+ * \date 2010
+ */
+
+#include
+#include
+
+#include
+
+#include "HardwareAddressRetriever.h"
+
+/**
+ * \brief Returns the byte array representing hardware address.
+ * \param env JVM environment
+ * \param clazz Java class
+ * \param ifName name of the interface
+ * \return byte array representing the hardware address or NULL if anything
+ * goes wrong
+ */
+JNIEXPORT jbyteArray JNICALL Java_net_java_sip_communicator_impl_netaddr_HardwareAddressRetriever_getHardwareAddress
+ (JNIEnv* env, jclass clazz, jstring ifName)
+{
+ return getHardwareAddress(env, ifName);
+}
+
diff --git a/src/native/hwaddressretriever/net_java_sip_communicator_impl_netaddr_HardwareAddressRetriever.h b/src/native/hwaddressretriever/net_java_sip_communicator_impl_netaddr_HardwareAddressRetriever.h
new file mode 100644
index 000000000..528674185
--- /dev/null
+++ b/src/native/hwaddressretriever/net_java_sip_communicator_impl_netaddr_HardwareAddressRetriever.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class net_java_sip_communicator_impl_netaddr_HardwareAddressRetriever */
+
+#ifndef _Included_net_java_sip_communicator_impl_netaddr_HardwareAddressRetriever
+#define _Included_net_java_sip_communicator_impl_netaddr_HardwareAddressRetriever
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: net_java_sip_communicator_impl_netaddr_HardwareAddressRetriever
+ * Method: getHardwareAddress
+ * Signature: (Ljava/lang/String;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_net_java_sip_communicator_impl_netaddr_HardwareAddressRetriever_getHardwareAddress
+ (JNIEnv *, jclass, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/net/java/sip/communicator/impl/netaddr/HardwareAddressRetriever.java b/src/net/java/sip/communicator/impl/netaddr/HardwareAddressRetriever.java
new file mode 100644
index 000000000..823342582
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/netaddr/HardwareAddressRetriever.java
@@ -0,0 +1,33 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.netaddr;
+
+/**
+ * Class to retrieve hardware address of a specific interface.
+ *
+ * We know that starting Java 6, NetworkInterface has getHardwareAddress method
+ * but as we still support Java 5 we have to do it ourself.
+ *
+ * @author Sebastien Vincent
+ */
+public class HardwareAddressRetriever
+{
+ /* load library */
+ static
+ {
+ System.loadLibrary("hwaddressretriever");
+ }
+
+ /**
+ * Returns the hardware address of a particular interface.
+ *
+ * @param ifName name of the interface
+ * @return byte array representing the hardware address of the interface or
+ * null if interface is not found or other system related errors
+ */
+ public static native byte[] getHardwareAddress(String ifName);
+}
diff --git a/src/net/java/sip/communicator/impl/netaddr/NetworkAddressManagerServiceImpl.java b/src/net/java/sip/communicator/impl/netaddr/NetworkAddressManagerServiceImpl.java
index 11cbcab04..042a7d806 100644
--- a/src/net/java/sip/communicator/impl/netaddr/NetworkAddressManagerServiceImpl.java
+++ b/src/net/java/sip/communicator/impl/netaddr/NetworkAddressManagerServiceImpl.java
@@ -6,6 +6,7 @@
*/
package net.java.sip.communicator.impl.netaddr;
+import java.lang.reflect.*;
import java.beans.*;
import java.io.*;
import java.net.*;
@@ -119,7 +120,8 @@ public void stop()
* @return an InetAddress instance representing the local host, and that
* a socket can bind upon or distribute to peers as a contact address.
*/
- public synchronized InetAddress getLocalHost(InetAddress intendedDestination)
+ public synchronized InetAddress getLocalHost(
+ InetAddress intendedDestination)
{
InetAddress localHost = null;
String osVersion = System.getProperty("os.version");
@@ -128,18 +130,20 @@ public synchronized InetAddress getLocalHost(InetAddress intendedDestination)
logger.trace(
"Querying a localhost addr for dst=" + intendedDestination);
- /* use native code (JNI) to find source address for a specific destination
- * address on Windows XP SP1 and over.
+ /* use native code (JNI) to find source address for a specific
+ * destination address on Windows XP SP1 and over.
*
* For other systems, we used method based on DatagramSocket.connect
* which will returns us source address. The reason why we cannot use it
- * on Windows is because its socket implementation returns the any address...
+ * on Windows is because its socket implementation returns the any
+ * address...
*/
if(OSUtils.IS_WINDOWS &&
!osVersion.startsWith("4") && /* 95/98/Me/NT */
!osVersion.startsWith("5.0")) /* 2000 */
{
- byte[] src = Win32LocalhostRetriever.getSourceForDestination(intendedDestination.getAddress());
+ byte[] src = Win32LocalhostRetriever.getSourceForDestination(
+ intendedDestination.getAddress());
if(src == null)
{
@@ -160,7 +164,8 @@ public synchronized InetAddress getLocalHost(InetAddress intendedDestination)
else
{
- //no point in making sure that the localHostFinderSocket is initialized.
+ //no point in making sure that the localHostFinderSocket is
+ //initialized.
//better let it through a NullPointerException.
localHostFinderSocket.connect(intendedDestination,
RANDOM_ADDR_DISC_PORT);
@@ -235,8 +240,8 @@ public synchronized InetAddress getLocalHost(InetAddress intendedDestination)
if (!(localHost instanceof Inet4Address))
{
// return the first non localhost interface we find.
- Enumeration interfaces = NetworkInterface
- .getNetworkInterfaces();
+ Enumeration interfaces =
+ NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements())
{
@@ -278,6 +283,51 @@ public synchronized InetAddress getLocalHost(InetAddress intendedDestination)
return localHost;
}
+ /**
+ * Returns the hardware address (i.e. MAC address) of the specified
+ * interface name.
+ *
+ * @param iface the NetworkInterface
+ * @return array of bytes representing the layer 2 address or null if
+ * interface does not exist
+ */
+ public byte[] getHardwareAddress(NetworkInterface iface)
+ {
+ String ifName = null;
+ byte hwAddress[] = null;
+
+ /* try reflection */
+ try
+ {
+ Method method = iface.getClass().
+ getMethod("getHardwareAddress");
+
+ if(method != null)
+ {
+ hwAddress = (byte[])method.invoke(iface, new Object[]{});
+ return hwAddress;
+ }
+ }
+ catch(Exception e)
+ {
+ }
+
+ /* maybe getHardwareAddress not available on this JVM try
+ * with our JNI
+ */
+ if(OSUtils.IS_WINDOWS)
+ {
+ ifName = iface.getDisplayName();
+ }
+ else
+ {
+ ifName = iface.getName();
+ }
+
+ hwAddress = HardwareAddressRetriever.getHardwareAddress(ifName);
+
+ return hwAddress;
+ }
/**
* Tries to obtain an for the specified port.
@@ -556,8 +606,8 @@ public StunCandidateHarvester discoverStunServer(String domainName,
if(srvrAddress != null)
{
- //yay! we seem to have a TURN server, so we'll be using it for both
- //TURN and STUN harvesting.
+ //yay! we seem to have a TURN server, so we'll be using it for
+ //both TURN and STUN harvesting.
return new TurnCandidateHarvester(
new TransportAddress(srvrAddress, Transport.UDP),
new LongTermCredential(userName, password));
diff --git a/src/net/java/sip/communicator/service/netaddr/NetworkAddressManagerService.java b/src/net/java/sip/communicator/service/netaddr/NetworkAddressManagerService.java
index 0893e33a6..90737e412 100644
--- a/src/net/java/sip/communicator/service/netaddr/NetworkAddressManagerService.java
+++ b/src/net/java/sip/communicator/service/netaddr/NetworkAddressManagerService.java
@@ -7,7 +7,6 @@
package net.java.sip.communicator.service.netaddr;
import java.net.*;
-import java.text.*;
import java.io.*;
import org.ice4j.ice.*;
@@ -90,6 +89,15 @@ public InetSocketAddress getPublicAddressFor(
throws IOException,
BindException;
+ /**
+ * Returns the hardware address (i.e. MAC address) of the specified
+ * interface name.
+ *
+ * @param iface the NetworkInterface
+ * @return array of bytes representing the layer 2 address
+ */
+ public byte[] getHardwareAddress(NetworkInterface iface);
+
/**
* Creates a DatagramSocket and binds it to on the specified
* localAddress and a port in the range specified by the