javasnmpmibsnmp4j

how get system info in snmpv3 using snmp4j-2.7.0


I'm trying to create small app to manage snmp devices and for start i want to get the system info.

I'm using snmp4j version 2.7.0, java 1.8 and the device use snmpv3. For start i want to get the data synchronously. I try to do it in two ways but i keep getting time out

here is my code

    //Normal request
public class SynchronouslySnmp 
{
    protected String PORT="/161";
    protected String PROTOCOL="udp:";
    protected SnmpData snmpData;
    protected Snmp snmp;

    public SynchronouslySnmp(SnmpData snmpData)
    {
        this.snmpData=snmpData;

    }

    public void start()
    {
        createSNMPsession(); 
        addSnmpUser();
        sendSnmp();
    }


    private void sendSnmp() 
    {
           // send the PDU
        ResponseEvent response;
        try 
        {
            response = snmp.send(getPDU(), getTarget());
            // extract the response PDU (could be null if timed out)
            PDU responsePDU = response.getResponse();
            // extract the address used by the agent to send the response:
            if(responsePDU == null)
            {
                System.out.println("ERROR: table OID [" + SnmpContants.system + "] time out" );  
            }
            else
            {
                Address peerAddress = response.getPeerAddress();
                System.out.println("pdu: "+responsePDU.toString());
                System.out.println("Address: "+peerAddress.toString());
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            try 
            {
                snmp.close();
            } catch (IOException e) 
            {
                e.printStackTrace();
            }
        }
    }

    protected void createSNMPsession() 
    {
        TransportMapping<? extends Address> transport;
        try 
        {
            transport = new DefaultUdpTransportMapping();
            snmp = new Snmp(transport);
            USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
            SecurityModels.getInstance().addSecurityModel(usm);
            transport.listen();
            //snmp.listen();
        } 
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    }

    protected void addSnmpUser()
    {
        // add user to the USM
        snmp.getUSM().addUser(new OctetString(snmpData.getUsmUser()),
                              new UsmUser(new OctetString(snmpData.getUsmUser()),
                                          snmpData.getAuthProtocol(),
                                          new OctetString(snmpData.getAuthPassword()),
                                          snmpData.getPrivProtocol(),
                                          new OctetString(snmpData.getPrivPassword())));
    }

    protected Target getTarget()
    {
         // create the target
           UserTarget target = new UserTarget();
           Address targetAddress = GenericAddress.parse(PROTOCOL+snmpData.getIpAddress()+PORT);
           target.setAddress(targetAddress);
           target.setRetries(snmpData.getRetryTimes());
           target.setTimeout(snmpData.getTimeout());
           target.setVersion(snmpData.getSnmpVersion());
           target.setSecurityLevel(snmpData.getSecurityLevel());
           target.setSecurityName(new OctetString(snmpData.getUsmUser()));
           return target;
    }

    protected PDU getPDU() 
    {
        // create the PDU
        PDU pdu = new ScopedPDU();
        pdu.add(new VariableBinding(SnmpConstants.system));
        pdu.setType(PDU.GETBULK);
        return pdu;
    }
}

I try to use the treeUtil but got the same error as in the Normal request the follow is my code

    public class SynchronouslySnmpUsingTree extends SynchronouslySnmp
{
    private OID tableOid;
    private LinkedHashMap<String, List<VariableBinding>> resultMap;

    public SynchronouslySnmpUsingTree(SnmpData snmpData)
    {
        super(snmpData);
        resultMap = new LinkedHashMap<String, List<VariableBinding>>();
        tableOid=new OID(".1.3.6.1.2.1.1");
        createSNMPsession(); 
        addSnmpUser();
        sendSnmp();
    }

    private void sendSnmp()
    {
        try 
        {
            TreeUtils treeUtils = new TreeUtils(snmp, new PDUFactory()
            {
                @Override
                public PDU createPDU(MessageProcessingModel arg0) {
                    return  getPDU();
                }

                @Override
                public PDU createPDU(Target arg0) {

                    return getPDU();
                }
            });
            List<TreeEvent> events = treeUtils.getSubtree(getTarget(), tableOid);
            if (events == null || events.size() == 0)
            {
                System.out.println("Error: Unable to read table...");
                return;
            }
            for (TreeEvent event : events)
            {
                if (event != null && !event.isError()) 
                {
                    VariableBinding[] varBindings = event.getVariableBindings();
                    if (varBindings != null && varBindings.length != 0)
                    {
                        for (VariableBinding varBinding : varBindings) 
                        {
                            if (varBinding != null)
                            {
                                OID oid = varBinding.getOid();
                                List<VariableBinding> binds = resultMap.get(oid.toString());
                                if( binds == null)
                                {
                                    binds = new ArrayList<VariableBinding>();
                                    resultMap.put(oid.toString(), binds);
                                }
                                binds.add(varBinding);
                            }
                        }
                    }
                }
                else
                {
                    System.out.println("Error: table OID [" + tableOid + "] " + event.getErrorMessage());
                    continue;
                }
            }
        }
        catch(Throwable t)
        {
                System.out.println("Failed operation: getMibTableWithNext");
                t.printStackTrace();
        }
        finally 
        {
            try
            {
                snmp.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }
}

main function

public static void main(String[] args){
    SynchronouslySnmp synchronouslySnmp =new SynchronouslySnmp (new SnmpData());
    synchronouslySnmp.start();
    SynchronouslySnmpUsingTree synchronouslySnmpUsingTree = new SynchronouslySnmpUsingTree(new SnmpData());
}

Result of running the program

Error: table OID [1.3.6.1.2.1.1] time out); <---nurmal
Error: table OID [1.3.6.1.2.1.1] Request time out); <---tree

I look in https://www.snmp4j.org/html/faq.html

Why am I always getting a time-out (response == null) when sending a request?

Probably you have forgotten to call the listen() method of the TransportMapping (once) or the Snmp class before sending the request.

but i do that in the method createSNMPsession() so what am i doing wrong? thanks. :)


Solution

  • So after I've broken my head for an entire day, the answer is attached to anyone who needs to know how to use SNMPV3 with SNMP4J.

    Let start with the normal request. well the problem was that i use the PDU with GETBULK but i didn't set the Max Repetitions so the default was 0 and i got empty VBS

    to fix it just use:

    protected PDU getPDU() 
    {
        // create the PDU
        PDU pdu = new ScopedPDU();
        pdu.add(new VariableBinding(SnmpConstants.system));
        pdu.setType(PDU.GETBULK);
        pdu.setMaxRepetitions(10);//or any number you wish
        return pdu;
    }
    

    for the tree issue there is no need to define the Max Repetitions this is the all point of getSubTree. so the problem there was that i set the timeOut in sec as 30 instead of millisec as 30000 stupid error. but then i got bigger error "Agent did not return variable bindings in lexicographic order". wall to fix it i use:

    treeUtils.setIgnoreLexicographicOrder(true);
    List<TreeEvent> events = treeUtils.getSubtree(getTarget(), tableOid);
    if (events == null || events.size() == 0)
    {
        System.out.println("Error: Unable to read table...");
        return;
    }
     .
     .
     .
    if( binds == null)
    {
        binds = new ArrayList<VariableBinding>();
        binds.add(varBinding);
        resultMap.put(oid.toString(), binds); 
    }