harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From telli...@apache.org
Subject svn commit: r547205 [1/2] - in /harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni: shared/netif.c unix/exports.txt unix/helpers.c unix/helpers.h windows/helpers.c windows/helpers.h
Date Thu, 14 Jun 2007 10:33:21 GMT
Author: tellison
Date: Thu Jun 14 03:33:19 2007
New Revision: 547205

URL: http://svn.apache.org/viewvc?view=rev&rev=547205
Log:
Apply patch HARMONY-4155 ([classlib][luni][java6] Modify Net native code for java.net.NetworkInterface)

Modified:
    harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/shared/netif.c
    harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/exports.txt
    harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.c
    harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.h
    harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/helpers.c
    harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/helpers.h

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/shared/netif.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/shared/netif.c?view=diff&rev=547205&r1=547204&r2=547205
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/shared/netif.c (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/shared/netif.c Thu Jun 14 03:33:19 2007
@@ -1,19 +1,19 @@
 /*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (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.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
+*  Licensed to the Apache Software Foundation (ASF) under one or more
+*  contributor license agreements.  See the NOTICE file distributed with
+*  this work for additional information regarding copyright ownership.
+*  The ASF licenses this file to You under the Apache License, Version 2.0
+*  (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.apache.org/licenses/LICENSE-2.0
+*
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*  See the License for the specific language governing permissions and
+*  limitations under the License.
+*/
 
 #include "nethelp.h"
 #include "jclprots.h"
@@ -21,194 +21,1394 @@
 #include "harmonyglob.h"
 #include "hysock.h"
 
+#if (defined(WIN32))
+#include <Winsock2.h>
+#include <ws2tcpip.h>
+#include <Iphlpapi.h>
+#include <windows.h>
+#else
+#include <sys/socket.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <stdio.h>
+#include <arpa/inet.h>
+#endif
 /**
- * Answer an array of NetworkInterface objects.  One for each network interface within the system
- *
- * @param	env	pointer to the JNI library
- * @param	clazz	the class of the object invoking the JNI function
- *
- * @return			an array of NetworkInterface objects of length 0 or more
- */
+* Answer an array of NetworkInterface objects.  One for each network interface within the system
+*
+* @param	env	pointer to the JNI library
+* @param	clazz	the class of the object invoking the JNI function
+*
+* @return			an array of NetworkInterface objects of length 0 or more
+*/
+
+#if defined(WIN32)
+typedef CRITICAL_SECTION MUTEX;
+typedef struct HyPortControlData
+{
+	UDATA sig_flags;
+	UDATA shmem_group_perm;
+} HyPortControlData;
+typedef struct HyNLSDataCache
+{
+	char *baseCatalogPaths[4];
+	UDATA nPaths;
+	char *baseCatalogName;
+	char *baseCatalogExtension;
+	char *catalog;
+	char language[4];
+	char region[4];
+	char variant[32];
+	struct HyThreadMonitor *monitor;
+	struct HyNLSHashEntry *hash_buckets[256];
+	struct HyNLSHashEntry *old_hashEntries;
+} HyNLSDataCache;
+typedef struct HyPortLibraryGlobalData
+{
+	struct HyPortControlData control;
+	struct HyNLSDataCache nls_data;
+	hythread_tls_key_t tls_key;
+	MUTEX tls_mutex;
+	void *buffer_list;
+	struct HyPortPlatformGlobals platformGlobals;
+} HyPortLibraryGlobalData;
+
+
+#define LOOP_BACK_NUM_ADDRESSES   1
+typedef DWORD (WINAPI * GetAdaptersAddressesFunctionAddress) (ULONG, DWORD,
+															  PVOID,
+															  PIP_ADAPTER_ADDRESSES,
+															  PULONG);
+
+#if (UT_TRACE_OVERHEAD>=1)
+#define Trc_PRT_mem_hymem_allocate_memory_Entry(P1) do { \
+	if ((unsigned char) hyprt_UtActive[96] != 0){ \
+	hyprt_UtModuleInfo.intf->Trace((void *)NULL, &hyprt_UtModuleInfo, ((96 << 8) | hyprt_UtActive[96]), "\4", P1);} \
+} while(0)
+#else
+#define Trc_PRT_mem_hymem_allocate_memory_Entry(P1)     /* tracepoint name: hyprt.96 */
+#endif
+
+#if (UT_TRACE_OVERHEAD>=1)
+#define Trc_PRT_mem_hymem_allocate_memory_Exit(P1) do { \
+	if ((unsigned char) hyprt_UtActive[97] != 0){ \
+	hyprt_UtModuleInfo.intf->Trace((void *)NULL, &hyprt_UtModuleInfo, ((97 << 8) | hyprt_UtActive[97]), "\6", P1);} \
+} while(0)
+#else
+#define Trc_PRT_mem_hymem_allocate_memory_Exit(P1)      /* tracepoint name: hyprt.97 */
+#endif
+#endif
+
+#define LOOP_BACK_NAME            "loopback"
+#define LOOP_BACK_DISPLAY_NAME    "loopback interface"
+#define LOOP_BACK_IPV4_ADDRESS    "127.0.0.1"
+#define LOOP_BACK_NUM_ADDRESSES   1
 
 JNIEXPORT jobjectArray JNICALL
 Java_java_net_NetworkInterface_getNetworkInterfacesImpl (JNIEnv * env,
-                                                         jclass clazz)
+														 jclass clazz)
 {
-  /* variables to store network interfac edata returned by call to port library */
-  struct hyNetworkInterfaceArray_struct networkInterfaceArray;
-  I_32 result = 0;
-
-  /* variables for class and method objects needed to create bridge to java */
-  jclass networkInterfaceClass = NULL;
-  jclass inetAddressClass = NULL;
-  jclass utilClass = NULL;
-  jmethodID methodID = NULL;
-  jmethodID utilMid = NULL;
-
-  /* JNI objects used to return values from native call */
-  jstring name = NULL;
-  jstring displayName = NULL;
-  jobjectArray addresses = NULL;
-  jobjectArray networkInterfaces = NULL;
-  jbyteArray bytearray = NULL;
-
-  /* jobjects used to build the object arrays returned */
-  jobject currentInterface = NULL;
-  jobject element = NULL;
-
-  /* misc variables needed for looping and determining inetAddress info */
-  U_32 i = 0;
-  U_32 j = 0;
-  U_32 nameLength = 0;
-
-  /* required call if we are going to call port library methods */
-  PORT_ACCESS_FROM_ENV (env);
-
-  /* get the classes and methods that we need for later calls */
-  networkInterfaceClass =
-    (*env)->FindClass (env, "java/net/NetworkInterface");
-  if (networkInterfaceClass == NULL)
-    {
-      throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
-      return NULL;
-    }
 
-  inetAddressClass = (*env)->FindClass (env, "java/net/InetAddress");
-  if (inetAddressClass == NULL)
+	/* variables to store network interface data returned by call to port library */
+	struct hyNetworkInterfaceArray_struct networkInterfaceArray;
+	struct hyNetworkInterface_struct *interfaces = NULL;
+
+	U_32 currentAdapterIndex = 0;
+  	U_32 counter  = 0;
+  	U_32 counter2 = 0;
+  	U_32 numAddresses = 0;
+  	U_32 currentIPAddressIndex = 0;
+  	I_32 numAdapters = 0;
+	int len = 0;
+	int socketP = 0;
+	U_32 totalInterfaces = 0;
+	I_32 err = 0;
+
+	/* variables for class and method objects needed to create bridge to java */
+	jclass networkInterfaceClass = NULL;
+	jclass inetAddressClass = NULL;
+	jclass utilClass = NULL;
+	jmethodID methodID = NULL;
+	jmethodID utilMid = NULL;
+
+	/* JNI objects used to return values from native call */
+	jstring name = NULL;
+	jstring displayName = NULL;
+	jobjectArray addresses = NULL;
+	jobjectArray networkInterfaces = NULL;
+	jbyteArray bytearray = NULL;
+
+	/* jobjects used to build the object arrays returned */
+	jobject currentInterface = NULL;
+	jobject element = NULL;
+
+	/* misc variables needed for looping and determining inetAddress info */
+	U_32 i = 0;
+	U_32 j = 0;
+	U_32 nameLen = 0;
+
+#if defined(WIN32)
+	DWORD returnVal = 0;
+	ULONG bufferLength = 0;
+	U_32 pseudoLoopbackFound = 0;
+	U_32 numLoopbackAddresses = LOOP_BACK_NUM_ADDRESSES;
+	int ethIndex = 0;
+	int tunIndex = 0;
+	GetAdaptersAddressesFunctionAddress getAdaptersAddresses_functionAddress =
+		NULL;
+	HINSTANCE libInstance = NULL;
+	I_32 result = 0;
+#else
+	struct ifreq reqCopy;
+	struct ifconf ifc;
+	int ifconfCommand = SIOCGIFCONF;
+	char * lastName;
+#endif
+	/* required call if we are going to call port library methods */
+	PORT_ACCESS_FROM_ENV (env);
+	HyPortLibrary * portLibrary = privatePortLibrary; 
+
+	networkInterfaceArray.length = 0;
+	networkInterfaceArray.elements = NULL;
+
+	/* get the classes and methods that we need for later calls */
+	networkInterfaceClass =
+		(*env)->FindClass (env, "java/net/NetworkInterface");
+	if (networkInterfaceClass == NULL)
+	{
+		throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
+		return NULL;
+	}
+
+	inetAddressClass = (*env)->FindClass (env, "java/net/InetAddress");
+	if (inetAddressClass == NULL)
+	{
+		throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
+		return NULL;
+	}
+
+	methodID =
+		(*env)->GetMethodID (env, networkInterfaceClass, "<init>",
+		"(Ljava/lang/String;Ljava/lang/String;[Ljava/net/InetAddress;I)V");
+	if (methodID == NULL)
+	{
+		throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
+		return NULL;
+	}
+
+	utilClass = (*env)->FindClass (env, "org/apache/harmony/luni/util/Util");
+	if (!utilClass)
+	{
+		return NULL;
+	}
+
+	utilMid =
+		((*env)->
+		GetStaticMethodID (env, utilClass, "toString",
+		"([BII)Ljava/lang/String;"));
+	if (!utilMid)
+		return NULL;
+
+#if defined(WIN32)
+
+	/* validate that we were passed the required structure to return network interfaces */
+	if (NULL == &networkInterfaceArray)
+	{
+		result = HYPORT_ERROR_SOCKET_NORECOVERY;
+	}
+	else
+	{
+		/* initialize the structure so that freeing it would not a cause an issue */
+		networkInterfaceArray.length = 0;
+		networkInterfaceArray.elements = NULL;
+	}
+	/* try to load the function that gives us the IPV6 info.  If it is not available on this platform then 
+	* we will default to using the other function which does not give us the IPV6 info but is available on earlier platforms 
+	*/
+	libInstance = LoadLibrary (TEXT ("Iphlpapi"));
+	if (NULL != libInstance)
+	{
+		getAdaptersAddresses_functionAddress =
+			(GetAdaptersAddressesFunctionAddress) GetProcAddress (libInstance,
+			TEXT
+			("GetAdaptersAddresses"));
+	}
+
+	/* only use the function that returns the IPV6 info if we could load the function and we
+	* have not been told to prefer the IPv4 stack */
+	if ((NULL != getAdaptersAddresses_functionAddress) && (!preferIPv4Stack(env)))
+	{
+		/* For the functions to get network interface information that are supported on the
+		* IPV6 platforms, the loopback interface is included in the list */
+
+		IP_ADAPTER_ADDRESSES *adaptersList = NULL;
+		IP_ADAPTER_ADDRESSES *currentAdapter = NULL;
+		IP_ADAPTER_ADDRESSES *tempAdapter = NULL;
+		IP_ADAPTER_UNICAST_ADDRESS *currentIPAddress = NULL;
+
+		/* get the required buffer size and allocate the memory required */
+		returnVal =
+			(getAdaptersAddresses_functionAddress) (AF_UNSPEC,
+			(GAA_FLAG_SKIP_ANYCAST |
+			GAA_FLAG_SKIP_MULTICAST |
+			GAA_FLAG_SKIP_DNS_SERVER),
+			NULL, adaptersList,
+			&bufferLength);
+
+		/* GetAdaptorsInfo fails if there are no adaptors configured,  
+		so just return 0, the structure is allready initialized to 
+		indicate that there are no interfaces */
+		if (returnVal == ERROR_BUFFER_OVERFLOW)
+		{
+			/* this is ok since we did not pass in a buffer */
+		}
+		else
+		{
+			if (libInstance != NULL)
+			{
+				FreeLibrary (libInstance);
+			}
+			result = 0;
+		}
+
+		Trc_PRT_mem_hymem_allocate_memory_Entry (bufferLength);
+		if (bufferLength == 0)
+		{				/* prevent GlobalLock from failing causing allocate to return null */
+			bufferLength = 1;
+		}
+		adaptersList = (IP_ADAPTER_ADDRESSES *)hymem_allocate_memory (bufferLength);
+		Trc_PRT_mem_hymem_allocate_memory_Exit (pointer);
+
+		/* now get the actual adaptor information  and the fill in the hyNetworkInterface_struct */
+		if ((returnVal =
+			(getAdaptersAddresses_functionAddress) (AF_UNSPEC,
+			(GAA_FLAG_SKIP_ANYCAST |
+			GAA_FLAG_SKIP_MULTICAST |
+			GAA_FLAG_SKIP_DNS_SERVER),
+			NULL, adaptersList,
+			&bufferLength) ==
+			ERROR_SUCCESS))
+		{
+
+			/* first get the number of adaptors */
+			currentAdapter = adaptersList;
+			while (currentAdapter)
+			{
+				/* on windows to be compatible we don't return the Loopback Pseudo Interface we just merge its addresses into
+				the loopback interface with the IPv4 loopback address */
+				if (strcmp (currentAdapter->AdapterName, pseudoLoopbackGUID) !=
+					0)
+				{
+					numAdapters = numAdapters + 1;
+				}
+				currentAdapter = currentAdapter->Next;
+			}
+
+			/* now allocate the space for the hyNetworkInterface structs and fill it in */
+			interfaces =
+				portLibrary->mem_allocate_memory (portLibrary,
+				numAdapters *
+				sizeof
+				(hyNetworkInterface_struct));
+
+			/* set up the return stucture */
+			networkInterfaceArray.elements = interfaces;
+			networkInterfaceArray.length = numAdapters;
+
+			currentAdapter = adaptersList;
+			while (currentAdapter)
+			{
+				/* on windows to be compatible we don't return the Loopback Pseudo Interface we just merge
+				* its addresses into the loopback interface with the IPv4 loopback address.  Note the name
+				* should never be null but we do the check to be safe  */
+				if ((currentAdapter->AdapterName != NULL) &&
+					(strcmp (currentAdapter->AdapterName, pseudoLoopbackGUID) !=
+					0))
+				{
+
+					/* set the index for the interface */
+					interfaces[currentAdapterIndex].index =
+						currentAdapter->Ipv6IfIndex == 0? currentAdapter->IfIndex : currentAdapter->Ipv6IfIndex;
+					nameLen = strlen (currentAdapter->AdapterName);
+					interfaces[currentAdapterIndex].name =
+						portLibrary->mem_allocate_memory (portLibrary,
+						nameLen + 1);
+
+					/* get the name and display name for the adapter */
+					switch(currentAdapter->IfType) {
+	case IF_TYPE_SOFTWARE_LOOPBACK:
+		sprintf(interfaces[currentAdapterIndex].name, "lo");
+		break;
+	case IF_TYPE_ETHERNET_CSMACD:
+		sprintf(interfaces[currentAdapterIndex].name, "eth%d", ethIndex++);
+		break;
+	case IF_TYPE_TUNNEL:
+		sprintf(interfaces[currentAdapterIndex].name, "tun%d", tunIndex++);
+		break;
+	default:
+
+		strncpy (interfaces[currentAdapterIndex].name,
+			currentAdapter->AdapterName, nameLen);
+
+		interfaces[currentAdapterIndex].name[nameLen] = 0;
+					}
+
+					nameLen =
+						WideCharToMultiByte (CP_ACP, WC_COMPOSITECHECK,
+						currentAdapter->FriendlyName, -1,
+						NULL, 0, NULL, NULL);
+
+					if (nameLen != 0)
+					{
+						interfaces[currentAdapterIndex].displayName =
+							portLibrary->mem_allocate_memory (portLibrary,
+							nameLen + 1);
+					}
+					else
+					{
+						interfaces[currentAdapterIndex].displayName =
+							portLibrary->mem_allocate_memory (portLibrary, 1);
+						interfaces[currentAdapterIndex].displayName[0] = 0;
+					}
+
+					if (nameLen != 0)
+					{
+						WideCharToMultiByte (CP_ACP, WC_COMPOSITECHECK,
+							currentAdapter->FriendlyName, -1,
+							interfaces[currentAdapterIndex].
+							displayName, nameLen, NULL,
+							NULL);
+						interfaces[currentAdapterIndex].
+							displayName[nameLen] = 0;
+					}
+
+					/* now get the interface information */
+
+					/* first count the number of IP addreses and allocate the memory required
+					* for the ip address info that will be returned */
+					numAddresses = 0;
+					currentIPAddress = currentAdapter->FirstUnicastAddress;
+					while (currentIPAddress)
+					{
+						numAddresses = numAddresses + 1;
+						currentIPAddress = currentIPAddress->Next;
+					}
+
+					/* if this is the loopback address then we need to add the addresses from
+					* the Loopback Pseudo-Interface */
+					pseudoLoopbackFound = 0;
+					if ((NULL != currentAdapter->FirstUnicastAddress) &&
+						(AF_INET ==
+						((struct sockaddr_in *) (currentAdapter->
+						FirstUnicastAddress->Address.
+						lpSockaddr))->sin_family)
+						&& (127 ==
+						((struct sockaddr_in *) (currentAdapter->
+						FirstUnicastAddress->
+						Address.lpSockaddr))->
+						sin_addr.S_un.S_un_b.s_b1))
+					{
+						/* find the pseudo interface and get the first unicast address */
+						tempAdapter = adaptersList;
+						pseudoLoopbackFound = 0;
+						while ((tempAdapter) && (0 == pseudoLoopbackFound))
+						{
+							if (strcmp
+								(tempAdapter->AdapterName,
+								pseudoLoopbackGUID) == 0)
+							{
+								pseudoLoopbackFound = 1;
+							}
+							else
+							{
+								tempAdapter = tempAdapter->Next;
+							}
+						}
+
+						if (1 == pseudoLoopbackFound)
+						{				
+							/* now if we found the adapter add the count for the addresses on it */
+							currentIPAddress = tempAdapter->FirstUnicastAddress;
+							while (currentIPAddress)
+							{
+								numAddresses = numAddresses + 1;
+								currentIPAddress = currentIPAddress->Next;
+							}
+
+							/* also if we found the pseudo interface we must have to use the interface
+							* id associated with this interface */
+							interfaces[currentAdapterIndex].index =
+								tempAdapter->Ipv6IfIndex;
+							//strncpy (interfaces[currentAdapterIndex].name,  "aa", 3);
+						}
+					}
+
+					interfaces[currentAdapterIndex].addresses =
+						portLibrary->mem_allocate_memory (portLibrary,
+						numAddresses *
+						sizeof
+						(hyipAddress_struct));
+
+					interfaces[currentAdapterIndex].numberAddresses =
+						numAddresses;
+
+					/* now get the actual ip address info */
+					currentIPAddressIndex = 0;
+					currentIPAddress = currentAdapter->FirstUnicastAddress;
+					while (currentIPAddress)
+					{
+						if (currentIPAddress->Address.iSockaddrLength ==
+							sizeof (struct sockaddr_in6))
+						{
+							memcpy (interfaces[currentAdapterIndex].
+								addresses[currentIPAddressIndex].addr.bytes,
+								&(((struct sockaddr_in6 *)
+								currentIPAddress->Address.lpSockaddr)->
+								sin6_addr.u.Byte),
+								sizeof (struct in6_addr));
+							interfaces[currentAdapterIndex].
+								addresses[currentIPAddressIndex].length =
+								sizeof (struct in6_addr);
+							interfaces[currentAdapterIndex].
+								addresses[currentIPAddressIndex].scope =
+								((struct sockaddr_in6 *) currentIPAddress->
+								Address.lpSockaddr)->sin6_scope_id;
+						}
+						else if (currentIPAddress->Address.iSockaddrLength ==
+							sizeof (struct sockaddr_in6_old))
+						{
+							memcpy (interfaces[currentAdapterIndex].
+								addresses[currentIPAddressIndex].addr.bytes,
+								&(((struct sockaddr_in6_old *)
+								currentIPAddress->Address.lpSockaddr)->
+								sin6_addr.u.Byte),
+								sizeof (struct in6_addr));
+							interfaces[currentAdapterIndex].
+								addresses[currentIPAddressIndex].length =
+								sizeof (struct in6_addr);
+							interfaces[currentAdapterIndex].
+								addresses[currentIPAddressIndex].scope = 0;
+						}
+						else
+						{
+							interfaces[currentAdapterIndex].
+								addresses[currentIPAddressIndex].addr.inAddr.S_un.
+								S_addr =
+								((struct sockaddr_in *) currentIPAddress->Address.
+								lpSockaddr)->sin_addr.S_un.S_addr;
+							interfaces[currentAdapterIndex].
+								addresses[currentIPAddressIndex].length =
+								sizeof (struct in_addr);
+							interfaces[currentAdapterIndex].
+								addresses[currentIPAddressIndex].scope = 0;
+						}
+
+						currentIPAddress = currentIPAddress->Next;
+						currentIPAddressIndex = currentIPAddressIndex + 1;
+					}
+
+					/* now add in the addresses from the loopback pseudo-interface if appropriate */
+					if (1 == pseudoLoopbackFound)
+					{
+						currentIPAddress = tempAdapter->FirstUnicastAddress;
+						while (currentIPAddress)
+						{
+							if (currentIPAddress->Address.iSockaddrLength ==
+								sizeof (struct sockaddr_in6))
+							{
+								memcpy (interfaces[currentAdapterIndex].
+									addresses[currentIPAddressIndex].addr.
+									bytes,
+									&(((struct sockaddr_in6 *)
+									currentIPAddress->Address.
+									lpSockaddr)->sin6_addr.u.Byte),
+									sizeof (struct in6_addr));
+								interfaces[currentAdapterIndex].
+									addresses[currentIPAddressIndex].length =
+									sizeof (struct in6_addr);
+								interfaces[currentAdapterIndex].
+									addresses[currentIPAddressIndex].scope =
+									((struct sockaddr_in6 *) currentIPAddress->
+									Address.lpSockaddr)->sin6_scope_id;
+							}
+							else if (currentIPAddress->Address.
+								iSockaddrLength ==
+								sizeof (struct sockaddr_in6_old))
+							{
+								memcpy (interfaces[currentAdapterIndex].
+									addresses[currentIPAddressIndex].addr.
+									bytes,
+									&(((struct sockaddr_in6_old *)
+									currentIPAddress->Address.
+									lpSockaddr)->sin6_addr.u.Byte),
+									sizeof (struct in6_addr));
+								interfaces[currentAdapterIndex].
+									addresses[currentIPAddressIndex].length =
+									sizeof (struct in6_addr);
+								interfaces[currentAdapterIndex].
+									addresses[currentIPAddressIndex].scope = 0;
+							}
+							else
+							{
+								interfaces[currentAdapterIndex].
+									addresses[currentIPAddressIndex].addr.inAddr.
+									S_un.S_addr =
+									((struct sockaddr_in *) currentIPAddress->
+									Address.lpSockaddr)->sin_addr.S_un.S_addr;
+								interfaces[currentAdapterIndex].
+									addresses[currentIPAddressIndex].length =
+									sizeof (struct in_addr);
+								interfaces[currentAdapterIndex].
+									addresses[currentIPAddressIndex].scope = 0;
+							}
+
+							currentIPAddress = currentIPAddress->Next;
+							currentIPAddressIndex = currentIPAddressIndex + 1;
+						}
+					}
+					currentAdapterIndex = currentAdapterIndex + 1;
+				}		/* not adaptor to exlude */
+				currentAdapter = currentAdapter->Next;
+			}
+
+			/* free the memory used for the call to the getAdaptorAddresses info call */
+			portLibrary->mem_free_memory (portLibrary, adaptersList);
+
+			/* free the dll we don't need anymore */
+			if (libInstance != NULL)
+			{
+				FreeLibrary (libInstance);
+			}
+
+			/* return OK */
+			result = 0;
+
+		}
+		else
+		{
+			/* GetAdaptorsInfo fails if there are no adaptors configured, so just return 0, the structure is
+			* already initialized to indicate that there are no interfaces */
+
+			/* free the dll we don't need anymore */
+			if (libInstance != NULL)
+			{
+				FreeLibrary (libInstance);
+			}
+
+			if (returnVal == ERROR_BUFFER_OVERFLOW)
+			{
+				result = HYPORT_ERROR_SOCKET_NOBUFFERS;
+			}
+			else
+			{
+				result = 0;
+			}
+		}
+	}
+	else
+
+	{
+		/* For the functions to get network interface information that are supported on the pre- IPV6
+		platforms, the loopback interface is NOT included in the list.  Therefore, we have to add it ourselves */
+
+		IP_ADAPTER_INFO *adaptersList = NULL;
+		IP_ADAPTER_INFO *currentAdapter = NULL;
+		IP_ADDR_STRING *currentIPAddress = NULL;
+
+		/* get the required buffer size and allocate the memory required */
+		returnVal = GetAdaptersInfo (adaptersList, &bufferLength);
+
+		/* GetAdaptorsInfo fails if there are no adaptors configured, so just return 0, the structure is
+		* already initialized to indicate that there are no interfaces */
+		if (returnVal != ERROR_SUCCESS)
+		{
+			if (returnVal == ERROR_NO_DATA)
+			{
+				numAdapters = 0;
+				bufferLength = 0;
+				adaptersList = NULL;
+			}
+			else if (returnVal == ERROR_BUFFER_OVERFLOW)
+			{
+				/*  this is ok since we did not pass in a buffer */
+			}
+			else
+			{
+				result = HYPORT_ERROR_SOCKET_NORECOVERY;
+			}
+		}
+
+		if (bufferLength != 0)
+		{
+			adaptersList =
+				(IP_ADAPTER_INFO *) portLibrary->mem_allocate_memory (portLibrary,
+				bufferLength);
+
+			/* now get the actual adaptor information  and the fill in the hyNetworkInterface_struct */
+			if ((returnVal =
+				GetAdaptersInfo (adaptersList,
+				&bufferLength)) == ERROR_SUCCESS)
+			{
+
+				/* first get the number of adaptors */
+				currentAdapter = adaptersList;
+				while (currentAdapter)
+				{
+					currentAdapter = currentAdapter->Next;
+					numAdapters = numAdapters + 1;
+				}
+			}
+			else
+			{
+				numAdapters = 0;
+				if (returnVal == ERROR_NO_DATA)
+				{
+					bufferLength = 0;
+					adaptersList = NULL;
+				}
+				else if (returnVal == ERROR_BUFFER_OVERFLOW)
+				{
+					result = HYPORT_ERROR_SOCKET_NOBUFFERS;
+				}
+				else
+				{
+					result = HYPORT_ERROR_SOCKET_NORECOVERY;
+				}
+			}
+		}
+
+		/* now allocate the space for the hyNetworkInterface structs and fill it in */
+		/* allow space for one more than was returned as the system call does not include the loopback interface
+		which we must add */
+		interfaces =
+			portLibrary->mem_allocate_memory (portLibrary,
+			(numAdapters +
+			1) *
+			sizeof (hyNetworkInterface_struct));
+
+		// set up the return stucture
+		networkInterfaceArray.elements = interfaces;
+		networkInterfaceArray.length = numAdapters + 1;
+		currentAdapter = adaptersList;
+		while (currentAdapter)
+		{
+			/* set the index to 0 as for non-IPV6 we don't fill in this value */
+			interfaces[currentAdapterIndex].index = 0;
+
+			/* get the name and display name for the adapter */
+			nameLen = strlen (currentAdapter->AdapterName);
+			interfaces[currentAdapterIndex].name =
+				portLibrary->mem_allocate_memory (portLibrary, nameLen+1);
+
+			switch(currentAdapter->Type) {
+	case MIB_IF_TYPE_LOOPBACK:
+		sprintf(interfaces[currentAdapterIndex].name, "lo");
+		break;
+	case MIB_IF_TYPE_ETHERNET:
+		sprintf(interfaces[currentAdapterIndex].name, "eth%d", ethIndex++);
+		break;
+		break;
+	default:
+
+		strncpy (interfaces[currentAdapterIndex].name,
+			currentAdapter->AdapterName, nameLen);
+		interfaces[currentAdapterIndex].name[nameLen] = 0;
+			}
+
+			nameLen = strlen (currentAdapter->Description);
+			interfaces[currentAdapterIndex].displayName =
+				portLibrary->mem_allocate_memory (portLibrary, nameLen + 1);
+
+			strncpy (interfaces[currentAdapterIndex].displayName,
+				currentAdapter->Description, nameLen);
+			interfaces[currentAdapterIndex].displayName[nameLen] = 0;
+
+			/* now get the interface information */
+
+			/* first count the number of IP addreses and allocate the memory required for
+			* the ip address info that will be returned */
+			numAddresses = 0;
+			currentIPAddress = &(currentAdapter->IpAddressList);
+			while (currentIPAddress)
+			{
+				/* don't count the any address which seems to be returned as the first address
+				* for interfaces with no addresses */
+				if (inet_addr (currentIPAddress->IpAddress.String) != 0)
+				{
+					numAddresses = numAddresses + 1;
+				}
+				currentIPAddress = currentIPAddress->Next;
+			}
+			interfaces[currentAdapterIndex].addresses =
+				portLibrary->mem_allocate_memory (portLibrary,
+				numAddresses *
+				sizeof (hyipAddress_struct));
+
+			interfaces[currentAdapterIndex].numberAddresses = numAddresses;
+
+			/* now get the actual ip address info */
+			currentIPAddressIndex = 0;
+			currentIPAddress = &(currentAdapter->IpAddressList);
+			while (currentIPAddress)
+			{
+				if (inet_addr (currentIPAddress->IpAddress.String) != 0)
+				{
+					interfaces[currentAdapterIndex].
+						addresses[currentIPAddressIndex].addr.inAddr.S_un.S_addr =
+						inet_addr (currentIPAddress->IpAddress.String);
+					interfaces[currentAdapterIndex].
+						addresses[currentIPAddressIndex].length =
+						sizeof (struct in_addr);
+					interfaces[currentAdapterIndex].
+						addresses[currentIPAddressIndex].scope = 0;
+					currentIPAddressIndex = currentIPAddressIndex + 1;
+				}
+				currentIPAddress = currentIPAddress->Next;
+			}
+
+			currentAdapter = currentAdapter->Next;
+			currentAdapterIndex = currentAdapterIndex + 1;
+		}
+
+		/* now fill in the loopback adaptor */
+		interfaces[currentAdapterIndex].index = 0;
+		nameLen = strlen (LOOP_BACK_NAME);
+
+		interfaces[currentAdapterIndex].name =
+			portLibrary->mem_allocate_memory (portLibrary, nameLen + 1);
+
+		strncpy (interfaces[currentAdapterIndex].name, LOOP_BACK_NAME,
+			nameLen);
+		interfaces[currentAdapterIndex].name[nameLen] = 0;
+
+		nameLen = strlen (LOOP_BACK_DISPLAY_NAME);
+		interfaces[currentAdapterIndex].displayName =
+			portLibrary->mem_allocate_memory (portLibrary, nameLen + 1);
+
+		strncpy (interfaces[currentAdapterIndex].displayName,
+			LOOP_BACK_DISPLAY_NAME, nameLen);
+		interfaces[currentAdapterIndex].displayName[nameLen] = 0;
+
+		/* now get interface information */
+
+		interfaces[currentAdapterIndex].addresses =
+			portLibrary->mem_allocate_memory (portLibrary,
+			numLoopbackAddresses *
+			sizeof (hyipAddress_struct));
+
+		/* now the actual ip address info */
+		interfaces[currentAdapterIndex].numberAddresses = numLoopbackAddresses;
+		interfaces[currentAdapterIndex].addresses[0].addr.inAddr.S_un.S_addr =
+			inet_addr (LOOP_BACK_IPV4_ADDRESS);
+		interfaces[currentAdapterIndex].addresses[0].length =
+			sizeof (struct in_addr);
+		interfaces[currentAdapterIndex].addresses[0].scope = 0;
+
+		/* free the memory used for the call to the getAdaptors info call */
+		if (bufferLength != 0)
+		{
+			portLibrary->mem_free_memory (portLibrary, adaptersList);
+		}
+
+		/* return ok */
+		result = 0;
+	}    
+#else
+  /* first get the list of interfaces.  We do not know how long the buffer needs to be so we try with one that allows for
+     32 interfaces.  If this turns out not to be big enough then we expand the buffer to be able to support another
+     32 interfaces and try again.  We do this until the result indicates that the result fit into the buffer provided */
+  /* we need  socket to do the ioctl so create one */
+  socketP =
+    socket (AF_INET6, SOCK_DGRAM, 0);
+  if (socketP < 0)
     {
       throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
-      return NULL;
+	   return NULL;
     }
 
-  methodID =
-    (*env)->GetMethodID (env, networkInterfaceClass, "<init>",
-                         "(Ljava/lang/String;Ljava/lang/String;[Ljava/net/InetAddress;I)V");
-  if (methodID == NULL)
+  for (;;)
     {
-      throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
-      return NULL;
-    }
-
-  utilClass = (*env)->FindClass (env, "org/apache/harmony/luni/util/Util");
-  if (!utilClass)
-    {
-      return NULL;
+      char *data =
+        (char *) portLibrary->mem_allocate_memory (portLibrary, len);
+#if (defined(VALIDATE_ALLOCATIONS))
+      if (data == NULL)
+        {
+          close (socketP);
+          throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
+			return NULL;
+        }
+#endif
+      ifc.ifc_len = len;
+      ifc.ifc_buf = data;
+      errno = 0;
+      if (ioctl (socketP, ifconfCommand, &ifc) != 0)
+        {
+          err = errno;
+          portLibrary->mem_free_memory (portLibrary, ifc.ifc_buf);
+          close (socketP);
+          throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
+			return NULL;
+        }
+      if (ifc.ifc_len < len)
+        break;
+      /* the returned data was likely truncated, expand the buffer and try again */
+      portLibrary->mem_free_memory (portLibrary, ifc.ifc_buf);
+      len += 32 * sizeof (struct ifreq);
     }
-
-  utilMid =
-    ((*env)->
-     GetStaticMethodID (env, utilClass, "toString",
-                        "([BII)Ljava/lang/String;"));
-  if (!utilMid)
-    return NULL;
-
-  result =
-    hysock_get_network_interfaces (&networkInterfaceArray,
-                                   preferIPv4Stack (env));
-
-  if (result < 0)
+  /* get the number of distinct interfaces */
+  if (ifc.ifc_len != 0)
     {
-      /* this means an error occured.  The value returned is the socket error that should be returned */
-      throwJavaNetSocketException (env, result);
-      return NULL;
+      totalInterfaces = ifc.ifc_len / sizeof (struct ifreq);
     }
 
-  /* now loop through the interfaces and extract the information to be returned */
-  for (j = 0; j < networkInterfaceArray.length; j++)
+  lastName = NULL;
+  for (counter = 0; counter < totalInterfaces; counter++)
     {
-      /* set the name and display name and reset the addresses object array */
-      addresses = NULL;
-      name = NULL;
-      displayName = NULL;
-
-      if (networkInterfaceArray.elements[j].name != NULL)
+      if ((NULL == lastName)
+          || (strncmp (lastName, ifc.ifc_req[counter].ifr_name, IFNAMSIZ) !=
+              0))
         {
-          nameLength = strlen (networkInterfaceArray.elements[j].name);
-          bytearray = (*env)->NewByteArray (env, nameLength);
-          if (bytearray == NULL)
-            {
-              /* NewByteArray should have thrown an exception */
-              return NULL;
-            }
-          (*env)->SetByteArrayRegion (env, bytearray, (jint) 0, nameLength,
-                                      (jbyte *)networkInterfaceArray.elements[j].name);
-          name =
-            (*env)->CallStaticObjectMethod (env, utilClass, utilMid,
-                                            bytearray, (jint) 0, nameLength);
-          if ((*env)->ExceptionCheck (env))
+          /* make sure the interface is up */
+          reqCopy = ifc.ifc_req[counter];
+          ioctl (socketP, SIOCGIFFLAGS, &reqCopy);
+          if ((reqCopy.ifr_flags & IFF_UP) == IFF_UP)
             {
-              return NULL;
+              numAdapters++;
             }
         }
+      lastName = ifc.ifc_req[counter].ifr_name;
+    }
+  /* now allocate the space for the hyNetworkInterface structs and fill it in */
+  interfaces =
+    portLibrary->mem_allocate_memory (portLibrary,
+                                      numAdapters *
+                                      sizeof (hyNetworkInterface_struct));
+#if (defined(VALIDATE_ALLOCATIONS))
+  if (NULL == interfaces)
+    {
+      portLibrary->mem_free_memory (portLibrary, ifc.ifc_buf);
+      close (socketP);
+	   throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
+		return NULL;
+    }
+  /* initialize the structure so that we can free allocated if a failure occurs */
+  for (counter = 0; counter < numAdapters; counter++)
+    {
+      interfaces[counter].name = NULL;
+      interfaces[counter].displayName = NULL;
+      interfaces[counter].addresses = NULL;
+    }
+#endif
 
-      if (networkInterfaceArray.elements[j].displayName != NULL)
+/* set up the return stucture */
+  networkInterfaceArray.elements = interfaces;
+  networkInterfaceArray.length = numAdapters;
+  lastName = NULL;
+  FILE * ipv6 = NULL;
+  for (counter = 0; counter < totalInterfaces; counter++)
+    {
+      /* make sure the interface is still up */
+      reqCopy = ifc.ifc_req[counter];
+      ioctl (socketP, SIOCGIFFLAGS, &reqCopy);
+      if ((reqCopy.ifr_flags & IFF_UP) == IFF_UP)
         {
-          nameLength = strlen (networkInterfaceArray.elements[j].displayName);
-          bytearray = (*env)->NewByteArray (env, nameLength);
-          if (bytearray == NULL)
-            {
-              /* NewByteArray should have thrown an exception */
-              return NULL;
-            }
-          (*env)->SetByteArrayRegion (env, bytearray, (jint) 0, nameLength,
-                                      (jbyte *)networkInterfaceArray.elements[j].
-                                      displayName);
-          displayName =
-            (*env)->CallStaticObjectMethod (env, utilClass, utilMid,
-                                            bytearray, (jint) 0, nameLength);
-          if ((*env)->ExceptionCheck (env))
+          /* since this function can return multiple entries for the same name, only do it for the first one with any given name */
+          if ((NULL == lastName)
+              || (strncmp (lastName, ifc.ifc_req[counter].ifr_name, IFNAMSIZ)
+                  != 0))
             {
-              return NULL;
-            }
-        }
+	           char ifname6[IFNAMSIZ];
+	           int oct6[8];
+	           char addr6[40];
+              int index6 = 0;
+              int scope = 0;
+              int other = 0;
+              /* get the index for the interface.  This is only truely necessary on platforms that support IPV6 */
+#if defined(IPv6_FUNCTION_SUPPORT)
+              interfaces[currentAdapterIndex].index =
+                if_nametoindex (ifc.ifc_req[counter].ifr_name);
+#else
+              interfaces[currentAdapterIndex].index = 0;
+#endif
+/* get the name and display name for the adapter */
+              /* there only seems to be one name so use it for both the name and the display name */
+              nameLen = strlen (ifc.ifc_req[counter].ifr_name);
+              interfaces[currentAdapterIndex].name =
+                portLibrary->mem_allocate_memory (portLibrary,
+                                                  nameLen + 1);
+#if (defined(VALIDATE_ALLOCATIONS))
+              if (NULL == interfaces[currentAdapterIndex].name)
+                {
+                  portLibrary->mem_free_memory (portLibrary, ifc.ifc_buf);
+                  hysock_free_network_interface_struct (portLibrary, networkInterfaceArray);
+                  close (socketP);
+					throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
+					return NULL;
+                }
+#endif
+              strncpy (interfaces[currentAdapterIndex].name,
+                       ifc.ifc_req[counter].ifr_name, nameLen);
+              interfaces[currentAdapterIndex].name[nameLen] = 0;
+              nameLen = strlen (ifc.ifc_req[counter].ifr_name);
+              interfaces[currentAdapterIndex].displayName =
+                portLibrary->mem_allocate_memory (portLibrary,
+                                                  nameLen + 1);
+#if (defined(VALIDATE_ALLOCATIONS))
+              if (NULL == interfaces[currentAdapterIndex].displayName)
+                {
+                  portLibrary->mem_free_memory (portLibrary, ifc.ifc_buf);
+                  hysock_free_network_interface_struct (portLibrary, networkInterfaceArray);
+                  close (socketP);
+					throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
+					return NULL;
+                }
+#endif
+              strncpy (interfaces[currentAdapterIndex].displayName,
+                       ifc.ifc_req[counter].ifr_name, nameLen);
+              interfaces[currentAdapterIndex].displayName[nameLen] = 0;
+
+              /* check how many addresses/aliases this adapter has.  aliases show up as adaptors with the same name */
+              numAddresses = 0;
+              for (counter2 = counter; counter2 < totalInterfaces; counter2++)
+                {
+                  if (strncmp
+                      (ifc.ifc_req[counter].ifr_name,
+                       ifc.ifc_req[counter2].ifr_name, IFNAMSIZ) == 0)
+                    {
+                      if (
+#if defined(IPv6_FUNCTION_SUPPORT)
+                           (ifc.ifc_req[counter2].ifr_addr.sa_family ==
+                            AF_INET6) ||
+#endif
+                           (ifc.ifc_req[counter2].ifr_addr.sa_family ==
+                            AF_INET))
+                        {
+                          numAddresses++;
+                        }
+                    }
+                  else
+                    {
+                      break;
+                    }
+                }
+				ipv6 = fopen("/proc/net/if_inet6", "r");
+              while(fscanf(ipv6, "%4x%4x%4x%4x%4x%4x%4x%4x %x %x %x %x %s\n", &oct6[0], &oct6[1], &oct6[2], &oct6[3], &oct6[4], &oct6[5], &oct6[6], &oct6[7],
+              		&index6, &other, &scope, &other, ifname6) != EOF) {
+              		if(strncmp(ifc.ifc_req[counter].ifr_name, ifname6, IFNAMSIZ) == 0) {
+              				numAddresses++;
+              			}
+               }
+				fclose(ipv6);
+
+              /* allocate space for the addresses */
+              interfaces[currentAdapterIndex].numberAddresses = numAddresses;
+              interfaces[currentAdapterIndex].addresses =
+                portLibrary->mem_allocate_memory (portLibrary,
+                                                  numAddresses *
+                                                  sizeof
+                                                  (hyipAddress_struct));
+#if (defined(VALIDATE_ALLOCATIONS))
+              if (NULL == interfaces[currentAdapterIndex].addresses)
+                {
+                  portLibrary->mem_free_memory (portLibrary, ifc.ifc_buf);
+                  hysock_free_network_interface_struct (portLibrary, networkInterfaceArray);
+                  close (socketP);
+					throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
+					return NULL;
+                }
+#endif
+/* now get the addresses */
+              currentIPAddressIndex = 0;
+              lastName = ifc.ifc_req[counter].ifr_name;
+
+              for (;;)
+                {
+                  if (ifc.ifc_req[counter].ifr_addr.sa_family == AF_INET)
+                    {
+                      interfaces[currentAdapterIndex].
+                        addresses[currentIPAddressIndex].addr.inAddr.s_addr =
+                        ((struct sockaddr_in *) (&ifc.ifc_req[counter].
+                                                 ifr_addr))->sin_addr.s_addr;
+                      interfaces[currentAdapterIndex].
+                        addresses[currentIPAddressIndex].length =
+                        sizeof (struct in_addr);
+                      interfaces[currentAdapterIndex].
+                        addresses[currentIPAddressIndex].scope = 0;
+                      currentIPAddressIndex++;
+                    }
+#if defined(IPv6_FUNCTION_SUPPORT)
+                  else if (ifc.ifc_req[counter].ifr_addr.sa_family ==
+                           AF_INET6)
+                    {
+                      memcpy (interfaces[currentAdapterIndex].
+                              addresses[currentIPAddressIndex].addr.bytes,
+                              &(((struct sockaddr_in6 *) (&ifc.
+                                                          ifc_req[counter].
+                                                          ifr_addr))->
+                                sin6_addr), sizeof (struct in6_addr));
+                      interfaces[currentAdapterIndex].
+                        addresses[currentIPAddressIndex].length =
+                        sizeof (struct in6_addr);
+                      interfaces[currentAdapterIndex].
+                        addresses[currentIPAddressIndex].scope =
+                        ((struct sockaddr_in6 *) (&ifc.ifc_req[counter].
+                                                    ifr_addr))->
+                          sin6_scope_id;
+                      currentIPAddressIndex++;
+                    }
+
+              ipv6 = fopen("/proc/net/if_inet6", "r");
+              while(fscanf(ipv6, "%4x%4x%4x%4x%4x%4x%4x%4x %x %x %x %x %s\n", &oct6[0], &oct6[1], &oct6[2], &oct6[3], &oct6[4], &oct6[5], &oct6[6], &oct6[7],
+              	&index6, &other, &scope, &other, ifname6) != EOF) {
+              	if(strncmp(ifc.ifc_req[counter].ifr_name, ifname6, IFNAMSIZ) == 0) {
+              		sprintf(addr6, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", oct6[0], oct6[1], oct6[2], oct6[3], oct6[4], oct6[5], oct6[6], oct6[7]);
+              		inet_pton(AF_INET6, addr6, 
+              			(void *)(&interfaces[currentAdapterIndex].addresses[currentIPAddressIndex].addr.in6Addr));
+
+    	              interfaces[currentAdapterIndex].
+       	             addresses[currentIPAddressIndex].length = sizeof (struct in6_addr);
+                       interfaces[currentAdapterIndex].addresses[currentIPAddressIndex].scope = scope;
+   				         currentIPAddressIndex++;
+              			}
+               }
+			fclose(ipv6);
+
+#endif
+/* we mean to increment the outside counter here as we want to skip the next entry as it is for the same interface
+					   as we are currently working on */
+                  if ((counter + 1 < totalInterfaces)
+                      &&
+                      (strncmp
+                       (ifc.ifc_req[counter + 1].ifr_name, lastName,
+                        IFNAMSIZ) == 0))
+                    {
+                      counter++;
+                    }
+                  else
+                    {
+                      break;
+                    }
 
-      /* generate the object with the inet addresses for the itnerface       */
-      for (i = 0; i < networkInterfaceArray.elements[j].numberAddresses; i++)
-        {
-          element = newJavaNetInetAddressGenericB (env,
-                                                   (jbyte *)networkInterfaceArray.
-                                                   elements[j].addresses[i].
-                                                   addr.bytes,
-                                                   networkInterfaceArray.
-                                                   elements[j].addresses[i].
-                                                   length,
-                                                   networkInterfaceArray.
-                                                   elements[j].addresses[i].
-                                                   scope);
-          if (i == 0)
-            {
-              addresses =
-                (*env)->NewObjectArray (env,
-                                        networkInterfaceArray.elements[j].
-                                        numberAddresses, inetAddressClass,
-                                        element);
-            }
-          else
-            {
-              (*env)->SetObjectArrayElement (env, addresses, i, element);
+                }
+              currentAdapterIndex++;
             }
         }
+    }                           /* for over all interfaces */
+  /* now an interface might have been taken down since we first counted them */
+  networkInterfaceArray.length = currentAdapterIndex;
+  /* free the memory now that we are done with it */
+  portLibrary->mem_free_memory (portLibrary, ifc.ifc_buf);
+  close (socketP);
+
+#endif
+	
+	/* now loop through the interfaces and extract the information to be returned */
+	for (j = 0; j < networkInterfaceArray.length; j++)
+	{
+		/* set the name and display name and reset the addresses object array */
+		addresses = NULL;
+		name = NULL;
+		displayName = NULL;
+
+		if (networkInterfaceArray.elements[j].name != NULL)
+		{
+			nameLen = strlen (networkInterfaceArray.elements[j].name);
+			bytearray = (*env)->NewByteArray (env, nameLen);
+			if (bytearray == NULL)
+			{
+				/* NewByteArray should have thrown an exception */
+				return NULL;
+			}
+			(*env)->SetByteArrayRegion (env, bytearray, (jint) 0, nameLen,
+				(jbyte *)networkInterfaceArray.elements[j].name);
+			name =
+				(*env)->CallStaticObjectMethod (env, utilClass, utilMid,
+				bytearray, (jint) 0, nameLen);
+			if ((*env)->ExceptionCheck (env))
+			{
+				return NULL;
+			}
+		}
+
+		if (networkInterfaceArray.elements[j].displayName != NULL)
+		{
+			nameLen = strlen (networkInterfaceArray.elements[j].displayName);
+			bytearray = (*env)->NewByteArray (env, nameLen);
+			if (bytearray == NULL)
+			{
+				/* NewByteArray should have thrown an exception */
+				return NULL;
+			}
+			(*env)->SetByteArrayRegion (env, bytearray, (jint) 0, nameLen,
+				(jbyte *)networkInterfaceArray.elements[j].
+				displayName);
+			displayName =
+				(*env)->CallStaticObjectMethod (env, utilClass, utilMid,
+				bytearray, (jint) 0, nameLen);
+			if ((*env)->ExceptionCheck (env))
+			{
+				return NULL;
+			}
+		}
+
+		/* generate the object with the inet addresses for the itnerface       */
+		for (i = 0; i < networkInterfaceArray.elements[j].numberAddresses; i++)
+		{
+			element = newJavaNetInetAddressGenericB (env,
+				(jbyte *)networkInterfaceArray.
+				elements[j].addresses[i].
+				addr.bytes,
+				networkInterfaceArray.
+				elements[j].addresses[i].
+				length,
+				networkInterfaceArray.
+				elements[j].addresses[i].
+				scope);
+			if (i == 0)
+			{
+				addresses =
+					(*env)->NewObjectArray (env,
+					networkInterfaceArray.elements[j].
+					numberAddresses, inetAddressClass,
+					element);
+			}
+			else
+			{
+				(*env)->SetObjectArrayElement (env, addresses, i, element);
+			}
+		}
+
+		/* now  create the NetworkInterface object for this interface and then add it it ot the arrary that will be returned */
+		if( NULL == addresses ) {
+			addresses =
+					(*env)->NewObjectArray (env,
+					0, inetAddressClass,
+					NULL);
+		}
+		currentInterface =
+			(*env)->NewObject (env, networkInterfaceClass, methodID, name,
+			displayName, addresses,
+			networkInterfaceArray.elements[j].index);
+
+		if (j == 0)
+		{
+			networkInterfaces =
+				(*env)->NewObjectArray (env, networkInterfaceArray.length,
+				networkInterfaceClass, currentInterface);
+		}
+		else
+		{
+			(*env)->SetObjectArrayElement (env, networkInterfaces, j,
+				currentInterface);
+		}
+	}
+	/* free the memory for the interfaces struct and return the new NetworkInterface List */
+	hysock_free_network_interface_struct (&networkInterfaceArray);
+	return networkInterfaces;
+}
 
-      /* now  create the NetworkInterface object for this interface and then add it it ot the arrary that will be returned */
-      currentInterface =
-        (*env)->NewObject (env, networkInterfaceClass, methodID, name,
-                           displayName, addresses,
-                           networkInterfaceArray.elements[j].index);
+/**
+* Answer whether a specific NetworkInterface is up.
+*
+* @param	env		pointer to the JNI library 
+* @param	ifname	name of NetworkInterface
+*
+* @return	a boolean value indicates whether an network interface is up
+*/
+
+JNIEXPORT jboolean JNICALL
+Java_java_net_NetworkInterface_isUpImpl
+(JNIEnv * env, jobject obj, jstring ifname, jint jindex)
+{
+	return getPlatformIsUp(env, ifname, jindex);
+}
 
-      if (j == 0)
-        {
-          networkInterfaces =
-            (*env)->NewObjectArray (env, networkInterfaceArray.length,
-                                    networkInterfaceClass, currentInterface);
-        }
-      else
-        {
-          (*env)->SetObjectArrayElement (env, networkInterfaces, j,
-                                         currentInterface);
-        }
-    }
+/**
+* Answer whether a specific NetworkInterface is Loopback.
+*
+* @param	env		pointer to the JNI library 
+* @param	ifname	name of NetworkInterface
+*
+* @return	a boolean value indicates whether an network interface is a loopback one
+*/
+
+JNIEXPORT jboolean JNICALL
+Java_java_net_NetworkInterface_isLoopbackImpl (JNIEnv * env, jobject obj, jstring ifname, jint jindex)
+{
+	return getPlatformIsLoopback(env, ifname, jindex);
+}
+
+/**
+* Answer whether a specific NetworkInterface is up.
+*
+* @param	env		pointer to the JNI library 
+* @param	ifname	name of NetworkInterface
+*
+* @return	a boolean value indicates whether an network interface is a point to point one
+*/
+
+JNIEXPORT jboolean JNICALL
+Java_java_net_NetworkInterface_isPoint2PointImpl
+(JNIEnv * env, jobject obj, jstring ifname, jint jindex)
+
+{
+	return getPlatformIsPoint2Point(env, ifname, jindex);
+}
+
+/**
+* Answer whether a specific NetworkInterface supports multicast.
+*
+* @param	env		pointer to the JNI library 
+* @param	ifname	name of NetworkInterface
+*
+* @return	a boolean value indicates whether an network interface supports multicast
+*/
 
