通过snmp获取设备名称和型号

时间:2016-04-15 10:47:08

标签: java networking snmp

我正在尝试通过snmp获取交换机设备和型号名称。当我尝试使用Nortell或Juniper交换机时,它运行正常,但Cisco交换机会导致问题。我使用这个oid值:“。1.3.6.1.2.1.1.1.0”,但我也试过“1.3.6.1.2.1.1.1”。返回值为null。 这是我的代码:

package list;

public class DeviceInfo {
    private static String ipAddress = "10.20.X.XX";

    private static String port = "161";

    private static String oidValue = ".1.3.6.1.2.1.1.1";

    private static int snmpVersion = SnmpConstants.version1; // or version2c

    private static String community = "myreadcommunity";

    public static void main(String[] args) throws Exception {

        TransportMapping transport = new DefaultUdpTransportMapping();
        transport.listen();

        CommunityTarget comtarget = new CommunityTarget();
        comtarget.setCommunity(new OctetString(community));
        comtarget.setVersion(snmpVersion);
        comtarget.setAddress(new UdpAddress(ipAddress + "/" + port));
        comtarget.setRetries(2);
        comtarget.setTimeout(1000);

        PDU pdu = new PDU();
        pdu.add(new VariableBinding(new OID(oidValue)));
        pdu.setType(PDU.GET);
        pdu.setRequestID(new Integer32(1));

        Snmp snmp = new Snmp(transport);

        System.out.println("Sending request.");
        ResponseEvent response = snmp.get(pdu, comtarget);

        if (response != null) {

            System.out.println("Got results.");
            PDU responsePDU = response.getResponse();

            if (responsePDU != null) {
                int errorStatus = responsePDU.getErrorStatus();
                int errorIndex = responsePDU.getErrorIndex();
                String errorStatusText = responsePDU.getErrorStatusText();

                if (errorStatus == PDU.noError) {
                    System.out.println("Switch Name: = " + responsePDU.getVariableBindings());
                    System.out.println(responsePDU.size());
                } else {
                    System.out.println("Error");
                    System.out.println("Error code: " + errorStatus);
                    System.out.println("Error Name: " + errorStatusText);
                }
            } else {
                System.out.println("NULL");
            }
        } else {
            System.out.println("Error: Timeout ");
        }
        snmp.close();
    }
}

5 个答案:

答案 0 :(得分:3)

我建议首先确保你真的从交换机获得snmp响应。我怀疑在交换机上没有完全配置snmp,你的代码会超时而不是snmp响应。

示例:

$ tcpdump udp and port 161

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 10:36:26.980138 IP host.example.com.41226 > rtr.example.com.snmp: GetRequest(28) system.sysName.0 10:36:26.983971 IP rtr.example.com.snmp > host.example.com.41226: GetResponse(43) system.sysName.0="rtr.example.com"

由于您正在执行snmp GET请求,因此您的oid必须以“.0”结尾。 响应oid sysName.0

返回设备名称

$ snmptranslate -IR -On sysName.0 .1.3.6.1.2.1.1.5.0

示例:

$ snmpget -v1 -c public rtr sysName.0 SNMPv2-MIB::sysName.0 = STRING: rtr.example.com

你正在使用的oid:

$ snmptranslate -IR -On sysDescr.0 .1.3.6.1.2.1.1.1.0

不太可能提供设备名称甚至是确切的型号。

$ snmpget -v1 -c public rtr sysDescr.0 SNMPv2-MIB::sysDescr.0 = STRING: Cisco Internetwork Operating System Software IOS (tm) C2600 Software (C2600-IPBASE-M), Version 12.3(6c), RELEASE SOFTWARE (fc1) Copyright (c) 1986-2004 by cisco Systems, Inc. Compiled Tue 20-Jul-04 05:24 by kellythw

可以使用sysObjectID:

请求设备模型

$ snmptranslate -IR -On sysObjectID.0 .1.3.6.1.2.1.1.2.0

