package com.activequant.utils.snmp; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.apache.log4j.Logger; 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.MOScalar; 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.Variable; import org.snmp4j.transport.TransportMappings; /** * Copy-paste. * * @author ustaudinger * */ class SNMP4JFacade extends BaseAgent { private static Logger log = Logger.getLogger(SNMP4JFacade.class); private String address = null; private HashMap<String, MOScalar> scalars = new HashMap<String, MOScalar>(); // static final OID interfacesTable = new OID(".1.3.6.1.2.1.2.2.1"); static final String baseOID = new String(""); private Map<String, OID> oidMap = new HashMap<String, OID>(); /** * Constructor * * @param add * @throws IOException */ SNMP4JFacade(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; start(); } public void registerOID(String key, String suffix) { String oidID = baseOID + suffix; log.info("Registering OID " + oidID); OID oid = new OID(oidID); oidMap.put(key, oid); } /** * 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); } /* * Empty implementation */ @Override protected void addNotificationTargets(SnmpTargetMIB targetMIB, SnmpNotificationMIB notificationMIB) { } /** * User based Security Model, only applicable to SNMP v.3 * */ protected void addUsmUser(USM usm) { } /** * 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); } protected void initTransportMappings() throws IOException { transportMappings = new TransportMapping[1]; Address addr = GenericAddress.parse(address); TransportMapping tm = TransportMappings.getInstance().createTransportMapping(addr); transportMappings[0] = tm; } /** * Clients can register the MO they need */ public void registerManagedObject(ManagedObject mo, String oid) { try { server.register(mo, new OctetString("public")); } catch (DuplicateRegistrationException ex) { throw new RuntimeException(ex); } } /** * We let clients of this agent register the MO they need so this method * does nothing */ @Override protected void registerManagedObjects() { } /** * Method to set an SNMP value on the facade. * * @param key * @param value */ public void setValue(String key, Integer value) throws Exception { if (!scalars.containsKey(key)) { if (!oidMap.containsKey(key)) throw new Exception("OID for " + key + " not registered. "); OID oid = oidMap.get(key); MOScalar mo = MOScalarFactory.createReadOnly(oid, key); scalars.put(key, mo); registerManagedObject(mo, oid.toString()); } MOScalar mo = scalars.get(key); if (mo != null) { mo.setValue(new Integer32(value)); } } /** * Start method invokes some initialization methods needed to start the * agent * * @throws IOException */ private 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(); unregisterManagedObject(getSnmpv2MIB()); } private void unregisterManagedObject(MOGroup moGroup) { moGroup.unregisterMOs(server, getContext(moGroup)); } protected void unregisterManagedObjects() { // here we should unregister those objects previously registered... } }