唐宋源码清 2013-06-17
想在PC端起一个snmp模拟器,在网上搜了一段时间,例子也不算少,但一般都有些问题,可能是自己某个地方出错了。
索性直接从源码的example开始,看了几天snmp4j-agent源码后,虽然啥也没看懂,但还是被我找到了一些突破口。
直接将org.snmp4j.agent.example下的例子复制出来,然后修改即可。这几天刚写好的例子,也懒得作修饰了。
1. 将源码中的SampleAgentConfig.properties(org.snmp4j.agent.example下)复制出来。
2. 建立如图的包层次结构
3. 代码明细
SysDate.java
package celul.snmpSeverTest.scalar; import org.snmp4j.agent.mo.MOAccessImpl; import org.snmp4j.agent.mo.MOScalar; import org.snmp4j.smi.OID; import org.snmp4j.smi.OctetString; public class SysDate extends MOScalar<OctetString> { public SysDate() { super(new OID("1.3.6.1.4.1.12321.1.1.1.2.0"), MOAccessImpl.ACCESS_READ_ONLY, new OctetString("com")); } @Override public OctetString getValue() { return new OctetString("com"); } }
SysInitDevice.java
package celul.snmpSeverTest.scalar; import org.snmp4j.agent.mo.MOAccessImpl; import org.snmp4j.agent.mo.MOScalar; import org.snmp4j.smi.Integer32; import org.snmp4j.smi.OID; public class SysInitDevice extends MOScalar<Integer32> { public SysInitDevice() { super(new OID("1.3.6.1.4.1.12321.1.1.1.3.0"), MOAccessImpl.ACCESS_READ_WRITE, new Integer32(3)); } @Override public Integer32 getValue() { return super.getValue(); } @Override public int setValue(Integer32 value) { return super.setValue(value); } }
SysInitParams.java与SysTimeUp.java不再赘述。
MoTableUtil.java
package celul.snmpSeverTest.table; import org.snmp4j.agent.MOAccess; import org.snmp4j.agent.mo.DefaultMOMutableTableModel; import org.snmp4j.agent.mo.DefaultMOTable; import org.snmp4j.agent.mo.DefaultMOTableRow; import org.snmp4j.agent.mo.MOAccessImpl; import org.snmp4j.agent.mo.MOColumn; import org.snmp4j.agent.mo.MOMutableColumn; import org.snmp4j.agent.mo.MOTableIndex; import org.snmp4j.agent.mo.MOTableSubIndex; import org.snmp4j.agent.mo.snmp.RowStatus; 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 celul.snmpSeverTest.Constant; public class MoTableUtil{ @SuppressWarnings("rawtypes") private static DefaultMOTable emuTable; private static final String emuTableEntryOid = "1.3.6.1.4.1.19547.1.6.1.1.1"; private static final Object[][] columnEmuDefined = { { 1, "1", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 2, "2", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 3, "3", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 4, "4", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 5, "5", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 6, "6", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 7, "7", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 8, "8", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 9, "9", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 10, Constant.ROWSTATUS, MOAccessImpl.ACCESS_READ_CREATE, SMIConstants.SYNTAX_INTEGER32 } }; @SuppressWarnings("rawtypes") private static DefaultMOTable edfaTable; private static final String edfaTableEntryOid = "1.3.6.1.4.1.19547.1.6.1.2.1"; private static final Object[][] columnEdfaDefined = { { 1, "1", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 2, "2", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 3, "3", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 4, "4", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 5, "5", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 6, "6", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 7, "7", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 8, "8", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 9, "9", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 10, "10", MOAccessImpl.ACCESS_READ_ONLY, SMIConstants.SYNTAX_OCTET_STRING }, { 11, Constant.ROWSTATUS, MOAccessImpl.ACCESS_READ_CREATE, SMIConstants.SYNTAX_INTEGER32 } }; //private static DefaultMOTable defaTable; @SuppressWarnings("rawtypes") public static DefaultMOTable getEmuTable(){ if(emuTable == null){ initEmuTable(); } return emuTable; } @SuppressWarnings("rawtypes") public static DefaultMOTable getEdfaTable(){ if(edfaTable == null){ initEdfaTable(); } return edfaTable; } @SuppressWarnings({ "rawtypes", "unchecked" }) private static void initEmuTable(){ int columnLength = columnEmuDefined.length; MOColumn[] edfaColumns = new MOColumn[columnLength]; for( int i=0; i<columnLength; i++){ Object[] acol = columnEmuDefined[i]; int index = (Integer) acol[0]; String name = (String) acol[1]; MOAccess access = (MOAccess) acol[2]; int operType = (Integer) acol[3]; Variable valueDefault = new Integer32(1); if(name.startsWith(Constant.ROWSTATUS)){ edfaColumns[i] = new RowStatus(index); }else{ edfaColumns[i] = new MOMutableColumn<Variable>(index, operType, access, valueDefault, true); } } emuTable = new DefaultMOTable( new OID(emuTableEntryOid), new MOTableIndex( new MOTableSubIndex[] { new MOTableSubIndex( new OID(emuTableEntryOid + ".1001"), SMIConstants.SYNTAX_OCTET_STRING, 1, 16) }, true), edfaColumns, new DefaultMOMutableTableModel<DefaultMOTableRow>() ); } @SuppressWarnings({ "rawtypes", "unchecked" }) private static void initEdfaTable(){ int columnLength = columnEdfaDefined.length; MOColumn[] edfaColumns = new MOColumn[columnLength]; for( int i=0; i<columnLength; i++){ Object[] acol = columnEdfaDefined[i]; int index = (Integer) acol[0]; String name = (String) acol[1]; MOAccess access = (MOAccess) acol[2]; int operType = (Integer) acol[3]; Variable valueDefault = new Integer32(1); if(name.startsWith(Constant.ROWSTATUS)){ edfaColumns[i] = new RowStatus(index); }else{ edfaColumns[i] = new MOMutableColumn<Variable>(index, operType, access, valueDefault, true); } } edfaTable = new DefaultMOTable( new OID(edfaTableEntryOid), new MOTableIndex( new MOTableSubIndex[] { new MOTableSubIndex( new OID(edfaTableEntryOid + ".1001"), SMIConstants.SYNTAX_OCTET_STRING, 1, 16) }, true), edfaColumns, new DefaultMOMutableTableModel<DefaultMOTableRow>() ); } @SuppressWarnings("unchecked") public static void fillDefaultDataIntoEmuTable(){ for (int rowId = 1; rowId < 2; rowId++) { Variable[] values = new Variable[10]; values[0] = new OctetString("a.0." + rowId); values[1] = new OctetString("b.0." + rowId); values[2] = new OctetString("c.0." + rowId); values[3] = new OctetString("d.0." + rowId); values[4] = new OctetString("e.0." + rowId); values[5] = new OctetString("f.0." + rowId); values[6] = new OctetString("g.0." + rowId); values[7] = new OctetString("h.0." + rowId); values[8] = new OctetString("i.0." + rowId); values[9] = new Integer32(rowId); emuTable.addRow(new DefaultMOTableRow(new OID("1.0." + rowId), values)); } } @SuppressWarnings("unchecked") public static void fillDefaultDataIntoEdfaTable(){ for (int rowId = 1; rowId < 5; rowId++) { Variable[] values = new Variable[11]; values[0] = new OctetString("edfa.a.0." + rowId); values[1] = new OctetString("edfa.b.0." + rowId); values[2] = new OctetString("edfa.c.0." + rowId); values[3] = new OctetString("edfa.d.0." + rowId); values[4] = new OctetString("edfa.e.0." + rowId); values[5] = new OctetString("edfa.f.0." + rowId); values[6] = new OctetString("edfa.g.0." + rowId); values[7] = new OctetString("edfa.h.0." + rowId); values[8] = new OctetString("edfa.i.0." + rowId); values[9] = new OctetString("edfa.j.0." + rowId); values[10] = new Integer32(rowId); edfaTable.addRow(new DefaultMOTableRow(new OID("1.0." + rowId), values)); } } }
Constant.java
public class Constant { public static final String ROWSTATUS="rowStatus"; }
主要入口snmp4jAgent.java
package celul.snmpSeverTest; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Properties; import org.apache.log4j.BasicConfigurator; import org.snmp4j.MessageDispatcher; import org.snmp4j.MessageDispatcherImpl; import org.snmp4j.TransportMapping; import org.snmp4j.agent.AgentConfigManager; import org.snmp4j.agent.DefaultMOContextScope; import org.snmp4j.agent.DefaultMOServer; import org.snmp4j.agent.DuplicateRegistrationException; import org.snmp4j.agent.MOQuery; import org.snmp4j.agent.MOQueryWithSource; import org.snmp4j.agent.MOScope; import org.snmp4j.agent.MOServer; import org.snmp4j.agent.ManagedObject; import org.snmp4j.agent.cfg.EngineBootsCounterFile; import org.snmp4j.agent.io.DefaultMOPersistenceProvider; import org.snmp4j.agent.io.MOInput; import org.snmp4j.agent.io.MOInputFactory; import org.snmp4j.agent.io.prop.PropertyMOInput; import org.snmp4j.agent.mo.util.VariableProvider; import org.snmp4j.agent.request.Request; import org.snmp4j.agent.request.RequestStatus; import org.snmp4j.agent.request.SubRequest; import org.snmp4j.agent.request.SubRequestIterator; import org.snmp4j.log.Log4jLogFactory; import org.snmp4j.log.LogAdapter; import org.snmp4j.log.LogFactory; import org.snmp4j.log.LogLevel; import org.snmp4j.mp.MPv3; import org.snmp4j.security.SecurityProtocols; import org.snmp4j.smi.Address; import org.snmp4j.smi.GenericAddress; import org.snmp4j.smi.OID; import org.snmp4j.smi.OctetString; import org.snmp4j.smi.Variable; import org.snmp4j.smi.VariableBinding; import org.snmp4j.transport.TransportMappings; import org.snmp4j.util.ThreadPool; import celul.snmpSeverTest.scalar.SysDate; import celul.snmpSeverTest.scalar.SysInitDevice; import celul.snmpSeverTest.scalar.SysInitParams; import celul.snmpSeverTest.scalar.SysTimeUp; import celul.snmpSeverTest.table.MoTableUtil; public class SNMP4JAgent implements VariableProvider { static{ LogFactory.setLogFactory(new Log4jLogFactory()); BasicConfigurator.configure(); LogFactory.getLogFactory().getRootLogger().setLogLevel(LogLevel.ALL); } private LogAdapter logger = LogFactory.getLogger(SNMP4JAgent.class); protected AgentConfigManager agent; protected MOServer server; private String configFile; private File bootCounterFile; public SNMP4JAgent(){ configFile = "configFile.cfg"; bootCounterFile = new File("bootCounterFile.bc"); server = new DefaultMOServer(); MOServer[] moServers = new MOServer[] { server }; final Properties props = new Properties(); try { props.load(SNMP4JAgent.class.getResourceAsStream("SampleAgentConfig.properties")); } catch (IOException ex) { ex.printStackTrace(); } MOInputFactory configurationFactory = new MOInputFactory(){ @Override public MOInput createMOInput() { return new PropertyMOInput(props, SNMP4JAgent.this); } }; MessageDispatcher messageDispatcher = new MessageDispatcherImpl(); List<String> list = new ArrayList<String>(); list.add("udp:0.0.0.0/161"); addListenAddresses(messageDispatcher,list); agent = new AgentConfigManager( new OctetString(MPv3.createLocalEngineID()), messageDispatcher, null, moServers, ThreadPool.create("snmp4JAgent", 3), configurationFactory, new DefaultMOPersistenceProvider(moServers, configFile), new EngineBootsCounterFile(bootCounterFile) ); } @Override public Variable getVariable(String name) { OID oid; OctetString context = null; int pos = name.indexOf(':'); if (pos >= 0) { context = new OctetString(name.substring(0, pos)); oid = new OID(name.substring(pos + 1, name.length())); } else { oid = new OID(name); } final DefaultMOContextScope scope = new DefaultMOContextScope(context, oid, true, oid, true); MOQuery query = new MOQueryWithSource(scope, false, this); ManagedObject mo = server.lookup(query); if (mo != null) { final VariableBinding vb = new VariableBinding(oid); final RequestStatus status = new RequestStatus(); SubRequest req = new SubRequest() { private boolean completed; private MOQuery query; public boolean hasError() { return false; } public void setErrorStatus(int errorStatus) { status.setErrorStatus(errorStatus); } public int getErrorStatus() { return status.getErrorStatus(); } public RequestStatus getStatus() { return status; } public MOScope getScope() { return scope; } public VariableBinding getVariableBinding() { return vb; } public Request getRequest() { return null; } public Object getUndoValue() { return null; } public void setUndoValue(Object undoInformation) { } public void completed() { completed = true; } public boolean isComplete() { return completed; } public void setTargetMO(ManagedObject managedObject) { } public ManagedObject getTargetMO() { return null; } public int getIndex() { return 0; } public void setQuery(MOQuery query) { this.query = query; } public MOQuery getQuery() { return query; } public SubRequestIterator repetitions() { return null; } public void updateNextRepetition() { } public Object getUserObject() { return null; } public void setUserObject(Object userObject) { } }; mo.get(req); return vb.getVariable(); } return null; } protected void addListenAddresses(MessageDispatcher md, List<String> addresses) { for (String addressString : addresses) { Address address = GenericAddress.parse(addressString); if (address == null) { logger.fatal("Could not parse address string '" + addressString + "'"); return; } @SuppressWarnings("rawtypes") TransportMapping tm = TransportMappings.getInstance().createTransportMapping(address); if (tm != null) { md.addTransportMapping(tm); } else { logger.warn("No transport mapping available for address '" + address + "'."); } } } public void registerMIBs(){ try { server.register(new SysTimeUp(), null); server.register(new SysDate(), null); server.register(new SysInitDevice(), null); server.register(new SysInitParams(), null); server.register(MoTableUtil.getEmuTable(), null); server.register(MoTableUtil.getEdfaTable(), null); MoTableUtil.fillDefaultDataIntoEmuTable(); MoTableUtil.fillDefaultDataIntoEdfaTable(); } catch (DuplicateRegistrationException e) { e.printStackTrace(); } } public void run() { agent.initialize(); registerMIBs(); agent.setupProxyForwarder(); agent.setTableSizeLimits(new Properties()); agent.run(); } public static void main(String[] args){ SNMP4JAgent sa = new SNMP4JAgent(); SecurityProtocols.getInstance().addDefaultProtocols(); sa.run(); } }
运行snmp4jAgent.java,这样,我们的服务端就已经起来了。通过mibBrowser可以访问。
.1.3.6.1.4.1.19547.1.6.1.1.1.1.1.0.1 a.0.1 .1.3.6.1.4.1.19547.1.6.1.1.1.2.1.0.1 b.0.1 .1.3.6.1.4.1.19547.1.6.1.1.1.3.1.0.1 c.0.1 .1.3.6.1.4.1.19547.1.6.1.1.1.4.1.0.1 d.0.1 .1.3.6.1.4.1.19547.1.6.1.1.1.5.1.0.1 e.0.1 .1.3.6.1.4.1.19547.1.6.1.1.1.6.1.0.1 f.0.1 .1.3.6.1.4.1.19547.1.6.1.1.1.7.1.0.1 g.0.1 .1.3.6.1.4.1.19547.1.6.1.1.1.8.1.0.1 h.0.1 .1.3.6.1.4.1.19547.1.6.1.1.1.9.1.0.1 i.0.1 .1.3.6.1.4.1.19547.1.6.1.1.1.10.1.0.1 1 .1.3.6.1.4.1.19547.1.6.1.2.1.1.1.0.1 edfa.a.0.1 .1.3.6.1.4.1.19547.1.6.1.2.1.1.1.0.2 edfa.a.0.2 .1.3.6.1.4.1.19547.1.6.1.2.1.1.1.0.3 edfa.a.0.3 .1.3.6.1.4.1.19547.1.6.1.2.1.1.1.0.4 edfa.a.0.4 .1.3.6.1.4.1.19547.1.6.1.2.1.2.1.0.1 edfa.b.0.1 .1.3.6.1.4.1.19547.1.6.1.2.1.2.1.0.2 edfa.b.0.2 .1.3.6.1.4.1.19547.1.6.1.2.1.2.1.0.3 edfa.b.0.3 .1.3.6.1.4.1.19547.1.6.1.2.1.2.1.0.4 edfa.b.0.4 .1.3.6.1.4.1.19547.1.6.1.2.1.3.1.0.1 edfa.c.0.1 .1.3.6.1.4.1.19547.1.6.1.2.1.3.1.0.2 edfa.c.0.2 .1.3.6.1.4.1.19547.1.6.1.2.1.3.1.0.3 edfa.c.0.3 .1.3.6.1.4.1.19547.1.6.1.2.1.3.1.0.4 edfa.c.0.4 .1.3.6.1.4.1.19547.1.6.1.2.1.4.1.0.1 edfa.d.0.1 .1.3.6.1.4.1.19547.1.6.1.2.1.4.1.0.2 edfa.d.0.2 .1.3.6.1.4.1.19547.1.6.1.2.1.4.1.0.3 edfa.d.0.3 .1.3.6.1.4.1.19547.1.6.1.2.1.4.1.0.4 edfa.d.0.4 .1.3.6.1.4.1.19547.1.6.1.2.1.5.1.0.1 edfa.e.0.1 .1.3.6.1.4.1.19547.1.6.1.2.1.5.1.0.2 edfa.e.0.2 .1.3.6.1.4.1.19547.1.6.1.2.1.5.1.0.3 edfa.e.0.3 .1.3.6.1.4.1.19547.1.6.1.2.1.5.1.0.4 edfa.e.0.4 .1.3.6.1.4.1.19547.1.6.1.2.1.6.1.0.1 edfa.f.0.1 .1.3.6.1.4.1.19547.1.6.1.2.1.6.1.0.2 edfa.f.0.2 .1.3.6.1.4.1.19547.1.6.1.2.1.6.1.0.3 edfa.f.0.3 .1.3.6.1.4.1.19547.1.6.1.2.1.6.1.0.4 edfa.f.0.4 .1.3.6.1.4.1.19547.1.6.1.2.1.7.1.0.1 edfa.g.0.1 .1.3.6.1.4.1.19547.1.6.1.2.1.7.1.0.2 edfa.g.0.2 .1.3.6.1.4.1.19547.1.6.1.2.1.7.1.0.3 edfa.g.0.3 .1.3.6.1.4.1.19547.1.6.1.2.1.7.1.0.4 edfa.g.0.4 .1.3.6.1.4.1.19547.1.6.1.2.1.8.1.0.1 edfa.h.0.1 .1.3.6.1.4.1.19547.1.6.1.2.1.8.1.0.2 edfa.h.0.2 .1.3.6.1.4.1.19547.1.6.1.2.1.8.1.0.3 edfa.h.0.3 .1.3.6.1.4.1.19547.1.6.1.2.1.8.1.0.4 edfa.h.0.4
.1.3.6.1.4.1.12321.1.1.1.3.0 3
也可以通过snmp4j客户端程序访问该服务器资源。后续再跟踪。