I'm trying to respond to SNMP GET requests from SnmpB with SNMP4j 2.3.1 (running on Windows).
In "Discover" mode, SnmpB queries by broadcasting 255.255.255.255 (checked with Wireshark) and I receive a GET request with standard OID (sysDescr, sysUpTime, sysContact, sysName and sysLocation). It finds my instance with the information I coded ("My System", "Myself", ...) (note that it also works when I enter the IP address under the "IP networks" textboxes, though I don't see any traffic on Wireshark but I receive the GET request):
I did write a very simple MIB file that I imported into SnmpB. It defines a single Integer32
data that I want to retrieve using an SNMP GET request from SnmpB.
However, using the same code than for the standard sys* OID, SnmpB doesn't seem to receive that data ("Timeout" in red on the top-right):
I did try Wireshark to check network activity and I don't see anything, so I guess it takes place on localhost (which is not accessible with Wireshark on Windows)? But the traces below show it does not (peerAddress=192.168.56.1
)...
Here is the MIB file (code follows):
MY-TEST-MIB DEFINITIONS ::= BEGIN
IMPORTS
enterprises, MODULE-IDENTITY, OBJECT-TYPE, Integer32
FROM SNMPv2-SMI;
myTest MODULE-IDENTITY
LAST-UPDATED "201412301216Z"
ORGANIZATION "My org"
CONTACT-INFO "Matthieu Labas"
DESCRIPTION "MIB Test"
REVISION "201412301216Z"
DESCRIPTION "Generated"
::= { enterprises 12121 }
myData OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION "My data for test"
::= { myTest 1 }
END
... and the code:
public class RespondGET implements CommandResponder {
public static final OID sysDescr = new OID("1.3.6.1.2.1.1.1.0");
public static final OID sysUpTime = new OID("1.3.6.1.2.1.1.3.0");
public static final OID sysContact = new OID("1.3.6.1.2.1.1.4.0");
public static final OID sysName = new OID("1.3.6.1.2.1.1.5.0");
public static final OID sysLocation = new OID("1.3.6.1.2.1.1.6.0");
public static final OID myData = new OID("1.3.6.1.4.1.12121.1.0");
private Snmp snmp;
public RespondGET() throws IOException {
MessageDispatcher dispatcher = new MessageDispatcherImpl();
dispatcher.addMessageProcessingModel(new MPv2c()); // v2c only
snmp = new Snmp(dispatcher, new DefaultUdpTransportMapping(new UdpAddress("192.168.56.1/161"), true));
snmp.addCommandResponder(this);
snmp.listen();
}
@Override
public void processPdu(CommandResponderEvent event) {
System.out.println("Received PDU "+event);
PDU pdu = event.getPDU();
switch (pdu.getType()) {
case PDU.GET:
List<VariableBinding> responses = new ArrayList<VariableBinding>(pdu.size());
for (VariableBinding v : pdu.getVariableBindings()) {
OID oid = v.getOid();
// Answer the usual SNMP requests
if (sysDescr.equals(oid)) {
responses.add(new VariableBinding(oid, new OctetString("My System description")));
} else if (sysUpTime.equals(oid)) {
responses.add(new VariableBinding(oid, new TimeTicks(ManagementFactory.getRuntimeMXBean().getUptime())));
} else if (sysContact.equals(oid)) {
responses.add(new VariableBinding(oid, new OctetString("Myself")));
} else if (sysName.equals(oid)) {
responses.add(new VariableBinding(oid, new OctetString("My System")));
} else if (sysLocation.equals(oid)) {
responses.add(new VariableBinding(oid, new OctetString("In here")));
} else if (myData.equals(oid)) { // MyData handled here
responses.add(new VariableBinding(oid, new Integer32(18)));
}
}
try {
CommunityTarget comm = new CommunityTarget(event.getPeerAddress(), new OctetString(event.getSecurityName()));
comm.setSecurityLevel(event.getSecurityLevel());
comm.setSecurityModel(event.getSecurityModel());
PDU resp = new PDU(PDU.RESPONSE, responses);
System.out.println(String.format("Sending response PDU to %s/%s: %s", event.getPeerAddress(), new String(event.getSecurityName()), resp));
snmp.send(resp, comm);
} catch (IOException e) {
System.err.println(String.format("Unable to send response PDU! (%s)", e.getMessage()));
}
event.setProcessed(true);
break;
default:
System.err.println(String.format("Unhandled PDU type %s.", PDU.getTypeString(pdu.getType())));
break;
}
}
public static void main(String[] args) throws IOException {
RespondGET rg = new RespondGET();
System.out.println("Listening...");
int n = 300; // 5 min
while (true) {
try { Thread.sleep(1000); } catch (InterruptedException e) { }
if (--n <= 0) break;
}
System.out.println("Stopping...");
rg.snmp.close();
}
}
It produces the following output when I click "discover" under SnmpB and right-click on myData
in the MIB Tree and "Get" (slightly reformatted for readability):
Listening...
Received PDU CommandResponderEvent[securityModel=2, securityLevel=1, maxSizeResponsePDU=65535,
pduHandle=PduHandle[16736], stateReference=StateReference[msgID=0,pduHandle=PduHandle[16736],
securityEngineID=null,securityModel=null,securityName=public,securityLevel=1,
contextEngineID=null,contextName=null,retryMsgIDs=null], pdu=GET[requestID=16736, errorStatus=Success(0), errorIndex=0,
VBS[1.3.6.1.2.1.1.1.0 = Null; 1.3.6.1.2.1.1.3.0 = Null; 1.3.6.1.2.1.1.4.0 = Null; 1.3.6.1.2.1.1.5.0 = Null; 1.3.6.1.2.1.1.6.0 = Null]],
messageProcessingModel=1, securityName=public, processed=false, peerAddress=192.168.56.1/49561, transportMapping=org.snmp4j.transport.DefaultUdpTransportMapping@120d62b, tmStateReference=null]
Sending response PDU to 192.168.56.1/49561/public: RESPONSE[requestID=0, errorStatus=Success(0), errorIndex=0,
VBS[1.3.6.1.2.1.1.1.0 = My System description; 1.3.6.1.2.1.1.3.0 = 0:01:03.18; 1.3.6.1.2.1.1.4.0 = Myself; 1.3.6.1.2.1.1.5.0 = My System; 1.3.6.1.2.1.1.6.0 = In here]]
Received PDU CommandResponderEvent[securityModel=2, securityLevel=1, maxSizeResponsePDU=65535,
pduHandle=PduHandle[1047], stateReference=StateReference[msgID=0,pduHandle=PduHandle[1047],
securityEngineID=null,securityModel=null,securityName=public,securityLevel=1,
contextEngineID=null,contextName=null,retryMsgIDs=null], pdu=GET[requestID=1047, errorStatus=Success(0), errorIndex=0,
VBS[1.3.6.1.4.1.12121.1.0 = Null]], messageProcessingModel=1, securityName=public, processed=false, peerAddress=192.168.56.1/49560, transportMapping=org.snmp4j.transport.DefaultUdpTransportMapping@120d62b, tmStateReference=null]
Sending response PDU to 192.168.56.1/49560/public: RESPONSE[requestID=0, errorStatus=Success(0), errorIndex=0, VBS[1.3.6.1.4.1.12121.1.0 = 18]]
Stopping...
What am I missing here? Could that "just" be a network routing issue?
After setting up a VM and checking with Wireshark, it turned out I forgot to set, on the response PDU, the same request ID than the GET PDU.
It was solved by adding resp.setRequestID(pdu.getRequestID());
when building the response PDU
CommunityTarget comm = new CommunityTarget(event.getPeerAddress(), new OctetString(event.getSecurityName()));
comm.setSecurityLevel(event.getSecurityLevel());
comm.setSecurityModel(event.getSecurityModel());
PDU resp = new PDU(PDU.RESPONSE, responses);
resp.setRequestID(pdu.getRequestID()); // Forgot that!
snmp.send(resp, comm);
Thanks to @Jolta for his patience during New Year holiday and his insisting on using Wireshark for further checking. :)