Package net.azib.ipscan.core.net

Source Code of net.azib.ipscan.core.net.WindowsPinger

/**
* This file is a part of Angry IP Scanner source code,
* see http://www.angryip.org/ for more information.
* Licensed under GPLv2.
*/
package net.azib.ipscan.core.net;

import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import net.azib.ipscan.core.ScanningSubject;
import net.azib.ipscan.core.net.WinIpHlpDll.IcmpEchoReply;
import net.azib.ipscan.core.net.WinIpHlpDll.IpAddrByVal;

import java.io.IOException;
import java.net.InetAddress;
import java.util.Arrays;

import static java.lang.Thread.currentThread;
import static net.azib.ipscan.core.net.WinIpHlpDll.dll;

/**
* Windows-only pinger that uses Microsoft's ICMP.DLL for its job.
* <p/>
* This pinger exists to provide adequate pinging to Windows users,
* because Microsoft has removed Raw Socket support from consumer
* versions of Windows since XP SP2.
*
* @author Anton Keks
*/
public class WindowsPinger implements Pinger {
  private int timeout;

  public WindowsPinger(int timeout) {
    this.timeout = timeout;
  }

  public PingResult ping(ScanningSubject subject, int count) throws IOException {
    Pointer handle = dll.IcmpCreateFile();
    if (handle == null) throw new IOException("Unable to create Windows native ICMP handle");

    IpAddrByVal ipaddr = new IpAddrByVal();
    ipaddr.bytes = subject.getAddress().getAddress();

    int sendDataSize = 56;
    int replyDataSize = sendDataSize + (new IcmpEchoReply().size()) + 10;
    Pointer sendData = new Memory(sendDataSize);
    sendData.clear(sendDataSize);
    Pointer replyData = new Memory(replyDataSize);

    PingResult result = new PingResult(subject.getAddress());
    try {
      for (int i = 1; i <= count && !currentThread().isInterrupted(); i++) {
        int numReplies = dll.IcmpSendEcho(handle, ipaddr, sendData, (short) sendDataSize, null, replyData, replyDataSize, timeout);
        IcmpEchoReply echoReply = new IcmpEchoReply(replyData);
        if (numReplies > 0 && echoReply.status == 0 && Arrays.equals(echoReply.address.bytes, ipaddr.bytes)) {
          result.addReply(echoReply.roundTripTime);
          result.setTTL(echoReply.options.ttl & 0xFF);
        }
      }
    }
    finally {
      dll.IcmpCloseHandle(handle);
    }

    return result;
  }

  public void close() {
    // not needed in this pinger
  }

  public static void main(String[] args) throws IOException {
    PingResult ping = new WindowsPinger(5000).ping(new ScanningSubject(InetAddress.getLocalHost()), 3);
    System.out.println(ping.getAverageTime() + "ms");
    System.out.println("TTL " + ping.getTTL());
  }
}
TOP

Related Classes of net.azib.ipscan.core.net.WindowsPinger

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.