77 /************************************************************************ 78 * NetworkInterface 79 */ 80 81 #include "java_net_NetworkInterface.h" 82 83 /************************************************************************ 84 * NetworkInterface 85 */ 86 jclass ni_class; 87 jfieldID ni_nameID; 88 jfieldID ni_indexID; 89 jfieldID ni_descID; 90 jfieldID ni_addrsID; 91 jfieldID ni_bindsID; 92 jfieldID ni_virutalID; 93 jfieldID ni_childsID; 94 jfieldID ni_parentID; 95 jmethodID ni_ctrID; 96 97 static jclass ni_iacls; 98 static jclass ni_ia4cls; 99 static jclass ni_ia6cls; 100 static jclass ni_ibcls; 101 static jmethodID ni_ia4ctrID; 102 static jmethodID ni_ia6ctrID; 103 static jmethodID ni_ibctrID; 104 static jfieldID ni_iaaddressID; 105 static jfieldID ni_iafamilyID; 106 static jfieldID ni_ia6ipaddressID; 107 static jfieldID ni_ibaddressID; 108 static jfieldID ni_ib4broadcastID; 109 static jfieldID ni_ib4maskID; 110 111 static jobject createNetworkInterface(JNIEnv *env, netif *ifs); 112 113 static netif *enumInterfaces(JNIEnv *env); 114 static netif *enumIPv4Interfaces(JNIEnv *env, netif *ifs); 115 #ifdef AF_INET6 116 static netif *enumIPv6Interfaces(JNIEnv *env, netif *ifs); 117 #endif 118 119 static netif *addif(JNIEnv *env, netif *ifs, char *if_name, int index, 120 int family, struct sockaddr *new_addrP, int new_addrlen, 121 short prefix); 122 static void freeif(netif *ifs); 123 static struct sockaddr *getBroadcast(JNIEnv *env, const char *ifname); 124 static short getSubnet(JNIEnv *env, const char *ifname); 125 126 /* 127 * Class: java_net_NetworkInterface 128 * Method: init 129 * Signature: ()V 130 */ 131 JNIEXPORT void JNICALL 132 Java_java_net_NetworkInterface_init(JNIEnv *env, jclass cls) { 133 ni_class = (*env)->FindClass(env,"java/net/NetworkInterface"); 134 ni_class = (*env)->NewGlobalRef(env, ni_class); 135 ni_nameID = (*env)->GetFieldID(env, ni_class,"name", "Ljava/lang/String;"); 136 ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I"); 137 ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", "[Ljava/net/InetAddress;"); 138 ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings", "[Ljava/net/InterfaceAddress;"); 139 ni_descID = (*env)->GetFieldID(env, ni_class, "displayName", "Ljava/lang/String;"); 140 ni_virutalID = (*env)->GetFieldID(env, ni_class, "virtual", "Z"); 141 ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", "[Ljava/net/NetworkInterface;"); 142 ni_parentID = (*env)->GetFieldID(env, ni_class, "parent", "Ljava/net/NetworkInterface;"); 143 ni_ctrID = (*env)->GetMethodID(env, ni_class, "<init>", "()V"); 144 145 ni_iacls = (*env)->FindClass(env, "java/net/InetAddress"); 146 ni_iacls = (*env)->NewGlobalRef(env, ni_iacls); 147 ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address"); 148 ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls); 149 ni_ia6cls = (*env)->FindClass(env, "java/net/Inet6Address"); 150 ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls); 151 ni_ibcls = (*env)->FindClass(env, "java/net/InterfaceAddress"); 152 ni_ibcls = (*env)->NewGlobalRef(env, ni_ibcls); 153 ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V"); 154 ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V"); 155 ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V"); 156 ni_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I"); 157 ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I"); 158 ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B"); 159 ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;"); 160 ni_ib4broadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;"); 161 ni_ib4maskID = (*env)->GetFieldID(env, ni_ibcls, "maskLength", "S"); 162 } 163 164 165 /* 166 * Class: java_net_NetworkInterface 167 * Method: getByName0 168 * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface; 169 */ 170 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0 171 (JNIEnv *env, jclass cls, jstring name) { 172 173 netif *ifs, *curr; 174 jboolean isCopy; 175 const char* name_utf = (*env)->GetStringUTFChars(env, name, &isCopy); 176 jobject obj = NULL; 177 178 ifs = enumInterfaces(env); 179 if (ifs == NULL) { 180 return NULL; 181 } 237 238 /* if found create a NetworkInterface */ 239 if (curr != NULL) {; 240 obj = createNetworkInterface(env, curr); 241 } 242 243 freeif(ifs); 244 return obj; 245 } 246 247 /* 248 * Class: java_net_NetworkInterface 249 * Method: getByInetAddress0 250 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface; 251 */ 252 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0 253 (JNIEnv *env, jclass cls, jobject iaObj) { 254 255 netif *ifs, *curr; 256 #ifdef AF_INET6 257 int family = (*env)->GetIntField(env, iaObj, ni_iafamilyID) == IPv4? 258 AF_INET : AF_INET6; 259 #else 260 int family = AF_INET; 261 #endif 262 jobject obj = NULL; 263 jboolean match = JNI_FALSE; 264 265 ifs = enumInterfaces(env); 266 if (ifs == NULL) { 267 return NULL; 268 } 269 270 curr = ifs; 271 while (curr != NULL) { 272 netaddr *addrP = curr->addr; 273 274 /* 275 * Iterate through each address on the interface 276 */ 277 while (addrP != NULL) { 278 279 if (family == addrP->family) { 280 if (family == AF_INET) { 281 int address1 = htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr); 282 int address2 = (*env)->GetIntField(env, iaObj, ni_iaaddressID); 283 284 if (address1 == address2) { 285 match = JNI_TRUE; 286 break; 287 } 288 } 289 290 #ifdef AF_INET6 291 if (family == AF_INET6) { 292 jbyte *bytes = (jbyte *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr); 293 jbyteArray ipaddress = (*env)->GetObjectField(env, iaObj, ni_ia6ipaddressID); 294 jbyte caddr[16]; 295 int i; 296 297 (*env)->GetByteArrayRegion(env, ipaddress, 0, 16, caddr); 298 i = 0; 299 while (i < 16) { 300 if (caddr[i] != bytes[i]) { 301 break; 302 } 303 i++; 304 } 305 if (i >= 16) { 306 match = JNI_TRUE; 307 break; 308 } 309 } 310 #endif 311 312 } 313 417 return NULL; 418 } 419 (*env)->SetObjectField(env, netifObj, ni_nameID, name); 420 (*env)->SetObjectField(env, netifObj, ni_descID, name); 421 (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index); 422 (*env)->SetBooleanField(env, netifObj, ni_virutalID, ifs->virtual ? JNI_TRUE : JNI_FALSE); 423 424 /* 425 * Count the number of address on this interface 426 */ 427 addr_count = 0; 428 addrP = ifs->addr; 429 while (addrP != NULL) { 430 addr_count++; 431 addrP = addrP->next; 432 } 433 434 /* 435 * Create the array of InetAddresses 436 */ 437 addrArr = (*env)->NewObjectArray(env, addr_count, ni_iacls, NULL); 438 if (addrArr == NULL) { 439 return NULL; 440 } 441 442 bindArr = (*env)->NewObjectArray(env, addr_count, ni_ibcls, NULL); 443 if (bindArr == NULL) { 444 return NULL; 445 } 446 addrP = ifs->addr; 447 addr_index = 0; 448 bind_index = 0; 449 while (addrP != NULL) { 450 jobject iaObj = NULL; 451 jobject ibObj = NULL; 452 453 if (addrP->family == AF_INET) { 454 iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID); 455 if (iaObj) { 456 (*env)->SetIntField(env, iaObj, ni_iaaddressID, 457 htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr)); 458 } 459 ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID); 460 if (ibObj) { 461 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj); 462 if (addrP->brdcast) { 463 jobject ia2Obj = NULL; 464 ia2Obj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID); 465 if (ia2Obj) { 466 (*env)->SetIntField(env, ia2Obj, ni_iaaddressID, 467 htonl(((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr)); 468 (*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj); 469 (*env)->SetShortField(env, ibObj, ni_ib4maskID, addrP->mask); 470 } 471 } 472 (*env)->SetObjectArrayElement(env, bindArr, bind_index++, ibObj); 473 } 474 } 475 476 #ifdef AF_INET6 477 if (addrP->family == AF_INET6) { 478 int scope=0; 479 iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID); 480 if (iaObj) { 481 jbyteArray ipaddress = (*env)->NewByteArray(env, 16); 482 if (ipaddress == NULL) { 483 return NULL; 484 } 485 (*env)->SetByteArrayRegion(env, ipaddress, 0, 16, 486 (jbyte *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr)); 487 #ifdef __linux__ 488 if (!kernelIsV22()) { 489 scope = ((struct sockaddr_in6*)addrP->addr)->sin6_scope_id; 490 } 491 #else 492 scope = ((struct sockaddr_in6*)addrP->addr)->sin6_scope_id; 493 #endif 494 if (scope != 0) { /* zero is default value, no need to set */ 495 (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope); 496 (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE); 497 (*env)->SetObjectField(env, iaObj, ia6_scopeifnameID, netifObj); 498 } 499 (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress); 500 } 501 ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID); 502 if (ibObj) { 503 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj); 504 (*env)->SetShortField(env, ibObj, ni_ib4maskID, addrP->mask); 505 (*env)->SetObjectArrayElement(env, bindArr, bind_index++, ibObj); 506 } 507 } 508 #endif 509 510 if (iaObj == NULL) { 511 return NULL; 512 } 513 514 (*env)->SetObjectArrayElement(env, addrArr, addr_index++, iaObj); 515 addrP = addrP->next; 516 } 517 518 /* 519 * See if there is any virtual interface attached to this one. | 77 /************************************************************************ 78 * NetworkInterface 79 */ 80 81 #include "java_net_NetworkInterface.h" 82 83 /************************************************************************ 84 * NetworkInterface 85 */ 86 jclass ni_class; 87 jfieldID ni_nameID; 88 jfieldID ni_indexID; 89 jfieldID ni_descID; 90 jfieldID ni_addrsID; 91 jfieldID ni_bindsID; 92 jfieldID ni_virutalID; 93 jfieldID ni_childsID; 94 jfieldID ni_parentID; 95 jmethodID ni_ctrID; 96 97 static jclass ni_ibcls; 98 static jmethodID ni_ibctrID; 99 static jfieldID ni_ibaddressID; 100 static jfieldID ni_ib4broadcastID; 101 static jfieldID ni_ib4maskID; 102 103 static jobject createNetworkInterface(JNIEnv *env, netif *ifs); 104 105 static netif *enumInterfaces(JNIEnv *env); 106 static netif *enumIPv4Interfaces(JNIEnv *env, netif *ifs); 107 #ifdef AF_INET6 108 static netif *enumIPv6Interfaces(JNIEnv *env, netif *ifs); 109 #endif 110 111 static netif *addif(JNIEnv *env, netif *ifs, char *if_name, int index, 112 int family, struct sockaddr *new_addrP, int new_addrlen, 113 short prefix); 114 static void freeif(netif *ifs); 115 static struct sockaddr *getBroadcast(JNIEnv *env, const char *ifname); 116 static short getSubnet(JNIEnv *env, const char *ifname); 117 118 /* 119 * Class: java_net_NetworkInterface 120 * Method: init 121 * Signature: ()V 122 */ 123 JNIEXPORT void JNICALL 124 Java_java_net_NetworkInterface_init(JNIEnv *env, jclass cls) { 125 if (ni_ib4maskID == NULL) { 126 ni_class = (*env)->FindClass(env,"java/net/NetworkInterface"); 127 ni_class = (*env)->NewGlobalRef(env, ni_class); 128 ni_nameID = (*env)->GetFieldID(env, ni_class,"name", "Ljava/lang/String;"); 129 ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I"); 130 ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", "[Ljava/net/InetAddress;"); 131 ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings", "[Ljava/net/InterfaceAddress;"); 132 ni_descID = (*env)->GetFieldID(env, ni_class, "displayName", "Ljava/lang/String;"); 133 ni_virutalID = (*env)->GetFieldID(env, ni_class, "virtual", "Z"); 134 ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", "[Ljava/net/NetworkInterface;"); 135 ni_parentID = (*env)->GetFieldID(env, ni_class, "parent", "Ljava/net/NetworkInterface;"); 136 ni_ctrID = (*env)->GetMethodID(env, ni_class, "<init>", "()V"); 137 138 ni_ibcls = (*env)->FindClass(env, "java/net/InterfaceAddress"); 139 ni_ibcls = (*env)->NewGlobalRef(env, ni_ibcls); 140 ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V"); 141 ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;"); 142 ni_ib4broadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;"); 143 ni_ib4maskID = (*env)->GetFieldID(env, ni_ibcls, "maskLength", "S"); 144 } 145 146 init(env); 147 } 148 149 150 /* 151 * Class: java_net_NetworkInterface 152 * Method: getByName0 153 * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface; 154 */ 155 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0 156 (JNIEnv *env, jclass cls, jstring name) { 157 158 netif *ifs, *curr; 159 jboolean isCopy; 160 const char* name_utf = (*env)->GetStringUTFChars(env, name, &isCopy); 161 jobject obj = NULL; 162 163 ifs = enumInterfaces(env); 164 if (ifs == NULL) { 165 return NULL; 166 } 222 223 /* if found create a NetworkInterface */ 224 if (curr != NULL) {; 225 obj = createNetworkInterface(env, curr); 226 } 227 228 freeif(ifs); 229 return obj; 230 } 231 232 /* 233 * Class: java_net_NetworkInterface 234 * Method: getByInetAddress0 235 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface; 236 */ 237 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0 238 (JNIEnv *env, jclass cls, jobject iaObj) { 239 240 netif *ifs, *curr; 241 #ifdef AF_INET6 242 int family = (*env)->GetIntField(env, iaObj, ia_familyID) == IPv4? 243 AF_INET : AF_INET6; 244 #else 245 int family = AF_INET; 246 #endif 247 jobject obj = NULL; 248 jboolean match = JNI_FALSE; 249 250 ifs = enumInterfaces(env); 251 if (ifs == NULL) { 252 return NULL; 253 } 254 255 curr = ifs; 256 while (curr != NULL) { 257 netaddr *addrP = curr->addr; 258 259 /* 260 * Iterate through each address on the interface 261 */ 262 while (addrP != NULL) { 263 264 if (family == addrP->family) { 265 if (family == AF_INET) { 266 int address1 = htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr); 267 int address2 = (*env)->GetIntField(env, iaObj, ia_addressID); 268 269 if (address1 == address2) { 270 match = JNI_TRUE; 271 break; 272 } 273 } 274 275 #ifdef AF_INET6 276 if (family == AF_INET6) { 277 jbyte *bytes = (jbyte *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr); 278 jbyteArray ipaddress = (*env)->GetObjectField(env, iaObj, ia6_ipaddressID); 279 jbyte caddr[16]; 280 int i; 281 282 (*env)->GetByteArrayRegion(env, ipaddress, 0, 16, caddr); 283 i = 0; 284 while (i < 16) { 285 if (caddr[i] != bytes[i]) { 286 break; 287 } 288 i++; 289 } 290 if (i >= 16) { 291 match = JNI_TRUE; 292 break; 293 } 294 } 295 #endif 296 297 } 298 402 return NULL; 403 } 404 (*env)->SetObjectField(env, netifObj, ni_nameID, name); 405 (*env)->SetObjectField(env, netifObj, ni_descID, name); 406 (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index); 407 (*env)->SetBooleanField(env, netifObj, ni_virutalID, ifs->virtual ? JNI_TRUE : JNI_FALSE); 408 409 /* 410 * Count the number of address on this interface 411 */ 412 addr_count = 0; 413 addrP = ifs->addr; 414 while (addrP != NULL) { 415 addr_count++; 416 addrP = addrP->next; 417 } 418 419 /* 420 * Create the array of InetAddresses 421 */ 422 addrArr = (*env)->NewObjectArray(env, addr_count, ia_class, NULL); 423 if (addrArr == NULL) { 424 return NULL; 425 } 426 427 bindArr = (*env)->NewObjectArray(env, addr_count, ni_ibcls, NULL); 428 if (bindArr == NULL) { 429 return NULL; 430 } 431 addrP = ifs->addr; 432 addr_index = 0; 433 bind_index = 0; 434 while (addrP != NULL) { 435 jobject iaObj = NULL; 436 jobject ibObj = NULL; 437 438 if (addrP->family == AF_INET) { 439 iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID); 440 if (iaObj) { 441 (*env)->SetIntField(env, iaObj, ia_addressID, 442 htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr)); 443 } 444 ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID); 445 if (ibObj) { 446 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj); 447 if (addrP->brdcast) { 448 jobject ia2Obj = NULL; 449 ia2Obj = (*env)->NewObject(env, ia4_class, ia4_ctrID); 450 if (ia2Obj) { 451 (*env)->SetIntField(env, ia2Obj, ia_addressID, 452 htonl(((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr)); 453 (*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj); 454 (*env)->SetShortField(env, ibObj, ni_ib4maskID, addrP->mask); 455 } 456 } 457 (*env)->SetObjectArrayElement(env, bindArr, bind_index++, ibObj); 458 } 459 } 460 461 #ifdef AF_INET6 462 if (addrP->family == AF_INET6) { 463 int scope=0; 464 iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID); 465 if (iaObj) { 466 jbyteArray ipaddress = (*env)->NewByteArray(env, 16); 467 if (ipaddress == NULL) { 468 return NULL; 469 } 470 (*env)->SetByteArrayRegion(env, ipaddress, 0, 16, 471 (jbyte *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr)); 472 #ifdef __linux__ 473 if (!kernelIsV22()) { 474 scope = ((struct sockaddr_in6*)addrP->addr)->sin6_scope_id; 475 } 476 #else 477 scope = ((struct sockaddr_in6*)addrP->addr)->sin6_scope_id; 478 #endif 479 if (scope != 0) { /* zero is default value, no need to set */ 480 (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope); 481 (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE); 482 (*env)->SetObjectField(env, iaObj, ia6_scopeifnameID, netifObj); 483 } 484 (*env)->SetObjectField(env, iaObj, ia6_ipaddressID, ipaddress); 485 } 486 ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID); 487 if (ibObj) { 488 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj); 489 (*env)->SetShortField(env, ibObj, ni_ib4maskID, addrP->mask); 490 (*env)->SetObjectArrayElement(env, bindArr, bind_index++, ibObj); 491 } 492 } 493 #endif 494 495 if (iaObj == NULL) { 496 return NULL; 497 } 498 499 (*env)->SetObjectArrayElement(env, addrArr, addr_index++, iaObj); 500 addrP = addrP->next; 501 } 502 503 /* 504 * See if there is any virtual interface attached to this one. |