[SNMP4J] How to use ProxyForwarder

Kanda Norimichi nkanda at fsi.co.jp
Tue Mar 20 11:22:00 CET 2007


Dear Mr. Fock:

I am Kanda and I work at Fujisoft.

I hope to use ProxyForwarder.
But SNMPv1-Trap forward doesn't operate correctly.

I'll show below specifically.
I'm designing the following system structure.

    MA - TestProxy - NMS

"MA" is Managed-Agent, it is SNMP agent that support SNMPv1.
I hope that message from MA will be forwarded to NMS with 
the addition of contextEngineID that generated from
MA's IP address in TestProxy and fixed contextName.

But in TestProxy made by our system, contextEngineID configured actually is 
replaced by snmpEngineID of TestProxy.
ContextEngineID and contextName that should be configured forwarded Trap are 
already added to snmpCommunityTable.

I guess, maybe I failed in making TestProxy.
But I couldn't find sample program and I have no idea what should I do.
Would you give me any advice?

I'll attach TestProxy made by arranging org.snmp4j.agent.test.TestAgent.

Sincerely.

Norimichi Kanda
----
/*_############################################################################
  _##
  _##  SNMP4J-Agent - TestAgent.java
  _##
  _##  Copyright 2005-2006  Frank Fock (SNMP4J.org)
  _##
  _##  Licensed under the Apache License, Version 2.0 (the "License");
  _##  you may not use this file except in compliance with the License.
  _##  You may obtain a copy of the License at
  _##
  _##      http://www.apache.org/licenses/LICENSE-2.0
  _##
  _##  Unless required by applicable law or agreed to in writing, software
  _##  distributed under the License is distributed on an "AS IS" BASIS,
  _##  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  _##  See the License for the specific language governing permissions and
  _##  limitations under the License.
  _##
  _##########################################################################*/


package test;

import java.io.*;

import org.apache.log4j.*;
import org.snmp4j.*;
import org.snmp4j.agent.*;
import org.snmp4j.agent.mo.*;
import org.snmp4j.agent.mo.snmp.*;
import org.snmp4j.mp.*;
import org.snmp4j.security.*;
import org.snmp4j.smi.*;
import org.snmp4j.transport.*;
import org.snmp4j.agent.io.ImportModes;
import org.snmp4j.util.ThreadPool;
import org.snmp4j.log.Log4jLogFactory;
import org.snmp4j.log.LogFactory;
import org.snmp4j.agent.mo.snmp4j.example.Snmp4jHeartbeatMib;
import org.snmp4j.agent.security.MutableVACM;
import org.snmp4j.agent.test.IfMib;
import org.snmp4j.agent.mo.ext.AgentppSimulationMib;

/**
 * The <code>TestAgent</code> is a sample SNMP agent implementation of all
 * features (MIB implementations) provided by the SNMP4J-Agent framework.
 * The <code>TestAgent</code> extends the <code>BaseAgent</code> which provides
 * a framework for custom agent implementations through hook methods. Those
 * abstract hook methods need to be implemented by extending the
 * <code>BaseAgent</code>.
 * <p>
 * This IF-MIB implementation part of this test agent, is instrumentation as
 * a simulation MIB. Thus, by changing the agentppSimMode
 * (1.3.6.1.4.1.4976.2.1.1.0) from 'oper(1)' to 'config(2)' any object of the
 * IF-MIB is writable and even creatable (columnar objects) via SNMP. Check it
 * out!
 *
 * @author Frank Fock
 * @version 1.0
 */
public class TestProxy extends BaseAgent {

  // initialize Log4J logging
  static {
    LogFactory.setLogFactory(new Log4jLogFactory());
    ma = new UdpAddress("172.19.0.1/161");
//    ma = new UdpAddress("10.30.34.17/161");
//    ma = new UdpAddress("127.0.0.1/0");  // localhost

//    nms = new UdpAddress("172.19.0.1/162");
    nms = new UdpAddress("10.30.34.17/162");
//    nms = new UdpAddress("127.0.0.1/1162");  // localhost
  }

  static final UdpAddress ma;   // Managed Agent
  static final UdpAddress nms;  // Network Management System
  protected String address;
  private Snmp4jHeartbeatMib heartbeatMIB;
  private IfMib ifMIB;
  private AgentppSimulationMib agentppSimulationMIB;

