diff --git a/.classpath b/.classpath index 72e90083..184317e4 100755 --- a/.classpath +++ b/.classpath @@ -5,17 +5,14 @@ + + - - - - - - - + + diff --git a/.settings/org.eclipse.core.runtime.prefs b/.settings/org.eclipse.core.runtime.prefs index d321418f..03c92a61 100644 --- a/.settings/org.eclipse.core.runtime.prefs +++ b/.settings/org.eclipse.core.runtime.prefs @@ -1,3 +1,4 @@ -#Thu Jan 04 10:25:32 EET 2007 +#Tue Jul 24 22:19:33 EEST 2007 eclipse.preferences.version=1 +instance/org.eclipse.core.net/org.eclipse.core.net.hasMigrated=true line.separator=\n diff --git a/build.xml b/build.xml index 97dab312..21eca2be 100755 --- a/build.xml +++ b/build.xml @@ -125,7 +125,8 @@ - + + @@ -198,7 +199,7 @@ - + diff --git a/ext/rocksaw/lib/tmp.jar b/ext/rocksaw/lib/tmp.jar deleted file mode 100755 index a2187642..00000000 Binary files a/ext/rocksaw/lib/tmp.jar and /dev/null differ diff --git a/ext/rocksaw/src/java/org/savarese/rocksaw/net/RawSocket.java b/ext/rocksaw/src/java/org/savarese/rocksaw/net/RawSocket.java index 7da14268..3c57ed05 100755 --- a/ext/rocksaw/src/java/org/savarese/rocksaw/net/RawSocket.java +++ b/ext/rocksaw/src/java/org/savarese/rocksaw/net/RawSocket.java @@ -19,14 +19,13 @@ package org.savarese.rocksaw.net; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.InterruptedIOException; -import java.io.OutputStream; import java.net.InetAddress; import java.net.SocketException; +import net.azib.ipscan.core.LibraryLoader; + /** *

