You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by rufio <ru...@op.pl> on 2003/09/26 05:55:42 UTC

[PATCH][NET] org.apache.commons.net.PingICMP

Hi all
Few days ago I asked on users list about pinging.
Daniel F. Savarese answered it's impossible since it requires raw sockets.
I pointed that there is possible implementation in perl and Daniel suggested me
 to implement it and send a patch.

So here it is, my 1st contribution.

There is no javadoc comments fo privates since they are all the same and names are
descriptive.
Also there is no real support for MacOS - it's assumed it's compatible with UNIX.

Tested on Linux and Windows
to test call PingICMP.ping("localhost",1,0);

---PingICMP.diff---cut here---

--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ org/apache/commons/net/PingICMP.java	2003-09-26 05:44:51.000000000 +0200
@@ -0,0 +1,149 @@
+package org.apache.commons.net;
+
+/*
+ *  Apache License 1.1 to be included here
+ */
+import java.io.IOException;
+import java.net.InetAddress;
+
+/**
+ *  This class provides a way to sending ICMP (RFC792) ECHO request and
+ *  receiving ECHO response. Since on all modern operating systems this would
+ *  require access to raw sockets and java has currently no such access this is
+ *  implemented by executing operating system's ping command with system
+ *  specific parameters Currently only Unix (including Linux,MacOSX) and windows
+ *  are supported. Older MacOSes are not supported because I have no idea how tu
+ *  ping under MacOSes.
+ *  <H3>Requirements:</h3>
+ *  <ul>
+ *    <li> ping has to be in your PATH environment variable</li>
+ *    <li> you have to have permission to execute ping</li>
+ *  </ul>
+ *  <h3>About timeout</h3>
+ *  Under win32 it's easy to set timeout for pings - you
+ *  use -w parameter but on UNIX there is no option to set timeout, so we have
+ *  to simulate its behaviour somehow.<br>
+ *  This is done by simply executing ping command and checking its state by
+ *  method Process.exitValue(), wich throws IllegalThreadStateException if the
+ *  command is still running. Process' state is checked every 500ms. Note that
+ *  ping method can return earlier than <i>timeout</i> when ping command's
+ *  internal timeout is reached.
+ *
+ *@author     Rafal Krupinski
+ *@created    26 september 2003
+ *@version    $Id$
+ */
+
+public final class PingICMP {
+
+	/**
+	 *  This is basic method for pinging host. It checks your system's name and
+	 *  timeout value and calls aprioprate method, wich executes ping command
+	 *
+	 *@param  target                    host name or IP (v4) to ping
+	 *@param  count                     number of pingecho packets to send
+	 *@param  timeout                   time to wait on ping responses, see above.
+	 *@return                           true if target host is reachable; false
+	 *      otherwise
+	 *@exception  IOException           if an I/O error occurs
+	 *@exception  InterruptedException  if the current thread is interrupted by
+	 *      another thread while it is waiting, then the wait is ended and an
+	 *      InterruptedException is thrown.
+	 */
+	public static boolean ping(String target, int count, long timeout)
+		throws IOException, InterruptedException {
+		String os = System.getProperty("os.name");
+		if (os.startsWith("Windows")) {
+			return pingWin(target, count, timeout);
+		}
+		//if(os.startsWith("Mac OS")){return pingMac(target,count,timeout);}
+		else {
+			if (timeout != 0) {
+				return pingUnix(target, count, timeout);
+			}
+			else {
+				return pingUnix(target, count);
+			}
+		}
+	}
+
+
+	/**
+	 *  This is the same as ping(target,count,0) timeout value is system specific;
+	 *  probably you shouldn't use this method
+	 *
+	 *@param  target                    host name or IP (v4) to ping
+	 *@param  count                     number of pingecho packets to send
+	 *@return                           true if target host is reachable; false
+	 *      otherwise
+	 *@exception  IOException           if an I/O error occurs
+	 *@exception  InterruptedException  if the current thread is interrupted by
+	 *      another thread while it is waiting, then the wait is ended and an
+	 *      InterruptedException is thrown.
+	 */
+	public static boolean ping(String target, int count)
+		throws IOException, InterruptedException {
+		return ping(target, count, 0);
+	}
+
+	private static boolean pingWin(String target, int count, long timeout)
+		throws IOException, InterruptedException {
+		String[] cmd = {};
+		if (timeout == 0) {
+			cmd = new String[4];
+		}
+		else {
+			cmd = new String[6];
+			cmd[3] = "-w";
+			cmd[4] = Long.toString(timeout);
+		}
+		cmd[0] = "ping";
+		cmd[1] = "-n";
+		cmd[2] = Integer.toString(count);
+		cmd[cmd.length - 1] = target;
+		return ping(cmd);
+	}
+
+
+//miliseconds in second
+	private final static long SECMSEC = 1000;
+
+//delay between checks
+	private final static long DELAY = 500;
+
+	private static boolean pingUnix(String target, int count, long timeout)
+		throws IOException, InterruptedException {
+		Process ping = Runtime.getRuntime().exec(new String[]{"ping", "-c", Integer.toString(count), target});
+		//sleep until we can expect result, ie. DELAY or temeout after last ping, whichever comes sooner
+		long sleep = count * SECMSEC - 1 + Math.min(timeout, DELAY);
+		timeout -= Math.min(timeout, DELAY);
+		Thread.sleep(sleep);
+		//if initial timeout was less than DELAY than timeout is already 0, but still we must check status
+		do {
+			//this makes timeout is always nonnegative
+			timeout -= Math.min(timeout, DELAY);
+			Thread.sleep(timeout);
+			try {
+				return ping.exitValue() == 0;
+			}
+			catch (IllegalThreadStateException e) {
+				/*
+				 *  process still running; do nothing; wait another DELAYms
+				 */
+			}
+		} while (timeout > 0);
+		//timeout reached
+		return false;
+	}
+
+	private static boolean pingUnix(String target, int count)
+		throws IOException, InterruptedException {
+		return ping(new String[]{"ping", "-c", Integer.toString(count), target});
+	}
+
+	private static boolean ping(String[] cmd)
+		throws IOException, InterruptedException {
+		Process ping = Runtime.getRuntime().exec(cmd);
+		return ping.waitFor() == 0;
+	}
+}

---cut here---

Regards, Rufio
-- 
nmap -sS -O -p80,81 www.microsoft.com
[..]
Running: Linux 2.5.X
OS details: Linux Kernel 2.4.18 - 2.5.70 (X86)

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org