489 close(fd); 490 return JNI_FALSE; 491 } 492 } 493 SET_NONBLOCKING(fd); 494 495 do { 496 icmp6 = (struct icmp6_hdr *) sendbuf; 497 icmp6->icmp6_type = ICMP6_ECHO_REQUEST; 498 icmp6->icmp6_code = 0; 499 /* let's tag the ECHO packet with our pid so we can identify it */ 500 icmp6->icmp6_id = htons(pid); 501 icmp6->icmp6_seq = htons(seq); 502 seq++; 503 icmp6->icmp6_cksum = 0; 504 gettimeofday(&tv, NULL); 505 memcpy(sendbuf + sizeof(struct icmp6_hdr), &tv, sizeof(tv)); 506 plen = sizeof(struct icmp6_hdr) + sizeof(tv); 507 n = sendto(fd, sendbuf, plen, 0, (struct sockaddr*) him, sizeof(struct sockaddr_in6)); 508 if (n < 0 && errno != EINPROGRESS) { 509 NET_ThrowNew(env, errno, "Can't send ICMP packet"); 510 return JNI_FALSE; 511 } 512 513 tmout2 = timeout > 1000 ? 1000 : timeout; 514 do { 515 tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2); 516 517 if (tmout2 >= 0) { 518 len = sizeof(sa_recv); 519 n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr*) &sa_recv, &len); 520 icmp6 = (struct icmp6_hdr *) (recvbuf); 521 recv_caddr = (jbyte *)&(sa_recv.sin6_addr); 522 /* 523 * We did receive something, but is it what we were expecting? 524 * I.E.: An ICMP6_ECHO_REPLY packet with the proper PID and 525 * from the host that we are trying to determine is reachable. 526 */ 527 if (n >= 8 && icmp6->icmp6_type == ICMP6_ECHO_REPLY && 528 (ntohs(icmp6->icmp6_id) == pid) && 529 NET_IsEqual(caddr, recv_caddr)) { | 489 close(fd); 490 return JNI_FALSE; 491 } 492 } 493 SET_NONBLOCKING(fd); 494 495 do { 496 icmp6 = (struct icmp6_hdr *) sendbuf; 497 icmp6->icmp6_type = ICMP6_ECHO_REQUEST; 498 icmp6->icmp6_code = 0; 499 /* let's tag the ECHO packet with our pid so we can identify it */ 500 icmp6->icmp6_id = htons(pid); 501 icmp6->icmp6_seq = htons(seq); 502 seq++; 503 icmp6->icmp6_cksum = 0; 504 gettimeofday(&tv, NULL); 505 memcpy(sendbuf + sizeof(struct icmp6_hdr), &tv, sizeof(tv)); 506 plen = sizeof(struct icmp6_hdr) + sizeof(tv); 507 n = sendto(fd, sendbuf, plen, 0, (struct sockaddr*) him, sizeof(struct sockaddr_in6)); 508 if (n < 0 && errno != EINPROGRESS) { 509 #ifdef __linux__ 510 if (errno == EINVAL) { 511 /* 512 * On some Linuxes, when bound to the loopback interface, sendto 513 * will fail and errno will be set to EINVAL. When that happens, 514 * don't throw an exception, just return false. 515 */ 516 close(fd); 517 return JNI_FALSE; 518 } 519 #endif /*__linux__ */ 520 NET_ThrowNew(env, errno, "Can't send ICMP packet"); 521 close(fd); 522 return JNI_FALSE; 523 } 524 525 tmout2 = timeout > 1000 ? 1000 : timeout; 526 do { 527 tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2); 528 529 if (tmout2 >= 0) { 530 len = sizeof(sa_recv); 531 n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr*) &sa_recv, &len); 532 icmp6 = (struct icmp6_hdr *) (recvbuf); 533 recv_caddr = (jbyte *)&(sa_recv.sin6_addr); 534 /* 535 * We did receive something, but is it what we were expecting? 536 * I.E.: An ICMP6_ECHO_REPLY packet with the proper PID and 537 * from the host that we are trying to determine is reachable. 538 */ 539 if (n >= 8 && icmp6->icmp6_type == ICMP6_ECHO_REPLY && 540 (ntohs(icmp6->icmp6_id) == pid) && 541 NET_IsEqual(caddr, recv_caddr)) { |