-  /* free the memory for the interfaces struct and return the new NetworkInterface List */
-  hysock_free_network_interface_struct (&networkInterfaceArray);
-  return networkInterfaces;
+JNIEXPORT jboolean JNICALL
+Java_java_net_NetworkInterface_supportMulticastImpl (JNIEnv * env, jobject obj, jstring ifname, jint jindex)
+{
+	return getPlatformSupportMulticast(env, ifname, jindex);
+}
+
+JNIEXPORT jint JNICALL
+Java_java_net_NetworkInterface_getMTUImpl (JNIEnv * env, jobject obj, jstring ifname, jint index)
+{
+	return getPlatformGetMTU(env, ifname, index);
+}
+
+char* 
+convertInterfaceName(JNIEnv * env, jstring ifname)
+{
+	char * interfaceName = 0;
+	jsize nameLen = 0;
+	const jchar * p;
+	int l = 0;
+
+	PORT_ACCESS_FROM_ENV (env);
+
+	nameLen = (*env)->GetStringLength (env, ifname);
+	interfaceName= hymem_allocate_memory (sizeof(char) * (nameLen + 1));
+#if defined(VALIDATE_ALLOCATIONS)
+	if (NULL == interfaceName){
+		return NULL;
+	}
+#endif
+	p = (*env)->GetStringChars(env, ifname, NULL);
+	for(; l < nameLen; l++) {
+		interfaceName[l] = (char)p[l]; 
+	}
+	interfaceName[nameLen] = '\0';
+	return interfaceName;
+}
+
+I_32
+freeInterfaceAddressArray(JNIEnv * env, struct interfaceAddressArray_struct * array)
+{
+	U_32 i = 0;
+
+	PORT_ACCESS_FROM_ENV (env);
+
+	if ((array != NULL) && (array->elements != NULL))
+	{
+		/* free the allocated memory in each of the structures */
+		for (i = 0; i < array->length; i++)
+		{
+			if (array->elements[i].address != NULL)
+			{
+				hymem_free_memory(array->elements[i].address);
+			}
+		}
+
+		/* now free the array itself */
+		hymem_free_memory(array->elements);
+	}
+	return 0;
+}
+
+JNIEXPORT jobjectArray JNICALL
+Java_java_net_NetworkInterface_getInterfaceAddressesImpl (JNIEnv * env, jobject obj, jstring ifname, jint index)
+{
+	U_32 i = 0;
+	I_32 result = 0;
+
+	interfaceAddressArray_struct interfaceAddressArray;
+
+	jobjectArray interfaceAddresses = NULL;
+	jobject currentInterfaceAddress = NULL;
+	jclass interfaceAddressClass = NULL;
+	jmethodID methodID = NULL;
+
+	PORT_ACCESS_FROM_ENV (env);
+	
+	interfaceAddressClass =
+		(*env)->FindClass (env, "java/net/InterfaceAddress");
+	if (interfaceAddressClass == NULL)
+	{
+		throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
+		return NULL;
+	}
+
+	methodID =
+		(*env)->GetMethodID (env, interfaceAddressClass, "<init>",
+		"(Ljava/net/InetAddress;S)V");
+	if (methodID == NULL)
+	{
+		throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
+		return NULL;
+	}
+
+	// initialize interfaceAddressArray struct
+	interfaceAddressArray.elements = NULL;
+	interfaceAddressArray.length = 0;
+	
+	// get the interface address info according to different system calls.
+    
+	result = getPlatformGetInterfaceAddresses(env, ifname, index, &interfaceAddressArray);
+
+	if (result != 0) {
+		/* this means an error occured.  The value returned is the socket error that should be returned */
+		throwJavaNetSocketException (env, result);
+		return NULL;
+	}
+
+    // use JNI to encapsulate interfaceAddress_struct to jobject InterfaceAddress
+	for (i = 0; i < interfaceAddressArray.length; i++)
+	{
+		jobject inetAddress = NULL;
+		jshort prefix = 0;
+
+		inetAddress = newJavaNetInetAddressGenericB (env,
+			(jbyte *)interfaceAddressArray.elements[i].address->addr.bytes,
+            interfaceAddressArray.elements[i].address->length,
+			interfaceAddressArray.elements[i].address->scope);
+
+		prefix = (jshort) interfaceAddressArray.elements[i].prefixLength;
+
+		currentInterfaceAddress = (*env)->NewObject (env,
+			interfaceAddressClass, methodID, 
+			inetAddress, prefix);
+
+        if (i == 0)
+		{
+			interfaceAddresses =
+				(*env)->NewObjectArray (env, interfaceAddressArray.length,
+				interfaceAddressClass, currentInterfaceAddress);
+		}
+		else
+		{
+			(*env)->SetObjectArrayElement (env, interfaceAddresses, i,
+				currentInterfaceAddress);
+		}
+	}
+      
+	freeInterfaceAddressArray(env, &interfaceAddressArray);
+	
+	return interfaceAddresses;
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_java_net_NetworkInterface_getHardwareAddressImpl(JNIEnv * env, jobject obj, jstring ifname, jint index)
+{
+	return getPlatformGetHardwareAddress(env, ifname, index);
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/exports.txt
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/exports.txt?view=diff&rev=547205&r1=547204&r2=547205
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/exports.txt (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/exports.txt Thu Jun 14 03:33:19 2007
@@ -146,7 +146,13 @@
 Java_java_net_InetAddress_inetAddrImpl
 Java_java_net_InetAddress_inetNtoaImpl
 Java_java_net_InetAddress_oneTimeInitialization
+Java_java_net_NetworkInterface_isLoopbackImpl
+Java_java_net_NetworkInterface_getHardwareAddressImpl
+Java_java_net_NetworkInterface_getInterfaceAddressesImpl
+Java_java_net_NetworkInterface_getMTUImpl
 Java_java_net_NetworkInterface_getNetworkInterfacesImpl
+Java_java_net_NetworkInterface_isUpImpl
+Java_java_net_NetworkInterface_supportMulticastImpl
 Java_java_util_TimeZone_getCustomTimeZone
 JNI_OnLoad
 JNI_OnUnload

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.c?view=diff&rev=547205&r1=547204&r2=547205
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.c (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.c Thu Jun 14 03:33:19 2007
@@ -15,6 +15,13 @@
  *  limitations under the License.
  */
 
+#include <errno.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -34,6 +41,35 @@
 #include "jclprots.h"
 #include "harmonyglob.h"
 
+#include <asm/types.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#define NETLINK_DATA_BUFFER_SIZE 2048
+#define NETLINK_READTIMEOUT_SECS 20
+
+typedef struct linkReq_struct
+{
+  struct nlmsghdr netlinkHeader;
+  struct ifinfomsg msg;
+} linkReq_struct;
+
+typedef struct addrReq_struct
+{
+  struct nlmsghdr netlinkHeader;
+  struct ifaddrmsg msg;
+} addrReq_struct;
+
+typedef struct netlinkContext_struct
+{
+  int netlinkSocketHandle;
+  char *buffer;
+  int bufferSize;
+  struct nlmsghdr *netlinkHeader;
+  U_32 remainingLength;
+  U_32 done;
+} netlinkContext_struct;
+
 int portCmp (const void **a, const void **b);
 
 /**
@@ -211,3 +247,562 @@
 
   hysock_setopt_bool (socketP, HY_SOL_SOCKET, HY_SO_REUSEADDR, &value);
 }
+
+jboolean 
+getPlatformNetworkInterfaceAttribute(JNIEnv * env, jstring ifname, u_long iiFlag)
+{    
+	struct ifconf ifc;
+	char buff[2048];
+	int fd, i, n, result;
+	struct ifreq *ifr = NULL;	
+       char* interfaceName = 0;
+
+       /* required call if we are going to call port library methods */
+	PORT_ACCESS_FROM_ENV (env);
+
+	if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
+		throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
+	}
+
+	memset(buff, 0, sizeof(buff));
+	ifc.ifc_len = sizeof(buff);
+	ifc.ifc_buf = buff;
+	if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) != 0) {
+		close(fd);	
+		throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);	
+              return 0;	
+	}
+
+	ifr = ifc.ifc_req;
+	n = ifc.ifc_len / sizeof(struct ifreq);
+
+      interfaceName = convertInterfaceName(env, ifname);         
+
+	/* Loop through interfaces, looking for given IP address */
+	for (i=0; i<n; i++) {		
+		if((ioctl(fd, SIOCGIFADDR, &ifr[i]) == 0) 
+			&& (strcmp(interfaceName, ifr[i].ifr_name) == 0)) {	       
+				if ( (result = ioctl(fd, SIOCGIFFLAGS, &ifr[i])) != 0) {
+					close(fd);
+					throwJavaNetSocketException (env, result); 
+                                   hymem_free_memory(interfaceName);
+      	   	                     return 0;	
+				}
+				close(fd);
+                           hymem_free_memory(interfaceName);
+			      return (ifr[i].ifr_flags & iiFlag) == iiFlag;	        
+			}		
+	}	
+	close(fd);
+       hymem_free_memory(interfaceName);
+	return 0;
+}
+
+
+jboolean
+getPlatformIsUp(JNIEnv * env, jstring ifname, jint jindex)
+{
+   return getPlatformNetworkInterfaceAttribute(env, ifname, IFF_UP);
+}
+
+jboolean
+getPlatformIsLoopback(JNIEnv * env, jstring ifname, jint jindex)
+{
+    return getPlatformNetworkInterfaceAttribute(env, ifname, IFF_LOOPBACK);	
+}
+
+jboolean
+getPlatformIsPoint2Point(JNIEnv * env, jstring ifname, jint jindex)
+{
+    return getPlatformNetworkInterfaceAttribute(env, ifname, IFF_POINTOPOINT);	
+}
+
+jboolean
+getPlatformSupportMulticast(JNIEnv * env, jstring ifname, jint jindex)
+{
+    return getPlatformNetworkInterfaceAttribute(env, ifname, IFF_MULTICAST);	
+}
+
+jint
+getPlatformGetMTU(JNIEnv * env, jstring ifname, jint index)
+{
+       struct ifconf ifc;
+	char buff[2048];
+	int fd, i, n, result;
+	struct ifreq *ifr = NULL;
+	char * interfaceName = 0;	
+       int mtu = 0;
+	
+	/* required call if we are going to call port library methods */
+	PORT_ACCESS_FROM_ENV (env);
+
+	if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
+		throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
+		return 0;
+	}
+	
+	memset(buff, 0, sizeof(buff));
+	ifc.ifc_len = sizeof(buff);
+	ifc.ifc_buf = buff;
+	if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) != 0) {
+		close(fd);	
+		throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
+		return 0; 
+	}
+
+	ifr = ifc.ifc_req;
+	n = ifc.ifc_len / sizeof(struct ifreq);
+	        
+	interfaceName = convertInterfaceName (env, ifname);
+	/* Loop through interfaces, looking for given interface name */
+	for (i=0; i<n; i++) {
+		if((ioctl(fd, SIOCGIFADDR, &ifr[i]) == 0) 
+			&& (strcmp(interfaceName, ifr[i].ifr_name) == 0)) {	       
+			if ( (result = ioctl(fd, SIOCGIFMTU, &ifr[i])) != 0) {
+				close(fd);
+                            hymem_free_memory (interfaceName);	
+				throwJavaNetSocketException (env, result);  
+				return 0;     	   	
+			}
+			mtu = ifr[i].ifr_mtu;
+                     break;
+		}		
+	}	
+	close(fd);
+	hymem_free_memory (interfaceName);	
+	return mtu;
+}
+
+jbyteArray 
+getPlatformGetHardwareAddress(JNIEnv * env, jstring ifname, jint index)
+{
+       const int MAC_ADDR_SIZE = 6;
+
+	struct ifconf ifc;
+	char buff[2048];
+	int fd, i, j, n, result;
+	struct ifreq *ifr = NULL;
+	char * interfaceName = 0;
+	char array[MAC_ADDR_SIZE];
+	jboolean isEmpty = JNI_TRUE;        
+	jbyteArray bytearray = NULL;
+
+	/* required call if we are going to call port library methods */
+	PORT_ACCESS_FROM_ENV (env);
+
+	if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
+		throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);
+		return NULL; 
+	}
+
+	memset(buff, 0, sizeof(buff));
+	ifc.ifc_len = sizeof(buff);
+	ifc.ifc_buf = buff;
+	if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) != 0) {
+		close(fd);	
+		throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_NORECOVERY);		
+	}
+
+	ifr = ifc.ifc_req;
+	n = ifc.ifc_len / sizeof(struct ifreq);
+
+	// Transfer ifname to type char*
+       interfaceName = convertInterfaceName (env, ifname);
+
+	/* Loop through interfaces, looking for given IP address */
+	for (i=0; i<n; i++) {
+	   if((ioctl(fd, SIOCGIFADDR, &ifr[i]) == 0) 
+		&& (strcmp(interfaceName, ifr[i].ifr_name) == 0)) {	       
+		if ( (result = ioctl(fd, SIOCGIFHWADDR, &ifr[i])) != 0) {
+			close(fd);
+                     hymem_free_memory (interfaceName);	
+	       	throwJavaNetSocketException (env, result);
+			return NULL;        	   	
+		}
+
+		// Transfer char to jbyteArray		    
+		for(j = 0; j < MAC_ADDR_SIZE; j++) {
+			array[j] = (unsigned char)ifr[i].ifr_hwaddr.sa_data[j]; 
+			if (array[j] != 0) {
+	       		isEmpty = JNI_FALSE;
+			}
+		}
+		// if all bytes are zero, return null
+		if(!isEmpty) {
+                  bytearray = (*env)->NewByteArray (env, MAC_ADDR_SIZE);
+                  (*env)->SetByteArrayRegion (env, bytearray, 0, MAC_ADDR_SIZE, (jbyte *)array);				
+		}
+		break;
+	    }
+	}	
+	close(fd);
+	hymem_free_memory (interfaceName);	
+	return bytearray;
+}
+
+void 
+initNetlinkContext (I_32 netlinkSocketHandle,
+                    struct netlinkContext_struct * netlinkContext)
+{
+  netlinkContext->netlinkSocketHandle = netlinkSocketHandle;
+  netlinkContext->netlinkHeader = NULL;
+  netlinkContext->remainingLength = 0;
+  netlinkContext->done = 0;
+}
+
+
+void cleanupNetlinkContext(JNIEnv * env, struct netlinkContext_struct *nlc) 
+{
+    if (nlc && nlc->buffer) {
+        PORT_ACCESS_FROM_ENV (env);
+        hymem_free_memory(nlc->buffer);
+        nlc->buffer = NULL;
+        nlc->bufferSize = 0;
+    }
+}
+
+getNextNetlinkMsg (JNIEnv * env, 
+                   struct netlinkContext_struct * netlinkContext,
+                   struct nlmsghdr ** nextMessage)
+{
+  struct sockaddr_nl address;
+  U_32 receiveLength;
+  socklen_t addressLength = sizeof (address);
+
+  PORT_ACCESS_FROM_ENV (env);
+
+  for (;;)
+    {
+      /* check if we are done */
+      if (netlinkContext->done == 1)
+        {
+          *nextMessage = NULL;
+          return 0;
+        }
+
+      if (netlinkContext->remainingLength > 0)
+        {
+          /* there is data left from the last read, get the next header from this existing data */
+          netlinkContext->netlinkHeader =
+            NLMSG_NEXT (netlinkContext->netlinkHeader,
+                        netlinkContext->remainingLength);
+        }
+
+    /* 
+     * if the remainingLength is 0 then there was no messages available in the existing data 
+     * so read another datagram containing messages we first use a select to make sure we 
+     * don't block forever if for some reason there is no netlink message to read 
+     */
+     
+      if (netlinkContext->remainingLength == 0)
+        {
+          fd_set waitSockets;
+          struct timeval waitTime;
+          waitTime.tv_sec = NETLINK_READTIMEOUT_SECS;
+          waitTime.tv_usec = 0;
+          FD_ZERO (&waitSockets);
+          FD_SET (netlinkContext->netlinkSocketHandle, &waitSockets);
+                     
+          if (select
+              (netlinkContext->netlinkSocketHandle + 1, &waitSockets, NULL,
+               NULL, &waitTime) > 0)
+            {
+                
+                struct sockaddr_nl nladdr;
+                struct msghdr msg;
+                struct iovec iov;
+                iov.iov_base = netlinkContext->buffer;
+                iov.iov_len = netlinkContext->bufferSize;
+                msg.msg_name = (void *)&(nladdr);
+                msg.msg_namelen = sizeof(nladdr);
+                msg.msg_iov = &iov;
+                msg.msg_iovlen = 1;
+                
+                int reallocLoop = 1;
+
+                while (reallocLoop) {
+                    int len = recvmsg(netlinkContext->netlinkSocketHandle, &msg, MSG_PEEK);
+
+                    /*
+                     *  if the peek shows that we would truncate, realloc to 2x the buffer size
+                     */
+                    if (msg.msg_flags & MSG_TRUNC) {
+                        
+                        /*
+                         * safety - only go to 64k
+                         */
+                         
+                        if (netlinkContext->bufferSize * 2 > 65536) {
+                            reallocLoop = 0;
+                            break;
+                        }                        
+                        
+                        netlinkContext->buffer = hymem_reallocate_memory(netlinkContext->buffer, 
+                                   netlinkContext->bufferSize * 2);
+                        #if defined(VALIDATE_ALLOCATIONS)
+                            if (NULL == netlinkContext->buffer){
+                               return hyerror_set_last_error(errno, HYPORT_ERROR_SOCKET_NORECOVERY);
+                                 }
+                        #endif
+                        netlinkContext->bufferSize *= 2;
+                                
+                        iov.iov_base = netlinkContext->buffer;
+                        iov.iov_len = netlinkContext->bufferSize;
+                    }
+                    else { 
+                        reallocLoop = 0;
+                    }
+                }
+                
+                receiveLength = recvmsg(netlinkContext->netlinkSocketHandle, &msg, 0);
+                
+                if (receiveLength < 0) {
+                  /* we failed to get the response message */
+                  return hyerror_set_last_error(errno, HYPORT_ERROR_SOCKET_NORECOVERY);
+                }
+                
+              netlinkContext->remainingLength = receiveLength;
+              netlinkContext->netlinkHeader =
+                (struct nlmsghdr *) netlinkContext->buffer;
+            }
+          else
+            {
+              /* timeout waiting from netlink response messages */
+              return hyerror_set_last_error(errno, HYPORT_ERROR_SOCKET_NORECOVERY);
+            }
+        }
+
+      /* now return message if everything was ok */
+      if (NLMSG_OK
+          (netlinkContext->netlinkHeader, netlinkContext->remainingLength))
+        {
+          if (NLMSG_ERROR == netlinkContext->netlinkHeader->nlmsg_type)
+            {
+              /* we got an unexpected error message */
+              return hyerror_set_last_error(errno, HYPORT_ERROR_SOCKET_NORECOVERY);
+            }
+          /* we are done if the NLM_F_MULTI flag is not set in this header */
+          *nextMessage = netlinkContext->netlinkHeader;
+          if (netlinkContext->netlinkHeader->nlmsg_flags & NLM_F_MULTI !=
+              NLM_F_MULTI)
+            {
+              netlinkContext->done = 1;
+            }
+
+          /* if this is the message indicating that we are at the end of a multi-part message just each the message and
+             return NULL to indicate we are done */
+          if (netlinkContext->netlinkHeader->nlmsg_type == NLMSG_DONE)
+            {
+              /* end of multilink message so just return null as we don't need this message */
+              *nextMessage = NULL;
+            }
+        }
+      else
+        {
+          /* this is an error as we have to read all of the data in one shot */
+          /* It is assumed that the kernel uses a reasonable max size datagram and will break up response into multi-link messages
+             if a message larger than this size needs to be sent.  The max size seen so far is about  552 bytes */
+  
+          return hyerror_set_last_error(errno, HYPORT_ERROR_SOCKET_NORECOVERY);
+        }
+
+      /*  If this message is not a NOOP return, otherwise just eat the message and go look for the next one  */
+      if (netlinkContext->netlinkHeader->nlmsg_type != NLMSG_NOOP)
+        {
+          return 0;
+        }
+    }
+}
+
+I_32 
+getPlatformGetInterfaceAddresses(JNIEnv * env, 
+                                 jstring ifname, 
+                                 jint index,                               
+                                 interfaceAddressArray_struct* interfaceAddressArray)
+{
+       interfaceAddress_struct *interfaces = NULL;
+       int counter = 0;
+
+     	U_8 addressFamily = 0;
+       int netlinkSocketHandle = 0;	
+       netlinkContext_struct netlinkContext;	
+       struct addrReq_struct addrRequest;	
+       U_32 sendLength = 0;
+       U_32 result = 0;
+       U_32 numAddresses = 0;
+
+       struct nlmsghdr *currentNlHeader = NULL;
+       struct ifaddrmsg *returnedAddrHeader = NULL;
+	
+	PORT_ACCESS_FROM_ENV (env);
+	/*
+	*  initialize the buffer as it doesn't have one yet
+	*/
+	netlinkContext.buffer = hymem_allocate_memory(NETLINK_DATA_BUFFER_SIZE);
+	netlinkContext.bufferSize = NETLINK_DATA_BUFFER_SIZE;
+
+       /* set the address family based on the preferIPv4stack flag */
+	if (preferIPv4Stack(env)) {
+		addressFamily = AF_INET;
+	}else {
+		addressFamily = AF_UNSPEC;
+	}
+       
+       /* we need socket to do the netlink calls so create one */
+       netlinkSocketHandle = socket (PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);       
+       if (netlinkSocketHandle <= 0) {
+           cleanupNetlinkContext(env, &netlinkContext); 
+           return hyerror_set_last_error(errno, HYPORT_ERROR_SOCKET_NORECOVERY);
+        }
+
+       // inital address request message 
+      memset (&addrRequest, 0, sizeof (struct addrReq_struct));
+      addrRequest.netlinkHeader.nlmsg_len =
+        NLMSG_LENGTH (sizeof (struct addrReq_struct));
+      addrRequest.netlinkHeader.nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH;
+      addrRequest.netlinkHeader.nlmsg_type = RTM_GETADDR;
+      addrRequest.msg.ifa_index = index;
+      addrRequest.msg.ifa_family = addressFamily;
+      addrRequest.netlinkHeader.nlmsg_len = NLMSG_ALIGN (addrRequest.netlinkHeader.nlmsg_len);
+       // send the message out
+      sendLength =
+        send (netlinkSocketHandle, &addrRequest,
+              addrRequest.netlinkHeader.nlmsg_len, 0);
+      if (sendLength != addrRequest.netlinkHeader.nlmsg_len)
+        {
+          close (netlinkSocketHandle);          
+          cleanupNetlinkContext(env, &netlinkContext);        
+          return hyerror_set_last_error(errno, HYPORT_ERROR_SOCKET_NORECOVERY);
+        }
+
+       initNetlinkContext (netlinkSocketHandle, &netlinkContext);
+        // calculate the interface addresses number
+       do
+        {
+          if ((result =
+               getNextNetlinkMsg (env, &netlinkContext,
+                                  &currentNlHeader)) != 0)
+            {
+              close (netlinkSocketHandle);              
+              cleanupNetlinkContext(env, &netlinkContext);
+              return result;
+            }
+
+           if (currentNlHeader != NULL)
+             {
+               struct rtattr *rta;
+               U_32 attLength = IFA_PAYLOAD (currentNlHeader);
+               returnedAddrHeader = NLMSG_DATA (currentNlHeader);
+               if (((returnedAddrHeader->ifa_family == AF_INET) ||
+                    (returnedAddrHeader->ifa_family == AF_INET6)) &&
+                  (returnedAddrHeader->ifa_index == index))
+                 {
+                  rta = IFA_RTA (returnedAddrHeader);
+                  while (RTA_OK (rta, attLength))
+                    {
+                      if (IFA_ADDRESS == rta->rta_type)
+                        {
+                          numAddresses++;
+                        }
+                      rta = RTA_NEXT (rta, attLength);
+                    }
+                }
+             }
+          
+        } while (currentNlHeader != NULL); 
+
+        if (numAddresses > 0)
+         {
+           // allocate new spaces
+           interfaces = hymem_allocate_memory (sizeof(interfaceAddress_struct) * (numAddresses));
+           for (counter = 0; counter < numAddresses; counter++)
+             {
+		interfaces[counter].address = NULL;
+		interfaces[counter].prefixLength = 0;
+             }
+           counter = 0;
+           // fetch the addresses and prefix length
+           sendLength =
+                send (netlinkSocketHandle, &addrRequest,
+                      addrRequest.netlinkHeader.nlmsg_len, 0);
+           if (sendLength != addrRequest.netlinkHeader.nlmsg_len)
+             {
+                close (netlinkSocketHandle);          
+                cleanupNetlinkContext(env, &netlinkContext);        
+                return hyerror_set_last_error(errno, HYPORT_ERROR_SOCKET_NORECOVERY);
+             }
+
+           initNetlinkContext (netlinkSocketHandle, &netlinkContext);
+
+           do
+             {
+                if ((result =
+                    getNextNetlinkMsg (env, &netlinkContext,
+                                  &currentNlHeader)) != 0)
+                   {
+                    close (netlinkSocketHandle);              
+                    cleanupNetlinkContext(env, &netlinkContext);
+                    return result;
+                   }
+
+                if (currentNlHeader != NULL)
+                   {
+                    struct rtattr *rta;
+                    U_32 attLength = IFA_PAYLOAD (currentNlHeader);
+                    returnedAddrHeader = NLMSG_DATA (currentNlHeader);
+                    /* make sure that it is for the requested interface, and one of the types we are expecting */
+                    if (((returnedAddrHeader->ifa_family == AF_INET) ||
+                        (returnedAddrHeader->ifa_family == AF_INET6)) &&
+                        (returnedAddrHeader->ifa_index == index))
+                        {
+                         rta = IFA_RTA (returnedAddrHeader);
+                         while (RTA_OK (rta, attLength))
+                             {
+                            if (IFA_ADDRESS == rta->rta_type)
+                                 {
+                              // copy addresses
+                              interfaces[counter].address = 
+                                     hymem_allocate_memory (sizeof(hyipAddress_struct));
+                              if (returnedAddrHeader->ifa_family == AF_INET)
+                                    {
+                                   memcpy (interfaces[counter].address->addr.bytes, 
+                                           RTA_DATA (rta),
+                                           sizeof (struct in_addr));
+                                   interfaces[counter].address->length = sizeof (struct in_addr);
+                                   interfaces[counter].address->scope = 0;
+                                } else if (returnedAddrHeader->ifa_family ==  AF_INET6) {
+                                   memcpy (interfaces[counter].address->addr.bytes, 
+                                           RTA_DATA (rta),
+                                           sizeof (struct in6_addr));
+                                   interfaces[counter].address->length = sizeof (struct in6_addr);
+                                   if ((returnedAddrHeader->ifa_scope == RT_SCOPE_LINK) || 
+                                       (returnedAddrHeader->ifa_scope == RT_SCOPE_SITE))
+                                        {
+                                       interfaces[counter].address->scope = returnedAddrHeader->ifa_index;
+                                  } else {
+                                       interfaces[counter].address->scope = 0;
+                                        }
+                                     
+                                    }
+                              // copy prefix length
+                              // RI has bug about prefix length of loopback interface.
+                              interfaces[counter].prefixLength = returnedAddrHeader->ifa_prefixlen;
+                              counter++;                              
+                               }                          
+                          rta = RTA_NEXT (rta, attLength);
+                           }
+                       }
+                   }
+             } while (currentNlHeader != NULL);
+         }
+
+      
+       interfaceAddressArray -> length = numAddresses;
+	interfaceAddressArray -> elements = interfaces;
+
+       /* do any final clean up before returning */
+       close (netlinkSocketHandle);
+       cleanupNetlinkContext(env, &netlinkContext);
+	return 0;	
+}
+

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.h?view=diff&rev=547205&r1=547204&r2=547205
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.h (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.h Thu Jun 14 03:33:19 2007
@@ -18,6 +18,24 @@
 #if !defined(helpers_h)
 #define helpers_h
 #include "vmi.h"
+#include "hysock.h"
+
+/* structure for returning interface address information */
+typedef struct interfaceAddress_struct
+{
+  U_16 prefixLength;
+  struct hyipAddress_struct *address;
+  //struct hyipAddress_struct *mask;
+  //struct hyipAddress_struct *broadcast;
+} interfaceAddress_struct;
+
+/* array of interface address structures */
+typedef struct interfaceAddressArray_struct
+{
+  U_32 length;
+  struct interfaceAddress_struct *elements;
+} interfaceAddressArray_struct;
+
 int platformReadLink (char *link);
 jbyteArray getPlatformPath (JNIEnv * env, jbyteArray path);
 void setDefaultServerSocketOptions (JNIEnv * env, hysocket_t socketP);
@@ -35,4 +53,12 @@
 I_32 setPlatformLastModified (JNIEnv * env, char *path, I_64 time);
 I_32 setPlatformReadOnly (JNIEnv * env, char *path);
 int portCmp (const void **a, const void **b);
+char* convertInterfaceName(JNIEnv * env, jstring ifname);
+jboolean getPlatformNetworkInterfaceAttribute(JNIEnv * env, jstring ifname, u_long iiFlag);
+jboolean getPlatformIsUp(JNIEnv * env, jstring ifname, jint index);
+jboolean getPlatformIsLoopback(JNIEnv * env, jstring ifname, jint index);
+jboolean getPlatformIsPoint2Point(JNIEnv * env, jstring ifname, jint index);
+jboolean getPlatformSupportMulticast(JNIEnv * env, jstring ifname, jint index);
+jint getPlatformGetMTU(JNIEnv * env, jstring ifname, jint index);
+I_32 getPlatformGetInterfaceAddresses(JNIEnv * env, jstring ifname, jint index, interfaceAddressArray_struct* interfaceAddressArray);
 #endif /* helpers_h */



Mime
View raw message