364 /* 365 * create the ICMP request 366 */ 367 icmp = (struct icmp *) sendbuf; 368 icmp->icmp_type = ICMP_ECHO; 369 icmp->icmp_code = 0; 370 icmp->icmp_id = htons(pid); 371 icmp->icmp_seq = htons(seq); 372 seq++; 373 gettimeofday(&tv, NULL); 374 memcpy(icmp->icmp_data, &tv, sizeof(tv)); 375 plen = ICMP_ADVLENMIN + sizeof(tv); 376 icmp->icmp_cksum = 0; 377 icmp->icmp_cksum = in_cksum((u_short *)icmp, plen); 378 /* 379 * send it 380 */ 381 n = sendto(fd, sendbuf, plen, 0, (struct sockaddr *)him, 382 sizeof(struct sockaddr)); 383 if (n < 0 && errno != EINPROGRESS ) { 384 NET_ThrowNew(env, errno, "Can't send ICMP packet"); 385 close(fd); 386 return JNI_FALSE; 387 } 388 389 tmout2 = timeout > 1000 ? 1000 : timeout; 390 do { 391 tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2); 392 if (tmout2 >= 0) { 393 len = sizeof(sa_recv); 394 n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&sa_recv, &len); 395 ip = (struct ip*) recvbuf; 396 hlen1 = (ip->ip_hl) << 2; 397 icmp = (struct icmp *) (recvbuf + hlen1); 398 icmplen = n - hlen1; 399 /* 400 * We did receive something, but is it what we were expecting? 401 * I.E.: A ICMP_ECHOREPLY packet with the proper PID. 402 */ 403 if (icmplen >= 8 && icmp->icmp_type == ICMP_ECHOREPLY && | 364 /* 365 * create the ICMP request 366 */ 367 icmp = (struct icmp *) sendbuf; 368 icmp->icmp_type = ICMP_ECHO; 369 icmp->icmp_code = 0; 370 icmp->icmp_id = htons(pid); 371 icmp->icmp_seq = htons(seq); 372 seq++; 373 gettimeofday(&tv, NULL); 374 memcpy(icmp->icmp_data, &tv, sizeof(tv)); 375 plen = ICMP_ADVLENMIN + sizeof(tv); 376 icmp->icmp_cksum = 0; 377 icmp->icmp_cksum = in_cksum((u_short *)icmp, plen); 378 /* 379 * send it 380 */ 381 n = sendto(fd, sendbuf, plen, 0, (struct sockaddr *)him, 382 sizeof(struct sockaddr)); 383 if (n < 0 && errno != EINPROGRESS ) { 384 #ifdef __linux__ 385 if (errno == EINVAL) { 386 /* 387 * On some Linuxes, when bound to the loopback interface, sendto 388 * will fail and errno will be set to EINVAL. When that happens, 389 * don't throw an exception, just return false. 390 */ 391 close(fd); 392 return JNI_FALSE; 393 } 394 #endif /*__linux__ */ 395 NET_ThrowNew(env, errno, "Can't send ICMP packet"); 396 close(fd); 397 return JNI_FALSE; 398 } 399 400 tmout2 = timeout > 1000 ? 1000 : timeout; 401 do { 402 tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2); 403 if (tmout2 >= 0) { 404 len = sizeof(sa_recv); 405 n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&sa_recv, &len); 406 ip = (struct ip*) recvbuf; 407 hlen1 = (ip->ip_hl) << 2; 408 icmp = (struct icmp *) (recvbuf + hlen1); 409 icmplen = n - hlen1; 410 /* 411 * We did receive something, but is it what we were expecting? 412 * I.E.: A ICMP_ECHOREPLY packet with the proper PID. 413 */ 414 if (icmplen >= 8 && icmp->icmp_type == ICMP_ECHOREPLY && |