mirror of
https://github.com/angryip/ipscan.git
synced 2025-10-26 11:18:17 +00:00
\#129 first working IPv6 pinging implementation for Windows
This commit is contained in:
parent
021f2582ce
commit
42736eb515
17
ipscan.iml
17
ipscan.iml
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id="ipscan" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="3.5.5" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<output url="file://$MODULE_DIR$/out/production/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/out/test/classes" />
|
||||
<output url="file://$MODULE_DIR$/build/classes/java/main" />
|
||||
<output-test url="file://$MODULE_DIR$/build/classes/java/test" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/ext/rocksaw/src" isTestSource="false" />
|
||||
@ -27,6 +27,19 @@
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Gradle: com.google.dagger:dagger:2.19" level="project" />
|
||||
<orderEntry type="library" name="Gradle: javax.inject:javax.inject:1" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Gradle: com.google.dagger:dagger-compiler:2.19" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Gradle: com.google.dagger:dagger-spi:2.19" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Gradle: com.google.dagger:dagger-producers:2.19" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Gradle: com.google.googlejavaformat:google-java-format:1.5" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Gradle: com.google.guava:guava:25.0-jre" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Gradle: com.squareup:javapoet:1.11.1" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Gradle: javax.annotation:jsr250-api:1.0" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Gradle: org.checkerframework:checker-compat-qual:2.5.3" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Gradle: com.google.errorprone:javac-shaded:9-dev-r4023-3" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Gradle: com.google.code.findbugs:jsr305:1.3.9" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Gradle: com.google.errorprone:error_prone_annotations:2.1.3" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Gradle: com.google.j2objc:j2objc-annotations:1.1" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Gradle: org.codehaus.mojo:animal-sniffer-annotations:1.14" level="project" />
|
||||
<orderEntry type="module-library" scope="PROVIDED">
|
||||
<library name="Gradle: swt-linux64">
|
||||
<CLASSES>
|
||||
|
||||
20
src/net/azib/ipscan/core/net/WinIpHlp.java
Normal file
20
src/net/azib/ipscan/core/net/WinIpHlp.java
Normal file
@ -0,0 +1,20 @@
|
||||
package net.azib.ipscan.core.net;
|
||||
|
||||
import net.azib.ipscan.core.net.WinIpHlpDll.Ip6SockAddrByRef;
|
||||
import net.azib.ipscan.core.net.WinIpHlpDll.IpAddrByVal;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
public class WinIpHlp {
|
||||
public static IpAddrByVal toIpAddr(InetAddress address) {
|
||||
IpAddrByVal addr = new IpAddrByVal();
|
||||
addr.bytes = address.getAddress();
|
||||
return addr;
|
||||
}
|
||||
|
||||
public static Ip6SockAddrByRef toIp6Addr(InetAddress address) {
|
||||
Ip6SockAddrByRef addr = new Ip6SockAddrByRef();
|
||||
addr.bytes = address.getAddress();
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
@ -44,6 +44,11 @@ public interface WinIpHlpDll extends Library {
|
||||
*/
|
||||
Pointer IcmpCreateFile();
|
||||
|
||||
/**
|
||||
* Wrapper for Microsoft's <a href="https://docs.microsoft.com/en-us/windows/desktop/api/icmpapi/nf-icmpapi-icmp6createfile">Icmp6CreateFile</a>
|
||||
*/
|
||||
Pointer Icmp6CreateFile();
|
||||
|
||||
/**
|
||||
* Wrapper for Microsoft's <a href="http://msdn.microsoft.com/en-us/library/aa366043.aspx">IcmpCloseHandle</a>
|
||||
*/
|
||||
@ -63,6 +68,24 @@ public interface WinIpHlpDll extends Library {
|
||||
int timeout
|
||||
);
|
||||
|
||||
/**
|
||||
* Wrapper for Microsoft's <a href="https://docs.microsoft.com/en-us/windows/desktop/api/icmpapi/nf-icmpapi-icmp6sendecho2">Icmp6SendEcho2</a>
|
||||
*/
|
||||
int Icmp6SendEcho2(
|
||||
Pointer hIcmp,
|
||||
Pointer event,
|
||||
Pointer apcRoutine,
|
||||
Pointer apcContext,
|
||||
Ip6SockAddrByRef sourceAddress,
|
||||
Ip6SockAddrByRef destinationAddress,
|
||||
Pointer requestData,
|
||||
short requestSize,
|
||||
IpOptionInformationByRef requestOptions,
|
||||
Pointer replyBuffer,
|
||||
int replySize,
|
||||
int timeout
|
||||
);
|
||||
|
||||
/**
|
||||
* Wrapper for Microsoft's <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366358(v=vs.85).aspx">SendARP</a>
|
||||
*/
|
||||
@ -80,6 +103,17 @@ public interface WinIpHlpDll extends Library {
|
||||
class IpAddrByVal extends IpAddr implements Structure.ByValue {
|
||||
}
|
||||
|
||||
class Ip6SockAddr extends AutoOrderedStructure {
|
||||
public short family = 10;
|
||||
public short port;
|
||||
public int flowInfo;
|
||||
public byte[] bytes = new byte[16];
|
||||
public int scopeId;
|
||||
}
|
||||
|
||||
class Ip6SockAddrByRef extends Ip6SockAddr implements Structure.ByReference {
|
||||
}
|
||||
|
||||
class IpOptionInformation extends AutoOrderedStructure {
|
||||
public byte ttl;
|
||||
public byte tos;
|
||||
@ -113,4 +147,21 @@ public interface WinIpHlpDll extends Library {
|
||||
read();
|
||||
}
|
||||
}
|
||||
|
||||
class Icmp6EchoReply extends AutoOrderedStructure {
|
||||
public short port;
|
||||
public byte[] flowInfo = new byte[4];
|
||||
public byte[] addressBytes = new byte[16];
|
||||
public int scopeId;
|
||||
public int status;
|
||||
public int roundTripTime;
|
||||
|
||||
public Icmp6EchoReply() {
|
||||
}
|
||||
|
||||
public Icmp6EchoReply(Pointer p) {
|
||||
useMemory(p);
|
||||
read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,9 @@ 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.Icmp6EchoReply;
|
||||
import net.azib.ipscan.core.net.WinIpHlpDll.IcmpEchoReply;
|
||||
import net.azib.ipscan.core.net.WinIpHlpDll.Ip6SockAddrByRef;
|
||||
import net.azib.ipscan.core.net.WinIpHlpDll.IpAddrByVal;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -16,6 +18,8 @@ import java.net.InetAddress;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static java.lang.Thread.currentThread;
|
||||
import static net.azib.ipscan.core.net.WinIpHlp.toIp6Addr;
|
||||
import static net.azib.ipscan.core.net.WinIpHlp.toIpAddr;
|
||||
import static net.azib.ipscan.core.net.WinIpHlpDll.dll;
|
||||
|
||||
/**
|
||||
@ -29,18 +33,23 @@ import static net.azib.ipscan.core.net.WinIpHlpDll.dll;
|
||||
*/
|
||||
public class WindowsPinger implements Pinger {
|
||||
private int timeout;
|
||||
private Ip6SockAddrByRef anyIp6SourceAddr = new Ip6SockAddrByRef();
|
||||
|
||||
public WindowsPinger(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public PingResult ping(ScanningSubject subject, int count) throws IOException {
|
||||
if (subject.isIPv6())
|
||||
return ping6(subject, count);
|
||||
else
|
||||
return ping4(subject, count);
|
||||
}
|
||||
|
||||
private PingResult ping4(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);
|
||||
@ -50,6 +59,7 @@ public class WindowsPinger implements Pinger {
|
||||
PingResult result = new PingResult(subject.getAddress(), count);
|
||||
try {
|
||||
for (int i = 1; i <= count && !currentThread().isInterrupted(); i++) {
|
||||
IpAddrByVal ipaddr = toIpAddr(subject.getAddress());
|
||||
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)) {
|
||||
@ -61,6 +71,36 @@ public class WindowsPinger implements Pinger {
|
||||
finally {
|
||||
dll.IcmpCloseHandle(handle);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private PingResult ping6(ScanningSubject subject, int count) throws IOException {
|
||||
Pointer handle = dll.Icmp6CreateFile();
|
||||
if (handle == null) throw new IOException("Unable to create Windows native ICMP6 handle");
|
||||
|
||||
int sendDataSize = 56;
|
||||
int replyDataSize = sendDataSize + (new Icmp6EchoReply().size()) + 10;
|
||||
Pointer sendData = new Memory(sendDataSize);
|
||||
sendData.clear(sendDataSize);
|
||||
Pointer replyData = new Memory(replyDataSize);
|
||||
|
||||
PingResult result = new PingResult(subject.getAddress(), count);
|
||||
try {
|
||||
Ip6SockAddrByRef ipaddr = toIp6Addr(subject.getAddress());
|
||||
for (int i = 1; i <= count && !currentThread().isInterrupted(); i++) {
|
||||
int numReplies = dll.Icmp6SendEcho2(handle, null, null, null, anyIp6SourceAddr, toIp6Addr(subject.getAddress()), sendData, (short) sendDataSize, null, replyData, replyDataSize, timeout);
|
||||
Icmp6EchoReply echoReply = new Icmp6EchoReply(replyData);
|
||||
if (numReplies > 0 && echoReply.status == 0 && Arrays.equals(echoReply.addressBytes, ipaddr.bytes)) {
|
||||
result.addReply(echoReply.roundTripTime);
|
||||
//result.setTTL(echoReply.options.ttl & 0xFF);
|
||||
}
|
||||
System.err.println("Icmp6SendEcho2 response: " + numReplies + " " + echoReply.status + " " + InetAddress.getByAddress(echoReply.addressBytes) + " " + Arrays.toString(echoReply.addressBytes) + " vs " + InetAddress.getByAddress(ipaddr.bytes));
|
||||
System.err.println(echoReply.getFieldOrder());
|
||||
}
|
||||
}
|
||||
finally {
|
||||
dll.IcmpCloseHandle(handle);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -70,7 +110,7 @@ public class WindowsPinger implements Pinger {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
PingResult ping = new WindowsPinger(5000).ping(new ScanningSubject(InetAddress.getLocalHost()), 3);
|
||||
PingResult ping = new WindowsPinger(5000).ping(new ScanningSubject(InetAddress.getByName("::1")), 1);
|
||||
System.out.println(ping.getAverageTime() + "ms");
|
||||
System.out.println("TTL " + ping.getTTL());
|
||||
}
|
||||
|
||||
@ -2,25 +2,22 @@ package net.azib.ipscan.fetchers;
|
||||
|
||||
import com.sun.jna.Memory;
|
||||
import com.sun.jna.Pointer;
|
||||
import net.azib.ipscan.core.net.WinIpHlpDll.IpAddrByVal;
|
||||
|
||||
import javax.inject.Inject;
|
||||
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 {
|
||||
@Inject public WinMACFetcher() {}
|
||||
|
||||
@Override public String resolveMAC(InetAddress address) {
|
||||
IpAddrByVal destIP = new IpAddrByVal();
|
||||
destIP.bytes = address.getAddress();
|
||||
|
||||
Pointer pmac = new Memory(8);
|
||||
Pointer plen = new Memory(4);
|
||||
plen.setInt(0, 8);
|
||||
|
||||
int result = dll.SendARP(destIP, 0, pmac, plen);
|
||||
int result = dll.SendARP(toIpAddr(address), 0, pmac, plen);
|
||||
|
||||
if (result != 0) return null;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user