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

Getting device name and model via snmp

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

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

不能保证 .1.3.6.1.2.1.1.1.0 会给您想要的名字。请查看此型号的 Cisco 手册,以查看是否有配置方法,然后再进行查询。

给定的 oid 未达到您的预期。你必须从手册中学习正确的oid

由于您在使用 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,它会生成一个 XML 文件,其中包含支持 snmp 的设备及其各自的社区。 此脚本还接受 IP 地址和多个社区名称作为输入文件。

资源Link:

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

我建议首先确保您确实从交换机获得 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

中查找来解码响应

@PeerNet 我执行了您的代码,我所做的唯一更改是在 OID 中添加了一个“0”,即“.1.3.6.1.2.1.1.1.0”。

试试 Paessler SNMP 测试器,它会为您提供交换机上的所有 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;
    }

}