The RawSocket class provides a strictly utilitarian API for * performing I/O with raw sockets. The API is currently crude, but @@ -79,8 +78,8 @@ public class RawSocket { native static void __RockSawShutdown(); static { - // modified to reuse SWT's loading of jni libs from jar file - loadLibrary("rocksaw"); + // modified to load jni libs from jar file + LibraryLoader.loadLibrary("rocksaw"); if(__RockSawStartup() != 0) throw new UnsatisfiedLinkError(__getErrorMessage()); @@ -151,41 +150,7 @@ public class RawSocket { setUseSelectTimeout(false); } - - private static void loadLibrary(String library) { - String filename = System.mapLibraryName(library); - String fullFilename = System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") + filename; - try { - System.load(fullFilename); - } - catch (UnsatisfiedLinkError e) { - try { - // try to extract - InputStream is = RawSocket.class.getClassLoader().getResourceAsStream(filename); - byte[] buffer = new byte[4096]; - OutputStream os = new FileOutputStream(fullFilename); - int read; - while ((read = is.read(buffer)) != -1) { - os.write(buffer, 0, read); - } - os.close(); - is.close(); - if (!net.azib.ipscan.config.Platform.WINDOWS) { - // TODO: change this to new File(fullFilename).setExecutable(true) in case of Java 1.6 - try { - Runtime.getRuntime ().exec (new String []{"chmod", "755", fullFilename}).waitFor(); - } catch (Throwable t) {} - } - System.load(fullFilename); - } - catch (IOException ioe) { - throw new RuntimeException("Unable to extract native library: " + library, ioe); - } - } - - } - -/** + /** * Tests if the socket has been opened. * * @return True if the socket is open. diff --git a/ext/winping/jni/WindowsPinger.c b/ext/winping/jni/WindowsPinger.c deleted file mode 100755 index 80f7eaea..00000000 --- a/ext/winping/jni/WindowsPinger.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2007 Anton Keks - */ - -#include - -#include "WindowsPinger.h" - -FARPROC IcmpCreateFile; - -typedef BOOL (FAR WINAPI *TIcmpCloseHandle)(HANDLE IcmpHandle); -TIcmpCloseHandle IcmpCloseHandle; - -typedef DWORD (FAR WINAPI *TIcmpSendEcho)( - HANDLE IcmpHandle, /* handle returned from IcmpCreateFile() */ - u_long DestAddress, /* destination IP address (in network order) */ - LPVOID RequestData, /* pointer to buffer to send */ - WORD RequestSize, /* length of data in buffer */ - LPIPINFO RequestOptns, /* see Note 2 */ - LPVOID ReplyBuffer, /* see Note 1 */ - DWORD ReplySize, /* length of reply (must allow at least 1 reply) */ - DWORD Timeout /* time in milliseconds to wait for reply */ -); -TIcmpSendEcho IcmpSendEcho; - -/* - * Class: net_azib_ipscan_core_net_WindowsPinger - * Method: nativeIcmpCreateFile - */ -JNIEXPORT jint JNICALL -Java_net_azib_ipscan_core_net_WindowsPinger_nativeIcmpCreateFile -(JNIEnv *env, jclass cls) -{ - HMODULE hICMP = LoadLibrary("icmp.dll"); - if (!hICMP) { - // newer versions of Windows should include this one instead - hICMP = LoadLibrary("iphlpapi.dll"); - } - if (!hICMP) { - return -1; - } - IcmpCreateFile = (FARPROC)GetProcAddress(hICMP, "IcmpCreateFile"); - IcmpCloseHandle = (TIcmpCloseHandle)GetProcAddress(hICMP, "IcmpCloseHandle"); - IcmpSendEcho = (TIcmpSendEcho)GetProcAddress(hICMP, "IcmpSendEcho"); - - return IcmpCreateFile(); -} - -/* - * Class: net_azib_ipscan_core_net_WindowsPinger - * Method: nativeIcmpCloseHandle - */ -JNIEXPORT jint JNICALL -Java_net_azib_ipscan_core_net_WindowsPinger_nativeIcmpCloseHandle -(JNIEnv *env, jclass cls, jint handle) -{ - return IcmpCloseHandle(handle); -} - -/* - * Class: net_azib_ipscan_core_net_WindowsPinger - * Method: nativeIcmpSendEcho - */ -JNIEXPORT jint JNICALL -Java_net_azib_ipscan_core_net_WindowsPinger_nativeIcmpSendEcho -(JNIEnv *env, jclass cls, jint handle, - jbyteArray address, jbyteArray pingData, jbyteArray replyData, jint timeout) -{ - DWORD replyCount; - IPINFO IPInfo; - jbyte *addrBuf, *pingDataBuf, replyDataBuf; - jclass replyClass; - jfieldID fid; - - IPInfo.Ttl = 128; - IPInfo.Tos = 0; - IPInfo.Flags = 0; - IPInfo.OptionsSize = 0; - IPInfo.OptionsData = NULL; - - addrBuf = env->GetByteArrayElements(env, address, NULL); - pingDataBuf = env->GetByteArrayElements(env, pingData, NULL); - replyDataBuf = env->GetByteArrayElements(env, replyData, NULL); - - replyCount = IcmpSendEcho(handle, (DWORD)*addrBuf, pingDataBuf, env->GetArrayLength(pingData) * sizeof(jbyte), - &IPInfo, replyDataBuf, env->GetArrayLength(replyData), timeout); - - env->ReleaseByteArrayElements(env, address, addrBuf, JNI_ABORT); - env->ReleaseByteArrayElements(env, pingData, pingDataBuf, JNI_ABORT); - env->ReleaseByteArrayElements(env, replyData, replyDataBuf, NULL); - - return replyCount; -} diff --git a/ext/winping/lib/winping.dll b/ext/winping/lib/winping.dll new file mode 100644 index 00000000..0ecd2c57 Binary files /dev/null and b/ext/winping/lib/winping.dll differ diff --git a/ext/winping/jni/Makefile b/ext/winping/src/Makefile similarity index 65% rename from ext/winping/jni/Makefile rename to ext/winping/src/Makefile index c77c3aaa..8bebe695 100755 --- a/ext/winping/jni/Makefile +++ b/ext/winping/src/Makefile @@ -1,8 +1,13 @@ # +# This file is a part of Angry IP Scanner source code, +# see http://www.azib.net/ for more information. +# Licensed under GPLv2. +# # Windows JNI pinger using Microsoft's ICMP.DLL +# Author: Anton Keks # -# Copyright 2007 Anton Keks -# + +DEST = ..\lib JAVA_INCDIR = $(JDK_HOME)\include JAVA_INCDIR_PLAF = $(JAVA_INCDIR)\win32 @@ -22,10 +27,10 @@ CLEAN_EXTENSIONS = *.obj *.$(LIBEXTENSION) *.lib *.exp all: $(LIBWINPING) .c.obj: - $(CC) -nologo $(CFLAGS) $(CPPFLAGS) -c $< -o $@ + $(CC) -nologo $(CFLAGS) $(CPPFLAGS) -c $< -o $(DEST)\$@ $(LIBWINPING): $(OBJ) - $(CC) -nologo -MD -LD -o $@ $** + $(CC) -nologo -MD -LD -o $(DEST)\$@ $** clean: del $(CLEAN_EXTENSIONS) diff --git a/ext/winping/src/WindowsPinger.c b/ext/winping/src/WindowsPinger.c new file mode 100755 index 00000000..b43c097b --- /dev/null +++ b/ext/winping/src/WindowsPinger.c @@ -0,0 +1,103 @@ +/* + * This file is a part of Angry IP Scanner source code, + * see http://www.azib.net/ for more information. + * Licensed under GPLv2. + * + * Windows JNI pinger using Microsoft's ICMP.DLL + * Author: Anton Keks + */ + +#include + +#include "WindowsPinger.h" + + +FARPROC IcmpCreateFile = NULL; + +typedef BOOL (FAR WINAPI *TIcmpCloseHandle)(HANDLE IcmpHandle); +TIcmpCloseHandle IcmpCloseHandle = NULL; + +typedef DWORD (FAR WINAPI *TIcmpSendEcho)( + HANDLE IcmpHandle, /* handle returned from IcmpCreateFile() */ + u_long DestAddress, /* destination IP address (in network order) */ + LPVOID RequestData, /* pointer to buffer to send */ + WORD RequestSize, /* length of data in buffer */ + LPVOID RequestOptns, /* see Note 2 */ + LPVOID ReplyBuffer, /* see Note 1 */ + DWORD ReplySize, /* length of reply (must allow at least 1 reply) */ + DWORD Timeout /* time in milliseconds to wait for reply */ +); +TIcmpSendEcho IcmpSendEcho = NULL; + +/* + * Class: net_azib_ipscan_core_net_WindowsPinger + * Method: nativeIcmpCreateFile + */ +JNIEXPORT jint JNICALL +Java_net_azib_ipscan_core_net_WindowsPinger_nativeIcmpCreateFile +(JNIEnv *env, jclass cls) +{ + // Initialize dlls on first use + if (IcmpCreateFile == NULL) { + HMODULE hICMP = LoadLibrary("icmp.dll"); + if (!hICMP) { + // newer versions of Windows should include this one instead + hICMP = LoadLibrary("iphlpapi.dll"); + } + + if (!hICMP) { + return -1; + } + + IcmpCreateFile = (FARPROC) GetProcAddress(hICMP, "IcmpCreateFile"); + IcmpCloseHandle = (TIcmpCloseHandle) GetProcAddress(hICMP, "IcmpCloseHandle"); + IcmpSendEcho = (TIcmpSendEcho) GetProcAddress(hICMP, "IcmpSendEcho"); + } + + return IcmpCreateFile(); +} + +/* + * Class: net_azib_ipscan_core_net_WindowsPinger + * Method: nativeIcmpCloseHandle + */ +JNIEXPORT void JNICALL +Java_net_azib_ipscan_core_net_WindowsPinger_nativeIcmpCloseHandle +(JNIEnv *env, jclass cls, jint handle) +{ + return IcmpCloseHandle((HANDLE)handle); +} + +/* + * Class: net_azib_ipscan_core_net_WindowsPinger + * Method: nativeIcmpSendEcho + */ + +JNIEXPORT jint JNICALL +Java_net_azib_ipscan_core_net_WindowsPinger_nativeIcmpSendEcho +(JNIEnv *env, jclass cls, jint handle, jbyteArray address, jbyteArray pingData, jbyteArray replyData, jint timeout) +{ + DWORD replyCount; + jbyte *addrBuf, *pingDataBuf, *replyDataBuf; + jint pingDataLen, replyDataLen; + jclass replyClass; + jfieldID fid; + u_long ip; + + addrBuf = (*env)->GetByteArrayElements(env, address, NULL); + pingDataBuf = (*env)->GetByteArrayElements(env, pingData, NULL); + replyDataBuf = (*env)->GetByteArrayElements(env, replyData, NULL); + + pingDataLen = (*env)->GetArrayLength(env, pingData); + replyDataLen = (*env)->GetArrayLength(env, replyData); + + ip = *((u_long*)addrBuf); + replyCount = IcmpSendEcho((HANDLE)handle, ip, pingDataBuf, pingDataLen, + NULL, replyDataBuf, replyDataLen, timeout); + + (*env)->ReleaseByteArrayElements(env, address, addrBuf, JNI_ABORT); + (*env)->ReleaseByteArrayElements(env, pingData, pingDataBuf, JNI_ABORT); + (*env)->ReleaseByteArrayElements(env, replyData, replyDataBuf, 0); + + return replyCount; +} diff --git a/ext/winping/jni/WindowsPinger.h b/ext/winping/src/WindowsPinger.h similarity index 82% rename from ext/winping/jni/WindowsPinger.h rename to ext/winping/src/WindowsPinger.h index a920f8af..6925c333 100644 --- a/ext/winping/jni/WindowsPinger.h +++ b/ext/winping/src/WindowsPinger.h @@ -1,3 +1,12 @@ +/* + * This file is a part of Angry IP Scanner source code, + * see http://www.azib.net/ for more information. + * Licensed under GPLv2. + * + * Windows JNI pinger using Microsoft's ICMP.DLL + * Author: Anton Keks + */ + #include /* Header for class net_azib_ipscan_core_net_WindowsPinger */ diff --git a/resources/Labels.txt b/resources/Labels.txt index 64db1133..b7ac351d 100755 --- a/resources/Labels.txt +++ b/resources/Labels.txt @@ -134,6 +134,7 @@ list.alive.img=images/list/alive.png list.addinfo.img=images/list/addinfo.png pinger.icmp=ICMP Echo pinger.icmp2=ICMP Echo (Alternative) +pinger.windows=Windows ICMP.DLL pinger.udp=UDP packet pinger.tcp=TCP port probe opener.web=Web Browser diff --git a/src/net/azib/ipscan/core/LibraryLoader.java b/src/net/azib/ipscan/core/LibraryLoader.java new file mode 100644 index 00000000..ae9e72e9 --- /dev/null +++ b/src/net/azib/ipscan/core/LibraryLoader.java @@ -0,0 +1,64 @@ +/** + * This file is a part of Angry IP Scanner source code, + * see http://www.azib.net/ for more information. + * Licensed under GPLv2. + */ + +package net.azib.ipscan.core; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Utility class for loading of JNI libraries from jar files. + * + * @author Anton Keks + */ +public class LibraryLoader { + + /** + * Loads native library from the jar file (storing it in the temp dir) + * @param library JNI library name + */ + public static void loadLibrary(String library) { + String filename = System.mapLibraryName(library); + String fullFilename = System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") + filename; + try { + // try to load from the temp dir (in case it is already there) + System.load(fullFilename); + } + catch (UnsatisfiedLinkError err2) { + try { + // try to extract from the jar + InputStream is = LibraryLoader.class.getClassLoader().getResourceAsStream(filename); + if (is == null) { + throw new IOException(filename + " not found in the jar file (classpath)"); + } + byte[] buffer = new byte[4096]; + OutputStream os = new FileOutputStream(fullFilename); + int read; + while ((read = is.read(buffer)) != -1) { + os.write(buffer, 0, read); + } + os.close(); + is.close(); + if (!net.azib.ipscan.config.Platform.WINDOWS) { + // TODO: change this to new File(fullFilename).setExecutable(true) in case of + // Java 1.6 + try { + Runtime.getRuntime().exec(new String[] { "chmod", "755", fullFilename }).waitFor(); + } + catch (Throwable t) { + } + } + System.load(fullFilename); + } + catch (IOException ioe) { + throw new RuntimeException("Unable to extract native library: " + library, ioe); + } + } + } + +} diff --git a/src/net/azib/ipscan/core/net/ICMPPinger.java b/src/net/azib/ipscan/core/net/ICMPPinger.java index 6e73718d..54cbccc6 100644 --- a/src/net/azib/ipscan/core/net/ICMPPinger.java +++ b/src/net/azib/ipscan/core/net/ICMPPinger.java @@ -25,7 +25,7 @@ import org.savarese.vserv.tcpip.OctetConverter; */ public class ICMPPinger implements Pinger { - static final Logger LOG = Logger.getLogger(ICMPPinger.class.getName()); + private static final Logger LOG = Logger.getLogger(ICMPPinger.class.getName()); private int timeout; diff --git a/src/net/azib/ipscan/core/net/PingerRegistryImpl.java b/src/net/azib/ipscan/core/net/PingerRegistryImpl.java index 02dee4c0..09dc6494 100755 --- a/src/net/azib/ipscan/core/net/PingerRegistryImpl.java +++ b/src/net/azib/ipscan/core/net/PingerRegistryImpl.java @@ -14,12 +14,13 @@ import java.util.logging.Level; import java.util.logging.Logger; import net.azib.ipscan.config.GlobalConfig; +import net.azib.ipscan.config.Platform; import net.azib.ipscan.fetchers.FetcherException; /** * PingerRegistryImpl * - * @author Anton Keks Keks + * @author Anton Keks */ public class PingerRegistryImpl implements PingerRegistry { @@ -34,6 +35,10 @@ public class PingerRegistryImpl implements PingerRegistry { this.globalConfig = globalConfig; pingers = new LinkedHashMap>(); + if (Platform.WINDOWS) { + // this will be the preferred choice for Windows users + pingers.put("pinger.windows", WindowsPinger.class); + } pingers.put("pinger.icmp", ICMPSharedPinger.class); pingers.put("pinger.icmp2", ICMPPinger.class); pingers.put("pinger.udp", UDPPinger.class); diff --git a/src/net/azib/ipscan/core/net/WindowsPinger.java b/src/net/azib/ipscan/core/net/WindowsPinger.java index d2de107a..09eb0d2e 100644 --- a/src/net/azib/ipscan/core/net/WindowsPinger.java +++ b/src/net/azib/ipscan/core/net/WindowsPinger.java @@ -8,10 +8,13 @@ package net.azib.ipscan.core.net; import java.io.IOException; import java.net.InetAddress; +import net.azib.ipscan.core.LibraryLoader; + /** * Windows-only pinger that uses Microsoft's ICMP.DLL for its job. + *

* This pinger exists to provide adequate pinging to Windows users, - * because Microsoft has removed raw socket support from consumer + * because Microsoft has removed Raw Socket support from consumer * versions of Windows since XP SP2. * * @author Anton Keks @@ -19,12 +22,13 @@ import java.net.InetAddress; public class WindowsPinger implements Pinger { private int timeout; + private boolean libraryLoaded; public WindowsPinger(int timeout) { this.timeout = timeout; - } - - public void close() throws IOException { + if (!libraryLoaded) { + LibraryLoader.loadLibrary("winping"); + } } public PingResult ping(InetAddress address, int count) throws IOException { @@ -34,15 +38,22 @@ public class WindowsPinger implements Pinger { byte[] replyData = new byte[56 + 100]; int handle = nativeIcmpCreateFile(); + if (handle < 0) { + throw new IOException("Unable to create Windows native ICMP handle"); + } + try { // send a bunch of packets for (int i = 1; i <= count; i++) { if (nativeIcmpSendEcho(handle, address.getAddress(), pingData, replyData, timeout) > 0) { - /*if (replyData.status == 11000) { - result.addReply(replyData.roundTripTime); - result.setTTL(replyData.ttl); - }*/ + int status = replyData[4] + (replyData[5]<<8) + (replyData[6]<<16) + (replyData[7]<<24); + if (status == 0) { + int roundTripTime = replyData[8] + (replyData[9]<<8) + (replyData[10]<<16) + (replyData[11]<<24); + int timeToLive = replyData[20] & 0xFF; + result.addReply(roundTripTime); + result.setTTL(timeToLive); + } } } } @@ -53,9 +64,25 @@ public class WindowsPinger implements Pinger { return result; } + /** + * Wrapper for Microsoft's + * {@linkplain http://msdn2.microsoft.com/en-US/library/aa366045.aspx IcmpCreateFile} + */ private native static int nativeIcmpCreateFile(); + /** + * Wrapper for Microsoft's + * {@linkplain http://msdn2.microsoft.com/EN-US/library/aa366050.aspx IcmpSendEcho} + */ private native static int nativeIcmpSendEcho(int handle, byte[] address, byte[] pingData, byte[] replyData, int timeout); + /** + * Wrapper for Microsoft's IcmpCreateFile: + * {@linkplain http://msdn2.microsoft.com/en-us/library/Aa366043.aspx IcmpCloseHandle} + */ private native static void nativeIcmpCloseHandle(int handle); + + public void close() throws IOException { + // not needed in this pinger + } }