764 tmp = createNetworkInterface(env, childP);
765 if (tmp == NULL) {
766 return NULL;
767 }
768 (*env)->SetObjectField(env, tmp, ni_parentID, netifObj);
769 (*env)->SetObjectArrayElement(env, childArr, child_index++, tmp);
770 childP = childP->next;
771 }
772 (*env)->SetObjectField(env, netifObj, ni_addrsID, addrArr);
773 (*env)->SetObjectField(env, netifObj, ni_bindsID, bindArr);
774 (*env)->SetObjectField(env, netifObj, ni_childsID, childArr);
775
776 // return the NetworkInterface
777 return netifObj;
778 }
779
780 /*
781 * Enumerates all interfaces
782 */
783 static netif *enumInterfaces(JNIEnv *env) {
784 netif *ifs;
785 int sock;
786
787 // Enumerate IPv4 addresses
788 sock = openSocket(env, AF_INET);
789 if (sock < 0 && (*env)->ExceptionOccurred(env)) {
790 return NULL;
791 }
792
793 ifs = enumIPv4Interfaces(env, sock, NULL);
794 close(sock);
795
796 if (ifs == NULL && (*env)->ExceptionOccurred(env)) {
797 return NULL;
798 }
799
800 // return partial list if an exception occurs in the middle of process ???
801
802 // If IPv6 is available then enumerate IPv6 addresses.
803 #ifdef AF_INET6
804
805 // User can disable ipv6 explicitly by -Djava.net.preferIPv4Stack=true,
806 // so we have to call ipv6_available()
807 if (ipv6_available()) {
808
809 sock = openSocket(env, AF_INET6);
810 if (sock < 0 && (*env)->ExceptionOccurred(env)) {
811 freeif(ifs);
812 return NULL;
813 }
814
815 ifs = enumIPv6Interfaces(env, sock, ifs);
816 close(sock);
817
818 if ((*env)->ExceptionOccurred(env)) {
819 freeif(ifs);
820 return NULL;
821 }
822
823 }
824 #endif
825
826 return ifs;
827 }
828
829 #define CHECKED_MALLOC3(_pointer, _type, _size) \
830 do { \
831 _pointer = (_type)malloc(_size); \
832 if (_pointer == NULL) { \
833 JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed"); \
834 return ifs; /* return untouched list */ \
835 } \
836 } while(0)
837
838
839 /*
840 * Frees an interface list (including any attached addresses)
841 */
1012 if (addrP->brdcast != NULL) {
1013 tmpaddr->brdcast = (struct sockaddr *)
1014 ((char *)tmpaddr + sizeof(netaddr) + addr_size);
1015 memcpy(tmpaddr->brdcast, addrP->brdcast, addr_size);
1016 }
1017
1018 tmpaddr->next = currif->addr;
1019 currif->addr = tmpaddr;
1020 }
1021
1022 return ifs;
1023 }
1024
1025 /*
1026 * Opens a socket for further ioct calls. proto is one of AF_INET or AF_INET6.
1027 */
1028 static int openSocket(JNIEnv *env, int proto) {
1029 int sock;
1030
1031 if ((sock = socket(proto, SOCK_DGRAM, 0)) < 0) {
1032 // If EPROTONOSUPPORT is returned it means we don't have
1033 // support for this proto so don't throw an exception.
1034 if (errno != EPROTONOSUPPORT) {
1035 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1036 "Socket creation failed");
1037 }
1038 return -1;
1039 }
1040
1041 return sock;
1042 }
1043
1044
1045 /** Linux, AIX **/
1046 #if defined(__linux__) || defined(_AIX)
1047
1048 #ifdef AF_INET6
1049 /*
1050 * Opens a socket for further ioct calls. Tries AF_INET socket first and
1051 * if it falls return AF_INET6 socket.
1052 */
1053 // unused arg ifname and struct if2
1054 static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
1055 int sock;
1056 struct ifreq if2;
1057
1058 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
1059 if (errno == EPROTONOSUPPORT) {
1060 if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1061 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1062 "IPV6 Socket creation failed");
1063 return -1;
1064 }
1065 } else { // errno is not NOSUPPORT
1066 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1067 "IPV4 Socket creation failed");
1068 return -1;
1069 }
1070 }
1071
1072 // Linux starting from 2.6.? kernel allows ioctl call with either IPv4 or
1073 // IPv6 socket regardless of type of address of an interface.
1074 return sock;
1075 }
1076
1077 #else
1078 static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
1079 return openSocket(env,AF_INET);
1463 *flags = if2.ifr_flags;
1464 }
1465 return 0;
1466 }
1467
1468 #endif /* defined(__linux__) || defined(_AIX) */
1469
1470 /** Solaris **/
1471 #if defined(__solaris__)
1472
1473 /*
1474 * Opens a socket for further ioct calls. Tries AF_INET socket first and
1475 * if it falls return AF_INET6 socket.
1476 */
1477 #ifdef AF_INET6
1478 static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
1479 int sock, alreadyV6 = 0;
1480 struct lifreq if2;
1481
1482 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
1483 if (errno == EPROTONOSUPPORT) {
1484 if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1485 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1486 "IPV6 Socket creation failed");
1487 return -1;
1488 }
1489
1490 alreadyV6=1;
1491 } else { // errno is not NOSUPPORT
1492 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1493 "IPV4 Socket creation failed");
1494 return -1;
1495 }
1496 }
1497
1498
1499 // Solaris requires that we have an IPv6 socket to query an interface
1500 // without an IPv4 address - check it here. POSIX 1 require the kernel to
1501 // return ENOTTY if the call is inappropriate for a device e.g. the NETMASK
1502 // for a device having IPv6 only address but not all devices follow the
1503 // standard so fall back on any error. It's not an ecologically friendly
1836 return 0;
1837 }
1838
1839
1840 #endif /* __solaris__ */
1841
1842
1843 /** BSD **/
1844 #ifdef _ALLBSD_SOURCE
1845
1846 /*
1847 * Opens a socket for further ioct calls. Tries AF_INET socket first and
1848 * if it falls return AF_INET6 socket.
1849 */
1850 #ifdef AF_INET6
1851 static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
1852 int sock;
1853 struct ifreq if2;
1854
1855 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
1856 if (errno == EPROTONOSUPPORT) {
1857 if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1858 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1859 "IPV6 Socket creation failed");
1860 return -1;
1861 }
1862 }
1863 else{ // errno is not NOSUPPORT
1864 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1865 "IPV4 Socket creation failed");
1866 return -1;
1867 }
1868 }
1869
1870 return sock;
1871 }
1872
1873 #else
1874 static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
1875 return openSocket(env,AF_INET);
1876 }
|
764 tmp = createNetworkInterface(env, childP);
765 if (tmp == NULL) {
766 return NULL;
767 }
768 (*env)->SetObjectField(env, tmp, ni_parentID, netifObj);
769 (*env)->SetObjectArrayElement(env, childArr, child_index++, tmp);
770 childP = childP->next;
771 }
772 (*env)->SetObjectField(env, netifObj, ni_addrsID, addrArr);
773 (*env)->SetObjectField(env, netifObj, ni_bindsID, bindArr);
774 (*env)->SetObjectField(env, netifObj, ni_childsID, childArr);
775
776 // return the NetworkInterface
777 return netifObj;
778 }
779
780 /*
781 * Enumerates all interfaces
782 */
783 static netif *enumInterfaces(JNIEnv *env) {
784 netif *ifs = NULL;
785 int sock;
786
787 // Enumerate IPv4 addresses
788 sock = openSocket(env, AF_INET);
789 if (sock < 0 && (*env)->ExceptionOccurred(env)) {
790 return NULL;
791 }
792
793 if (sock >= 0) {
794 ifs = enumIPv4Interfaces(env, sock, ifs);
795 close(sock);
796
797 if ((*env)->ExceptionOccurred(env)) {
798 freeif(ifs);
799 return NULL;
800 }
801 }
802
803 // return partial list if an exception occurs in the middle of process ???
804
805 // If IPv6 is available then enumerate IPv6 addresses.
806 #ifdef AF_INET6
807
808 // User can disable ipv6 explicitly by -Djava.net.preferIPv4Stack=true,
809 // so we have to call ipv6_available()
810 if (ipv6_available()) {
811
812 sock = openSocket(env, AF_INET6);
813 if (sock < 0 && (*env)->ExceptionOccurred(env)) {
814 freeif(ifs);
815 return NULL;
816 }
817
818 if (sock >= 0) {
819 ifs = enumIPv6Interfaces(env, sock, ifs);
820 close(sock);
821
822 if ((*env)->ExceptionOccurred(env)) {
823 freeif(ifs);
824 return NULL;
825 }
826 }
827
828 }
829 #endif
830
831 return ifs;
832 }
833
834 #define CHECKED_MALLOC3(_pointer, _type, _size) \
835 do { \
836 _pointer = (_type)malloc(_size); \
837 if (_pointer == NULL) { \
838 JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed"); \
839 return ifs; /* return untouched list */ \
840 } \
841 } while(0)
842
843
844 /*
845 * Frees an interface list (including any attached addresses)
846 */
1017 if (addrP->brdcast != NULL) {
1018 tmpaddr->brdcast = (struct sockaddr *)
1019 ((char *)tmpaddr + sizeof(netaddr) + addr_size);
1020 memcpy(tmpaddr->brdcast, addrP->brdcast, addr_size);
1021 }
1022
1023 tmpaddr->next = currif->addr;
1024 currif->addr = tmpaddr;
1025 }
1026
1027 return ifs;
1028 }
1029
1030 /*
1031 * Opens a socket for further ioct calls. proto is one of AF_INET or AF_INET6.
1032 */
1033 static int openSocket(JNIEnv *env, int proto) {
1034 int sock;
1035
1036 if ((sock = socket(proto, SOCK_DGRAM, 0)) < 0) {
1037 // Don't throw an exception if the address family, or protocol, is not
1038 // supported.
1039 if (!(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)) {
1040 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1041 "Socket creation failed");
1042 }
1043 return -1;
1044 }
1045
1046 return sock;
1047 }
1048
1049
1050 /** Linux, AIX **/
1051 #if defined(__linux__) || defined(_AIX)
1052
1053 #ifdef AF_INET6
1054 /*
1055 * Opens a socket for further ioct calls. Tries AF_INET socket first and
1056 * if it falls return AF_INET6 socket.
1057 */
1058 // unused arg ifname and struct if2
1059 static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
1060 int sock;
1061 struct ifreq if2;
1062
1063 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
1064 if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) {
1065 if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1066 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1067 "IPV6 Socket creation failed");
1068 return -1;
1069 }
1070 } else { // errno is not NOSUPPORT
1071 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1072 "IPV4 Socket creation failed");
1073 return -1;
1074 }
1075 }
1076
1077 // Linux starting from 2.6.? kernel allows ioctl call with either IPv4 or
1078 // IPv6 socket regardless of type of address of an interface.
1079 return sock;
1080 }
1081
1082 #else
1083 static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
1084 return openSocket(env,AF_INET);
1468 *flags = if2.ifr_flags;
1469 }
1470 return 0;
1471 }
1472
1473 #endif /* defined(__linux__) || defined(_AIX) */
1474
1475 /** Solaris **/
1476 #if defined(__solaris__)
1477
1478 /*
1479 * Opens a socket for further ioct calls. Tries AF_INET socket first and
1480 * if it falls return AF_INET6 socket.
1481 */
1482 #ifdef AF_INET6
1483 static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
1484 int sock, alreadyV6 = 0;
1485 struct lifreq if2;
1486
1487 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
1488 if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) {
1489 if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1490 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1491 "IPV6 Socket creation failed");
1492 return -1;
1493 }
1494
1495 alreadyV6=1;
1496 } else { // errno is not NOSUPPORT
1497 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1498 "IPV4 Socket creation failed");
1499 return -1;
1500 }
1501 }
1502
1503
1504 // Solaris requires that we have an IPv6 socket to query an interface
1505 // without an IPv4 address - check it here. POSIX 1 require the kernel to
1506 // return ENOTTY if the call is inappropriate for a device e.g. the NETMASK
1507 // for a device having IPv6 only address but not all devices follow the
1508 // standard so fall back on any error. It's not an ecologically friendly
1841 return 0;
1842 }
1843
1844
1845 #endif /* __solaris__ */
1846
1847
1848 /** BSD **/
1849 #ifdef _ALLBSD_SOURCE
1850
1851 /*
1852 * Opens a socket for further ioct calls. Tries AF_INET socket first and
1853 * if it falls return AF_INET6 socket.
1854 */
1855 #ifdef AF_INET6
1856 static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
1857 int sock;
1858 struct ifreq if2;
1859
1860 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
1861 if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) {
1862 if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1863 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1864 "IPV6 Socket creation failed");
1865 return -1;
1866 }
1867 }
1868 else{ // errno is not NOSUPPORT
1869 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1870 "IPV4 Socket creation failed");
1871 return -1;
1872 }
1873 }
1874
1875 return sock;
1876 }
1877
1878 #else
1879 static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
1880 return openSocket(env,AF_INET);
1881 }
|