diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c')
-rw-r--r-- | libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c | 399 |
1 files changed, 399 insertions, 0 deletions
diff --git a/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c b/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c new file mode 100644 index 000000000..658299733 --- /dev/null +++ b/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c @@ -0,0 +1,399 @@ +/* VMNetworkInterface.c - Native methods for NetworkInterface class + Copyright (C) 2003, 2005, 2006, 2008 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif /* HAVE_CONFIG_H */ + +#include <sys/types.h> +#include <sys/socket.h> +#ifdef HAVE_IFADDRS_H +#include <ifaddrs.h> +#endif +#include <netinet/in.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <net/if.h> +#include <sys/ioctl.h> +/* Required on Solaris. */ +#include <unistd.h> + +#ifdef HAVE_SYS_SOCKIO_H +# include <sys/sockio.h> +#endif + +#include <jni.h> +#include <jcl.h> + +#include <cpnative.h> +#include <cpnet.h> + +#include "java_net_VMNetworkInterface.h" + +int iff_flags(JNIEnv *, jstring, jint *); + +static jmethodID java_net_VMNetworkInterface_init; +static jmethodID java_net_VMNetworkInterface_addAddress; + +/* + * Initialize our static method ID's. + * + * Class: java_net_VMNetworkInterface + * Method: initIds + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_java_net_VMNetworkInterface_initIds (JNIEnv *env, jclass clazz) +{ + java_net_VMNetworkInterface_init = + (*env)->GetMethodID (env, clazz, "<init>", "(Ljava/lang/String;)V"); + if (java_net_VMNetworkInterface_init == NULL) + { + if (!(*env)->ExceptionCheck (env)) + JCL_ThrowException (env, "java/lang/NoSuchMethodError", + "VMNetworkinterface.addAddress"); + return; + } + java_net_VMNetworkInterface_addAddress = + (*env)->GetMethodID (env, clazz, "addAddress", "(Ljava/nio/ByteBuffer;)V"); + if (java_net_VMNetworkInterface_addAddress == NULL) + { + if (!(*env)->ExceptionCheck (env)) + JCL_ThrowException (env, "java/lang/NoSuchMethodError", + "VMNetworkinterface.addAddress"); + } +} + +struct netif_entry +{ + char *name; + jobject netif; + int numaddrs; + struct netif_entry *next; +}; + +#if defined (HAVE_IFADDRS_H) && defined (HAVE_GETIFADDRS) +static void +free_netif_list (JNIEnv *env, struct netif_entry *list) +{ + while (list != NULL) + { + struct netif_entry *e = list->next; + JCL_free (env, list); + list = e; + } +} +#endif + +/* + * Returns all local network interfaces as an array. + */ +JNIEXPORT jobjectArray JNICALL +Java_java_net_VMNetworkInterface_getVMInterfaces (JNIEnv * env, + jclass clazz UNUSED) +{ +#if defined (HAVE_IFADDRS_H) && defined (HAVE_GETIFADDRS) + struct ifaddrs *ifaddrs, *i; + struct netif_entry *iflist = NULL, *e; + jobjectArray netifs; + int numifs = 0; + int k; + + if (getifaddrs (&ifaddrs) == -1) + { + JCL_ThrowException (env, "java/net/SocketException", strerror (errno)); + return NULL; + } + + for (i = ifaddrs; i != NULL; i = i->ifa_next) + { + if (iflist == NULL) + { + iflist = JCL_malloc (env, sizeof (struct netif_entry)); + if (iflist == NULL) + { + freeifaddrs (ifaddrs); + return NULL; + } + iflist->name = i->ifa_name; + iflist->numaddrs = 0; + iflist->next = NULL; + iflist->netif = (*env)->NewObject (env, clazz, java_net_VMNetworkInterface_init, + (*env)->NewStringUTF (env, i->ifa_name)); + if (iflist->netif == NULL) + { + freeifaddrs (ifaddrs); + JCL_free (env, iflist); + return NULL; + } + e = iflist; + } + else + { + struct netif_entry *p = NULL; + for (e = iflist; e != NULL; e = e->next) + { + if (strcmp (e->name, i->ifa_name) == 0) + break; + p = e; + } + + if (e == NULL) + { + p->next = (struct netif_entry *) JCL_malloc (env, sizeof (struct netif_entry)); + if (p->next == NULL) + { + free_netif_list (env, iflist); + freeifaddrs (ifaddrs); + return NULL; + } + e = p->next; + e->name = i->ifa_name; + e->numaddrs = 0; + e->next = NULL; + e->netif = (*env)->NewObject (env, clazz, java_net_VMNetworkInterface_init, + (*env)->NewStringUTF (env, i->ifa_name)); + if (e->netif == NULL) + { + free_netif_list (env, iflist); + freeifaddrs (ifaddrs); + return NULL; + } + } + } + + if (i->ifa_addr == NULL) + continue; + + if (i->ifa_addr->sa_family == AF_INET) + { + struct sockaddr_in *sin = (struct sockaddr_in *) i->ifa_addr; + jobject buffer = (*env)->NewDirectByteBuffer (env, &(sin->sin_addr.s_addr), 4); + (*env)->CallVoidMethod (env, e->netif, java_net_VMNetworkInterface_addAddress, + buffer); + if ((*env)->ExceptionCheck (env)) + { + free_netif_list (env, iflist); + freeifaddrs (ifaddrs); + return NULL; + } + (*env)->DeleteLocalRef (env, buffer); + e->numaddrs++; + } +#ifdef HAVE_INET6 + else if (i->ifa_addr->sa_family == AF_INET6) + { + struct sockaddr_in6 *sin = (struct sockaddr_in6 *) i->ifa_addr; + jobject buffer = (*env)->NewDirectByteBuffer (env, &(sin->sin6_addr.s6_addr), 16); + (*env)->CallVoidMethod (env, e->netif, java_net_VMNetworkInterface_addAddress, + buffer); + if ((*env)->ExceptionCheck (env)) + { + free_netif_list (env, iflist); + freeifaddrs (ifaddrs); + return NULL; + } + (*env)->DeleteLocalRef (env, buffer); + e->numaddrs++; + } +#endif /* HAVE_INET6 */ + } + + /* Count how many interfaces we have that have addresses. */ + for (e = iflist; e != NULL; e = e->next) + { + if (e->numaddrs != 0) + numifs++; + } + + netifs = (*env)->NewObjectArray (env, numifs, clazz, NULL); + k = 0; + for (e = iflist; e != NULL && k < numifs; e = e->next) + { + if (e->numaddrs != 0) + { + (*env)->SetObjectArrayElement (env, netifs, k, e->netif); + (*env)->DeleteLocalRef (env, e->netif); + k++; + } + } + + free_netif_list (env, iflist); + freeifaddrs (ifaddrs); + return netifs; +#else + JCL_ThrowException (env, "java/net/SocketException", "getifaddrs not supported"); + return NULL; +#endif /* HAVE_IFADDRS_H && HAVE_GETIFADDRS */ +} + +int iff_flags(JNIEnv *env, jstring name, jint *flags) +{ + struct ifreq iff; + const char *iff_name; + jint socket; + int error, retval; + + if ((error = cpnet_openSocketDatagram(env, &socket, AF_INET))) + { + return error; + } + + iff_name = JCL_jstring_to_cstring(env, name); + memset(&iff, 0, sizeof(iff)); + strcpy(iff.ifr_name, iff_name); + + if (ioctl(socket, SIOCGIFFLAGS, &iff) >= 0) + { + *flags = (jint) iff.ifr_flags; + + retval = 0; + } + else + { + retval = errno; + } + + cpnet_close(env, socket); + + JCL_free_cstring(env, name, iff_name); + + return retval; +} + +JNIEXPORT jboolean JNICALL +Java_java_net_VMNetworkInterface_isUp (JNIEnv *env, jclass class UNUSED, + jstring name) +{ + jint flags; + int error; + jboolean retval; + + if ((error = iff_flags(env, name, &flags))) + { + JCL_ThrowException(env, "java/net/SocketException", + cpnative_getErrorString(error)); + + retval = JNI_FALSE; + } + else + { + retval = (flags & (IFF_UP | IFF_RUNNING)) + ? JNI_TRUE + : JNI_FALSE; + } + + return retval; +} + +JNIEXPORT jboolean JNICALL +Java_java_net_VMNetworkInterface_isPointToPoint (JNIEnv *env, + jclass class UNUSED, + jstring name) +{ + jint flags; + int error; + jboolean retval; + + if ((error = iff_flags(env, name, &flags))) + { + JCL_ThrowException(env, "java/net/SocketException", + cpnative_getErrorString(error)); + + retval = JNI_FALSE; + } + else + { + retval = (flags & IFF_POINTOPOINT) ? JNI_TRUE + : JNI_FALSE; + } + + return retval; +} + +JNIEXPORT jboolean JNICALL +Java_java_net_VMNetworkInterface_isLoopback (JNIEnv *env, + jclass class UNUSED, + jstring name) +{ + jint flags; + int error; + jboolean retval; + + if ((error = iff_flags(env, name, &flags))) + { + JCL_ThrowException(env, "java/net/SocketException", + cpnative_getErrorString(error)); + + retval = JNI_FALSE; + } + else + { + retval = (flags & IFF_LOOPBACK) ? JNI_TRUE : JNI_FALSE; + } + + return retval; +} + +JNIEXPORT jboolean JNICALL +Java_java_net_VMNetworkInterface_supportsMulticast (JNIEnv *env, + jclass class UNUSED, + jstring name) +{ + jint flags; + int error; + jboolean retval; + + if ((error = iff_flags(env, name, &flags))) + { + JCL_ThrowException(env, "java/net/SocketException", + cpnative_getErrorString(error)); + + retval = JNI_FALSE; + } + else + { + retval = (flags & IFF_MULTICAST) ? JNI_TRUE : JNI_FALSE; + } + + return retval; +} + +/* end of file */ |