PeerNet
PeerNet

Reputation: 855

Getting device name and model via snmp

I am trying to get switches device and model name through snmp. When I try to get Nortell or Juniper switch, it works fine but Cisco switches cause a problem. I use this oid value: ".1.3.6.1.2.1.1.1.0" , but I tried "1.3.6.1.2.1.1.1" also. And return value is null. Here is my code:

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

Upvotes: 1

Views: 23640

Answers (6)

user20071792
user20071792

Reputation: 1

If you run a query using OID .1.3.6.1.2.1.1.5.0 (sysName) against a Cisco router or switch running a version of IOS you will get the values for these two configuration statements concatenated together:

router#hostname "hostname"

router#ip domain-name "domain_name"

Thus, querying using the above OID will yield "hostname"."domain_name". If "ip domain-name" is not set with a value you'll simply get "hostname".

If all you want is the hostname you need to query .1.3.6.1.4.1.9.2.1.3.0., which is in CISCO-MIB.mib. Querying .1.3.6.1.4.1.9.2.1.4.0 will return "domain_name".

If the device is running NX-OS then querying those two OIDs won't work and I don't know what will (although I currently have a query open to Cisco on that).

Upvotes: 0

Amit Lopes
Amit Lopes

Reputation: 41

@PeerNet I executed your code, the only change I made was adding a '0' to the OID i.e '.1.3.6.1.2.1.1.1.0'.

Try Paessler SNMP Tester, and it will give you all the OIDs that are on the switch, and accordingly you can use those in your code.

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

You can try this code I found on 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;
    }

}

Upvotes: 1

Yuri Lachin
Yuri Lachin

Reputation: 1500

I would suggest to start with making sure that you really get snmp response from a switch. I suspect that snmp is not fully configured on a switch and your code gets timeout instead of snmp response.

Example:

$ 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"

Since you are doing snmp GET requests your oids must end with ".0". Device name is returned in response to oid sysName.0

$ snmptranslate -IR -On sysName.0 .1.3.6.1.2.1.1.5.0

Example:

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

The oid you are using:

$ snmptranslate -IR -On sysDescr.0 .1.3.6.1.2.1.1.1.0

is unlikely to give device name or even exact model.

$ 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

Device model can be requested with 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

You can decode the response with lookup in CISCO-PRODUCTS-MIB

Upvotes: 3

SkyWalker
SkyWalker

Reputation: 29168

As you are getting problem with oid and want to get device name and model via snmp, then I will prefer you to check which are available in your network. Then you can choose.

You can use Nmap's snmp-brute command, like below

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

On the other hand,

you can use this script, which generates an XML file containing snmp-enabled devices and their respective communities. This script also accepts IP addresses and multiple community names as input files.

Resource 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

Upvotes: 1

Nathan
Nathan

Reputation: 29

The given oid has not to do what you expect. You have to learn the correct oid from manual

Upvotes: 1

Lex Li
Lex Li

Reputation: 63264

There is no guarantee that this .1.3.6.1.2.1.1.1.0 will give you the name you want. Please check Cisco manual for this model to see if there is a way to configure that before you make the queries.

Upvotes: 1

Related Questions