networkinterface.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 851 行 · 第 1/2 页

C
851
字号
/* * @(#)NetworkInterface.c	1.8 06/10/10  * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation.  *  * This program 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 version 2 for more details (a copy is * included at /legal/license.txt).  *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA  *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions.  */#include <errno.h>#include <strings.h>#include <netinet/in.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <net/if.h>#ifdef __linux__#include <sys/ioctl.h>#include <bits/ioctls.h>#include <linux/sockios.h>#include <stdio.h>#else#include <sys/sockio.h>#endif#ifdef __linux__#define ifr_index ifr_ifindex#define _PATH_PROCNET_IFINET6           "/proc/net/if_inet6"#endif#include "jvm.h"#include "jni_util.h"#include "net_util.h"typedef struct _netaddr  {    struct sockaddr *addr;    int family; /* to make searches simple */    struct _netaddr *next;} netaddr;typedef struct _netif {    char *name;    int index;    netaddr *addr;    struct _netif *next;} netif;/************************************************************************ * NetworkInterface */#include "java_net_NetworkInterface.h"/************************************************************************ * NetworkInterface */jclass ni_class;jfieldID ni_nameID;jfieldID ni_indexID;jfieldID ni_descID;jfieldID ni_addrsID;jmethodID ni_ctrID;static jclass ni_iacls;static jclass ni_ia4cls;static jclass ni_ia6cls;static jmethodID ni_ia4ctrID;static jmethodID ni_ia6ctrID;static jfieldID ni_iaaddressID;static jfieldID ni_iafamilyID;static jfieldID ni_ia6ipaddressID;static jobject createNetworkInterface(JNIEnv *env, netif *ifs);static netif *enumInterfaces(JNIEnv *env);static netif *enumIPv4Interfaces(JNIEnv *env, netif *ifs);#ifdef AF_INET6static netif *enumIPv6Interfaces(JNIEnv *env, netif *ifs);#endifstatic netif *addif(JNIEnv *env, netif *ifs, char *if_name, int index, 		    int family, struct sockaddr *new_addrP, int new_addrlen);static void freeif(netif *ifs);/* * Class:     java_net_NetworkInterface * Method:    init * Signature: ()V */JNIEXPORT void JNICALLJava_java_net_NetworkInterface_init(JNIEnv *env, jclass cls) {    init_IPv6Available(env);    ni_class = (*env)->FindClass(env,"java/net/NetworkInterface");    ni_class = (*env)->NewGlobalRef(env, ni_class);    ni_nameID = (*env)->GetFieldID(env, ni_class,"name", "Ljava/lang/String;");    ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I");    ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", "[Ljava/net/InetAddress;");    ni_descID = (*env)->GetFieldID(env, ni_class, "displayName", "Ljava/lang/String;");    ni_ctrID = (*env)->GetMethodID(env, ni_class, "<init>", "()V");    ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");    ni_iacls = (*env)->NewGlobalRef(env, ni_iacls);    ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");    ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);    ni_ia6cls = (*env)->FindClass(env, "java/net/Inet6Address");    ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls);    ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");    ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V");    ni_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I");    ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I");    ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B");}/* * Class:     java_net_NetworkInterface * Method:    getByName0 * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface; */JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0    (JNIEnv *env, jclass cls, jstring name) {    netif *ifs, *curr;    jboolean isCopy;    const char* name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);    jobject obj = NULL;    ifs = enumInterfaces(env);    if (ifs == NULL) {	return NULL;    }    /*     * Search the list of interface based on name     */    curr = ifs;    while (curr != NULL) {        if (strcmp(name_utf, curr->name) == 0) {            break;        }        curr = curr->next;    }    /* if found create a NetworkInterface */    if (curr != NULL) {;        obj = createNetworkInterface(env, curr);    }    /* release the UTF string and interface list */    (*env)->ReleaseStringUTFChars(env, name, name_utf);    freeif(ifs);    return obj;}/* * Class:     java_net_NetworkInterface * Method:    getByIndex * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface; */JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex    (JNIEnv *env, jclass cls, jint index) {    netif *ifs, *curr;    jobject obj = NULL;    if (index <= 0) {        return NULL;    }    ifs = enumInterfaces(env);    if (ifs == NULL) {        return NULL;    }    /*     * Search the list of interface based on index     */    curr = ifs;    while (curr != NULL) {	if (index == curr->index) {            break;        }        curr = curr->next;    }    /* if found create a NetworkInterface */    if (curr != NULL) {;        obj = createNetworkInterface(env, curr);    }    freeif(ifs);    return obj;}/* * Class:     java_net_NetworkInterface * Method:    getByInetAddress0 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface; */JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0    (JNIEnv *env, jclass cls, jobject iaObj) {    netif *ifs, *curr;    int family = (*env)->GetIntField(env, iaObj, ni_iafamilyID) == IPv4?        AF_INET : AF_INET6;    jobject obj = NULL;    jboolean match = JNI_FALSE;    ifs = enumInterfaces(env);    if (ifs == NULL) {	return NULL;    }    curr = ifs;    while (curr != NULL) {	netaddr *addrP = curr->addr;	/*	 * Iterate through each address on the interface	 */	while (addrP != NULL) {	    if (family == addrP->family) {		if (family == AF_INET) {		    int address1 = htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr);                    int address2 = (*env)->GetIntField(env, iaObj, ni_iaaddressID);                    if (address1 == address2) {			match = JNI_TRUE;			break;		    }		}#ifdef AF_INET6		if (family == AF_INET6) {		    jbyte *bytes = (jbyte *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr);		    jbyteArray ipaddress = (*env)->GetObjectField(env, iaObj, ni_ia6ipaddressID);		    jbyte caddr[16];		    int i;		    (*env)->GetByteArrayRegion(env, ipaddress, 0, 16, caddr);		    i = 0;		    while (i < 16) {                        if (caddr[i] != bytes[i]) {			    break;			}			i++;                    }		    if (i >= 16) {			match = JNI_TRUE;			break;		    }		}#endif	    }	    if (match) {		break;	    }	    addrP = addrP->next;	}	if (match) {	    break;	}	curr = curr->next;    }    /* if found create a NetworkInterface */    if (match) {;        obj = createNetworkInterface(env, curr);    }    freeif(ifs);    return obj;}/* * Class:     java_net_NetworkInterface * Method:    getAll * Signature: ()[Ljava/net/NetworkInterface; */JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll    (JNIEnv *env, jclass cls) {    netif *ifs, *curr;    jobjectArray netIFArr;    jint arr_index, ifCount;    ifs = enumInterfaces(env);    if (ifs == NULL) {        return NULL;    }    /* count the interface */    ifCount = 0;    curr = ifs;    while (curr != NULL) { 	ifCount++;	curr = curr->next;    }     /* allocate a NetworkInterface array */    netIFArr = (*env)->NewObjectArray(env, ifCount, cls, NULL);    if (netIFArr == NULL) {	freeif(ifs);        return NULL;    }    /*     * Iterate through the interfaces, create a NetworkInterface instance     * for each array element and populate the object.     */    curr = ifs;    arr_index = 0;    while (curr != NULL) {        jobject netifObj;        netifObj = createNetworkInterface(env, curr);        if (netifObj == NULL) {	    freeif(ifs);            return NULL;        }        /* put the NetworkInterface into the array */        (*env)->SetObjectArrayElement(env, netIFArr, arr_index++, netifObj);        curr = curr->next;    }    free(ifs);    return netIFArr;}/* * Create a NetworkInterface object, populate the name and index, and * populate the InetAddress array based on the IP addresses for this * interface. */jobject createNetworkInterface(JNIEnv *env, netif *ifs){    jobject netifObj;    jobject name;    jobjectArray addrArr;    /* eliminate compile time warning       netaddr *addrs;    */    jint addr_index, addr_count;    netaddr *addrP;    /*     * Create a NetworkInterface object and populate it     */    netifObj = (*env)->NewObject(env, ni_class, ni_ctrID);     name = (*env)->NewStringUTF(env, ifs->name);    if (netifObj == NULL || name == NULL) {        return NULL;    }    (*env)->SetObjectField(env, netifObj, ni_nameID, name);    (*env)->SetObjectField(env, netifObj, ni_descID, name);     (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index);    /*     * Count the number of address on this interface     */    addr_count = 0;    addrP = ifs->addr;    while (addrP != NULL) {	addr_count++;  	addrP = addrP->next;    }    /*     * Create the array of InetAddresses     */    addrArr = (*env)->NewObjectArray(env, addr_count,  ni_iacls, NULL);    if (addrArr == NULL) {        return NULL;    }    addrP = ifs->addr;    addr_index = 0;    while (addrP != NULL) {	jobject iaObj = NULL;	if (addrP->family == AF_INET) {            iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);            if (iaObj) {                 (*env)->SetIntField(env, iaObj, ni_iaaddressID,                      htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr));	    }	}#ifdef AF_INET6	if (addrP->family == AF_INET6) {	    iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID);		    if (iaObj) {		jbyteArray ipaddress = (*env)->NewByteArray(env, 16);		if (ipaddress == NULL) {		    return NULL;		}		(*env)->SetByteArrayRegion(env, ipaddress, 0, 16,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?