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.activities.Background;
027: import net.fenyo.gnetwatch.data.*;
028: import net.fenyo.gnetwatch.targets.*;
029:
030: import java.io.*;
031: import java.net.*;
032: import java.util.Arrays;
033: import java.util.Date;
034:
035: import org.apache.commons.logging.Log;
036: import org.apache.commons.logging.LogFactory;
037:
038: /**
039: * Instances of this action class can flood their target with UDP
040: * and create events of type EventFlood to log the throughput.
041: * @author Alexandre Fenyo
042: * @version $Id: ActionFlood.java,v 1.17 2007/03/12 05:04:15 fenyo Exp $
043: */
044:
045: public class ActionFlood extends Action {
046: private static Log log = LogFactory.getLog(ActionPing.class);
047:
048: private boolean interrupted = false;
049:
050: /**
051: * Constructor.
052: * @param target target this action works on.
053: * @param background queue manager by which this action will add events.
054: */
055: // GUI thread
056: // supports any thread
057: public ActionFlood(final Target target, final Background background) {
058: super (target, background);
059: setItem("flood");
060: }
061:
062: /**
063: * Constructor.
064: * @param none.
065: */
066: // GUI thread
067: // supports any thread
068: public ActionFlood() {
069: setItem("flood");
070: }
071:
072: /**
073: * Returns the associated target.
074: * @param none.
075: * @return Target associated target.
076: */
077: // any thread
078: public String getQueueName() {
079: return "flood";
080: }
081:
082: /**
083: * Returns the timeout associated with this action.
084: * @param none.
085: * @return long timeout.
086: */
087: // any thread
088: // bug : au bout de ce tps en ms ca s'arrete
089: public long getMaxDelay() {
090: return 30000000;
091: }
092:
093: /**
094: * Asks this action to stop rapidely.
095: * @param cause cause.
096: * @return void.
097: * @throws IOException IO exception.
098: */
099: // main & Background threads
100: // supports any thread
101: public void interrupt(final InterruptCause cause) {
102: interrupted = true;
103: }
104:
105: /**
106: * Floods the target.
107: * @param none.
108: * @return void.
109: * @throws IOException IO exception.
110: * @throws InterruptedException exception.
111: */
112: // Queue thread
113: // supports any thread
114: public void invoke() throws IOException, InterruptedException {
115: if (isDisposed() == true)
116: return;
117:
118: try {
119: super .invoke();
120:
121: // il faudrait copier les queriers à la création de l'action
122: final IPQuerier querier;
123: if (TargetIPv4.class.isInstance(getTarget())) {
124: querier = ((TargetIPv4) getTarget()).getIPQuerier();
125: } else if (TargetIPv6.class.isInstance(getTarget())) {
126: querier = ((TargetIPv6) getTarget()).getIPQuerier();
127: } else
128: return;
129:
130: DatagramSocket socket = new DatagramSocket(querier
131: .getPortSrc());
132: socket.setTrafficClass(querier.getTOS() << 2);
133: socket.setBroadcast(true);
134:
135: final byte[] buf = new byte[querier.getPDUMaxSize()];
136: Arrays.fill(buf, (byte) 0);
137: final DatagramPacket packet = new DatagramPacket(buf,
138: buf.length, new InetSocketAddress(querier
139: .getAddress(), querier.getPortDst()));
140:
141: long last_time = System.currentTimeMillis();
142: int bytes_sent = 0;
143: while (true) {
144: socket.send(packet);
145: bytes_sent += buf.length;
146:
147: if (System.currentTimeMillis() - last_time > 1000) {
148: getTarget().addEvent(new EventFlood(bytes_sent));
149: setDescription(""
150: + new Double(
151: ((double) 8 * 1000 * bytes_sent)
152: / (System
153: .currentTimeMillis() - last_time))
154: .intValue() + " bit/s");
155:
156: // getGUI().setStatus(bytes_sent + " bytes flooded to " + querier.getAddress().toString().substring(1) + " for the last second");
157: getGUI().setStatus(
158: getGUI().getConfig().getPattern(
159: "bytes_flooded",
160: bytes_sent,
161: querier.getAddress().toString()
162: .substring(1)));
163:
164: last_time = System.currentTimeMillis();
165: bytes_sent = 0;
166: }
167:
168: if (interrupted == true) {
169: socket.close();
170: return;
171: }
172: }
173: } catch (final InterruptedException ex) {
174: }
175: }
176:
177: /**
178: * Called when this element is being removed.
179: * @param none.
180: * @return void.
181: */
182: protected void disposed() {
183: // remove us from the flood queue
184: super .disposed();
185:
186: // interrupt if currently running
187: interrupt(InterruptCause.removed);
188: }
189: }
|