mirror of
https://github.com/angryip/ipscan.git
synced 2025-10-26 11:18:17 +00:00
introduce ScanningSubject.netIf to MACFetchers get the local MAC address from it
This commit is contained in:
parent
22e5ed36bd
commit
6e7826fdfe
@ -88,7 +88,7 @@ public class ScannerDispatcherThread extends Thread implements ThreadFactory, St
|
||||
if ((numActiveThreads.intValue() < config.maxThreads)) {
|
||||
subject = feeder.next();
|
||||
|
||||
if (config.skipBroadcastAddresses && isLikelyBroadcast(subject.getAddress(), subject.getIfAddr()))
|
||||
if (config.skipBroadcastAddresses && isLikelyBroadcast(subject.getAddress(), subject.getIfAddress()))
|
||||
continue;
|
||||
|
||||
ScanningResult result = scanningResultList.createResult(subject.getAddress());
|
||||
|
||||
@ -9,12 +9,16 @@ import net.azib.ipscan.config.Config;
|
||||
import net.azib.ipscan.config.ScannerConfig;
|
||||
import net.azib.ipscan.core.ScanningResult.ResultType;
|
||||
import net.azib.ipscan.core.net.PingResult;
|
||||
import net.azib.ipscan.util.InetAddressUtils;
|
||||
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InterfaceAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.util.*;
|
||||
|
||||
import static net.azib.ipscan.util.InetAddressUtils.matchingAddress;
|
||||
|
||||
/**
|
||||
* Scanning subject represents a single scanned
|
||||
* IP address and any additional arbitrary parameters,
|
||||
@ -30,6 +34,8 @@ public class ScanningSubject {
|
||||
|
||||
/** The address being scanned */
|
||||
private InetAddress address;
|
||||
/** Network interface in case of LAN scans, or null */
|
||||
private NetworkInterface netIf;
|
||||
/** Network interface address in case of LAN scans, or null */
|
||||
private InterfaceAddress ifAddr;
|
||||
/** The requested ports that the user wishes to put more attention to, can be null. E.g. port 3128 for scanning of proxy servers. */
|
||||
@ -44,11 +50,16 @@ public class ScanningSubject {
|
||||
int adaptedPortTimeout = -1;
|
||||
|
||||
public ScanningSubject(InetAddress address) {
|
||||
this(address, null);
|
||||
this(address, InetAddressUtils.getInterface(address));
|
||||
}
|
||||
|
||||
public ScanningSubject(InetAddress address, InterfaceAddress ifAddr) {
|
||||
public ScanningSubject(InetAddress address, NetworkInterface netIf) {
|
||||
this(address, netIf, matchingAddress(netIf, address));
|
||||
}
|
||||
|
||||
public ScanningSubject(InetAddress address, NetworkInterface netIf, InterfaceAddress ifAddr) {
|
||||
this.address = address;
|
||||
this.netIf = netIf;
|
||||
this.ifAddr = ifAddr;
|
||||
this.parameters = new HashMap<>(); // single-threaded access only
|
||||
this.config = Config.getConfig().forScanner();
|
||||
@ -58,7 +69,11 @@ public class ScanningSubject {
|
||||
return address;
|
||||
}
|
||||
|
||||
public InterfaceAddress getIfAddr() {
|
||||
public NetworkInterface getInterface() {
|
||||
return netIf;
|
||||
}
|
||||
|
||||
public InterfaceAddress getIfAddress() {
|
||||
return ifAddr;
|
||||
}
|
||||
|
||||
|
||||
@ -11,8 +11,11 @@ import org.savarese.vserv.tcpip.OctetConverter;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InterfaceAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import static net.azib.ipscan.util.InetAddressUtils.*;
|
||||
|
||||
/**
|
||||
* IP Range Feeder.
|
||||
* It contains the starting and ending values, which
|
||||
@ -21,6 +24,7 @@ import java.net.UnknownHostException;
|
||||
* @author Anton Keks
|
||||
*/
|
||||
public class RangeFeeder extends AbstractFeeder {
|
||||
private NetworkInterface netIf;
|
||||
private InterfaceAddress ifAddr;
|
||||
private InetAddress startIP;
|
||||
private InetAddress endIP;
|
||||
@ -47,9 +51,10 @@ public class RangeFeeder extends AbstractFeeder {
|
||||
|
||||
public RangeFeeder(String startIP, String endIP, InterfaceAddress ifAddr) {
|
||||
try {
|
||||
this.ifAddr = ifAddr;
|
||||
this.startIP = this.currentIP = InetAddress.getByName(startIP);
|
||||
this.endIP = this.originalEndIP = InetAddress.getByName(endIP);
|
||||
this.netIf = getInterface(ifAddr != null ? ifAddr.getAddress() : this.startIP);
|
||||
this.ifAddr = ifAddr != null ? ifAddr : matchingAddress(netIf, this.startIP);
|
||||
this.isReverse = false;
|
||||
}
|
||||
catch (UnknownHostException e) {
|
||||
@ -60,10 +65,10 @@ public class RangeFeeder extends AbstractFeeder {
|
||||
}
|
||||
if (InetAddressUtils.greaterThan(this.startIP, this.endIP)) {
|
||||
this.isReverse = true;
|
||||
this.endIP = InetAddressUtils.decrement(InetAddressUtils.decrement(this.endIP));
|
||||
this.endIP = decrement(decrement(this.endIP));
|
||||
}
|
||||
initPercentageIncrement();
|
||||
this.endIP = InetAddressUtils.increment(this.endIP);
|
||||
this.endIP = increment(this.endIP);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,11 +95,11 @@ public class RangeFeeder extends AbstractFeeder {
|
||||
percentageComplete += percentageIncrement;
|
||||
InetAddress prevIP = this.currentIP;
|
||||
if (this.isReverse) {
|
||||
this.currentIP = InetAddressUtils.decrement(prevIP);
|
||||
this.currentIP = decrement(prevIP);
|
||||
} else {
|
||||
this.currentIP = InetAddressUtils.increment(prevIP);
|
||||
this.currentIP = increment(prevIP);
|
||||
}
|
||||
return new ScanningSubject(prevIP, ifAddr);
|
||||
return new ScanningSubject(prevIP, netIf, ifAddr);
|
||||
}
|
||||
|
||||
public int percentageComplete() {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package net.azib.ipscan.fetchers;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import net.azib.ipscan.core.ScanningSubject;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.stream.Stream;
|
||||
@ -25,13 +26,13 @@ public class LinuxMACFetcher extends MACFetcher {
|
||||
}
|
||||
}
|
||||
|
||||
@Override public String resolveMAC(InetAddress address) {
|
||||
@Override public String resolveMAC(ScanningSubject subject) {
|
||||
try {
|
||||
String ip = address.getHostAddress();
|
||||
String ip = subject.getAddress().getHostAddress();
|
||||
return arpLines().filter(line -> line.startsWith(ip + " ")).findFirst()
|
||||
.map(line -> line.substring(macIndex, macIndex + macLength).toUpperCase())
|
||||
.filter(mac -> !unavailableMac.equals(mac))
|
||||
.orElse(getLocalMAC(address));
|
||||
.orElse(getLocalMAC(subject));
|
||||
}
|
||||
catch (Exception e) {
|
||||
return null;
|
||||
|
||||
@ -3,11 +3,9 @@ package net.azib.ipscan.fetchers;
|
||||
import net.azib.ipscan.core.ScanningSubject;
|
||||
import net.azib.ipscan.gui.fetchers.MACFetcherPrefs;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
// TODO: try using java.net.NetworkInterface.getMacAddr0 with reflection instead
|
||||
public abstract class MACFetcher extends AbstractFetcher {
|
||||
public static final String ID = "fetcher.mac";
|
||||
static final Pattern macAddressPattern = Pattern.compile("([a-fA-F0-9]{1,2}[-:]){5}[a-fA-F0-9]{1,2}");
|
||||
@ -20,12 +18,12 @@ public abstract class MACFetcher extends AbstractFetcher {
|
||||
|
||||
@Override public final String scan(ScanningSubject subject) {
|
||||
String mac = (String) subject.getParameter(ID);
|
||||
if (mac == null) mac = resolveMAC(subject.getAddress());
|
||||
if (mac == null) mac = resolveMAC(subject);
|
||||
subject.setParameter(ID, mac);
|
||||
return replaceSeparator(mac);
|
||||
}
|
||||
|
||||
protected abstract String resolveMAC(InetAddress address);
|
||||
protected abstract String resolveMAC(ScanningSubject subject);
|
||||
|
||||
static String bytesToMAC(byte[] bytes) {
|
||||
StringBuilder mac = new StringBuilder();
|
||||
|
||||
@ -1,14 +1,12 @@
|
||||
package net.azib.ipscan.fetchers;
|
||||
|
||||
import net.azib.ipscan.config.Platform;
|
||||
import net.azib.ipscan.core.ScanningSubject;
|
||||
import net.azib.ipscan.util.IOUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
public class UnixMACFetcher extends MACFetcher {
|
||||
private String arp;
|
||||
@ -20,8 +18,8 @@ public class UnixMACFetcher extends MACFetcher {
|
||||
arp = "arp -n "; // Mac and other BSD
|
||||
}
|
||||
|
||||
@Override public String resolveMAC(InetAddress address) {
|
||||
String ip = address.getHostAddress();
|
||||
@Override public String resolveMAC(ScanningSubject subject) {
|
||||
String ip = subject.getAddress().getHostAddress();
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
// highly inefficient implementation, there must be a better way (using JNA?)
|
||||
@ -32,7 +30,7 @@ public class UnixMACFetcher extends MACFetcher {
|
||||
if (line.contains(ip))
|
||||
return extractMAC(line);
|
||||
}
|
||||
return getLocalMAC(address);
|
||||
return getLocalMAC(subject);
|
||||
}
|
||||
catch (Exception e) {
|
||||
return null;
|
||||
@ -42,19 +40,7 @@ public class UnixMACFetcher extends MACFetcher {
|
||||
}
|
||||
}
|
||||
|
||||
static String getLocalMAC(InetAddress address) throws SocketException {
|
||||
Enumeration<NetworkInterface> ifs = NetworkInterface.getNetworkInterfaces();
|
||||
while (ifs.hasMoreElements()) {
|
||||
NetworkInterface netif = ifs.nextElement();
|
||||
if (netif.isUp() && !netif.isVirtual() && !netif.isLoopback()) {
|
||||
Enumeration<InetAddress> addrs = netif.getInetAddresses();
|
||||
while (addrs.hasMoreElements()) {
|
||||
InetAddress addr = addrs.nextElement();
|
||||
if (addr.equals(address))
|
||||
return bytesToMAC(netif.getHardwareAddress());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
static String getLocalMAC(ScanningSubject subject) throws SocketException {
|
||||
return subject.isLocalHost() ? bytesToMAC(subject.getInterface().getHardwareAddress()) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,24 +2,22 @@ package net.azib.ipscan.fetchers;
|
||||
|
||||
import com.sun.jna.Memory;
|
||||
import com.sun.jna.Pointer;
|
||||
import net.azib.ipscan.core.ScanningSubject;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
|
||||
import static net.azib.ipscan.core.net.WinIpHlp.toIpAddr;
|
||||
import static net.azib.ipscan.core.net.WinIpHlpDll.dll;
|
||||
|
||||
public class WinMACFetcher extends MACFetcher {
|
||||
public WinMACFetcher() {}
|
||||
|
||||
@Override public String resolveMAC(InetAddress address) {
|
||||
if (!(address instanceof Inet4Address)) return null; // TODO IPv6 support
|
||||
@Override public String resolveMAC(ScanningSubject subject) {
|
||||
if (!(subject.getAddress() instanceof Inet4Address)) return null; // TODO IPv6 support
|
||||
|
||||
Pointer pmac = new Memory(8);
|
||||
Pointer plen = new Memory(4);
|
||||
plen.setInt(0, 8);
|
||||
|
||||
int result = dll.SendARP(toIpAddr(address), 0, pmac, plen);
|
||||
int result = dll.SendARP(toIpAddr(subject.getAddress()), 0, pmac, plen);
|
||||
|
||||
if (result != 0) return null;
|
||||
|
||||
|
||||
@ -192,6 +192,20 @@ public class InetAddressUtils {
|
||||
return anyAddress;
|
||||
}
|
||||
|
||||
public static NetworkInterface getInterface(InetAddress address) {
|
||||
try {
|
||||
return NetworkInterface.getByInetAddress(address);
|
||||
}
|
||||
catch (SocketException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static InterfaceAddress matchingAddress(NetworkInterface netIf, InetAddress address) {
|
||||
if (netIf == null) return null;
|
||||
return netIf.getInterfaceAddresses().stream().filter(i -> i.getAddress().getClass() == address.getClass()).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public static List<NetworkInterface> getNetworkInterfaces() throws SocketException {
|
||||
List<NetworkInterface> interfaces = list(NetworkInterface.getNetworkInterfaces());
|
||||
if (!Platform.WINDOWS) reverse(interfaces);
|
||||
|
||||
@ -10,6 +10,9 @@ import net.azib.ipscan.core.net.PingResult;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
@ -25,9 +28,9 @@ public class ScanningSubjectTest {
|
||||
private PingResult pingResult;
|
||||
|
||||
@Before
|
||||
public void initTest() {
|
||||
public void initTest() throws UnknownHostException {
|
||||
config = mock(ScannerConfig.class);
|
||||
subject = new ScanningSubject(null);
|
||||
subject = new ScanningSubject(InetAddress.getLocalHost());
|
||||
subject.config = config;
|
||||
config.portTimeout = 1000;
|
||||
config.adaptPortTimeout = true;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package net.azib.ipscan.fetchers;
|
||||
|
||||
import net.azib.ipscan.config.Platform;
|
||||
import net.azib.ipscan.core.ScanningSubject;
|
||||
import org.junit.Test;
|
||||
|
||||
import static net.azib.ipscan.util.InetAddressUtils.getLocalInterface;
|
||||
@ -11,6 +12,7 @@ public class LinuxMACFetcherTest {
|
||||
@Test
|
||||
public void resolve() {
|
||||
assumeTrue(Platform.LINUX);
|
||||
assertEquals(17, new LinuxMACFetcher().resolveMAC(getLocalInterface().getAddress()).length());
|
||||
ScanningSubject subject = new ScanningSubject(getLocalInterface().getAddress());
|
||||
assertEquals(17, new LinuxMACFetcher().resolveMAC(subject).length());
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class MACFetcherTest {
|
||||
private MACFetcher fetcher = new MACFetcher() {
|
||||
@Override protected String resolveMAC(InetAddress address) {
|
||||
@Override protected String resolveMAC(ScanningSubject subject) {
|
||||
return "00:01:02:03:04:05";
|
||||
}
|
||||
};
|
||||
@ -28,8 +28,8 @@ public class MACFetcherTest {
|
||||
|
||||
@Test
|
||||
public void bytesToMAC() {
|
||||
assertEquals("", fetcher.bytesToMAC(new byte[0]));
|
||||
assertEquals("00:01:02:0D", fetcher.bytesToMAC(new byte[] {0, 1, 2, 13}));
|
||||
assertEquals("", MACFetcher.bytesToMAC(new byte[0]));
|
||||
assertEquals("00:01:02:0D", MACFetcher.bytesToMAC(new byte[] {0, 1, 2, 13}));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -1,16 +1,15 @@
|
||||
package net.azib.ipscan.fetchers;
|
||||
|
||||
import net.azib.ipscan.core.ScanningSubject;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class MACVendorFetcherTest {
|
||||
@Test
|
||||
public void findMACVendor() {
|
||||
MACFetcher macFetcher = new MACFetcher() {
|
||||
@Override protected String resolveMAC(InetAddress address) { return null; }
|
||||
@Override protected String resolveMAC(ScanningSubject subject) { return null; }
|
||||
};
|
||||
MACVendorFetcher fetcher = new MACVendorFetcher(macFetcher);
|
||||
fetcher.init();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user