Return-Path: Delivered-To: apmail-harmony-commits-archive@www.apache.org Received: (qmail 43849 invoked from network); 14 Jun 2007 10:33:46 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 14 Jun 2007 10:33:46 -0000 Received: (qmail 35676 invoked by uid 500); 14 Jun 2007 10:33:49 -0000 Delivered-To: apmail-harmony-commits-archive@harmony.apache.org Received: (qmail 35650 invoked by uid 500); 14 Jun 2007 10:33:49 -0000 Mailing-List: contact commits-help@harmony.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@harmony.apache.org Delivered-To: mailing list commits@harmony.apache.org Received: (qmail 35641 invoked by uid 99); 14 Jun 2007 10:33:49 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 14 Jun 2007 03:33:49 -0700 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 14 Jun 2007 03:33:43 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 17C7F1A981D; Thu, 14 Jun 2007 03:33:23 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: commits@harmony.apache.org From: tellison@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070614103323.17C7F1A981D@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#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, "", + "(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, "", - "(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, "", + "(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 +#include +#include +#include +#include +#include + #include #include #include @@ -34,6 +41,35 @@ #include "jclprots.h" #include "harmonyglob.h" +#include +#include +#include + +#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; iNewByteArray (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, + ¤tNlHeader)) != 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, + ¤tNlHeader)) != 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 */