如何使用snmp4j-2.7.0在snmpv3中获取系统信息

时间:2019-05-21 11:24:18

标签: java snmp mib snmp4j

我正试图创建一个小型应用程序来管理snmp设备,并且一开始我想获取系统信息。

我正在使用snmp4j版本2.7.0,java 1.8,并且设备使用了snmpv3。 首先,我想同步获取数据。 我尝试通过两种方式做到这一点,但我一直在超时。

这是我的代码

    //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;
    }
}

我尝试使用treeUtil,但出现了与“普通”请求中相同的错误,以下是我的代码

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

主要功能

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

运行程序的结果

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

我看着https://www.snmp4j.org/html/faq.html

  

为什么发送请求时我总是超时(响应== null)?

     
    

可能您忘记了在发送请求之前调用TransportMapping(一次)或Snmp类的listen()方法。

  

但是我在createSNMPsession()方法中做到了 那我在做什么错? 谢谢。 :)

1 个答案:

答案 0 :(得分:0)

因此,我整整一整天都没头脑,答案就附在需要知道如何将SNMPV3与SNMP4J结合使用的任何人上。

让我们从正常的请求开始。 很好的问题是我将PDU与GETBULK一起使用,但是我没有设置“最大重复次数”,因此默认值为0,并且我得到了空的VBS

要修复它,只需使用:

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

对于树问题,无需定义最大重复次数,这是getSubTree的全部要点。 因此,问题在于我将以秒为单位的timeOut设置为30,而不是将Millisec设置为30000的愚蠢错误。 但后来我得到了更大的错误“ Agent没有按字典顺序返回变量绑定”。 墙来修复它,我用:

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