001: /*
002: * GNetWatch
003: * Copyright 2006, 2007 Alexandre Fenyo
004: * gnetwatch@fenyo.net
005: *
006: * This file is part of GNetWatch.
007: *
008: * GNetWatch is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU General Public License as published by
010: * the Free Software Foundation; either version 2 of the License, or
011: * (at your option) any later version.
012: *
013: * GNetWatch is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public License
019: * along with GNetWatch; if not, write to the Free Software
020: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
021: */
022:
023: package net.fenyo.gnetwatch.actions;
024:
025: import net.fenyo.gnetwatch.*;
026: import net.fenyo.gnetwatch.GUI.GUI;
027: import net.fenyo.gnetwatch.actions.Action.InterruptCause;
028: import net.fenyo.gnetwatch.activities.Background;
029: import net.fenyo.gnetwatch.data.*;
030: import net.fenyo.gnetwatch.targets.*;
031:
032: import java.io.*;
033: import java.util.regex.Matcher;
034: import java.util.regex.Pattern;
035:
036: import org.apache.commons.logging.Log;
037: import org.apache.commons.logging.LogFactory;
038:
039: /**
040: * Instances of this action class can send/receive ICMP echo messages to their target
041: * and create events of type EventReachable.
042: * @author Alexandre Fenyo
043: * @version $Id: ActionPing.java,v 1.32 2007/03/12 05:04:14 fenyo Exp $
044: */
045:
046: public class ActionPing extends Action {
047: private static Log log = LogFactory.getLog(ActionPing.class);
048:
049: // main, Background & Queue threads
050: // supports any thread
051: private ExternalCommand cmd_ping = null;
052:
053: /**
054: * Constructor.
055: * @param target target this action works on.
056: * @param background queue manager by which this action will add events.
057: */
058: // GUI thread
059: // supports any thread
060: public ActionPing(final Target target, final Background background) {
061: super (target, background);
062: setItem("ping");
063: }
064:
065: /**
066: * Constructor.
067: * @param none.
068: */
069: // GUI thread
070: // supports any thread
071: public ActionPing() {
072: setItem("ping");
073: }
074:
075: /**
076: * Called to inform about the current GUI.
077: * @param gui current GUI instance.
078: * @return void.
079: */
080: protected void initialize(final GUI gui) {
081: super .initialize(gui);
082: if (gui != null)
083: setImageWatch();
084: }
085:
086: /**
087: * Returns the associated target.
088: * @param none.
089: * @return Target associated target.
090: */
091: // any thread
092: public String getQueueName() {
093: return "icmp";
094: }
095:
096: /**
097: * Returns the timeout associated with this action.
098: * @param none.
099: * @return long timeout.
100: */
101: // any thread
102: public long getMaxDelay() {
103: return 4000;
104: }
105:
106: /**
107: * Asks this action to stop rapidely.
108: * @param cause cause.
109: * @return void.
110: * @throws IOException IO exception.
111: */
112: // main & Background threads
113: // supports any thread
114: public void interrupt(final InterruptCause cause)
115: throws IOException {
116: if (cmd_ping != null)
117: cmd_ping.end();
118: }
119:
120: /**
121: * Computes the RTT to the target.
122: * @param none.
123: * @return void.
124: * @throws IOException IO exception.
125: * @throws InterruptedException exception.
126: */
127: // Queue thread
128: // supports any thread
129: public void invoke() throws IOException, InterruptedException {
130: if (isDisposed() == true)
131: return;
132:
133: try {
134: super .invoke();
135:
136: if (TargetIPv4.class.isInstance(getTarget())) {
137: final TargetIPv4 target = (TargetIPv4) getTarget();
138: String address = target.getAddress().toString();
139: // remplacer tous les substrin(1) par cette forme avec indexof
140: address = address.substring(1 + address.indexOf('/'));
141:
142: final String[] cmdLine = new String[] {
143: "ping",
144: getGUI().getConfig().getProperty(
145: "ping.countparameter"), "1", address
146: // "sleep", "10000"
147: };
148: String cmd_line = "";
149: for (final String part : cmdLine)
150: cmd_line += part + " ";
151: // getGUI().setStatus("forking external command: " + cmd_line);
152: getGUI().setStatus(
153: getGUI().getConfig().getPattern("forking",
154: cmd_line));
155: cmd_ping = new ExternalCommand(cmdLine, true);
156: cmd_ping.fork();
157:
158: final String cmd_output = cmd_ping.readStdout();
159: final Matcher match = Pattern.compile(
160: address
161: + getGUI().getConfig().getProperty(
162: "ping.regex")).matcher(
163: cmd_output);
164: if (match.find() == true) {
165: final int delay = new Integer(match.group(2))
166: .intValue();
167: getTarget().addEvent(
168: new EventReachable(true, new Integer(match
169: .group(2)).intValue()));
170: getGUI().setStatus(
171: getGUI().getConfig().getPattern(
172: "received_icmp", address));
173: setDescription("rtt: " + delay + " ms");
174: } else {
175: getTarget().addEvent(new EventReachable(false));
176: getGUI().setStatus(
177: getGUI().getConfig().getPattern(
178: "received_icmp_timeout", address));
179: setDescription(getGUI().getConfig().getString(
180: "unreachable"));
181: }
182: cmd_ping.end();
183: }
184:
185: if (TargetIPv6.class.isInstance(getTarget())) {
186: final TargetIPv6 target = (TargetIPv6) getTarget();
187: String address = target.getAddress().toString();
188: // remplacer tous les substrin(1) par cette forme avec indexof
189: address = address.substring(1 + address.indexOf('/'));
190:
191: final String[] cmdLine = new String[] {
192: "ping6",
193: getGUI().getConfig().getProperty(
194: "ping.countparameter"), "1", address
195: // "sleep", "10000"
196: };
197: cmd_ping = new ExternalCommand(cmdLine, true);
198: cmd_ping.fork();
199:
200: final String cmd_output = cmd_ping.readStdout();
201: // pattern could by a better matcher...
202: final Matcher match = Pattern.compile(
203: "(.|\r|\n)*:.*?([0-9]+)[^0-9]*ms(.|\r|\n)*")
204: .matcher(cmd_output);
205: if (match.find() == true) {
206: final int delay = new Integer(match.group(2))
207: .intValue();
208: getTarget().addEvent(
209: new EventReachable(true, new Integer(match
210: .group(2)).intValue()));
211: setDescription("rtt: " + delay + " ms");
212: } else {
213: getTarget().addEvent(new EventReachable(false));
214: setDescription(getGUI().getConfig().getString(
215: "unreachable"));
216: }
217: cmd_ping.end();
218: }
219:
220: } catch (final InterruptedException ex) {
221: getTarget().addEvent(new EventReachable(false));
222: setDescription(getGUI().getConfig()
223: .getString("unreachable"));
224: throw ex;
225: }
226: }
227:
228: /**
229: * Called when this element is being removed.
230: * @param none.
231: * @return void.
232: */
233: protected void disposed() {
234: // remove us from the action queue
235: super .disposed();
236:
237: // interrupt if currently running
238: try {
239: interrupt(InterruptCause.removed);
240: } catch (final IOException ex) {
241: log.error("Exception", ex);
242: }
243: }
244: }
|