Package net.azib.ipscan.fetchers

Source Code of net.azib.ipscan.fetchers.HostnameFetcher

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

import net.azib.ipscan.core.ScanningSubject;
import net.azib.ipscan.util.MDNSResolver;
import net.azib.ipscan.util.NetBIOSResolver;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.logging.Logger;

import static java.util.logging.Level.WARNING;

/**
* HostnameFetcher retrieves hostnames of IP addresses by reverse DNS lookups.
*
* @author Anton Keks
*/
public class HostnameFetcher extends AbstractFetcher {
  private static Logger LOG = Logger.getLogger(HostnameFetcher.class.getName());

  private static Object inetAddressImpl;
  private static Method getHostByAddr;

  static {
    try {
      Field impl = InetAddress.class.getDeclaredField("impl");
      impl.setAccessible(true);
      inetAddressImpl = impl.get(null);
      getHostByAddr = inetAddressImpl.getClass().getDeclaredMethod("getHostByAddr", byte[].class);
      getHostByAddr.setAccessible(true);
    }
    catch (Exception e) {
      LOG.log(WARNING, "Could not get InetAddressImpl", e);
    }
  }

  public static final String ID = "fetcher.hostname";

  public String getId() {
    return ID;
  }

  private String resolveWithRegularDNS(InetAddress ip) {
    try {
      // faster way to do lookup - getCanonicalHostName() actually does both reverse and forward lookups inside
      return (String)getHostByAddr.invoke(inetAddressImpl, ip.getAddress());
    }
    catch (Exception e) {
      if (e instanceof InvocationTargetException && e.getCause() instanceof UnknownHostException)
        return null;

      // return the returned hostname only if it is not the same as the IP address (this is how the above method works)
      String hostname = ip.getCanonicalHostName();
      return ip.getHostAddress().equals(hostname) ? null : hostname;
    }
  }

  private String resolveWithMulticastDNS(ScanningSubject subject) {
    try {
      MDNSResolver resolver = new MDNSResolver(subject.getAdaptedPortTimeout());
      String name = resolver.resolve(subject.getAddress());
      resolver.close();
      return name;
    }
    catch (SocketTimeoutException e) {
      return null;
    }
    catch (SocketException e) {
      return null;
    }
    catch (Exception e) {
      LOG.log(WARNING, "Failed to query mDNS for " + subject, e);
      return null;
    }
  }

  private String resolveWithNetBIOS(ScanningSubject subject) {
    try {
      NetBIOSResolver resolver = new NetBIOSResolver(subject.getAdaptedPortTimeout());
      String[] names = resolver.resolve(subject.getAddress());
      resolver.close();
      return names == null ? null : names[0];
    }
    catch (SocketTimeoutException e) {
      return null;
    }
    catch (SocketException e) {
      return null;
    }
    catch (Exception e) {
      LOG.log(WARNING, "Failed to query NetBIOS for " + subject, e);
      return null;
    }
  }

  public Object scan(ScanningSubject subject) {
    String name = resolveWithRegularDNS(subject.getAddress());
    if (name == null && subject.isLocal()) name = resolveWithMulticastDNS(subject);
    if (name == null && subject.isLocal()) name = resolveWithNetBIOS(subject);
    return name;
  }
}
TOP

Related Classes of net.azib.ipscan.fetchers.HostnameFetcher

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.