0
votes

I am trying to write my first snmp4j client. I have an agent running on 192.168.60.105. Using net-snmp I can query an OID and get a result. Using smnp4j the response event for the snmp get is returned with a null response and a null error. I think the message is timing out but I don't know why.

I get a result using net-snmp

jgaer@ljgaer2_~: snmpget 192.168.60.105 .1.3.6.1.4.1.27675.20.5.2.0
CW-NET-STG-SVR-MIB::cwNetStgSvrProvisioningEnable.0 = Hex-STRING: 00 00 00 00 

I've tried using a longer timeout and a larger number of retries and it takes longer to return. That's why I think I am timing out. I just don't understand why. I also would have expected that if a responseEvent is returned on a timeout the error would indicate that. I've tried using verions1. Using version 3 required a scoped PDU.

public static void main(String[] args) throws IOException {
        String address = ("udp:192.168.60.105/161");
        TransportMapping transport = new DefaultUdpTransportMapping();
        Snmp snmp = new Snmp(transport);
        transport.listen();
        PDU pdu = new PDU();
        pdu.setType(PDU.GET);
        pdu.add(new VariableBinding(new OID(".1.3.6.1.4.1.27675.20.5.2.0")));
        Address targetAddress = GenericAddress.parse(address);
        CommunityTarget target = new CommunityTarget();
        target.setCommunity(new OctetString("public"));
        target.setAddress(targetAddress);
        target.setRetries(2);
        target.setTimeout(1500);
        target.setVersion(SnmpConstants.version2c);
        ResponseEvent response = snmp.send(pdu,target);
        System.out.println(response);
        System.out.println(response.getResponse());
        System.out.println(response.getError());

    }

results from running the above code

org.snmp4j.event.ResponseEvent[source=org.snmp4j.Snmp@3f91beef]
null
null

I would expect that either the error or the response would be non null. I am using java version java version "1.8.0_191" and snmp4j version 2.5.0. The agent is running 2.5.3

I traced the packets using wireshark and can confirm that I am never getting a response from the agent using snmp4j.I don't really understand enough of the protocal to do a byte by byte comparison, but the info column for the net-snmp call looks very different from snmp4j calls.

net-snmp

 length       info           
 106          get-request                      : sent from client to agent
 159          report 1.3.6.1.6.3.15.1.1.4.0    : sent from agent to client
 192          encryptedPDI : privKey unknown   : sent from client to agent
 196          encryptedPDI : privKey unknown   : sent from agent to client

snmp4j - response never received three messages from client to agent

 89          get-request 1.3.6.1.4.1.27675.20.5.2.0 sent from client to agent

Looking at the text encoded version of the bytes I see the string 'public'

1
consider sniffing your wire traffic to/from that device while your code is running (and while the netsnmp get is running, to be sure 1) you're actually sending the PDU 2) the response is coming back 3) the PDU and response are similar in both casesGus

1 Answers

2
votes

Problem was the agent was SNMPv3 requiring me to use a ScopedPDU with some authorization information. The user and pass phrases were obtained from the ~/.snmp/snmp.conf file. I am now getting connected to and getting a response from the agent. Code is shown below. I am not getting the correct value but rather a counter of how many gets I have issued. But that is another problem.

The second issue was using the wrong values for authProtocol and privProtocol. Lesson learned check the pdu type of the response in addition to checking the errorResponse. A response type of report indicates a failure with the OID of the report being the key to the cause of the failure.

public static void main(String[] args) throws Exception {
        TransportMapping transport = new DefaultUdpTransportMapping();
        Snmp snmp = new Snmp(transport);

        OctetString localEngineId = new OctetString(MPv3.createLocalEngineID());
        USM usm = new USM(SecurityProtocols.getInstance(), localEngineId, 0);
        SecurityModels.getInstance().addSecurityModel(usm);

        OctetString securityName = new OctetString("masked");
        OID authProtocol = AuthMD5.ID;
        OID privProtocol = PrivDES.ID;
        OctetString authPassphrase = new OctetString("masked");
        OctetString privPassphrase = new OctetString("masked");

        snmp.getUSM().addUser(securityName, new UsmUser(securityName, authProtocol, authPassphrase, privProtocol, privPassphrase));


        UserTarget target = new UserTarget();
        target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
        target.setSecurityName(securityName);

        target.setAddress(GenericAddress.parse(String.format("udp:%s/%s", "192.168.60.105", "161")));
        target.setVersion(SnmpConstants.version3);
        target.setRetries(2);
        target.setTimeout(60000);
        transport.listen();

        PDU pdu = new ScopedPDU();
        pdu.add(new VariableBinding(new OID(".1.3.6.1.4.1.27675.20.10.1.2.0")));
        pdu.setType(PDU.GET);
        ResponseEvent event = snmp.send(pdu, target);
        if (event != null) {
            PDU pdu2 = event.getResponse();
            System.out.println(pdu2.get(0).getVariable().toString());
            if (pdu2.getErrorStatus() == PDU.noError) {
                System.out.println("SNMPv3 GET Successful!");
            } else {
                System.out.println("SNMPv3 GET Unsuccessful.");
            }
        } else {
            System.out.println("SNMP get unsuccessful.");
        }

}