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.VisualElement;
027: import net.fenyo.gnetwatch.actions.Action.InterruptCause;
028: import net.fenyo.gnetwatch.activities.*;
029: import net.fenyo.gnetwatch.data.*;
030: import net.fenyo.gnetwatch.targets.*;
031:
032: import java.io.*;
033: import java.net.*;
034: import java.util.*;
035:
036: import org.snmp4j.*;
037: import org.snmp4j.smi.*;
038: import org.snmp4j.mp.*;
039: import org.snmp4j.transport.*;
040: import org.snmp4j.util.*;
041: import org.snmp4j.event.*;
042:
043: import org.apache.commons.logging.Log;
044: import org.apache.commons.logging.LogFactory;
045:
046: /**
047: * Instances of this action class use SNMP to get the interface list of their target,
048: * and to get SNMP counters for each interface.
049: * @author Alexandre Fenyo
050: * @version $Id: ActionSNMP.java,v 1.21 2007/03/12 05:04:14 fenyo Exp $
051: */
052:
053: public class ActionSNMP extends Action {
054: private static Log log = LogFactory.getLog(ActionPing.class);
055:
056: private boolean interrupted = false;
057: private boolean interfaces_created = false;
058:
059: private Map<Integer, TargetInterface> targets = new HashMap<Integer, TargetInterface>();
060: private Map<Integer, Long> last_total_bytes_received = new HashMap<Integer, Long>();
061: private Map<Integer, Long> last_total_bytes_sent = new HashMap<Integer, Long>();
062: private Map<Integer, Long> last_total_bytes_received_time = new HashMap<Integer, Long>();
063: private Map<Integer, Long> last_total_bytes_sent_time = new HashMap<Integer, Long>();
064:
065: /**
066: * Constructor.
067: * @param target target this action works on.
068: * @param background queue manager by which this action will add events.
069: */
070: // GUI thread
071: // supports any thread
072: public ActionSNMP(final net.fenyo.gnetwatch.targets.Target target,
073: final Background background) {
074: super (target, background);
075: setItem("snmp");
076: }
077:
078: /**
079: * Constructor.
080: * @param none.
081: */
082: // GUI thread
083: // supports any thread
084: public ActionSNMP() {
085: setItem("snmp");
086: }
087:
088: /**
089: * Returns the associated target.
090: * @param none.
091: * @return Target associated target.
092: */
093: // any thread
094: public String getQueueName() {
095: return "snmp";
096: }
097:
098: /**
099: * Returns the timeout associated with this action.
100: * @param none.
101: * @return long timeout.
102: */
103: // any thread
104: public long getMaxDelay() {
105: return 30000000;
106: }
107:
108: /**
109: * Asks this action to stop rapidely.
110: * @param cause cause.
111: * @return void.
112: * @throws IOException IO exception.
113: */
114: // main & Background threads
115: // supports any thread
116: public void interrupt(final InterruptCause cause) {
117: interrupted = true;
118: }
119:
120: /**
121: * Gets the interface list to create interfaces and gets snmp counters.
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: super .invoke();
134:
135: if (interfaces_created == false) {
136: interfaces_created = true;
137:
138: final SNMPQuerier querier;
139: if (TargetIPv4.class.isInstance(getTarget())) {
140: querier = ((TargetIPv4) getTarget()).getSNMPQuerier();
141: } else if (TargetIPv6.class.isInstance(getTarget())) {
142: querier = ((TargetIPv6) getTarget()).getSNMPQuerier();
143: } else
144: return;
145:
146: getGUI().setStatus(
147: getGUI().getConfig().getPattern(
148: "get_if_list",
149: querier.getAddress().toString()
150: .substring(1)));
151: final java.util.List<TableEvent> interfaces = querier
152: .getInterfaces();
153: if (querier.isSNMPCapable())
154: getTarget().setImageHostSNMP();
155: for (final TableEvent table_event : interfaces) {
156: try {
157: synchronized (getGUI().sync_tree) {
158: if (table_event == null
159: || table_event.getColumns() == null
160: || table_event.getColumns().length < 2
161: || table_event.getColumns()[0] == null
162: || table_event.getColumns()[0]
163: .getVariable() == null
164: || table_event.getColumns()[1] == null
165: || table_event.getColumns()[1]
166: .getVariable() == null) {
167: log
168: .info("can not get the full interface list of "
169: + querier.getAddress()
170: .toString()
171: .substring(1));
172: getGUI().setStatus(
173: getGUI().getConfig().getPattern(
174: "cannot_get_if_list",
175: querier.getAddress()
176: .toString()
177: .substring(1)));
178: } else {
179: getGUI().setStatus(
180: getGUI().getConfig().getPattern(
181: "received_if_list",
182: querier.getAddress()
183: .toString()
184: .substring(1)));
185: final TargetInterface foo = new TargetInterface(
186: getTarget().toString()
187: + ".interface["
188: + table_event.getColumns()[0]
189: .getVariable()
190: .toString() + "]",
191: ((OctetString) table_event
192: .getColumns()[1]
193: .getVariable())
194: .toASCII(' '));
195: if (getGUI().containsCanonicalInstance(foo)) {
196: targets.put(new Integer(table_event
197: .getColumns()[0].getVariable()
198: .toString()),
199: (TargetInterface) getGUI()
200: .getCanonicalInstance(
201: foo));
202: return;
203: }
204: getGUI().asyncExecIfNeeded(new Runnable() {
205: public void run() {
206: synchronized (getGUI().sync_tree) {
207: if (getGUI()
208: .containsCanonicalInstance(
209: foo))
210: return;
211: foo.addTarget(getGUI(),
212: getTarget());
213: targets
214: .put(
215: new Integer(
216: table_event
217: .getColumns()[0]
218: .getVariable()
219: .toString()),
220: (TargetInterface) getGUI()
221: .getCanonicalInstance(
222: foo));
223: }
224: }
225: });
226: }
227: }
228: } catch (final AlgorithmException ex) {
229: log.error("Exception", ex);
230: }
231: }
232: }
233:
234: final SNMPQuerier querier;
235: if (TargetIPv4.class.isInstance(getTarget())) {
236: querier = ((TargetIPv4) getTarget()).getSNMPQuerier();
237: } else if (TargetIPv6.class.isInstance(getTarget())) {
238: querier = ((TargetIPv6) getTarget()).getSNMPQuerier();
239: } else
240: return;
241:
242: final java.util.List<TableEvent> interfaces = querier
243: .getInterfaces();
244: synchronized (getGUI().sync_tree) {
245: for (final TableEvent table_event : interfaces) {
246: if (table_event == null
247: || table_event.getColumns() == null
248: || table_event.getColumns().length == 0
249: || table_event.getColumns()[0] == null
250: || table_event.getColumns()[0].getVariable() == null)
251: continue;
252:
253: final int interface_index = table_event.getColumns()[0]
254: .getVariable().toInt();
255: final TargetInterface target_interface = targets
256: .get(interface_index);
257: if (target_interface == null)
258: continue;
259:
260: getGUI().setStatus(
261: getGUI().getConfig().getPattern(
262: "received_snmp",
263: querier.getAddress().toString()
264: .substring(1)));
265:
266: if (table_event.getColumns().length <= 8
267: || table_event.getColumns()[8] == null
268: || table_event.getColumns()[8].getVariable() == null)
269: continue;
270: final long total_bytes_received = table_event
271: .getColumns()[8].getVariable().toLong();
272:
273: if (last_total_bytes_received
274: .containsKey(interface_index) == false) {
275: last_total_bytes_received.put(interface_index,
276: total_bytes_received);
277: last_total_bytes_received_time.put(interface_index,
278: System.currentTimeMillis());
279: } else if (last_total_bytes_received
280: .get(interface_index) != total_bytes_received) {
281: target_interface.addEvent(new EventBytesReceived(
282: total_bytes_received
283: - last_total_bytes_received
284: .get(interface_index)));
285: final long last_time = last_total_bytes_received_time
286: .get(interface_index);
287: final long last_val = last_total_bytes_received
288: .get(interface_index);
289:
290: // limitation : seulement 2 fils pour les interfaces - il faudrait chercher les fils concernés : attention : locker
291: if (target_interface.getChildren().isEmpty() == false
292: && target_interface.getChildren().get(0)
293: .getItem().equals("ingress"))
294: target_interface
295: .getChildren()
296: .get(0)
297: .setDescription(
298: ""
299: + (int) ((8 * 1000 * (double) (total_bytes_received - last_val)) / (System
300: .currentTimeMillis() - last_time))
301: + " bit/s");
302:
303: if (target_interface.getChildren().size() == 2
304: && target_interface.getChildren().get(1)
305: .getItem().equals("ingress"))
306: target_interface
307: .getChildren()
308: .get(1)
309: .setDescription(
310: ""
311: + (int) ((8 * 1000 * (double) (total_bytes_received - last_val)) / (System
312: .currentTimeMillis() - last_time))
313: + " bit/s");
314:
315: last_total_bytes_received.put(interface_index,
316: total_bytes_received);
317: last_total_bytes_received_time.put(interface_index,
318: System.currentTimeMillis());
319: }
320:
321: if (table_event.getColumns().length <= 9
322: || table_event.getColumns()[9] == null
323: || table_event.getColumns()[9].getVariable() == null)
324: continue;
325: final long total_bytes_sent = table_event.getColumns()[9]
326: .getVariable().toLong();
327: if (last_total_bytes_sent.containsKey(interface_index) == false) {
328: last_total_bytes_sent.put(interface_index,
329: total_bytes_sent);
330: last_total_bytes_sent_time.put(interface_index,
331: System.currentTimeMillis());
332: } else if (last_total_bytes_sent.get(interface_index) != total_bytes_sent) {
333: target_interface.addEvent(new EventBytesSent(
334: total_bytes_sent
335: - last_total_bytes_sent
336: .get(interface_index)));
337: final long last_time = last_total_bytes_sent_time
338: .get(interface_index);
339: final long last_val = last_total_bytes_sent
340: .get(interface_index);
341:
342: if (target_interface.getChildren().isEmpty() == false
343: && target_interface.getChildren().get(0)
344: .getItem().equals("egress"))
345: target_interface
346: .getChildren()
347: .get(0)
348: .setDescription(
349: ""
350: + (int) ((8 * 1000 * (double) (total_bytes_sent - last_val)) / (System
351: .currentTimeMillis() - last_time))
352: + " bit/s");
353: if (target_interface.getChildren().size() == 2
354: && target_interface.getChildren().get(1)
355: .getItem().equals("egress"))
356: target_interface
357: .getChildren()
358: .get(1)
359: .setDescription(
360: ""
361: + (int) ((8 * 1000 * (double) (total_bytes_sent - last_val)) / (System
362: .currentTimeMillis() - last_time))
363: + " bit/s");
364:
365: last_total_bytes_sent.put(interface_index,
366: total_bytes_sent);
367: last_total_bytes_sent_time.put(interface_index,
368: System.currentTimeMillis());
369: }
370: }
371: }
372: }
373:
374: /**
375: * Called when this element is being removed.
376: * @param none.
377: * @return void.
378: */
379: protected void disposed() {
380: // remove us from the queue
381: super .disposed();
382:
383: // interrupt if currently running
384: interrupt(InterruptCause.removed);
385: }
386: }
|