70 static EnumerateNetAddresses enumAddresses_fn;
71
72 /* Windows 9x routines are external (not needed on 64-bit) */
73 #ifndef _WIN64
74 extern int enumInterfaces_win9x(JNIEnv *, netif **);
75 extern int enumAddresses_win9x(JNIEnv *, netif *, netaddr **);
76 extern int init_win9x(void);
77 #endif
78
79
80 /* Windows 95/98/ME running */
81 static jboolean isW9x;
82
83 /* Windows version supports */
84 static jboolean os_supports_ipv6;
85
86 /* various JNI ids */
87
88 jclass ni_class; /* NetworkInterface */
89
90 jmethodID ni_ctor; /* NetworkInterface() */
91
92 jfieldID ni_indexID; /* NetworkInterface.index */
93 jfieldID ni_addrsID; /* NetworkInterface.addrs */
94 jfieldID ni_bindsID; /* NetworkInterface.bindings */
95 jfieldID ni_nameID; /* NetworkInterface.name */
96 jfieldID ni_displayNameID; /* NetworkInterface.displayName */
97 jfieldID ni_childsID; /* NetworkInterface.childs */
98 jclass ni_iacls; /* InetAddress */
99 jfieldID ni_iaAddr; /* InetAddress.address */
100
101 jclass ni_ia4cls; /* Inet4Address */
102 jmethodID ni_ia4Ctor; /* Inet4Address() */
103
104 jclass ni_ia6cls; /* Inet6Address */
105 jmethodID ni_ia6ctrID; /* Inet6Address() */
106 jfieldID ni_ia6ipaddressID;
107 jfieldID ni_ia6ipaddressID;
108
109 jclass ni_ibcls; /* InterfaceAddress */
110 jmethodID ni_ibctrID; /* InterfaceAddress() */
111 jfieldID ni_ibaddressID; /* InterfaceAddress.address */
112 jfieldID ni_ibbroadcastID; /* InterfaceAddress.broadcast */
113 jfieldID ni_ibmaskID; /* InterfaceAddress.maskLength */
114
115 /*
116 * Support routines to free netif and netaddr lists
117 */
118 void free_netif(netif *netifP) {
119 netif *curr = netifP;
120 while (curr != NULL) {
121 if (curr->name != NULL)
122 free(curr->name);
123 if (curr->displayName != NULL)
124 free(curr->displayName);
125 if (curr->addrs != NULL)
126 free_netaddr (curr->addrs);
127 netifP = netifP->next;
128 free(curr);
528 if (isW9x) {
529 /* Use Windows 9x registry approach which requires initialization */
530 enumInterfaces_fn = enumInterfaces_win9x;
531 enumAddresses_fn = enumAddresses_win9x;
532 init_win9x();
533 } else
534 #endif
535 {
536 JNU_ThrowByName(env, "java/lang/Error",
537 "Incompatible IP helper library (iphlpapi.dll)");
538 return;
539 }
540 } else {
541 enumInterfaces_fn = enumInterfaces_win;
542 enumAddresses_fn = enumAddresses_win;
543 }
544
545 /*
546 * Get the various JNI ids that we require
547 */
548 ni_class = (*env)->NewGlobalRef(env, cls);
549 ni_nameID = (*env)->GetFieldID(env, ni_class, "name", "Ljava/lang/String;");
550 ni_displayNameID = (*env)->GetFieldID(env, ni_class, "displayName", "Ljava/lang/String;");
551 ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I");
552 ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", "[Ljava/net/InetAddress;");
553 ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings", "[Ljava/net/InterfaceAddress;");
554 ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", "[Ljava/net/NetworkInterface;");
555 ni_ctor = (*env)->GetMethodID(env, ni_class, "<init>", "()V");
556
557 ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
558 ni_iacls = (*env)->NewGlobalRef(env, ni_iacls);
559 ni_iaAddr = (*env)->GetFieldID(env, ni_iacls, "address", "I");
560
561 ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");
562 ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);
563 ni_ia4Ctor = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
564
565 ni_ia6cls = (*env)->FindClass(env, "java/net/Inet6Address");
566 ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls);
567 ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V");
568 ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B");
569
570 ni_ibcls = (*env)->FindClass(env, "java/net/InterfaceAddress");
571 ni_ibcls = (*env)->NewGlobalRef(env, ni_ibcls);
572 ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V");
573 ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;");
574 ni_ibbroadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;");
575 ni_ibmaskID = (*env)->GetFieldID(env, ni_ibcls, "maskLength", "S");
576
577 }
578
579 /*
580 * Create a NetworkInterface object, populate the name and index, and
581 * populate the InetAddress array based on the IP addresses for this
582 * interface.
583 */
584 jobject createNetworkInterface(JNIEnv *env, netif *ifs, int netaddrCount, netaddr *netaddrP)
585 {
586 jobject netifObj;
587 jobject name, displayName;
588 jobjectArray addrArr, bindsArr, childArr;
589 netaddr *addrs;
590 jint addr_index;
591 jint bind_index;
592
593 /*
594 * Create a NetworkInterface object and populate it
595 */
596 netifObj = (*env)->NewObject(env, ni_class, ni_ctor);
597 name = (*env)->NewStringUTF(env, ifs->name);
598 if (ifs->dNameIsUnicode) {
599 displayName = (*env)->NewString(env, (PWCHAR)ifs->displayName, wcslen ((PWCHAR)ifs->displayName));
600 } else {
601 displayName = (*env)->NewStringUTF(env, ifs->displayName);
602 }
603 if (netifObj == NULL || name == NULL || displayName == NULL) {
604 return NULL;
605 }
606 (*env)->SetObjectField(env, netifObj, ni_nameID, name);
607 (*env)->SetObjectField(env, netifObj, ni_displayNameID, displayName);
608 (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index);
609
610 /*
611 * Get the IP addresses for this interface if necessary
612 * Note that 0 is a valid number of addresses.
613 */
614 if (netaddrCount < 0) {
615 netaddrCount = (*enumAddresses_fn)(env, ifs, &netaddrP);
616 if ((*env)->ExceptionOccurred(env)) {
617 free_netaddr(netaddrP);
618 return NULL;
619 }
620 }
621 addrArr = (*env)->NewObjectArray(env, netaddrCount, ni_iacls, NULL);
622 if (addrArr == NULL) {
623 free_netaddr(netaddrP);
624 return NULL;
625 }
626
627 bindsArr = (*env)->NewObjectArray(env, netaddrCount, ni_ibcls, NULL);
628 if (bindsArr == NULL) {
629 free_netaddr(netaddrP);
630 return NULL;
631 }
632 addrs = netaddrP;
633 addr_index = 0;
634 bind_index = 0;
635 while (addrs != NULL) {
636 jobject iaObj, ia2Obj;
637 jobject ibObj = NULL;
638 if (addrs->addr.him.sa_family == AF_INET) {
639 iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4Ctor);
640 if (iaObj == NULL) {
641 free_netaddr(netaddrP);
642 return NULL;
643 }
644 /* default ctor will set family to AF_INET */
645
646 (*env)->SetIntField(env, iaObj, ni_iaAddr, ntohl(addrs->addr.him4.sin_addr.s_addr));
647 if (addrs->mask != -1) {
648 ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
649 if (ibObj == NULL) {
650 free_netaddr(netaddrP);
651 return NULL;
652 }
653 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
654 ia2Obj = (*env)->NewObject(env, ni_ia4cls, ni_ia4Ctor);
655 if (ia2Obj == NULL) {
656 free_netaddr(netaddrP);
657 return NULL;
658 }
659 (*env)->SetIntField(env, ia2Obj, ni_iaAddr,
660 ntohl(addrs->brdcast.him4.sin_addr.s_addr));
661 (*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
662 (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
663 (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
664 }
665 } else /* AF_INET6 */ {
666 int scope;
667 iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID);
668 if (iaObj) {
669 jbyteArray ipaddress = (*env)->NewByteArray(env, 16);
670 if (ipaddress == NULL) {
671 return NULL;
672 }
673 (*env)->SetByteArrayRegion(env, ipaddress, 0, 16,
674 (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr));
675 scope = addrs->addr.him6.sin6_scope_id;
676 if (scope != 0) { /* zero is default value, no need to set */
677 (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
678 (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
679 (*env)->SetObjectField(env, iaObj, ia6_scopeifnameID, netifObj);
680 }
681 (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress);
682 ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
683 if (ibObj == NULL) {
684 free_netaddr(netaddrP);
685 return NULL;
686 }
687 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
688 (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
689 (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
690 }
691 }
692 (*env)->SetObjectArrayElement(env, addrArr, addr_index, iaObj);
693 addrs = addrs->next;
694 addr_index++;
695 }
696 (*env)->SetObjectField(env, netifObj, ni_addrsID, addrArr);
697 (*env)->SetObjectField(env, netifObj, ni_bindsID, bindsArr);
698
699 free_netaddr(netaddrP);
700
701 /*
792 /* if found create a NetworkInterface */
793 if (curr != NULL) {
794 netifObj = createNetworkInterface(env, curr, -1, NULL);
795 }
796
797 /* release the interface list */
798 free_netif(ifList);
799
800 return netifObj;
801 }
802
803 /*
804 * Class: java_net_NetworkInterface
805 * Method: getByInetAddress0
806 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
807 */
808 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
809 (JNIEnv *env, jclass cls, jobject iaObj)
810 {
811 netif *ifList, *curr;
812 jint addr = (*env)->GetIntField(env, iaObj, ni_iaAddr);
813 jobject netifObj = NULL;
814
815 if (os_supports_ipv6 && ipv6_available()) {
816 return Java_java_net_NetworkInterface_getByInetAddress0_XP (env, cls, iaObj);
817 }
818
819 /* get the list of interfaces */
820 if ((*enumInterfaces_fn)(env, &ifList) < 0) {
821 return NULL;
822 }
823
824 /*
825 * Enumerate the addresses on each interface until we find a
826 * matching address.
827 */
828 curr = ifList;
829 while (curr != NULL) {
830 int count;
831 netaddr *addrList;
832 netaddr *addrP;
|
70 static EnumerateNetAddresses enumAddresses_fn;
71
72 /* Windows 9x routines are external (not needed on 64-bit) */
73 #ifndef _WIN64
74 extern int enumInterfaces_win9x(JNIEnv *, netif **);
75 extern int enumAddresses_win9x(JNIEnv *, netif *, netaddr **);
76 extern int init_win9x(void);
77 #endif
78
79
80 /* Windows 95/98/ME running */
81 static jboolean isW9x;
82
83 /* Windows version supports */
84 static jboolean os_supports_ipv6;
85
86 /* various JNI ids */
87
88 jclass ni_class; /* NetworkInterface */
89
90 jmethodID ni_ctrID; /* NetworkInterface() */
91
92 jfieldID ni_indexID; /* NetworkInterface.index */
93 jfieldID ni_addrsID; /* NetworkInterface.addrs */
94 jfieldID ni_bindsID; /* NetworkInterface.bindings */
95 jfieldID ni_nameID; /* NetworkInterface.name */
96 jfieldID ni_displayNameID; /* NetworkInterface.displayName */
97 jfieldID ni_childsID; /* NetworkInterface.childs */
98
99 jclass ni_ibcls; /* InterfaceAddress */
100 jmethodID ni_ibctrID; /* InterfaceAddress() */
101 jfieldID ni_ibaddressID; /* InterfaceAddress.address */
102 jfieldID ni_ibbroadcastID; /* InterfaceAddress.broadcast */
103 jfieldID ni_ibmaskID; /* InterfaceAddress.maskLength */
104
105 /*
106 * Support routines to free netif and netaddr lists
107 */
108 void free_netif(netif *netifP) {
109 netif *curr = netifP;
110 while (curr != NULL) {
111 if (curr->name != NULL)
112 free(curr->name);
113 if (curr->displayName != NULL)
114 free(curr->displayName);
115 if (curr->addrs != NULL)
116 free_netaddr (curr->addrs);
117 netifP = netifP->next;
118 free(curr);
518 if (isW9x) {
519 /* Use Windows 9x registry approach which requires initialization */
520 enumInterfaces_fn = enumInterfaces_win9x;
521 enumAddresses_fn = enumAddresses_win9x;
522 init_win9x();
523 } else
524 #endif
525 {
526 JNU_ThrowByName(env, "java/lang/Error",
527 "Incompatible IP helper library (iphlpapi.dll)");
528 return;
529 }
530 } else {
531 enumInterfaces_fn = enumInterfaces_win;
532 enumAddresses_fn = enumAddresses_win;
533 }
534
535 /*
536 * Get the various JNI ids that we require
537 */
538 if (ni_ibmaskID == NULL) {
539 ni_class = (*env)->NewGlobalRef(env, cls);
540 ni_nameID = (*env)->GetFieldID(env, ni_class, "name", "Ljava/lang/String;");
541 ni_displayNameID = (*env)->GetFieldID(env, ni_class, "displayName", "Ljava/lang/String;");
542 ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I");
543 ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", "[Ljava/net/InetAddress;");
544 ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings", "[Ljava/net/InterfaceAddress;");
545 ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", "[Ljava/net/NetworkInterface;");
546 ni_ctrID = (*env)->GetMethodID(env, ni_class, "<init>", "()V");
547
548 init(env);
549
550 ni_ibcls = (*env)->FindClass(env, "java/net/InterfaceAddress");
551 ni_ibcls = (*env)->NewGlobalRef(env, ni_ibcls);
552 ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V");
553 ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;");
554 ni_ibbroadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;");
555 ni_ibmaskID = (*env)->GetFieldID(env, ni_ibcls, "maskLength", "S");
556 }
557 }
558
559 /*
560 * Create a NetworkInterface object, populate the name and index, and
561 * populate the InetAddress array based on the IP addresses for this
562 * interface.
563 */
564 jobject createNetworkInterface(JNIEnv *env, netif *ifs, int netaddrCount, netaddr *netaddrP)
565 {
566 jobject netifObj;
567 jobject name, displayName;
568 jobjectArray addrArr, bindsArr, childArr;
569 netaddr *addrs;
570 jint addr_index;
571 jint bind_index;
572
573 /*
574 * Create a NetworkInterface object and populate it
575 */
576 netifObj = (*env)->NewObject(env, ni_class, ni_ctrID);
577 name = (*env)->NewStringUTF(env, ifs->name);
578 if (ifs->dNameIsUnicode) {
579 displayName = (*env)->NewString(env, (PWCHAR)ifs->displayName, wcslen ((PWCHAR)ifs->displayName));
580 } else {
581 displayName = (*env)->NewStringUTF(env, ifs->displayName);
582 }
583 if (netifObj == NULL || name == NULL || displayName == NULL) {
584 return NULL;
585 }
586 (*env)->SetObjectField(env, netifObj, ni_nameID, name);
587 (*env)->SetObjectField(env, netifObj, ni_displayNameID, displayName);
588 (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index);
589
590 /*
591 * Get the IP addresses for this interface if necessary
592 * Note that 0 is a valid number of addresses.
593 */
594 if (netaddrCount < 0) {
595 netaddrCount = (*enumAddresses_fn)(env, ifs, &netaddrP);
596 if ((*env)->ExceptionOccurred(env)) {
597 free_netaddr(netaddrP);
598 return NULL;
599 }
600 }
601 addrArr = (*env)->NewObjectArray(env, netaddrCount, ia_class, NULL);
602 if (addrArr == NULL) {
603 free_netaddr(netaddrP);
604 return NULL;
605 }
606
607 bindsArr = (*env)->NewObjectArray(env, netaddrCount, ni_ibcls, NULL);
608 if (bindsArr == NULL) {
609 free_netaddr(netaddrP);
610 return NULL;
611 }
612 addrs = netaddrP;
613 addr_index = 0;
614 bind_index = 0;
615 while (addrs != NULL) {
616 jobject iaObj, ia2Obj;
617 jobject ibObj = NULL;
618 if (addrs->addr.him.sa_family == AF_INET) {
619 iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
620 if (iaObj == NULL) {
621 free_netaddr(netaddrP);
622 return NULL;
623 }
624 /* default ctor will set family to AF_INET */
625
626 (*env)->SetIntField(env, iaObj, ia_addressID, ntohl(addrs->addr.him4.sin_addr.s_addr));
627 if (addrs->mask != -1) {
628 ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
629 if (ibObj == NULL) {
630 free_netaddr(netaddrP);
631 return NULL;
632 }
633 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
634 ia2Obj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
635 if (ia2Obj == NULL) {
636 free_netaddr(netaddrP);
637 return NULL;
638 }
639 (*env)->SetIntField(env, ia2Obj, ia_addressID,
640 ntohl(addrs->brdcast.him4.sin_addr.s_addr));
641 (*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
642 (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
643 (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
644 }
645 } else /* AF_INET6 */ {
646 int scope;
647 iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
648 if (iaObj) {
649 jbyteArray ipaddress = (*env)->NewByteArray(env, 16);
650 if (ipaddress == NULL) {
651 return NULL;
652 }
653 (*env)->SetByteArrayRegion(env, ipaddress, 0, 16,
654 (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr));
655 scope = addrs->addr.him6.sin6_scope_id;
656 if (scope != 0) { /* zero is default value, no need to set */
657 (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
658 (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
659 (*env)->SetObjectField(env, iaObj, ia6_scopeifnameID, netifObj);
660 }
661 (*env)->SetObjectField(env, iaObj, ia6_ipaddressID, ipaddress);
662 ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
663 if (ibObj == NULL) {
664 free_netaddr(netaddrP);
665 return NULL;
666 }
667 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
668 (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
669 (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
670 }
671 }
672 (*env)->SetObjectArrayElement(env, addrArr, addr_index, iaObj);
673 addrs = addrs->next;
674 addr_index++;
675 }
676 (*env)->SetObjectField(env, netifObj, ni_addrsID, addrArr);
677 (*env)->SetObjectField(env, netifObj, ni_bindsID, bindsArr);
678
679 free_netaddr(netaddrP);
680
681 /*
772 /* if found create a NetworkInterface */
773 if (curr != NULL) {
774 netifObj = createNetworkInterface(env, curr, -1, NULL);
775 }
776
777 /* release the interface list */
778 free_netif(ifList);
779
780 return netifObj;
781 }
782
783 /*
784 * Class: java_net_NetworkInterface
785 * Method: getByInetAddress0
786 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
787 */
788 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
789 (JNIEnv *env, jclass cls, jobject iaObj)
790 {
791 netif *ifList, *curr;
792 jint addr = (*env)->GetIntField(env, iaObj, ia_addressID);
793 jobject netifObj = NULL;
794
795 if (os_supports_ipv6 && ipv6_available()) {
796 return Java_java_net_NetworkInterface_getByInetAddress0_XP (env, cls, iaObj);
797 }
798
799 /* get the list of interfaces */
800 if ((*enumInterfaces_fn)(env, &ifList) < 0) {
801 return NULL;
802 }
803
804 /*
805 * Enumerate the addresses on each interface until we find a
806 * matching address.
807 */
808 curr = ifList;
809 while (curr != NULL) {
810 int count;
811 netaddr *addrList;
812 netaddr *addrP;
|