Question about snmp V3 GETNEXT

Hi,

I am new using snmp, and I have taken the example from How-to implement SNMPv3 GETNEXT with SNMP4J? - SNMP4J - AGENTPP and modify it because I am using an old version of snmp4j (1.10.1).

If I understand the code, there is a listener and a sender in this exemple ? I don’t really understand why, in the initSnmp() method, there is a call to `snmp.addTransportMapping(new DefaultUdpTransportMapping(new UdpAddress(0))); → Why 0 ? It should be the port we want to listen ? I modified this to 162, and I use the following parameters :

String targetAddress = “udp:localhost/162”;
String context = “”;
String securityName = “shasecurityname”;
String authPasssphrase = “authShaPassword”;
String privPasssphrase = “privShaPassword”;
String oids = new String{“1.3.6.1.2.1.1.1.0”,“1.3.6.1.2.1.1.1.10”};

And now, I always get the following response :

1.3.6.1.6.3.15.1.1.4.0 = 0
Engine ID ‘80:00:13:70:01:a9:fe:6e:99’ could not be added to engine ID cache for target address ‘127.0.0.1/162’ because engine ID matches local engine ID
onProcessPdu() method : commandResponderEvent.toString() = CommandResponderEvent[transportMapping=org.snmp4j.transport.DefaultUdpTransportMapping@5653d639peerAddress=127.0.0.1/162, processed=false, pdu=[REPORT[reqestID=0, errorStatus=0, errorIndex=0, VBS[1.3.6.1.6.3.15.1.1.4.0 = 0]]], securityName=, securityModel=3, securityLevel=1]
onResponse() method : Received responseEvent.getResponse() = REPORT[reqestID=0, errorStatus=0, errorIndex=0, VBS[1.3.6.1.6.3.15.1.1.4.0 = 0]]

Thank you !
Florian,

Hi Florian,

Why are you using such an old (outdated) version? It is really time for an up-date!
In

snmp.addTransportMapping(new DefaultUdpTransportMapping(new UdpAddress(0)));

the port 0 is used to allocate an arbitrary local port for listening for responses. Thinking of such a port that need to be 162 fix, is a common error in implementations and would not allow to run many SNMP command generators on a single machine (IP) as non-root processes.

By doing your change, you mixed up target and source and tried to use for both the same engine ID. That cannot work. Please rethink your port and communication setup and start over again.

Best regards,
Frank

1 Like

Thank you for these explanations!

However, when I set this port to 0, I always get a ‘timed out’ (even when I try to increase the value in the userTarget). With version 2.5.0 of snmp4j (still not the most recent version, sorry!), I get the following logs :

Initialized Salt to aa2a75891e6959f5.
UDP receive buffer size for socket 0.0.0.0/0 is set to: 8192
Adding user v3AuthSHAPrivDESSecName = UsmUser[secName=v3AuthSHAPrivDESSecName,authProtocol=1.3.6.1.6.3.10.1.1.5,authPassphrase=v3AuthHMAC192SHA256Password,privProtocol=1.3.6.1.6.3.10.1.2.4,privPassphrase=v3AuthPrivAES128Password,localizationEngineID=null]
RFC3414 §3.1.4.b Outgoing message is not encrypted
Adding cache entry: StateReference[msgID=902502545,pduHandle=PduHandle[1716264043],securityEngineID=,securityModel=org.snmp4j.security.USM@446cdf90,securityName=v3AuthSHAPrivDESSecName,securityLevel=1,contextEngineID=,contextName=contextName,retryMsgIDs=null]
Running pending async request with handle PduHandle[1716264043] and retry count left 1
Sending message to 127.0.0.1/162 with length 72: 30:46:02:01:03:30:11:02:04:35:cb:18:91:02:03:00:ff:ff:04:01:04:02:01:03:04:10:30:0e:04:00:02:01:00:02:01:00:04:00:04:00:04:00:30:1c:04:00:04:0b:63:6f:6e:74:65:78:74:4e:61:6d:65:a1:0b:02:01:00:02:01:00:02:01:00:30:00
RFC3414 §3.1.4.b Outgoing message is not encrypted
Adding cache entry: StateReference[msgID=902502546,pduHandle=PduHandle[1716264043],securityEngineID=,securityModel=org.snmp4j.security.USM@446cdf90,securityName=v3AuthSHAPrivDESSecName,securityLevel=1,contextEngineID=,contextName=contextName,retryMsgIDs=null]
Adding previous message IDs [902502545] to new entry StateReference[msgID=902502546,pduHandle=PduHandle[1716264043],securityEngineID=,securityModel=org.snmp4j.security.USM@446cdf90,securityName=v3AuthSHAPrivDESSecName,securityLevel=1,contextEngineID=,contextName=contextName,retryMsgIDs=null]
Running pending async request with handle PduHandle[1716264043] and retry count left 0
Sending message to 127.0.0.1/162 with length 72: 30:46:02:01:03:30:11:02:04:35:cb:18:92:02:03:00:ff:ff:04:01:04:02:01:03:04:10:30:0e:04:00:02:01:00:02:01:00:04:00:04:00:04:00:30:1c:04:00:04:0b:63:6f:6e:74:65:78:74:4e:61:6d:65:a1:0b:02:01:00:02:01:00:02:01:00:30:00
Request timed out: 1716264043
Timed out.
Cancelling pending request with handle PduHandle[1716264043]

Your are sending your SNMP request to 127.0.0.1 UDP port 162. Is there an agent listening on that port on your machine?
That would be very unusual. Normally an agent listens on port 161 for commands. SNMP4J agents listen on port 4700 by default, because that does not require root rights on Unix systems.

Thank you Frank, I had a problem with my agent…

Last question, I am extending BaseAgent for my agent. Currently, I register my MO with : agent.registerManagedObject(new MOScalar(…)); (I am working with snmp v2 this time)

Now, I would like to return a custom dynamic PDU response according to the incoming request

I have seen this post on stackoverflow : java - How to register a listener on a OID / Managed Object using SNMP4J to act on set or get requests the agent receives? - Stack Overflow

But since I am using BaseAgent and not the AgentConfigManager, I don’t know where I can add the
server.addLookupListener(…) in my manager ?

My current manager looks like :

public class SNMPAgent extends BaseAgent {

    private String address;

    public SNMPAgent(String address) throws IOException {
	    super(new File("conf.agent"), new File("bootCounter.agent"),
			new CommandProcessor(
					new OctetString(MPv3.createLocalEngineID())));
	    this.address = address;
    }

    @Override
    protected void registerManagedObjects() {
    }

    public void registerManagedObject(ManagedObject mo) {
	    try {
		    server.register(mo, null);
	    } catch (DuplicateRegistrationException ex) {
		    throw new RuntimeException(ex);
	   }

	    **// Maybe call server.addLookupListener(...,mo) here ?**
    }

    public void unregisterManagedObject(MOGroup moGroup) {
	    moGroup.unregisterMOs(server, getContext(moGroup));
    }

    @Override
    protected void addNotificationTargets(SnmpTargetMIB targetMIB,
		    SnmpNotificationMIB notificationMIB) {
    }

@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 addUsmUser(USM usm) {
}

@Override
protected void initTransportMappings() throws IOException {
	transportMappings = new TransportMapping[1];
	Address addr = GenericAddress.parse(address);
	TransportMapping tm = TransportMappings.getInstance()
			.createTransportMapping(addr);
	transportMappings[0] = tm;
}

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();
}

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

@Override
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);
 }
}

Thank you !!

You might overwrite the registerMansgedObjects empty method in BaseAgent for example.

Or switch to AgentConfigManager