53
54
55 #if defined(_ALLBSD_SOURCE) && !defined(HAS_GLIBC_GETHOSTBY_R)
56 extern jobjectArray lookupIfLocalhost(JNIEnv *env, const char *hostname, jboolean includeV6);
57
58 /* Use getaddrinfo(3), which is thread safe */
59 /************************************************************************
60 * Inet4AddressImpl
61 */
62
63 /*
64 * Class: java_net_Inet4AddressImpl
65 * Method: getLocalHostName
66 * Signature: ()Ljava/lang/String;
67 */
68 JNIEXPORT jstring JNICALL
69 Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
70 char hostname[NI_MAXHOST+1];
71
72 hostname[0] = '\0';
73 if (JVM_GetHostName(hostname, NI_MAXHOST)) {
74 /* Something went wrong, maybe networking is not setup? */
75 strcpy(hostname, "localhost");
76 } else {
77 struct addrinfo hints, *res;
78 int error;
79
80 memset(&hints, 0, sizeof(hints));
81 hints.ai_flags = AI_CANONNAME;
82 hints.ai_family = AF_UNSPEC;
83
84 error = getaddrinfo(hostname, NULL, &hints, &res);
85
86 if (error == 0) {
87 /* host is known to name service */
88 error = getnameinfo(res->ai_addr,
89 res->ai_addrlen,
90 hostname,
91 NI_MAXHOST,
92 NULL,
93 0,
315
316 /* the initial size of our hostent buffers */
317 #ifndef NI_MAXHOST
318 #define NI_MAXHOST 1025
319 #endif
320
321 /************************************************************************
322 * Inet4AddressImpl
323 */
324
325 /*
326 * Class: java_net_Inet4AddressImpl
327 * Method: getLocalHostName
328 * Signature: ()Ljava/lang/String;
329 */
330 JNIEXPORT jstring JNICALL
331 Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
332 char hostname[NI_MAXHOST+1];
333
334 hostname[0] = '\0';
335 if (JVM_GetHostName(hostname, sizeof(hostname))) {
336 /* Something went wrong, maybe networking is not setup? */
337 strcpy(hostname, "localhost");
338 } else {
339 struct addrinfo hints, *res;
340 int error;
341
342 hostname[NI_MAXHOST] = '\0';
343 memset(&hints, 0, sizeof(hints));
344 hints.ai_flags = AI_CANONNAME;
345 hints.ai_family = AF_INET;
346
347 error = getaddrinfo(hostname, NULL, &hints, &res);
348
349 if (error == 0) {/* host is known to name service */
350 getnameinfo(res->ai_addr,
351 res->ai_addrlen,
352 hostname,
353 NI_MAXHOST,
354 NULL,
355 0,
712 * for it.
713 */
714 if (!(IS_NULL(ifArray))) {
715 memset((char *) caddr, 0, sizeof(caddr));
716 (*env)->GetByteArrayRegion(env, ifArray, 0, 4, caddr);
717 addr = ((caddr[0]<<24) & 0xff000000);
718 addr |= ((caddr[1] <<16) & 0xff0000);
719 addr |= ((caddr[2] <<8) & 0xff00);
720 addr |= (caddr[3] & 0xff);
721 addr = htonl(addr);
722 inf.sin_addr.s_addr = addr;
723 inf.sin_family = AF_INET;
724 inf.sin_port = 0;
725 netif = &inf;
726 }
727
728 /*
729 * Let's try to create a RAW socket to send ICMP packets
730 * This usually requires "root" privileges, so it's likely to fail.
731 */
732 fd = JVM_Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
733 if (fd != -1) {
734 /*
735 * It didn't fail, so we can use ICMP_ECHO requests.
736 */
737 return ping4(env, fd, &him, timeout, netif, ttl);
738 }
739
740 /*
741 * Can't create a raw socket, so let's try a TCP socket
742 */
743 fd = JVM_Socket(AF_INET, SOCK_STREAM, 0);
744 if (fd == JVM_IO_ERR) {
745 /* note: if you run out of fds, you may not be able to load
746 * the exception class, and get a NoClassDefFoundError
747 * instead.
748 */
749 NET_ThrowNew(env, errno, "Can't create socket");
750 return JNI_FALSE;
751 }
752 if (ttl > 0) {
753 setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
754 }
755
756 /*
757 * A network interface was specified, so let's bind to it.
758 */
759 if (netif != NULL) {
760 if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in)) < 0) {
761 NET_ThrowNew(env, errno, "Can't bind socket");
762 close(fd);
763 return JNI_FALSE;
764 }
765 }
766
767 /*
768 * Make the socket non blocking so we can use select/poll.
769 */
770 SET_NONBLOCKING(fd);
771
772 /* no need to use NET_Connect as non-blocking */
773 him.sin_port = htons(7); /* Echo */
774 connect_rv = JVM_Connect(fd, (struct sockaddr *)&him, len);
775
776 /**
777 * connection established or refused immediately, either way it means
778 * we were able to reach the host!
779 */
780 if (connect_rv == 0 || errno == ECONNREFUSED) {
781 close(fd);
782 return JNI_TRUE;
783 } else {
784 int optlen;
785
786 switch (errno) {
787 case ENETUNREACH: /* Network Unreachable */
788 case EAFNOSUPPORT: /* Address Family not supported */
789 case EADDRNOTAVAIL: /* address is not available on the remote machine */
790 #ifdef __linux__
791 case EINVAL:
792 case EHOSTUNREACH:
793 /*
794 * On some Linux versions, when a socket is bound to the loopback
795 * interface, connect will fail and errno will be set to EINVAL
796 * or EHOSTUNREACH. When that happens, don't throw an exception,
797 * just return false.
798 */
799 #endif /* __linux__ */
800 close(fd);
801 return JNI_FALSE;
802 }
803
804 if (errno != EINPROGRESS) {
805 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
806 "connect failed");
807 close(fd);
808 return JNI_FALSE;
809 }
810
811 timeout = NET_Wait(env, fd, NET_WAIT_CONNECT, timeout);
812 if (timeout >= 0) {
813 /* has connection been established? */
814 optlen = sizeof(connect_rv);
815 if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
816 &optlen) <0) {
817 connect_rv = errno;
818 }
819 if (connect_rv == 0 || connect_rv == ECONNREFUSED) {
820 close(fd);
821 return JNI_TRUE;
822 }
823 }
824 close(fd);
825 return JNI_FALSE;
826 }
827 }
|
53
54
55 #if defined(_ALLBSD_SOURCE) && !defined(HAS_GLIBC_GETHOSTBY_R)
56 extern jobjectArray lookupIfLocalhost(JNIEnv *env, const char *hostname, jboolean includeV6);
57
58 /* Use getaddrinfo(3), which is thread safe */
59 /************************************************************************
60 * Inet4AddressImpl
61 */
62
63 /*
64 * Class: java_net_Inet4AddressImpl
65 * Method: getLocalHostName
66 * Signature: ()Ljava/lang/String;
67 */
68 JNIEXPORT jstring JNICALL
69 Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
70 char hostname[NI_MAXHOST+1];
71
72 hostname[0] = '\0';
73 if (gethostname(hostname, NI_MAXHOST)) {
74 /* Something went wrong, maybe networking is not setup? */
75 strcpy(hostname, "localhost");
76 } else {
77 struct addrinfo hints, *res;
78 int error;
79
80 memset(&hints, 0, sizeof(hints));
81 hints.ai_flags = AI_CANONNAME;
82 hints.ai_family = AF_UNSPEC;
83
84 error = getaddrinfo(hostname, NULL, &hints, &res);
85
86 if (error == 0) {
87 /* host is known to name service */
88 error = getnameinfo(res->ai_addr,
89 res->ai_addrlen,
90 hostname,
91 NI_MAXHOST,
92 NULL,
93 0,
315
316 /* the initial size of our hostent buffers */
317 #ifndef NI_MAXHOST
318 #define NI_MAXHOST 1025
319 #endif
320
321 /************************************************************************
322 * Inet4AddressImpl
323 */
324
325 /*
326 * Class: java_net_Inet4AddressImpl
327 * Method: getLocalHostName
328 * Signature: ()Ljava/lang/String;
329 */
330 JNIEXPORT jstring JNICALL
331 Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
332 char hostname[NI_MAXHOST+1];
333
334 hostname[0] = '\0';
335 if (gethostname(hostname, NI_MAXHOST)) {
336 /* Something went wrong, maybe networking is not setup? */
337 strcpy(hostname, "localhost");
338 } else {
339 struct addrinfo hints, *res;
340 int error;
341
342 hostname[NI_MAXHOST] = '\0';
343 memset(&hints, 0, sizeof(hints));
344 hints.ai_flags = AI_CANONNAME;
345 hints.ai_family = AF_INET;
346
347 error = getaddrinfo(hostname, NULL, &hints, &res);
348
349 if (error == 0) {/* host is known to name service */
350 getnameinfo(res->ai_addr,
351 res->ai_addrlen,
352 hostname,
353 NI_MAXHOST,
354 NULL,
355 0,
712 * for it.
713 */
714 if (!(IS_NULL(ifArray))) {
715 memset((char *) caddr, 0, sizeof(caddr));
716 (*env)->GetByteArrayRegion(env, ifArray, 0, 4, caddr);
717 addr = ((caddr[0]<<24) & 0xff000000);
718 addr |= ((caddr[1] <<16) & 0xff0000);
719 addr |= ((caddr[2] <<8) & 0xff00);
720 addr |= (caddr[3] & 0xff);
721 addr = htonl(addr);
722 inf.sin_addr.s_addr = addr;
723 inf.sin_family = AF_INET;
724 inf.sin_port = 0;
725 netif = &inf;
726 }
727
728 /*
729 * Let's try to create a RAW socket to send ICMP packets
730 * This usually requires "root" privileges, so it's likely to fail.
731 */
732 fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
733 if (fd != -1) {
734 /*
735 * It didn't fail, so we can use ICMP_ECHO requests.
736 */
737 return ping4(env, fd, &him, timeout, netif, ttl);
738 }
739
740 /*
741 * Can't create a raw socket, so let's try a TCP socket
742 */
743 fd = socket(AF_INET, SOCK_STREAM, 0);
744 if (fd == -1) {
745 /* note: if you run out of fds, you may not be able to load
746 * the exception class, and get a NoClassDefFoundError
747 * instead.
748 */
749 NET_ThrowNew(env, errno, "Can't create socket");
750 return JNI_FALSE;
751 }
752 if (ttl > 0) {
753 setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
754 }
755
756 /*
757 * A network interface was specified, so let's bind to it.
758 */
759 if (netif != NULL) {
760 if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in)) < 0) {
761 NET_ThrowNew(env, errno, "Can't bind socket");
762 close(fd);
763 return JNI_FALSE;
764 }
765 }
766
767 /*
768 * Make the socket non blocking so we can use select/poll.
769 */
770 SET_NONBLOCKING(fd);
771
772 him.sin_port = htons(7); /* Echo */
773 connect_rv = NET_Connect(fd, (struct sockaddr *)&him, len);
774
775 /**
776 * connection established or refused immediately, either way it means
777 * we were able to reach the host!
778 */
779 if (connect_rv == 0 || errno == ECONNREFUSED) {
780 close(fd);
781 return JNI_TRUE;
782 } else {
783 socklen_t optlen = (socklen_t)sizeof(connect_rv);
784
785 switch (errno) {
786 case ENETUNREACH: /* Network Unreachable */
787 case EAFNOSUPPORT: /* Address Family not supported */
788 case EADDRNOTAVAIL: /* address is not available on the remote machine */
789 #ifdef __linux__
790 case EINVAL:
791 case EHOSTUNREACH:
792 /*
793 * On some Linux versions, when a socket is bound to the loopback
794 * interface, connect will fail and errno will be set to EINVAL
795 * or EHOSTUNREACH. When that happens, don't throw an exception,
796 * just return false.
797 */
798 #endif /* __linux__ */
799 close(fd);
800 return JNI_FALSE;
801 }
802
803 if (errno != EINPROGRESS) {
804 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
805 "connect failed");
806 close(fd);
807 return JNI_FALSE;
808 }
809
810 timeout = NET_Wait(env, fd, NET_WAIT_CONNECT, timeout);
811 if (timeout >= 0) {
812 /* has connection been established? */
813 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
814 &optlen) <0) {
815 connect_rv = errno;
816 }
817 if (connect_rv == 0 || connect_rv == ECONNREFUSED) {
818 close(fd);
819 return JNI_TRUE;
820 }
821 }
822 close(fd);
823 return JNI_FALSE;
824 }
825 }
|