src/solaris/native/java/net/Inet6AddressImpl.c

Print this page




 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)) {