Reputation: 855
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
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
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
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
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
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.
Upvotes: 1
Reputation: 29
The given oid has not to do what you expect. You have to learn the correct oid from manual
Upvotes: 1
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