  /**
   * Creates the test agent with a file to read and store the boot counter and
   * a file to read and store its configuration.
   *
   * @param bootCounterFile
   *    a file containing the boot counter in serialized form (as expected by
   *    BaseAgent).
   * @param configFile
   *    a configuration file with serialized management information.
   * @throws IOException
   *    if the boot counter or config file cannot be read properly.
   */
  public TestProxy(File bootCounterFile, File configFile) throws IOException {
    super(bootCounterFile, configFile,
          new CommandProcessor(new OctetString(MPv3.createLocalEngineID())));
// Alternatively:       OctetString.fromHexString("00:00:00:00:00:00:02", ':');
    agent.setThreadPool(ThreadPool.create("RequestPool", 4));
  }

  /* (non-Javadoc)
   * @see org.snmp4j.agent.BaseAgent#init()
   */
  public void init() throws IOException {
    super.init();

//    // NOTE: 1st trial and error
//    session.addNotificationListener(new UdpAddress(162), new CommandResponder() {
//      public void processPdu(CommandResponderEvent event) {
//        processTrap(event);
//      }
//    });

    // NOTE: 2nd trial and error
    session.addNotificationListener(new UdpAddress(162), agent);
  }

  void processTrap(CommandResponderEvent event) {
    OctetString contextEngineID;
    OctetString contextName;
    if (event.getPDU() instanceof ScopedPDU) {
      ScopedPDU pdu = (ScopedPDU)event.getPDU();
      contextEngineID = pdu.getContextEngineID();
      contextName = pdu.getContextName();
    }
    else {
      contextEngineID = new OctetString(getInternalEngineID(event.getPeerAddress()));
      contextName = new OctetString();
    }
    ProxyForwardRequest request =
      new ProxyForwardRequest(event, contextEngineID, contextName);
    defaultProxyForwarder.forward(request);
  }

  protected void registerManagedObjects() {
    try {
//      server.register(createStaticIfTable(), null);
      agentppSimulationMIB.registerMOs(server, null);
      ifMIB.registerMOs(server, new OctetString("public"));
      heartbeatMIB.registerMOs(server, null);
    }
    catch (DuplicateRegistrationException ex) {
      ex.printStackTrace();
    }
  }

  protected void addNotificationTargets(SnmpTargetMIB targetMIB,
                                        SnmpNotificationMIB notificationMIB) {
    targetMIB.addDefaultTDomains();

    TDomainAddressFactoryImpl factory = new TDomainAddressFactoryImpl();
    targetMIB.addTargetAddress(new OctetString("notification"),
//                               TransportDomains.transportDomainUdpIpv4,
                               factory.getTransportDomain(nms), 
//                               new OctetString(new UdpAddress("127.0.0.1/162").getValue()),
                               factory.getAddress(nms),
                               200, 1,
                               new OctetString("notify"),
                               new OctetString("v2c"),
                               StorageType.permanent);
    targetMIB.addTargetParams(new OctetString("v2c"),
                              MessageProcessingModel.MPv2c,
                              SecurityModel.SECURITY_MODEL_SNMPv2c,
                              new OctetString("public"),
                              SecurityLevel.NOAUTH_NOPRIV,
                              StorageType.permanent);
    notificationMIB.addNotifyEntry(new OctetString("default"),
                                   new OctetString("notify"),
                                   SnmpNotificationMIB.SnmpNotifyTypeEnum.trap,
                                   StorageType.permanent);

    // NOTE: add SNMPv3 user
    OctetString sha = new OctetString("SHA");
    OctetString secName = new OctetString("SHA");
    OctetString tag = new OctetString("Nms");
    targetMIB.addTargetAddress(
        sha, 
        factory.getTransportDomain(nms), 
        factory.getAddress(nms),
        1500, 
        1, 
        tag, 
        sha, 
        StorageType.volatile_);
    targetMIB.addTargetParams(
        sha, 
        MessageProcessingModel.MPv3,
        SecurityModel.SECURITY_MODEL_USM,
        secName,
        SecurityLevel.AUTH_NOPRIV,
        StorageType.volatile_);
    notificationMIB.addNotifyEntry(
        sha, 
        tag, 
        SnmpNotificationMIB.SnmpNotifyTypeEnum.trap, 
        StorageType.volatile_);
  }

