// allocate array - at this point i contains the number of addresses
ret = (*env)->NewObjectArray(env, i, ia_class, NULL); if (IS_NULL(ret)) { goto cleanupAndReturn;
}
i = 0;
iterator = resNew; while (iterator != NULL) {
jobject iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID); if (IS_NULL(iaObj)) {
ret = NULL; goto cleanupAndReturn;
}
setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in *)
(iterator->ai_addr))->sin_addr.s_addr)); if ((*env)->ExceptionCheck(env)) goto cleanupAndReturn;
setInetAddress_hostName(env, iaObj, host); if ((*env)->ExceptionCheck(env)) goto cleanupAndReturn;
(*env)->SetObjectArrayElement(env, ret, i++, iaObj);
iterator = iterator->ai_next;
}
}
cleanupAndReturn:
JNU_ReleaseStringPlatformChars(env, host, hostname); while (resNew != NULL) {
last = resNew;
resNew = resNew->ai_next;
free(last);
} if (res != NULL) {
freeaddrinfo(res);
} return ret;
}
// open a TCP socket
fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) { // note: if you run out of fds, you may not be able to load // the exception class, and get a NoClassDefFoundError instead.
NET_ThrowNew(env, errno, "Can't create socket"); return JNI_FALSE;
}
// set TTL if (ttl > 0) {
setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
}
// A network interface was specified, so let's bind to it. if (netif != NULL) { if (bind(fd, &netif->sa, sizeof(struct sockaddr_in)) < 0) {
NET_ThrowNew(env, errno, "Can't bind socket");
close(fd); return JNI_FALSE;
}
}
// Make the socket non blocking so we can use select/poll.
SET_NONBLOCKING(fd);
// connection established or refused immediately, either way it means // we were able to reach the host! if (connect_rv == 0 || errno == ECONNREFUSED) {
close(fd); return JNI_TRUE;
}
switch (errno) { case ENETUNREACH: // Network Unreachable case EAFNOSUPPORT: // Address Family not supported case EADDRNOTAVAIL: // address is not available on the remote machine #ifdefined(__linux__) || defined(_AIX) // On some Linux versions, when a socket is bound to the loopback // interface, connect will fail and errno will be set to EINVAL // or EHOSTUNREACH. When that happens, don't throw an exception, // just return false. case EINVAL: case EHOSTUNREACH: // No route to host #endif
close(fd); return JNI_FALSE; case EINPROGRESS: // this is expected as we'll probably have to wait break; default:
NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException", "connect failed");
close(fd); return JNI_FALSE;
}
timeout = NET_Wait(env, fd, NET_WAIT_CONNECT, timeout); if (timeout >= 0) { // connection has been established, check for error condition
socklen_t optlen = (socklen_t)sizeof(connect_rv); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
&optlen) <0)
{
connect_rv = errno;
} if (connect_rv == 0 || connect_rv == ECONNREFUSED) {
close(fd); return JNI_TRUE;
}
}
close(fd); return JNI_FALSE;
}
// sets the ttl (max number of hops) if (ttl > 0) {
setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
}
// a specific interface was specified, so let's bind the socket // to that interface to ensure the requests are sent only through it. if (netif != NULL) { if (bind(fd, &netif->sa, sizeof(struct sockaddr_in)) < 0) {
NET_ThrowNew(env, errno, "Can't bind socket");
close(fd); return JNI_FALSE;
}
}
// icmp_id is a 16 bit data type, therefore down cast the pid
pid = (jchar)getpid();
// Make the socket non blocking so we can use select
SET_NONBLOCKING(fd); do { // create the ICMP request
icmp = (struct icmp *)sendbuf;
icmp->icmp_type = ICMP_ECHO;
icmp->icmp_code = 0; // let's tag the ECHO packet with our pid so we can identify it
icmp->icmp_id = htons(pid);
icmp->icmp_seq = htons(seq);
seq++;
gettimeofday(&tv, NULL);
memcpy(icmp->icmp_data, &tv, sizeof(tv));
icmp->icmp_cksum = 0; // manually calculate checksum
icmp->icmp_cksum = in_cksum((u_short *)icmp, plen); // send it
n = sendto(fd, sendbuf, plen, 0, &sa->sa, sizeof(struct sockaddr_in)); if (n < 0 && errno != EINPROGRESS) { #ifdefined(__linux__) /* *OnsomeLinuxversions,whenasocketisboundtotheloopback *interface,sendtowillfailanderrnowillbesetto *EINVALorEHOSTUNREACH.Whenthathappens,don'tthrowan *exception,justreturnfalse.
*/ if (errno != EINVAL && errno != EHOSTUNREACH) {
NET_ThrowNew(env, errno, "Can't send ICMP packet");
} #else
NET_ThrowNew(env, errno, "Can't send ICMP packet"); #endif
close(fd); return JNI_FALSE;
}
tmout2 = timeout > 1000 ? 1000 : timeout; do {
tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2); if (tmout2 >= 0) {
len = sizeof(sa_recv);
n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0,
(struct sockaddr *)&sa_recv, &len); // check if we received enough data if (n < (jint)sizeof(struct ip)) { continue;
}
ip = (struct ip *)recvbuf;
hlen = ((jint)(unsignedint)(ip->ip_hl)) << 2; // check if we received enough data if (n < (jint)(hlen + sizeof(struct icmp))) { continue;
}
icmp = (struct icmp *)(recvbuf + hlen); // We did receive something, but is it what we were expecting? // I.E.: An ICMP_ECHO_REPLY packet with the proper PID and // from the host that we are trying to determine is reachable. if (icmp->icmp_type == ICMP_ECHOREPLY &&
(ntohs(icmp->icmp_id) == pid))
{ if (sa->sa4.sin_addr.s_addr == sa_recv.sin_addr.s_addr) {
close(fd); return JNI_TRUE;
} elseif (sa->sa4.sin_addr.s_addr == 0) {
close(fd); return JNI_TRUE;
}
}
}
} while (tmout2 > 0);
timeout -= 1000;
} while (timeout > 0);
close(fd); return JNI_FALSE;
}
// Let's try to create a RAW socket to send ICMP packets. // This usually requires "root" privileges, so it's likely to fail.
fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (fd == -1) { return tcp_ping4(env, &sa, netif, timeout, ttl);
} else { // It didn't fail, so we can use ICMP_ECHO requests. return ping4(env, fd, &sa, netif, timeout, ttl);
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-06-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.