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 } else 517 #endif /*__linux__ */ 518 NET_ThrowNew(env, errno, "Can't send ICMP packet"); 519 close(fd); 520 return JNI_FALSE; 521 } 522 523 tmout2 = timeout > 1000 ? 1000 : timeout; 524 do { 525 tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2); 526 527 if (tmout2 >= 0) { 528 len = sizeof(sa_recv); 529 n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr*) &sa_recv, &len); 530 icmp6 = (struct icmp6_hdr *) (recvbuf); 531 recv_caddr = (jbyte *)&(sa_recv.sin6_addr); 532 /* 533 * We did receive something, but is it what we were expecting? 534 * I.E.: An ICMP6_ECHO_REPLY packet with the proper PID and 535 * from the host that we are trying to determine is reachable. 536 */ 537 if (n >= 8 && icmp6->icmp6_type == ICMP6_ECHO_REPLY && 538 (ntohs(icmp6->icmp6_id) == pid) && 539 NET_IsEqual(caddr, recv_caddr)) { |