  protected void addViews(VacmMIB vacm) {
    vacm.addGroup(SecurityModel.SECURITY_MODEL_SNMPv1,
                  new OctetString("cpublic"),
                  new OctetString("v1v2group"),
                  StorageType.nonVolatile);
    vacm.addGroup(SecurityModel.SECURITY_MODEL_SNMPv2c,
                  new OctetString("cpublic"),
                  new OctetString("v1v2group"),
                  StorageType.nonVolatile);
    vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
                  new OctetString("SHADES"),
                  new OctetString("v3group"),
                  StorageType.nonVolatile);
    vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
                  new OctetString("TEST"),
                  new OctetString("v3test"),
                  StorageType.nonVolatile);
    vacm.addGroup(SecurityModel.SECURITY_MODEL_USM,
                  new OctetString("SHA"),
                  new OctetString("v3restricted"),
                  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.addAccess(new OctetString("v3group"), new OctetString(),
                   SecurityModel.SECURITY_MODEL_USM,
                   SecurityLevel.AUTH_PRIV,
                   MutableVACM.VACM_MATCH_EXACT,
                   new OctetString("fullReadView"),
                   new OctetString("fullWriteView"),
                   new OctetString("fullNotifyView"),
                   StorageType.nonVolatile);
    vacm.addAccess(new OctetString("v3restricted"), new OctetString(),
                   SecurityModel.SECURITY_MODEL_USM,
                   SecurityLevel.AUTH_NOPRIV,
                   MutableVACM.VACM_MATCH_EXACT,
                   new OctetString("restrictedReadView"),
                   new OctetString("restrictedWriteView"),
                   new OctetString("restrictedNotifyView"),
                   StorageType.nonVolatile);
    vacm.addAccess(new OctetString("v3test"), new OctetString(),
                   SecurityModel.SECURITY_MODEL_USM,
                   SecurityLevel.AUTH_PRIV,
                   MutableVACM.VACM_MATCH_EXACT,
                   new OctetString("testReadView"),
                   new OctetString("testWriteView"),
                   new OctetString("testNotifyView"),
                   StorageType.nonVolatile);

    vacm.addViewTreeFamily(new OctetString("fullReadView"), new OID("1.3"),
                           new OctetString(), VacmMIB.vacmViewIncluded,
                           StorageType.nonVolatile);
    vacm.addViewTreeFamily(new OctetString("fullWriteView"), new OID("1.3"),
                           new OctetString(), VacmMIB.vacmViewIncluded,
                           StorageType.nonVolatile);
    vacm.addViewTreeFamily(new OctetString("fullNotifyView"), new OID("1.3"),
                           new OctetString(), VacmMIB.vacmViewIncluded,
                           StorageType.nonVolatile);

    vacm.addViewTreeFamily(new OctetString("restrictedReadView"),
                           new OID("1.3.6.1.2"),
                           new OctetString(), VacmMIB.vacmViewIncluded,
                           StorageType.nonVolatile);
    vacm.addViewTreeFamily(new OctetString("restrictedWriteView"),
                           new OID("1.3.6.1.2.1"),
                           new OctetString(),
                           VacmMIB.vacmViewIncluded,
                           StorageType.nonVolatile);
    vacm.addViewTreeFamily(new OctetString("restrictedNotifyView"),
                           new OID("1.3.6.1.2"),
                           new OctetString(), VacmMIB.vacmViewIncluded,
                           StorageType.nonVolatile);

    vacm.addViewTreeFamily(new OctetString("testReadView"),
                           new OID("1.3.6.1.2"),
                           new OctetString(), VacmMIB.vacmViewIncluded,
                           StorageType.nonVolatile);
    vacm.addViewTreeFamily(new OctetString("testReadView"),
                           new OID("1.3.6.1.2.1.1"),
                           new OctetString(), VacmMIB.vacmViewExcluded,
                           StorageType.nonVolatile);
    vacm.addViewTreeFamily(new OctetString("testWriteView"),
                           new OID("1.3.6.1.2.1"),
                           new OctetString(),
                           VacmMIB.vacmViewIncluded,
                           StorageType.nonVolatile);
    vacm.addViewTreeFamily(new OctetString("testNotifyView"),
                           new OID("1.3.6.1.2"),
                           new OctetString(), VacmMIB.vacmViewIncluded,
                           StorageType.nonVolatile);

  }

  protected void addUsmUser(USM usm) {
    UsmUser user = new UsmUser(new OctetString("SHADES"),
                               AuthSHA.ID,
                               new OctetString("SHADESAuthPassword"),
                               PrivDES.ID,
                               new OctetString("SHADESPrivPassword"));
    usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
    user = new UsmUser(new OctetString("TEST"),
                               AuthSHA.ID,
                               new OctetString("maplesyrup"),
                               PrivDES.ID,
                               new OctetString("maplesyrup"));
    usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
    user = new UsmUser(new OctetString("SHA"),
                               AuthSHA.ID,
                               new OctetString("SHAAuthPassword"),
                               null,
                               null);
    usm.addUser(user.getSecurityName(), usm.getLocalEngineID(), user);
  }

  /**
   * add Community-based agent for proxy-forwarding.
   * @param communityName
   * @param address
   */
  public void addCommunityAgent(OctetString communityName, Address address) {
    TDomainAddressFactoryImpl factory = new TDomainAddressFactoryImpl();

    // add community-table
    OctetString snmpCommunityIndex = new OctetString("uniqueCommunityIndex");
    OctetString secName = new OctetString("uniqueSecName");
    OctetString snmpCommunityTransportTag = new OctetString("uniqueTransportTag");
    OctetString contextEngineID = new OctetString(getInternalEngineID(address));
    System.out.println(contextEngineID);

    Variable[] vars = new Variable[] {
        communityName,                          // community name
        secName,                                // security name
        contextEngineID,                        // context engine id
        new OctetString(),                      // context name
        snmpCommunityTransportTag,              // transport tag
        new Integer32(StorageType.volatile_),   // storage type
        new Integer32(RowStatus.active)         // row status
    };
    MOTableRow row =
      getSnmpCommunityMIB().getSnmpCommunityEntry().createRow(
          snmpCommunityIndex.toSubIndex(true), vars);
    getSnmpCommunityMIB().getSnmpCommunityEntry().addRow(row);

    // add target-parameters-table
    OctetString snmpTargetParamsName = new OctetString("uniqueTargetParamsName");

    getSnmpTargetMIB().addTargetParams(
        snmpTargetParamsName, 
        MessageProcessingModel.MPv1, 
        SecurityModel.SECURITY_MODEL_SNMPv1, 
        communityName, 
        SecurityLevel.NOAUTH_NOPRIV, 
        StorageType.volatile_);

    // add target-address-table
    OctetString snmpTargetAddrName = new OctetString("uniqueTargetAddrName");

    getSnmpTargetMIB().addTargetAddress(
        snmpTargetAddrName, 
        factory.getTransportDomain(address),
        factory.getAddress(address),
        1500, 
        1, 
        snmpCommunityTransportTag,
        snmpTargetParamsName,
        StorageType.volatile_);

    // add proxy-table(trap)
    OctetString snmpProxyName1 = new OctetString("uniqueProxyName1");
    getSnmpProxyMIB().addProxyEntry(
        snmpProxyName1, 
        ProxyForwarder.PROXY_TYPE_NOTIFY, 
        contextEngineID,
        new OctetString(), 
        snmpTargetParamsName, 
        null, 
        new OctetString("Nms"), 
        StorageType.volatile_);

    // add proxy-table(get)
    OctetString snmpProxyName2 = new OctetString("uniqueProxyName2");
    getSnmpProxyMIB().addProxyEntry(
        snmpProxyName2, 
        ProxyForwarder.PROXY_TYPE_READ, 
        contextEngineID, 
        new OctetString(), 
        new OctetString("SHA"), 
        snmpTargetAddrName, 
        null, 
        StorageType.volatile_);

  }

  byte[] getInternalEngineID(Address address) {
    // NOTE: generate EngineID without PortNumber for return-value (ID) be same
    //  at request/response and notify.

    OctetString id;
    if (address instanceof IpAddress) {
      id = new OctetString(((IpAddress)address).getInetAddress().getAddress());
    } else {
      id = new OctetString();
    }
    return MPv3.createLocalEngineID(id);
  }

  /* This code illustrates how a table can be created and filled with static
data:

  private static DefaultMOTable createStaticIfTable() {
    MOTableSubIndex[] subIndexes =
        new MOTableSubIndex[] { new MOTableSubIndex(SMIConstants.SYNTAX_INTEGER) };
    MOTableIndex indexDef = new MOTableIndex(subIndexes, false);
    MOColumn[] columns = new MOColumn[8];
    int c = 0;
    columns[c++] =
        new MOColumn(c, SMIConstants.SYNTAX_INTEGER,
                     MOAccessImpl.ACCESS_READ_ONLY);     // ifIndex
    columns[c++] =
        new MOColumn(c, SMIConstants.SYNTAX_OCTET_STRING,
                     MOAccessImpl.ACCESS_READ_ONLY);// ifDescr
    columns[c++] =
        new MOColumn(c, SMIConstants.SYNTAX_INTEGER,
                     MOAccessImpl.ACCESS_READ_ONLY);     // ifType
    columns[c++] =
        new MOColumn(c, SMIConstants.SYNTAX_INTEGER,
                     MOAccessImpl.ACCESS_READ_ONLY);     // ifMtu
    columns[c++] =
        new MOColumn(c, SMIConstants.SYNTAX_GAUGE32,
                     MOAccessImpl.ACCESS_READ_ONLY);     // ifSpeed
    columns[c++] =
        new MOColumn(c, SMIConstants.SYNTAX_OCTET_STRING,
                     MOAccessImpl.ACCESS_READ_ONLY);// ifPhysAddress
    columns[c++] =
        new MOMutableColumn(c, SMIConstants.SYNTAX_INTEGER,     // ifAdminStatus
                            MOAccessImpl.ACCESS_READ_WRITE, null);
    columns[c++] =
        new MOColumn(c, SMIConstants.SYNTAX_INTEGER,
                     MOAccessImpl.ACCESS_READ_ONLY);     // ifOperStatus

    DefaultMOTable ifTable =
        new DefaultMOTable(new OID("1.3.6.1.2.1.2.2.1"), indexDef, columns);
    MOMutableTableModel model = (MOMutableTableModel) ifTable.getModel();
    Variable[] rowValues1 = new Variable[] {
        new Integer32(1),
        new OctetString("eth0"),
        new Integer32(6),
        new Integer32(1500),
        new Gauge32(100000000),
        new OctetString("00:00:00:00:01"),
        new Integer32(1),
        new Integer32(1)
    };
    Variable[] rowValues2 = new Variable[] {
        new Integer32(2),
        new OctetString("loopback"),
        new Integer32(24),
        new Integer32(1500),
        new Gauge32(10000000),
        new OctetString("00:00:00:00:02"),
        new Integer32(1),
        new Integer32(1)
    };
    model.addRow(new DefaultMOMutableRow2PC(new OID("1"), rowValues1));
    model.addRow(new DefaultMOMutableRow2PC(new OID("2"), rowValues2));
    ifTable.setVolatile(true);
    return ifTable;
  }
*/
  protected void initTransportMappings() throws IOException {
    transportMappings = new TransportMapping[1];
    Address addr = GenericAddress.parse(address);
    TransportMapping tm =
        TransportMappings.getInstance().createTransportMapping(addr);
    transportMappings[0] = tm;
  }

  public static void main(String[] args) {
    String address;
    if (args.length > 0) {
      address = args[0];
    }
    else {
      address = "0.0.0.0/161";
    }
    BasicConfigurator.configure();
    try {
      final TestProxy testAgent1 = new TestProxy(new File("SNMP4JTestAgentBC.cfg"),
                                           new File("SNMP4JTestAgentConfig.cfg"));
      testAgent1.address = address;
      testAgent1.init();
      testAgent1.loadConfig(ImportModes.UPDATE_CREATE);
      testAgent1.addShutdownHook();
      testAgent1.getServer().addContext(new OctetString("public"));
      testAgent1.finishInit();

      // NOTE: add SNMPv1-Trap (community-name: private) from Managed-Agent 'ma'
      //  as ProxyForward target.
      testAgent1.addCommunityAgent(new OctetString("private"), ma);

      testAgent1.run();
      while (true) {
        try {
          Thread.sleep(1000);
        }
        catch (InterruptedException ex1) {
          break;
        }
      }
    }
    catch (IOException ex) {
      ex.printStackTrace();
    }

  }

  protected void unregisterManagedObjects() {
    // here we should unregister those objects previously registered...
  }

  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);
//    snmpCommunityMIB.setSourceAddressFiltering(true);
  }

  protected void registerSnmpMIBs() {
    heartbeatMIB = new Snmp4jHeartbeatMib(super.getNotificationOriginator(),
                                          new OctetString(),
                                          super.snmpv2MIB.getSysUpTime());
    ifMIB = new IfMib();
    agentppSimulationMIB = new AgentppSimulationMib();
    super.registerSnmpMIBs();
  }
}
----




More information about the SNMP4J mailing list