[SNMP4J] snmpwalk fails with "No more variables left in this MIB View (It is past the end of the MIB tree)"
Maximilian Schmidt
mail at d1u.de
Thu Sep 23 17:50:31 CEST 2010
Hi there,
iam using the snmp4j API to create an SNMP-agent.
When i do a
snmpwalk -0s -c public -v 2c localhost:2001 1.3.6.1.4.1.6695.1
there is this error message at the end of the result:
"No more variables left in this MIB View (It is past the end of the MIB
tree)"
A snmpnext at the very last OID in this table, jumps to a column that
doesn't exist.
Many thanks in advance,
Greetings Max Schmidt.
Here is my agent-class:
###########################
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Timer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.rrd4j.ConsolFun;
import org.rrd4j.core.FetchData;
import org.rrd4j.core.FetchRequest;
import org.rrd4j.core.RrdDb;
import org.rrd4j.core.RrdDbPoolNew;
import org.rrd4j.core.Util;
import org.snmp4j.TransportMapping;
import org.snmp4j.agent.BaseAgent;
import org.snmp4j.agent.CommandProcessor;
import org.snmp4j.agent.DuplicateRegistrationException;
import org.snmp4j.agent.MOGroup;
import org.snmp4j.agent.ManagedObject;
import org.snmp4j.agent.mo.MOAccessImpl;
import org.snmp4j.agent.mo.MOMutableTableRow;
import org.snmp4j.agent.mo.MOTable;
import org.snmp4j.agent.mo.MOTableRow;
import org.snmp4j.agent.mo.snmp.RowStatus;
import org.snmp4j.agent.mo.snmp.SnmpCommunityMIB;
import org.snmp4j.agent.mo.snmp.SnmpNotificationMIB;
import org.snmp4j.agent.mo.snmp.SnmpTargetMIB;
import org.snmp4j.agent.mo.snmp.StorageType;
import org.snmp4j.agent.mo.snmp.VacmMIB;
import org.snmp4j.agent.security.MutableVACM;
import org.snmp4j.mp.MPv3;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.security.SecurityModel;
import org.snmp4j.security.USM;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.SMIConstants;
import org.snmp4j.smi.Variable;
import org.snmp4j.transport.TransportMappings;
/**
* This Agent contains mimimal functionality for running a version 2c snmp
* agent.
*/
public class SNMPAgent extends BaseAgent {
private Logger logger = Logger.getLogger(TTMReader.class.getName());
private String address;
private RrdDbPoolNew rrdPool = (RrdDbPoolNew) RrdDbPoolNew.getInstance();
private ArrayList<String> files = null;
private static final OID sysDescr = new OID(".1.3.6.1.2.1.1.1.0");
private static final OID root = new OID(".1.3.6.1.4.1.6695.1");
private ConfigCheck config = ConfigCheck.getInstance();
private MOTable table = null;
private Timer timer = null;
public SNMPAgent(String address) throws IOException {
// These files does not exist and are not used but has to be specified
// Read snmp4j docs for more info
super(new File("conf.agent"), new File("bootCounter.agent"), new
CommandProcessor(new OctetString(MPv3.createLocalEngineID())));
this.address = address;
// Build Table
MOTableBuilder builder = new MOTableBuilder(root);
builder.addColumnType(SMIConstants.SYNTAX_OCTET_STRING,MOAccessImpl.ACCESS_READ_ONLY);
builder.addColumnType(SMIConstants.SYNTAX_OCTET_STRING,MOAccessImpl.ACCESS_READ_ONLY);
builder.addColumnType(SMIConstants.SYNTAX_INTEGER,MOAccessImpl.ACCESS_READ_ONLY);
// Build array with rrd's that should be monitored
Destination[] destinations = config.getDestinations();
Source[] sources = TTMReader.getSources();
files = new ArrayList<String>();
for(int i = 0 ; i < sources.length ; ++i) {
for(int j = 0 ; j < destinations.length ; ++j) {
if (destinations[j].getTtm().matches(sources[i].getAlias()
+ "(b|d)")) {
continue;
}
if (config.mergeSource(sources[i].getAlias(),
destinations[j]) == null) {
continue;
}
files.add(config.getRRDdirectory() + sources[i].getAlias() + "_" +
destinations[j].getTtm() + "_delay.rrd");
builder.addRowValue(new OctetString(sources[i].getAlias() + "_" +
destinations[j].getTtm()));
builder.addRowValue(new
OctetString(config.mergeSource(sources[i].getAlias(),
destinations[j]).getSw() + "_" + destinations[j].getSw()));
builder.addRowValue(new Integer32(-1)); // -1 = unknown = Double.NaN
}
}
table = builder.build();
// initialize timers
timer = new Timer("snmpAgent-timer", true);
timer.schedule( new SNMPUpdateTask(this), 300 * 1000, 300 * 1000);
}
public void shutdown() {
if(timer != null) {
timer.cancel();
}
this.stop();
}
/**
* We let clients of this agent register the MO they
* need so this method does nothing
*/
@Override
protected void registerManagedObjects() {
registerManagedObject(MOScalarFactory.createReadOnly(sysDescr,"TTMreader"));
registerManagedObject(table);
}
/**
* An Error during fetching values from the rrds is indicated with
<code>-2</code> and Double.NaN is like <code>-1</code>.
* Values are calculated from floating point milliseconds to integer
microseconds.
*/
@SuppressWarnings("unchecked")
public void updateTable() {
long now_N = Util.normalize(System.currentTimeMillis() / 1000, 30);
Iterator<MOTableRow> iter = table.getModel().iterator();
for(int i = 0 ; i < files.size() ; ++i) {
MOMutableTableRow r = (MOMutableTableRow) iter.next();
try {
RrdDb db = rrdPool.requestRrdDb(files.get(i));
FetchRequest fetchRequest = db.createFetchRequest(ConsolFun.AVERAGE,
now_N-30, now_N-30, 300); // 5min average
FetchData fetchData = fetchRequest.fetchData();
double tmp[] = fetchData.getValues(0); // Get Delay Values;
1=jitter; 2=NTPerr
int value = ( Double.isNaN(tmp[0]) ? -1 : (int) (tmp[0] *
1000)); // if(Double.NaN){ -1} else {ms -> ns}
r.setValue(2, new Integer32(value));
logger.log(Level.FINE, "[{0}]read: {1}", new
Object[]{r.getValue(1), tmp[0]} );
rrdPool.release(db);
} catch (IOException e) {
logger.log(Level.WARNING, "[{0}]IOException during fetch values:
{1}", new Object[]{r.getValue(1), e.getMessage()});
r.setValue(2, new Integer32(-2));
}
}
}
/* ######################## Wrapper and start_up functions
######################## */
/**
* Start method invokes some initialization methods needed to
* start the agent
* @throws IOException
*/
public void start() throws IOException {
init();
// This method reads some old config from a file and causes
// unexpected behavior.
// loadConfig(ImportModes.REPLACE_CREATE);
addShutdownHook();
getServer().addContext(new OctetString("public"));
finishInit();
run();
sendColdStartNotification();
}
/**
* Overrides the default MIB.
*/
@Override
protected void registerSnmpMIBs() {
registerManagedObjects();
}
/**
* Clients can register the MO they need
*/
public void registerManagedObject(ManagedObject mo) {
try {
server.register(mo, null);
} catch (DuplicateRegistrationException ex) {
throw new RuntimeException(ex);
}
}
public void unregisterManagedObject(MOGroup moGroup) {
moGroup.unregisterMOs(server, getContext(moGroup));
}
/**
* Minimal View based Access Control
*
* http://www.faqs.org/rfcs/rfc2575.html
*/
@Override
protected void addViews(VacmMIB vacm) {
vacm.addGroup(SecurityModel.SECURITY_MODEL_SNMPv2c, new
OctetString("cpublic"), new
OctetString("v1v2group"),StorageType.nonVolatile);
vacm.addAccess(new OctetString("v1v2group"), new
OctetString("public"), SecurityModel.SECURITY_MODEL_ANY,
SecurityLevel.NOAUTH_NOPRIV,
MutableVACM.VACM_MATCH_EXACT, new OctetString("fullReadView"), new
OctetString("fullWriteView"), new OctetString("fullNotifyView"),
StorageType.nonVolatile);
vacm.addViewTreeFamily(new OctetString("fullReadView"), new
OID("1.3"), new OctetString(), VacmMIB.vacmViewIncluded,
StorageType.nonVolatile);
}
/**
*
*/
@Override
protected void initTransportMappings() throws IOException {
transportMappings = new TransportMapping[1];
Address addr = GenericAddress.parse(address);
TransportMapping tm =
TransportMappings.getInstance().createTransportMapping(addr);
transportMappings[0] = tm;
}
/**
* The table of community strings configured in the SNMP
* engine's Local Configuration Datastore (LCD).
*
* We only configure one, "public".
*/
protected void addCommunities(SnmpCommunityMIB communityMIB) {
Variable[] com2sec = new Variable[] {
new OctetString("public"), // community name
new OctetString("cpublic"), // security name
getAgent().getContextEngineID(), // local engine ID
new OctetString("public"), // default context name
new OctetString(), // transport tag
new Integer32(StorageType.nonVolatile), // storage type
new Integer32(RowStatus.active) // row status
};
MOTableRow row = communityMIB.getSnmpCommunityEntry().createRow(new
OctetString("public2public").toSubIndex(true), com2sec);
communityMIB.getSnmpCommunityEntry().addRow(row);
}
/**
*
*/
protected void unregisterManagedObjects() {
// here we should unregister those objects previously registered...
}
/**
* Empty implementation
*/
@Override
protected void addNotificationTargets(SnmpTargetMIB targetMIB,
SnmpNotificationMIB notificationMIB) {
/* NONE TO DO */
}
/**
* User based Security Model, only applicable to
* SNMP v.3
*/
protected void addUsmUser(USM usm) {
/* NONE TO DO */
}
}
More information about the SNMP4J
mailing list