/*
* GNetWatch
* Copyright 2006, 2007 Alexandre Fenyo
* gnetwatch@fenyo.net
*
* This file is part of GNetWatch.
*
* GNetWatch is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GNetWatch is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNetWatch; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.fenyo.gnetwatch.actions;
import net.fenyo.gnetwatch.*;
import net.fenyo.gnetwatch.GUI.VisualElement;
import net.fenyo.gnetwatch.actions.Action.InterruptCause;
import net.fenyo.gnetwatch.activities.*;
import net.fenyo.gnetwatch.data.*;
import net.fenyo.gnetwatch.targets.*;
import java.io.*;
import java.net.*;
import java.util.*;
import org.snmp4j.*;
import org.snmp4j.smi.*;
import org.snmp4j.mp.*;
import org.snmp4j.transport.*;
import org.snmp4j.util.*;
import org.snmp4j.event.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Instances of this action class use SNMP to get the interface list of their target,
* and to get SNMP counters for each interface.
* @author Alexandre Fenyo
* @version $Id: ActionSNMP.java,v 1.21 2007/03/12 05:04:14 fenyo Exp $
*/
public class ActionSNMP extends Action {
private static Log log = LogFactory.getLog(ActionPing.class);
private boolean interrupted = false;
private boolean interfaces_created = false;
private Map<Integer, TargetInterface> targets = new HashMap<Integer, TargetInterface>();
private Map<Integer, Long> last_total_bytes_received = new HashMap<Integer, Long>();
private Map<Integer, Long> last_total_bytes_sent = new HashMap<Integer, Long>();
private Map<Integer, Long> last_total_bytes_received_time = new HashMap<Integer, Long>();
private Map<Integer, Long> last_total_bytes_sent_time = new HashMap<Integer, Long>();
/**
* Constructor.
* @param target target this action works on.
* @param background queue manager by which this action will add events.
*/
// GUI thread
// supports any thread
public ActionSNMP(final net.fenyo.gnetwatch.targets.Target target, final Background background) {
super(target, background);
setItem("snmp");
}
/**
* Constructor.
* @param none.
*/
// GUI thread
// supports any thread
public ActionSNMP() {
setItem("snmp");
}
/**
* Returns the associated target.
* @param none.
* @return Target associated target.
*/
// any thread
public String getQueueName() {
return "snmp";
}
/**
* Returns the timeout associated with this action.
* @param none.
* @return long timeout.
*/
// any thread
public long getMaxDelay() {
return 30000000;
}
/**
* Asks this action to stop rapidely.
* @param cause cause.
* @return void.
* @throws IOException IO exception.
*/
// main & Background threads
// supports any thread
public void interrupt(final InterruptCause cause) {
interrupted = true;
}
/**
* Gets the interface list to create interfaces and gets snmp counters.
* @param none.
* @return void.
* @throws IOException IO exception.
* @throws InterruptedException exception.
*/
// Queue thread
// supports any thread
public void invoke() throws IOException, InterruptedException {
if (isDisposed() == true) return;
super.invoke();
if (interfaces_created == false) {
interfaces_created = true;
final SNMPQuerier querier;
if (TargetIPv4.class.isInstance(getTarget())) {
querier = ((TargetIPv4) getTarget()).getSNMPQuerier();
} else if (TargetIPv6.class.isInstance(getTarget())) {
querier = ((TargetIPv6) getTarget()).getSNMPQuerier();
} else return;
getGUI().setStatus(getGUI().getConfig().getPattern("get_if_list", querier.getAddress().toString().substring(1)));
final java.util.List<TableEvent> interfaces = querier.getInterfaces();
if (querier.isSNMPCapable()) getTarget().setImageHostSNMP();
for (final TableEvent table_event : interfaces) {
try {
synchronized (getGUI().sync_tree) {
if (table_event == null || table_event.getColumns() == null || table_event.getColumns().length < 2 ||
table_event.getColumns()[0] == null || table_event.getColumns()[0].getVariable() == null ||
table_event.getColumns()[1] == null || table_event.getColumns()[1].getVariable() == null) {
log.info("can not get the full interface list of " + querier.getAddress().toString().substring(1));
getGUI().setStatus(getGUI().getConfig().getPattern("cannot_get_if_list", querier.getAddress().toString().substring(1)));
} else {
getGUI().setStatus(getGUI().getConfig().getPattern("received_if_list", querier.getAddress().toString().substring(1)));
final TargetInterface foo =
new TargetInterface(getTarget().toString() + ".interface[" +
table_event.getColumns()[0].getVariable().toString() + "]",
((OctetString) table_event.getColumns()[1].getVariable()).toASCII(' '));
if (getGUI().containsCanonicalInstance(foo)) {
targets.put(new Integer(table_event.getColumns()[0].getVariable().toString()),
(TargetInterface) getGUI().getCanonicalInstance(foo));
return;
}
getGUI().asyncExecIfNeeded(new Runnable() {
public void run() {
synchronized (getGUI().sync_tree) {
if (getGUI().containsCanonicalInstance(foo)) return;
foo.addTarget(getGUI(), getTarget());
targets.put(new Integer(table_event.getColumns()[0].getVariable().toString()),
(TargetInterface) getGUI().getCanonicalInstance(foo));
}
}
});
}
}
} catch (final AlgorithmException ex) {
log.error("Exception", ex);
}
}
}
final SNMPQuerier querier;
if (TargetIPv4.class.isInstance(getTarget())) {
querier = ((TargetIPv4) getTarget()).getSNMPQuerier();
} else if (TargetIPv6.class.isInstance(getTarget())) {
querier = ((TargetIPv6) getTarget()).getSNMPQuerier();
} else return;
final java.util.List<TableEvent> interfaces = querier.getInterfaces();
synchronized (getGUI().sync_tree) {
for (final TableEvent table_event : interfaces) {
if (table_event == null || table_event.getColumns() == null || table_event.getColumns().length == 0 ||
table_event.getColumns()[0] == null || table_event.getColumns()[0].getVariable() == null) continue;
final int interface_index = table_event.getColumns()[0].getVariable().toInt();
final TargetInterface target_interface = targets.get(interface_index);
if (target_interface == null) continue;
getGUI().setStatus(getGUI().getConfig().getPattern("received_snmp", querier.getAddress().toString().substring(1)));
if (table_event.getColumns().length <= 8 || table_event.getColumns()[8] == null ||
table_event.getColumns()[8].getVariable() == null) continue;
final long total_bytes_received = table_event.getColumns()[8].getVariable().toLong();
if (last_total_bytes_received.containsKey(interface_index) == false) {
last_total_bytes_received.put(interface_index, total_bytes_received);
last_total_bytes_received_time.put(interface_index, System.currentTimeMillis());
}
else if (last_total_bytes_received.get(interface_index) != total_bytes_received) {
target_interface.addEvent(new EventBytesReceived(total_bytes_received - last_total_bytes_received.get(interface_index)));
final long last_time = last_total_bytes_received_time.get(interface_index);
final long last_val = last_total_bytes_received.get(interface_index);
// limitation : seulement 2 fils pour les interfaces - il faudrait chercher les fils concerns : attention : locker
if (target_interface.getChildren().isEmpty() == false && target_interface.getChildren().get(0).getItem().equals("ingress"))
target_interface.getChildren().get(0).setDescription("" + (int) ((8 * 1000 * (double) (total_bytes_received - last_val)) / (System.currentTimeMillis() - last_time)) + " bit/s");
if (target_interface.getChildren().size() == 2 && target_interface.getChildren().get(1).getItem().equals("ingress"))
target_interface.getChildren().get(1).setDescription("" + (int) ((8 * 1000 * (double) (total_bytes_received - last_val)) / (System.currentTimeMillis() - last_time)) + " bit/s");
last_total_bytes_received.put(interface_index, total_bytes_received);
last_total_bytes_received_time.put(interface_index, System.currentTimeMillis());
}
if (table_event.getColumns().length <= 9 || table_event.getColumns()[9] == null ||
table_event.getColumns()[9].getVariable() == null) continue;
final long total_bytes_sent = table_event.getColumns()[9].getVariable().toLong();
if (last_total_bytes_sent.containsKey(interface_index) == false) {
last_total_bytes_sent.put(interface_index, total_bytes_sent);
last_total_bytes_sent_time.put(interface_index, System.currentTimeMillis());
}
else if (last_total_bytes_sent.get(interface_index) != total_bytes_sent) {
target_interface.addEvent(new EventBytesSent(total_bytes_sent - last_total_bytes_sent.get(interface_index)));
final long last_time = last_total_bytes_sent_time.get(interface_index);
final long last_val = last_total_bytes_sent.get(interface_index);
if (target_interface.getChildren().isEmpty() == false && target_interface.getChildren().get(0).getItem().equals("egress"))
target_interface.getChildren().get(0).setDescription("" + (int) ((8 * 1000 * (double) (total_bytes_sent - last_val)) / (System.currentTimeMillis() - last_time)) + " bit/s");
if (target_interface.getChildren().size() == 2 && target_interface.getChildren().get(1).getItem().equals("egress"))
target_interface.getChildren().get(1).setDescription("" + (int) ((8 * 1000 * (double) (total_bytes_sent - last_val)) / (System.currentTimeMillis() - last_time)) + " bit/s");
last_total_bytes_sent.put(interface_index, total_bytes_sent);
last_total_bytes_sent_time.put(interface_index, System.currentTimeMillis());
}
}
}
}
/**
* Called when this element is being removed.
* @param none.
* @return void.
*/
protected void disposed() {
// remove us from the queue
super.disposed();
// interrupt if currently running
interrupt(InterruptCause.removed);
}
}
|