$ snmpget -v1 -c public rtr sysObjectID.0 SNMPv2-MIB::sysObjectID.0 = OID: SNMPv2-SMI::enterprises.9.1.469

您可以使用CISCO-PRODUCTS-MIB

中的查找解码响应

答案 1 :(得分:1)

无法保证此.1.3.6.1.2.1.1.1.0会为您提供所需的名称。请查看此型号的Cisco手册,以确定在进行查询之前是否有办法对其进行配置。

答案 2 :(得分:1)

给定的oid没有按照你的期望做。你必须从手册

学习正确的oid

答案 3 :(得分:1)

当您遇到oidwant to get device name and model via snmp的问题时,我希望您检查网络中可用的内容。然后你可以选择。

您可以使用Nmap的snmp-brute命令,如下所示

nmap -sU -p161 --script snmp-brute --script-args snmplist=community.lst 10.20.X.XX/24

另一方面,

您可以使用this script生成包含启用snmp的设备及其各自社区的XML文件。 此脚本还接受IP地址和多个社区名称作为输入文件。

资源链接:

  1. How to find all the snmp enabled devices in my network?
  2. 1.3.6.1.2.1.1 - SNMP MIB-2 System

答案 4 :(得分:1)

@PeerNet我执行了你的代码,我做的唯一改变就是给OID添加一个'0',即'.1.3.6.1.2.1.1.1.0'。

尝试使用Paessler SNMP Tester,它会为您提供交换机上的所有OID,因此您可以在代码中使用这些OID。

https://www.paessler.com/tools/snmptester

您可以尝试我在http://www.jitendrazaa.com/blog/java/snmp/create-snmp-client-in-java-using-snmp4j/

上找到的代码
public class SNMPManager 
{

    Snmp snmp = null;
    String address = null;

    /**
    * Constructor
    * @param add
    */
    public SNMPManager(String add)
    {
        address = add;
    }

    public static void main(String[] args) throws IOException 
    {
        /**
        * Port 161 is used for Read and Other operations
        * Port 162 is used for the trap generation
        */
        SNMPManager client = new SNMPManager("udp:127.0.0.1/161");
        //System.out.println(client);
        client.start();
        /**
        * OID - .1.3.6.1.2.1.1.1.0 => SysDec
        * OID - .1.3.6.1.2.1.1.5.0 => SysName
        * => MIB explorer will be useful here, as discussed in previous article
        */
        String sysDescr = client.getAsString(new OID("1.3.6.1.2.1.1.1.0"));
        System.out.println(sysDescr);
    }

    /**
    * Start the Snmp session. If you forget the listen() method you will not
    * get any answers because the communication is asynchronous
    * and the listen() method listens for answers.
    * @throws IOException
    */
    void start() throws IOException 
    {
        TransportMapping transport = new DefaultUdpTransportMapping();
        snmp = new Snmp(transport);
        // Do not forget this line!
        transport.listen();
    }

    /**
    * Method which takes a single OID and returns the response from the agent as a String.
    * @param oid
    * @return
    * @throws IOException
    */
    public String getAsString(OID oid) throws IOException 
    {
        ResponseEvent event = get(new OID[] { oid });
        //System.out.println(oid);
        return event.getResponse().get(0).getVariable().toString();
    }

    /**
    * This method is capable of handling multiple OIDs
    * @param oids
    * @return
    * @throws IOException
    */
    public ResponseEvent get(OID oids[]) throws IOException 
    {
        PDU pdu = new PDU();
        for (OID oid : oids) 
        {
            pdu.add(new VariableBinding(oid));

        }
        pdu.setType(PDU.GET);
        ResponseEvent event = snmp.send(pdu, getTarget(), null);
        if(event != null) 
        {
            return event;
        }
        throw new RuntimeException("GET timed out");
    }

    /**
    * This method returns a Target, which contains information about
    * where the data should be fetched and how.
    * @return
    */
    private Target getTarget() 
    {
        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);
        return target;
    }

}