first version of WindowsPinger

git-svn-id: https://ipscan.svn.sourceforge.net/svnroot/ipscan/trunk@175 375186e5-ef17-0410-b0b6-91563547dcda
This commit is contained in:
angryziber 2007-07-24 18:43:43 +00:00
parent 8552884b71
commit 21bfc726c6
4 changed files with 221 additions and 0 deletions

31
ext/winping/jni/Makefile Executable file
View File

@ -0,0 +1,31 @@
#
# Windows JNI pinger using Microsoft's ICMP.DLL
#
# Copyright 2007 Anton Keks
#
JAVA_INCDIR = $(JDK_HOME)\include
JAVA_INCDIR_PLAF = $(JAVA_INCDIR)\win32
CC = cl
CFLAGS = -TC
CPPFLAGS = -I$(JAVA_INCDIR) -I$(JAVA_INCDIR_PLAF)
SRC = WindowsPinger.c
OBJ = $(SRC:.c=.obj)
LIBNAME = winping
LIBEXTENSION = dll
LIBWINPING = $(LIBNAME).$(LIBEXTENSION)
CLEAN_EXTENSIONS = *.obj *.$(LIBEXTENSION) *.lib *.exp
all: $(LIBWINPING)
.c.obj:
$(CC) -nologo $(CFLAGS) $(CPPFLAGS) -c $< -o $@
$(LIBWINPING): $(OBJ)
$(CC) -nologo -MD -LD -o $@ $**
clean:
del $(CLEAN_EXTENSIONS)

93
ext/winping/jni/WindowsPinger.c Executable file
View File

@ -0,0 +1,93 @@
/*
* Copyright 2007 Anton Keks
*/
#include <windows.h>
#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;
}

View File

@ -0,0 +1,36 @@
#include <jni.h>
/* Header for class net_azib_ipscan_core_net_WindowsPinger */
#ifndef _Included_net_azib_ipscan_core_net_WindowsPinger
#define _Included_net_azib_ipscan_core_net_WindowsPinger
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: net_azib_ipscan_core_net_WindowsPinger
* Method: nativeIcmpCreateFile
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_net_azib_ipscan_core_net_WindowsPinger_nativeIcmpCreateFile
(JNIEnv *, jclass);
/*
* Class: net_azib_ipscan_core_net_WindowsPinger
* Method: nativeIcmpSendEcho
* Signature: (I[B[B[BI)I
*/
JNIEXPORT jint JNICALL Java_net_azib_ipscan_core_net_WindowsPinger_nativeIcmpSendEcho
(JNIEnv *, jclass, jint, jbyteArray, jbyteArray, jbyteArray, jint);
/*
* Class: net_azib_ipscan_core_net_WindowsPinger
* Method: nativeIcmpCloseHandle
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_net_azib_ipscan_core_net_WindowsPinger_nativeIcmpCloseHandle
(JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,61 @@
/**
* 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.net;
import java.io.IOException;
import java.net.InetAddress;
/**
* 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
* 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 void close() throws IOException {
}
public PingResult ping(InetAddress address, int count) throws IOException {
PingResult result = new PingResult(address);
byte[] pingData = new byte[56];
byte[] replyData = new byte[56 + 100];
int handle = nativeIcmpCreateFile();
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);
}*/
}
}
}
finally {
nativeIcmpCloseHandle(handle);
}
return result;
}
private native static int nativeIcmpCreateFile();
private native static int nativeIcmpSendEcho(int handle, byte[] address, byte[] pingData, byte[] replyData, int timeout);
private native static void nativeIcmpCloseHandle(int handle);
}