import java.io.IOException;
import java.util.Vector;
import org.apache.log4j.*;
import org.snmp4j.*;
import org.snmp4j.mp.*;
import org.snmp4j.security.*;
import org.snmp4j.smi.*;
import org.snmp4j.transport.*;
import org.snmp4j.util.*;
import org.snmp4j.log.LogFactory;
import org.snmp4j.log.Log4jLogFactory;
import org.snmp4j.asn1.BER;
import org.snmp4j.event.ResponseEvent;
public class SnmpUtil extends Thread implements PDUFactory, CommandResponder {
public static final int DEFAULT = 0;
public static final int WALK = 1;
private Target _target;
private Address _address;
private OID _authProtocol;
private OID _privProtocol;
private OctetString _privPassphrase;
private OctetString _authPassphrase;
private OctetString _community = new OctetString("public");
private OctetString _contextEngineID;
private OctetString _contextName = new OctetString();
private OctetString _securityName = new OctetString();
private static Snmp _snmp = null;
private int _numThreads = 1;
private int _port = 0;
private ThreadPool _threadPool = null;
private boolean _isReceiver = false;
private OctetString _authoritativeEngineID = new OctetString("1234567");
private TransportMapping _transport = null;
private TimeTicks _sysUpTime = new TimeTicks(0);
private OID _trapOID = new OID("1.3.6.1.4.1.2789.2005");
private int _version = 0;
private int _retries = 1;
private int _timeout = 1000;
private int _pduType = 0;
private Vector _vbs = new Vector();
protected int _operation = DEFAULT;
static {
if (System.getProperty("log4j.configuration") == null) {
BasicConfigurator.configure();
}
}
public SnmpUtil(String host, String varbind, boolean receiver, int type){
_version = SnmpConstants.version2c;
_isReceiver = receiver;
if(type == 2){
_pduType = PDU.INFORM;
} else if (type == 1) {
_pduType = PDU.TRAP;
}
setPort();
if(!_isReceiver) {
init(host,varbind);
} else {
initReceiver(host);
}
}
public SnmpUtil(String host, String varbind, String user, String authProtocol,
String authPasshrase, String privProtocol, String privPassphrase,
boolean receiver,int type) {
_version = SnmpConstants.version3;
_isReceiver = receiver;
_privPassphrase = new OctetString(privPassphrase);
_authPassphrase = new OctetString(authPasshrase);
_securityName = new OctetString(user);
if (authProtocol.equals("MD5")) {
_authProtocol = AuthMD5.ID;
} else if (authProtocol.equals("SHA")) {
_authProtocol = AuthSHA.ID;
}
if (privProtocol.equals("DES")) {
_privProtocol = PrivDES.ID;
} else if ((privProtocol.equals("AES128")) || (privProtocol.equals("AES"))) {
_privProtocol = PrivAES128.ID;
} else if (privProtocol.equals("AES192")) {
_privProtocol = PrivAES192.ID;
} else if (privProtocol.equals("AES256")) {
_privProtocol = PrivAES256.ID;
}
if(type == 2){
_pduType = PDU.INFORM;
} else if (type == 1) {
_pduType = PDU.TRAP;
}
setPort();
if(!_isReceiver) {
init(host,varbind);
} else {
initReceiver(host);
}
}
public void setVersion(int version) {
_version = version;
}
public void setOperation(int operation) {
_operation = operation;
if(_operation == WALK){
_pduType = PDU.GETNEXT;
}
}
public int getOperation() {
return _operation;
}
public int getPduType() {
return _pduType;
}
public void setPort() {
if(_pduType == PDU.INFORM || _pduType == PDU.TRAP ||
_isReceiver) {
_port = 162;
}else{
_port = 161;
}
}
public void init(String host, String varbind){
_vbs = getVariableBinding(varbind);
if(_pduType == PDU.INFORM || _pduType == PDU.TRAP) {
checkTrapVariables(_vbs);
}
_address = new UdpAddress(host+"/"+_port);
LogFactory.setLogFactory(new Log4jLogFactory());
BER.setCheckSequenceLength(false);
}
public Vector getVariableBindings() {
return _vbs;
}
private void addUsmUser(Snmp snmp) {
snmp.getUSM().addUser(_securityName, new UsmUser(_securityName,
_authProtocol,
_authPassphrase,
_privProtocol,
_privPassphrase));
}
private Snmp createSnmpSession() throws IOException {
AbstractTransportMapping transport;
if (_address instanceof TcpAddress) {
transport = new DefaultTcpTransportMapping();
} else {
transport = new DefaultUdpTransportMapping();
}
// Could save some CPU cycles:
// transport.setAsyncMsgProcessingSupported(false);
Snmp snmp = new Snmp(transport);
if (_version == SnmpConstants.version3) {
USM usm = new USM(SecurityProtocols.getInstance(),
new OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
addUsmUser(snmp);
}
return snmp;
}
private Target createTarget() {
if (_version == SnmpConstants.version3) {
UserTarget target = new UserTarget();
if (_authPassphrase != null) {
if (_privPassphrase != null) {
target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
} else {
target.setSecurityLevel(SecurityLevel.AUTH_NOPRIV);
}
} else {
target.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV);
}
target.setSecurityName(_securityName);
return target;
} else {
CommunityTarget target = new CommunityTarget();
target.setCommunity(_community);
return target;
}
}
public PDU send() throws IOException {
_snmp = createSnmpSession();
this._target = createTarget();
_target.setVersion(_version);
_target.setAddress(_address);
_target.setRetries(_retries);
_target.setTimeout(_timeout);
_snmp.listen();
PDU request = createPDU(_target);
for (int i=0; i<_vbs.size(); i++) {
request.add((VariableBinding)_vbs.get(i));
}
PDU response = null;
if(_operation == WALK) {
response = walk(_snmp, request, _target);
}else{
ResponseEvent responseEvent;
long startTime = System.currentTimeMillis();
responseEvent = _snmp.send(request, _target);
if (responseEvent != null) {
response = responseEvent.getResponse();
System.out.println("Received response after "+
(System.currentTimeMillis()-startTime)+" millis");
}
}
_snmp.close();
return response;
}
protected static void printVariableBindings(PDU response) {
for (int i=0; i<response.size(); i++) {
VariableBinding vb = response.get(i);
System.out.println(vb.toString());
}
}
protected static void printReport(PDU response) {
if (response.size() < 1) {
System.out.println("REPORT PDU does not contain a variable binding.");
return;
}
VariableBinding vb = response.get(0);
OID oid =vb.getOid();
if (SnmpConstants.usmStatsUnsupportedSecLevels.equals(oid)) {
System.out.print("REPORT: Unsupported Security Level.");
} else if (SnmpConstants.usmStatsNotInTimeWindows.equals(oid)) {
System.out.print("REPORT: Message not within time window.");
} else if (SnmpConstants.usmStatsUnknownUserNames.equals(oid)) {
System.out.print("REPORT: Unknown user name.");
} else if (SnmpConstants.usmStatsUnknownEngineIDs.equals(oid)) {
System.out.print("REPORT: Unknown engine id.");
} else if (SnmpConstants.usmStatsWrongDigests.equals(oid)) {
System.out.print("REPORT: Wrong digest.");
} else if (SnmpConstants.usmStatsDecryptionErrors.equals(oid)) {
System.out.print("REPORT: Decryption error.");
} else if (SnmpConstants.snmpUnknownSecurityModels.equals(oid)) {
System.out.print("REPORT: Unknown security model.");
} else if (SnmpConstants.snmpInvalidMsgs.equals(oid)) {
System.out.print("REPORT: Invalid message.");
} else if (SnmpConstants.snmpUnknownPDUHandlers.equals(oid)) {
System.out.print("REPORT: Unknown PDU handler.");
} else if (SnmpConstants.snmpUnavailableContexts.equals(oid)) {
System.out.print("REPORT: Unavailable context.");
} else if (SnmpConstants.snmpUnknownContexts.equals(oid)) {
System.out.print("REPORT: Unknown context.");
} else {
System.out.print("REPORT contains unknown OID ("
+ oid.toString() + ").");
}
System.out.println(" Current counter value is " +
vb.getVariable().toString() + ".");
}
public PDU createPDU(Target target) {
PDU request;
if (_target.getVersion() == SnmpConstants.version3) {
request = new ScopedPDU();
ScopedPDU scopedPDU = (ScopedPDU)request;
if (_contextEngineID != null) {
scopedPDU.setContextEngineID(_contextEngineID);
}
if (_contextName != null) {
scopedPDU.setContextName(_contextName);
}
} else {
request = new PDU();
}
request.setType(_pduType);
return request;
}
private Vector getVariableBinding(String varbind) {
Vector v = new Vector(varbind.length());
String oid = null;
char type = 'i';
String value = null;
int equal = varbind.indexOf("={");
if (equal > 0) {
oid = varbind.substring(0, equal);
type = varbind.charAt(equal+2);
value = varbind.substring(varbind.indexOf('}')+1);
}else{
v.add(new VariableBinding(new OID(varbind)));
return v;
}
VariableBinding vb = new VariableBinding(new OID(oid));
if (value != null) {
Variable variable;
switch (type) {
case 'i':
variable = new Integer32(Integer.parseInt(value));
break;
case 'u':
variable = new UnsignedInteger32(Long.parseLong(value));
break;
case 's':
variable = new OctetString(value);
break;
case 'x':
variable = OctetString.fromString(value, ':', 16);
break;
case 'd':
variable = OctetString.fromString(value, '.', 10);
break;
case 'b':
variable = OctetString.fromString(value, ' ', 2);
break;
case 'n':
variable = new Null();
break;
case 'o':
variable = new OID(value);
break;
case 't':
variable = new TimeTicks(Long.parseLong(value));
break;
case 'a':
variable = new IpAddress(value);
break;
default:
throw new IllegalArgumentException("Variable type "+type+
" not supported");
}
vb.setVariable(variable);
}
v.add(vb);
return v;
}
private static PDU walk(Snmp snmp, PDU request, Target target)
throws IOException {
request.setNonRepeaters(0);
OID rootOID = request.get(0).getOid();
PDU response = null;
int objects = 0;
int requests = 0;
long startTime = System.currentTimeMillis();
do {
requests++;
ResponseEvent responseEvent = _snmp.send(request, target);
response = responseEvent.getResponse();
if (response != null) {
objects += response.size();
}
}
while (!processWalk(response, request, rootOID));
System.out.println();
System.out.println("Total requests sent: "+requests);
System.out.println("Total objects received: "+objects);
System.out.println("Total walk time: "+
(System.currentTimeMillis()-startTime)+" milliseconds");
return response;
}
private static boolean processWalk(PDU response, PDU request, OID rootOID) {
if ((response == null) || (response.getErrorStatus() != 0)
|| (response.getType() == PDU.REPORT)) {
return true;
}
boolean finished = false;
OID lastOID = request.get(0).getOid();
for (int i=0; (!finished) && (i<response.size()); i++) {
VariableBinding vb = response.get(i);
if ((vb.getOid() == null) || (vb.getOid().size() < rootOID.size())
|| (rootOID.leftMostCompare(rootOID.size(), vb.getOid()) != 0)) {
finished = true;
} else if (Null.isExceptionSyntax(vb.getVariable().getSyntax())) {
System.out.println(vb.toString());
finished = true;
} else if (vb.getOid().compareTo(lastOID) <= 0) {
System.out.println("Variable received is not lexicographic successor of requested one:");
System.out.println(vb.toString() + " <= "+lastOID);
finished = true;
} else {
System.out.println(vb.toString());
lastOID = vb.getOid();
}
}
if (response.size() == 0) {
finished = true;
}
if (!finished) {
VariableBinding next = response.get(response.size()-1);
next.setVariable(new Null());
request.set(0, next);
request.setRequestID(new Integer32(0));
}
return finished;
}
public void initReceiver(String host) {
Address address = new UdpAddress(host + "/" + _port);
try {
_transport = new DefaultUdpTransportMapping((UdpAddress) address);
} catch(IOException ioex) {
System.out.println("Unable to bind to local IP and port: " + ioex);
System.exit(-1);
}
_threadPool = ThreadPool.create(this.getClass().getName(), _numThreads);
MessageDispatcher mtDispatcher =
new MultiThreadedMessageDispatcher(_threadPool, new MessageDispatcherImpl());
// add message processing models
mtDispatcher.addMessageProcessingModel(new MPv1());
mtDispatcher.addMessageProcessingModel(new MPv2c());
// add all security protocols
SecurityProtocols.getInstance().addDefaultProtocols();
_snmp = new Snmp(mtDispatcher, _transport);
if(_snmp != null){
_snmp.addCommandResponder(this);
} else {
System.out.println("Unable to create Target object");
System.exit(-1);
}
if(_version == SnmpConstants.version3) {
mtDispatcher.addMessageProcessingModel(new MPv3());
MPv3 mpv3 =
(MPv3)_snmp.getMessageProcessingModel(MessageProcessingModel.MPv3);
USM usm = new USM(SecurityProtocols.getInstance(),
new OctetString(mpv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
if (_authoritativeEngineID != null) {
_snmp.setLocalEngine(_authoritativeEngineID.getValue(), 0, 0);
}
this.addUsmUser(_snmp);
}
}
public synchronized void listen() {
try {
_transport.listen();
} catch(IOException ioex) {
System.out.println("Unable to listen: " + ioex);
System.exit(-1);
}
System.out.println("Waiting for traps..");
try {
this.wait();//Wait for traps to come in
} catch (InterruptedException ex) {
System.out.println("Interrupted while waiting for traps: " + ex);
System.exit(-1);
}
}
public synchronized void processPdu(CommandResponderEvent e) {
PDU command = e.getPDU();
if (command != null) {
System.out.println(command.toString());
if ((command.getType() != PDU.TRAP) &&
(command.getType() != PDU.V1TRAP) &&
(command.getType() != PDU.REPORT) &&
(command.getType() != PDU.RESPONSE)) {
command.setErrorIndex(0);
command.setErrorStatus(0);
command.setType(PDU.RESPONSE);
StatusInformation statusInformation = new StatusInformation();
StateReference ref = e.getStateReference();
try {
e.getMessageDispatcher().returnResponsePdu(e.
getMessageProcessingModel(),
e.getSecurityModel(),
e.getSecurityName(),
e.getSecurityLevel(),
command,
e.getMaxSizeResponsePDU(),
ref,
statusInformation);
}catch (MessageException ex) {
System.err.println("Error while sending response: "+ex.getMessage());
}
}
}
}
public void sendAndProcessResponse() {
try {
PDU response = this.send();
if ((getPduType() == PDU.TRAP) ||
(getPduType() == PDU.REPORT) ||
(getPduType() == PDU.V1TRAP) ||
(getPduType() == PDU.RESPONSE)) {
System.out.println(PDU.getTypeString(getPduType()) +
" sent successfully");
} else if (response == null) {
System.out.println("Request timed out.");
} else if (response.getType() == PDU.REPORT) {
printReport(response);
} else if (getOperation() == WALK) {
System.out.println("End of walked subtree '"+
((VariableBinding)getVariableBindings().get(0)).getOid()+
"' reached at:");
printVariableBindings(response);
} else {
System.out.println("Received something strange: requestID=" +
response.getRequestID() +
", errorIndex=" +
response.getErrorIndex() + ", " +
"errorStatus=" + response.getErrorStatusText()+
"("+response.getErrorStatus()+")");
printVariableBindings(response);
}
} catch (IOException ex) {
System.err.println("Error while trying to send request: " +
ex.getMessage());
ex.printStackTrace();
}
}
private void checkTrapVariables(Vector vbs) {
if ((_pduType == PDU.INFORM) || (_pduType == PDU.TRAP)) {
if ((vbs.size() == 0) ||
((vbs.size() > 1) &&
(!((VariableBinding) vbs.get(0)).getOid().equals(SnmpConstants.
sysUpTime)))) {
vbs.add(0, new VariableBinding(SnmpConstants.sysUpTime, _sysUpTime));
}
if ((vbs.size() == 1) || ((vbs.size() > 2) &&
(!((VariableBinding) vbs.get(1)).getOid().equals(SnmpConstants.
snmpTrapOID)))) {
vbs.add(1, new VariableBinding(SnmpConstants.snmpTrapOID, _trapOID));
}
}
}
}
|