PeerNet PeerNet - 5 months ago 46
Java Question

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

Answer

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