setDaemon(true);
setPriority(Thread.MAX_PRIORITY);
}
public void run() {
ICMPEchoPacket packet = new ICMPEchoPacket(1);
byte[] data = new byte[84];
packet.setData(data);
packet.setIPHeaderLength(5);
packet.setICMPDataByteLength(56);
// we use this address for receiving
// due to some reason, raw sockets return packets coming from any addresses anyway
InetAddress tmpAddress = null;
try {
tmpAddress = InetAddress.getLocalHost();
}
catch (UnknownHostException e) {
LOG.log(SEVERE, null, e);
}
try {
// Windows OS cannot read from a raw socket before anything has been sent through it
receivingSocket.write(tmpAddress, data);
}
catch (IOException e) {
LOG.log(WARNING, "Sending of test packet failed", e);
}
do {
try {
receivingSocket.read(tmpAddress, data);
if (packet.getType() == ICMPPacket.TYPE_ECHO_REPLY &&
packet.getIdentifier() == (ICMPSharedPinger.this.hashCode() & 0xFFFF) &&
packet.getSequenceNumber() > 0) {
long endTime = System.currentTimeMillis();
PingResult result = results.get(packet.getSourceAsInetAddress());
if (result == null) {
LOG.warning("ICMP packet received from an unknown address: " + packet.getSourceAsInetAddress());
continue;
}
long startTime = OctetConverter.octetsToLong(data, timeOffsetInPacket);
long time = endTime - startTime;
if (LOG.isLoggable(FINEST)) {
LOG.finest("Received " + packet.getSequenceNumber() + packet.getSourceAsInetAddress() + ": " + time);
}
result.addReply(time);
// TTL should be the same among all packets
result.setTTL(packet.getTTL() & 0xFF);
synchronized (result) {
// notify the sender that we have an answer :-)
result.notifyAll();
}
}
else
if (packet.getType() == ICMPPacket.TYPE_HOST_UNREACHABLE) {
// TODO: received non-ECHO_REPLY packets may also be useful, saying "destination is unreachable"
// packet body in this case is the sent ICMP_REQUEST packet
}
}
catch (InterruptedIOException e) {