/** * Copyright 2014 Comcast Cable Communications Management, LLC * * This file is part of CATS. * * CATS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * CATS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with CATS. If not, see <http://www.gnu.org/licenses/>. */ package com.comcast.cats; import static com.comcast.cats.service.WebServiceReturnEnum.FAILURE; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; import java.util.Vector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.snmp4j.CommunityTarget; import org.snmp4j.PDU; import org.snmp4j.ScopedPDU; import org.snmp4j.Snmp; import org.snmp4j.Target; import org.snmp4j.TransportMapping; import org.snmp4j.UserTarget; import org.snmp4j.event.ResponseEvent; import org.snmp4j.mp.MPv3; import org.snmp4j.mp.SnmpConstants; import org.snmp4j.security.AuthMD5; import org.snmp4j.security.PrivDES; import org.snmp4j.security.SecurityLevel; import org.snmp4j.security.SecurityModels; import org.snmp4j.security.SecurityProtocols; import org.snmp4j.security.USM; import org.snmp4j.security.UsmUser; import org.snmp4j.smi.Address; import org.snmp4j.smi.Counter32; import org.snmp4j.smi.Counter64; import org.snmp4j.smi.Gauge32; import org.snmp4j.smi.Integer32; import org.snmp4j.smi.IpAddress; import org.snmp4j.smi.Null; import org.snmp4j.smi.OID; import org.snmp4j.smi.OctetString; import org.snmp4j.smi.SMIConstants; import org.snmp4j.smi.TcpAddress; import org.snmp4j.smi.TimeTicks; import org.snmp4j.smi.UdpAddress; import org.snmp4j.smi.UnsignedInteger32; import org.snmp4j.smi.VariableBinding; import org.snmp4j.transport.DefaultUdpTransportMapping; import com.comcast.cats.info.SetValueTypes; import com.comcast.cats.info.SnmpServiceReturnEnum; import com.comcast.cats.info.SnmpServiceReturnMesage; import com.comcast.cats.info.SnmpWalkResult; /** * Snmp4j specific implementation of the SnmpManager. Supports V1,V2 & V3 * versions of SNMP get and set operations. * * @author TATA * @bemman01c : modified to add info log messages for set and get operations. * processResponse() method has been modified to handle SNMP errors. * */ public class SnmpManagerImpl implements SnmpManager { /** * Holds the snmp engine boot up count for snmp V3. */ private static final int DEFAULT_ENGINE_REBOOTS = 0; /** * The log4j logger instance for this class. */ private static Logger logger = LoggerFactory.getLogger( SnmpManagerImpl.class ); /** * The snmp object that performs the underlying set and get operation. */ private Snmp snmp; /** * GET operation for V1 and V2 versions of SNMP messages.This will return * error message when oId or target IP is null and otherwise returns the * correct value. * * @param oId * Object identifier representing the functionality * @param communityName * Community Name (by default public) * @param targetIP * IP address of target machine * @param portNumber * Port number (by default 161) * @return SnmpServiceReturnMesage represents the return value and status */ @Override public SnmpServiceReturnMesage get( final String oId, String communityName, final String targetIP, int portNumber ) { ResponseEvent responseEvent = null; final boolean isVersion3Message = false; SnmpServiceReturnMesage snmpServiceReturnMessage = new SnmpServiceReturnMesage(); if ( ( null == oId ) || ( null == targetIP ) || ( !SnmpUtil.isValidIp( targetIP ) ) || ( !SnmpUtil.isValidOid( oId ) ) ) { snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_INVALID_INPUT ); snmpServiceReturnMessage.setResult( FAILURE ); if ( logger.isDebugEnabled() ) { logger.debug( "Either IP or OID is invalid: IP=" + targetIP + ", OID=" + oId ); } } else { try { // Set default community name and port number if ( null == communityName || communityName.isEmpty() ) { communityName = DEFAULT_COMMUNITY_NAME; } if ( portNumber <= INVALID_VALUE ) { portNumber = DEFAULT_PORT_NUMBER; } final Target target = setUpTarget( communityName, targetIP, portNumber ); if ( logger.isDebugEnabled() ) { logger.debug( "Sending SNMP V1/V2 GET request" ); } final PDU pdu = createGetPDU( oId, isVersion3Message ); responseEvent = snmp.get( pdu, target ); snmp.close(); snmpServiceReturnMessage = processResponse( responseEvent ); } catch ( IOException e ) { logger.error("{}", e ); snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_FAILURE ); snmpServiceReturnMessage.setResult( FAILURE ); snmpServiceReturnMessage.setMessage( e.getMessage() ); } } logger.info("Get request for OID"+oId+", target:"+targetIP+" Result:"+snmpServiceReturnMessage.getResult() +" Result message:"+snmpServiceReturnMessage.getMessage()); return snmpServiceReturnMessage; } /** * GET operation for V3 version of SNMP messages.This will return error * message when oId or target IP or userName or authenticatePassword or * privacyPassword is null and otherwise returns the correct value. * * @param oId * Object identifier representing the functionality. * @param targetIP * IP address of target machine * @param portNumber * Port number (by default 161) * @param userName * the security name of the user * @param authenticatePassword * the authentication password * @param privacyPassword * he privacy password * @return SnmpServiceReturnMesage represents the return value and status */ @Override public SnmpServiceReturnMesage get( final String oId, final String targetIP, int portNumber, final String userName, final String authenticatePassword, final String privacyPassword ) { ResponseEvent responseEvent = null; final boolean isVersion3Message = true; SnmpServiceReturnMesage snmpServiceReturnMessage = new SnmpServiceReturnMesage(); if ( ( null == oId ) || ( null == targetIP ) || ( null == userName ) || ( null == authenticatePassword ) || ( null == privacyPassword ) || ( userName.isEmpty() ) || ( privacyPassword.isEmpty() ) || ( authenticatePassword.isEmpty() ) || ( !SnmpUtil.isValidIp( targetIP ) ) || ( !SnmpUtil.isValidOid( oId ) ) || ( !SnmpUtil.isValidPassword( authenticatePassword ) ) || ( !SnmpUtil.isValidPassword( privacyPassword ) ) ) { snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_INVALID_INPUT ); snmpServiceReturnMessage.setResult( FAILURE ); if ( logger.isDebugEnabled() ) { logger.debug( "One of the input parameters is invalid: IP=" + targetIP + ", OID=" + oId + ", User Name=" + userName + ", Authentication Password=" + authenticatePassword + ", Privacy Password=" + privacyPassword ); } } else { try { // Set port number if ( portNumber <= INVALID_VALUE ) { portNumber = DEFAULT_PORT_NUMBER; } final UserTarget userTarget = setUpTarget( targetIP, portNumber, userName, authenticatePassword, privacyPassword ); final PDU pdu = createGetPDU( oId, isVersion3Message ); if ( logger.isDebugEnabled() ) { logger.debug( "Sending SNMP V3 GET request" ); } responseEvent = snmp.get( pdu, userTarget ); snmp.close(); snmpServiceReturnMessage = processResponse( responseEvent ); } catch ( IOException e ) { logger.error( "{}", e ); snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_FAILURE ); snmpServiceReturnMessage.setResult( FAILURE ); snmpServiceReturnMessage.setMessage( e.getMessage() ); } } logger.info("Get request for OID"+oId+", target:"+targetIP+" Result:"+snmpServiceReturnMessage.getResult() +" Result message:"+snmpServiceReturnMessage.getMessage()); return snmpServiceReturnMessage; } @Override public SnmpServiceReturnMesage walk(final String oId, String communityName, final String targetIP, int portNumber) { logger.debug( " Walk request started for {} ", oId ); ResponseEvent responseEvent = null; final boolean isVersion3Message = false; SnmpServiceReturnMesage snmpServiceReturnMessage = new SnmpServiceReturnMesage(); if ( ( null == oId ) || ( null == targetIP ) || ( !SnmpUtil.isValidIp( targetIP ) ) || ( !SnmpUtil.isValidOid( oId ) ) ) { snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_INVALID_INPUT ); snmpServiceReturnMessage.setResult( FAILURE ); if ( logger.isDebugEnabled() ) { logger.debug( "Either IP or OID is invalid: IP=" + targetIP + ", OID=" + oId ); } } else { try { // Set default community name and port number if ( null == communityName || communityName.isEmpty() ) { communityName = DEFAULT_COMMUNITY_NAME; } if ( portNumber <= INVALID_VALUE ) { portNumber = DEFAULT_PORT_NUMBER; } final Target target = setUpTarget( communityName, targetIP, portNumber ); if ( logger.isDebugEnabled() ) { logger.debug( "Sending SNMP V1/V2 GET request" ); } boolean isWalkComplete = false; PDU pdu = null; PDU responsePDU = null; pdu = createGetNextPDU(oId, isVersion3Message ); VariableBinding vb = null; OID targetOID = new OID(oId); List<SnmpWalkResult> resultData = new ArrayList< SnmpWalkResult >(); String message = ""; while ( !isWalkComplete ) { responseEvent = snmp.getNext( pdu, target ); responsePDU = responseEvent.getResponse(); if ( responsePDU != null ) { vb = responsePDU.get( 0 ); } if ( responsePDU == null ) { message = "Empty Response"; isWalkComplete = true; } else if ( responsePDU.getErrorStatus() != 0 ) { message = responsePDU.getErrorStatusText(); isWalkComplete = true; } else if ( vb.getOid() == null ) { message = "Empty OID"; isWalkComplete = true; } else if ( vb.getOid().size() < targetOID.size() ) { message = "Response OID length shorter than target OID"; isWalkComplete = true; } else if ( targetOID.leftMostCompare( targetOID.size(), vb.getOid() ) != 0 ) { message = "Base OID changes"; isWalkComplete = true; } else if ( Null.isExceptionSyntax( vb.getVariable().getSyntax() ) ) { message = " Variable Syntax Error"; isWalkComplete = true; } else if ( vb.getOid().compareTo( targetOID ) <= 0 ) { message = " Received variable is not successor of requested"; isWalkComplete = true; } else { SnmpWalkResult snmpWalkResult = new SnmpWalkResult(); snmpWalkResult.setOid( vb.getOid().toString() ); snmpWalkResult.setValue( vb.toValueString() ); resultData.add(snmpWalkResult ); // Reinitialise the PDU. pdu.setRequestID( new Integer32( 0 ) ); pdu.set( 0, vb ); } } if ( null != resultData && !resultData.isEmpty() ) { snmpServiceReturnMessage.setComplexResultObject( resultData ); } else { snmpServiceReturnMessage.setMessage( message ); snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_FAILURE ); } snmp.close(); } catch ( IOException e ) { logger.error("{}", e ); snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_FAILURE ); snmpServiceReturnMessage.setResult( FAILURE ); snmpServiceReturnMessage.setMessage( e.getMessage() ); } } logger.info("Walk request for OID"+oId+", target:"+targetIP+" Result:"+snmpServiceReturnMessage.getComplexResultObject() +" Result message:"+snmpServiceReturnMessage.getMessage()); return snmpServiceReturnMessage; } /** * SET operation for V1 and V2 versions of SNMP messages.This will return * error message when oId or target IP is null otherwise returns the newly * set value and status of operation. * * @param oId * Object identifier representing the functionality to be set. * @param communityName * Community Name (by default public) * @param targetIP * IP address of target machine * @param portNumber * Port number (by default 161) * @param value * Value to be set * @param type * type to the value to be set * @return SnmpServiceReturnMesage represents the value that is set and * status of operation */ @Override public SnmpServiceReturnMesage set( final String oId, String communityName, final String targetIP, int portNumber, final String value, final String type ) { ResponseEvent responseEvent = null; final boolean isVersion3Message = false; SnmpServiceReturnMesage snmpServiceReturnMessage = new SnmpServiceReturnMesage(); if ( ( null == oId ) || ( null == targetIP ) || ( !SnmpUtil.isValidIp( targetIP ) ) || ( !SnmpUtil.isValidOid( oId ) ) ) { snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_INVALID_INPUT ); snmpServiceReturnMessage.setResult( FAILURE ); if ( logger.isDebugEnabled() ) { logger.debug( "Either IP or OID is invalid: IP=" + targetIP + ", OID=" + oId ); } } else { try { // Set default community name and port number if ( null == communityName || communityName.isEmpty() ) { communityName = DEFAULT_COMMUNITY_NAME; } if ( portNumber <= INVALID_VALUE ) { portNumber = DEFAULT_PORT_NUMBER; } final Target target = setUpTarget( communityName, targetIP, portNumber ); final PDU pdu = createSetPDU( oId, value, type, isVersion3Message ); if ( logger.isDebugEnabled() ) { logger.debug( "Sending SNMP V1/V2 SET request" ); } responseEvent = snmp.send( pdu, target ); snmp.close(); snmpServiceReturnMessage = processResponse( responseEvent ); } catch ( NumberFormatException e ) { logger.error( "{}", e ); snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_FAILURE ); snmpServiceReturnMessage.setResult( FAILURE ); snmpServiceReturnMessage.setMessage( e.getMessage() ); } catch ( IllegalArgumentException e ) { logger.error( "{}", e ); snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_FAILURE ); snmpServiceReturnMessage.setResult( FAILURE ); snmpServiceReturnMessage.setMessage( e.getMessage() ); } catch ( UnknownHostException e ) { logger.error( "{}", e ); snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_FAILURE ); snmpServiceReturnMessage.setResult( FAILURE ); snmpServiceReturnMessage.setMessage( e.getMessage() ); } catch ( IOException e ) { logger.error( "{}", e ); snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_FAILURE ); snmpServiceReturnMessage.setResult( FAILURE ); snmpServiceReturnMessage.setMessage( e.getMessage() ); } } logger.info("Set request for OID"+oId+", target ip:"+targetIP+"value"+value+", Result:"+snmpServiceReturnMessage.getResult() +" Result message:"+snmpServiceReturnMessage.getMessage()); return snmpServiceReturnMessage; } /** * SET operation for V3 version of SNMP messages.This will return error * message when oId or target IP or userName or authenticatePassword or * privacyPassword is null otherwise returns the newly set value and status * of operation. * * @param oId * Object identifier representing the functionality to be set. * @param targetIP * IP address of target machine * @param portNumber * Port number (by default 161) * @param value * Value to be set * @param type * type to the value to be set * @param userName * the security name of the user * @param authenticatePassword * the authentication password * @param privacyPassword * the privacy password * @return SnmpServiceReturnMesage represents the value that is set and * status of operation */ @Override public SnmpServiceReturnMesage set( final String oId, final String targetIP, int portNumber, final String value, final String type, final String userName, final String authenticatePassword, final String privacyPassword ) { ResponseEvent responseEvent = null; final boolean isVersion3Message = true; SnmpServiceReturnMesage snmpServiceReturnMessage = new SnmpServiceReturnMesage(); if ( ( null == oId ) || ( null == targetIP ) || ( null == userName ) || ( null == authenticatePassword ) || ( null == privacyPassword ) || ( userName.isEmpty() ) || ( privacyPassword.isEmpty() ) || ( authenticatePassword.isEmpty() ) || ( !SnmpUtil.isValidIp( targetIP ) ) || ( !SnmpUtil.isValidOid( oId ) ) || ( !SnmpUtil.isValidPassword( authenticatePassword ) ) || ( !SnmpUtil.isValidPassword( privacyPassword ) ) ) { snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_INVALID_INPUT ); snmpServiceReturnMessage.setResult( FAILURE ); if ( logger.isDebugEnabled() ) { logger.debug( "One of the input parameters is invalid: IP=" + targetIP + ", OID=" + oId + ", User Name=" + userName + ", Authentication Password=" + authenticatePassword + ", Privacy Password=" + privacyPassword ); } } else { try { // Set port number if ( portNumber <= INVALID_VALUE ) { portNumber = DEFAULT_PORT_NUMBER; } final UserTarget userTarget = setUpTarget( targetIP, portNumber, userName, authenticatePassword, privacyPassword ); final PDU pdu = createSetPDU( oId, value, type, isVersion3Message ); if ( logger.isDebugEnabled() ) { logger.debug( "Sending SNMP V3 SET request" ); } responseEvent = snmp.send( pdu, userTarget ); snmp.close(); snmpServiceReturnMessage = processResponse( responseEvent ); } catch ( NumberFormatException e ) { logger.error( "{}", e ); snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_FAILURE ); snmpServiceReturnMessage.setResult( FAILURE ); snmpServiceReturnMessage.setMessage( e.getMessage() ); } catch ( IllegalArgumentException e ) { logger.error( "{}", e ); snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_FAILURE ); snmpServiceReturnMessage.setResult( FAILURE ); snmpServiceReturnMessage.setMessage( e.getMessage() ); } catch ( UnknownHostException e ) { logger.error( "{}", e ); snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_FAILURE ); snmpServiceReturnMessage.setResult( FAILURE ); snmpServiceReturnMessage.setMessage( e.getMessage() ); } catch ( IOException e ) { logger.error( "{}", e ); snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_FAILURE ); snmpServiceReturnMessage.setResult( FAILURE ); snmpServiceReturnMessage.setMessage( e.getMessage() ); } } logger.info("Set request for OID"+oId+", target ip:"+targetIP+"value"+value+", Result:"+snmpServiceReturnMessage.getResult() +" Result message:"+snmpServiceReturnMessage.getMessage()); return snmpServiceReturnMessage; } /** * Helper method that initializes the snmp target to listening mode. This * method is explicitly for V1 and V2 messages. This method will create and * set up the TransportMapping and target for SNMP V1 and V2. It creates a * TransportMapping and puts it in the listening mode. Also Creates * CommunityTarget object and sets SNMP target properties. * * @param communityName * Community name of the target * @param targetIP * IP address of Target machine * @param portNumber * Port number * @return The Target created * @throws IOException * IOException */ private Target setUpTarget( final String communityName, final String targetIP, final int portNumber ) throws IOException { final InetAddress inetAddress = InetAddress.getByName( targetIP ); final Address address = new UdpAddress( inetAddress, portNumber ); final OctetString community = new OctetString( communityName ); final TransportMapping transport = new DefaultUdpTransportMapping(); snmp = new Snmp( transport ); snmp.listen(); // Creating the communityTarget object and setting its properties final CommunityTarget communityTarget = new CommunityTarget(); communityTarget.setCommunity( community ); // TODO Needs to check also for v2 messages communityTarget.setVersion( SnmpConstants.version1 ); communityTarget.setAddress( address ); // TODO Need to confirm, whether this value needs to be configures communityTarget.setRetries( SnmpManager.DEFAULT_RETRIES ); // TODO Need to confirm, whether this value needs to be configures communityTarget.setTimeout( SnmpManager.DEFAULT_TIMEOUT ); return communityTarget; } /** * Helper method that initializes the snmp target to listening mode. This * method is explicitly for V3 messages. This method will create and set up * the TransportMapping and target for SNMP V3. It creates a * TransportMapping and puts it in the listening mode. Also Creates * CommunityTarget object and sets SNMP target properties. * * @param targetIP * IP address of Target machine * @param portNumber * Port number * @param userName * The security name of the user * @param authenticatePassword * The authentication password * @param privacyPassword * The privacy password * @return The created UserTarget * @throws IOException * IOException */ private UserTarget setUpTarget( final String targetIP, final int portNumber, final String userName, final String authenticatePassword, final String privacyPassword ) throws IOException { // Creates a TransportMapping and puts the transport mapping in to // listen mode final TransportMapping transportMapping = new DefaultUdpTransportMapping(); snmp = new Snmp( transportMapping ); transportMapping.listen(); // Creating a USM with the support for the supplied security protocols final SecurityProtocols securityProtocols = SecurityProtocols.getInstance(); securityProtocols.addDefaultProtocols(); final OctetString engineId = new OctetString( MPv3.createLocalEngineID() ); final USM usm = new USM( securityProtocols, engineId, DEFAULT_ENGINE_REBOOTS ); SecurityModels.getInstance().addSecurityModel( usm ); final OctetString username = new OctetString( userName ); final OctetString authenticationPassphrase = new OctetString( authenticatePassword ); final OctetString privacyPassphrase = new OctetString( privacyPassword ); // Creating UsmUser and adds the UsmUser to the internal user name table // TODO Need to confirm, whether AuthMD5 and PrivDES needs to be changed final UsmUser usmuser = new UsmUser( username, AuthMD5.ID, authenticationPassphrase, PrivDES.ID, privacyPassphrase ); snmp.getUSM().addUser( username, usmuser ); // Create a target for a user based security model target and setting // its properties final UserTarget userTarget = new UserTarget(); final InetAddress inetAddress = InetAddress.getByName( targetIP ); final Address address = new UdpAddress( inetAddress, portNumber ); userTarget.setAddress( address ); // TODO Need to confirm, whether this value needs to be configures userTarget.setRetries( SnmpManager.DEFAULT_RETRIES ); // TODO Need to confirm, whether this value needs to be configures userTarget.setTimeout( SnmpManager.DEFAULT_TIMEOUT ); userTarget.setVersion( SnmpConstants.version3 ); // TODO Need to confirm, whether this value needs to be configures userTarget.setSecurityLevel( SecurityLevel.AUTH_PRIV ); userTarget.setSecurityName( username ); return userTarget; } /** * * This method is creating and returning a GET PDU. This method creates * ScopedPDU object if the SNMP Version is 3 else PDU object and sets the * PDU type as GET. It also creates a VariableBinding with the supplied * Object Identifier and a Null value, and adding it to the PDU. * * @param oId * Object identifier * @param isSNMPV3 * True for SNMP Version 3 else false * @return The created GET PDU * @throws IOException * IOException */ private PDU createGetPDU( final String oId, final boolean isSNMPV3 ) throws IOException { PDU pdu = null; final OID oid = new OID( oId ); if ( isSNMPV3 ) { pdu = new ScopedPDU(); } else { pdu = new PDU(); } pdu.setType( PDU.GET ); final VariableBinding varBinding = new VariableBinding( oid ); pdu.add( varBinding ); return pdu; } /** * * This method is creating and returning a GET PDU. This method creates * ScopedPDU object if the SNMP Version is 3 else PDU object and sets the * PDU type as GET. It also creates a VariableBinding with the supplied * Object Identifier and a Null value, and adding it to the PDU. * * @param oId * Object identifier * @param isSNMPV3 * True for SNMP Version 3 else false * @return The created GET PDU * @throws IOException * IOException */ private PDU createGetNextPDU( final String oId, final boolean isSNMPV3 ) throws IOException { PDU pdu = null; final OID oid = new OID( oId ); if ( isSNMPV3 ) { pdu = new ScopedPDU(); } else { pdu = new PDU(); } pdu.setType( PDU.GETNEXT ); final VariableBinding varBinding = new VariableBinding( oid ); pdu.add( varBinding ); return pdu; } /** * This method is creating and returning a SET PDU. It creates ScopedPDU * object if the SNMP Version is 3 else PDU object and sets the PDU type as * SET. It also creates a VariableBinding with the supplied Object * Identifier and value,depending on the type of the value to be set and * adding it to the PDU. * * @param oId * Object identifier * @param value * The value to be set * @param type * The Type of the value to be set as per rfc2570 * [INTEGER,COUNTER32 * ,COUNTER64,GAUGE32,UNSIGNEDINTEGER32,TIMETICKS, * OID,IPADDRESS,TCPADDRESS,UDPADDRESS,STRING] * @param isSNMPV3 * True for SNMP Version 3 else false * @return The created SET PDU * @throws IOException * @throws IllegalArgumentException */ private PDU createSetPDU( final String oId, final String value, final String type, final boolean isSNMPV3 ) throws IOException { VariableBinding varBinding = null; PDU pdu = null; final OID oid = new OID( oId ); final Long valuetoset; // Taking the value of the type of the value to be set as enum constant // for each type the value will be bind to the OID in different manner SetValueTypes setValueType = SetValueTypes.valueOf( type.toUpperCase() ); switch ( setValueType ) { case INTEGER: final Integer intValue = Integer.parseInt( value ); final Integer32 setInteger32Value = new Integer32( intValue ); varBinding = new VariableBinding( oid, setInteger32Value ); break; case COUNTER32: valuetoset = Long.parseLong( value ); final Counter32 setCounter32Value = new Counter32( valuetoset ); varBinding = new VariableBinding( oid, setCounter32Value ); break; case COUNTER64: valuetoset = Long.parseLong( value ); final Counter64 setCounter64Value = new Counter64( valuetoset ); varBinding = new VariableBinding( oid, setCounter64Value ); break; case GAUGE32: valuetoset = Long.parseLong( value ); final Gauge32 setGauge32Value = new Gauge32( valuetoset ); varBinding = new VariableBinding( oid, setGauge32Value ); break; case UNSIGNEDINTEGER32: valuetoset = Long.parseLong( value ); final UnsignedInteger32 setUnsignedInteger32Value = new UnsignedInteger32( valuetoset ); varBinding = new VariableBinding( oid, setUnsignedInteger32Value ); break; case TIMETICKS: valuetoset = Long.parseLong( value ); final TimeTicks setTimeTicksValue = new TimeTicks( valuetoset ); varBinding = new VariableBinding( oid, setTimeTicksValue ); break; case STRING: final OctetString setValue = new OctetString( value ); varBinding = new VariableBinding( oid, setValue ); break; case OID: final OID setOIDValue = new OID( value ); varBinding = new VariableBinding( oid, setOIDValue ); break; case IPADDRESS: final IpAddress setIpAddressValue = new IpAddress( value ); varBinding = new VariableBinding( oid, setIpAddressValue ); break; case TCPADDRESS: final TcpAddress setTcpAddressValue = new TcpAddress( value ); varBinding = new VariableBinding( oid, setTcpAddressValue ); break; case UDPADDRESS: final UdpAddress setUdpAddressValue = new UdpAddress( value ); varBinding = new VariableBinding( oid, setUdpAddressValue ); break; default: final OctetString setdefaultValue = new OctetString( value ); varBinding = new VariableBinding( oid, setdefaultValue ); break; } if ( isSNMPV3 ) { pdu = new ScopedPDU(); } else { pdu = new PDU(); } pdu.setType( PDU.SET ); pdu.add( varBinding ); return pdu; } /** * Helper method for creating SnmpServiceReturnMesage from the response got * from the snmp device. This method will process the ResponseEvent and * returns the SnmpServiceReturnMesage object with the operation result or * appropriate error information. The ResponseEvent will be null if the sent * PDU is an unconfirmed PDU(notification, response, or report) and * ResponseEvent.getResponse() will be null if the request is timed out. * * @param responseEvent * ResponseEvent got from the snmp set/get operations * @return SnmpServiceReturnMesage Represents the status of operation */ private SnmpServiceReturnMesage processResponse( final ResponseEvent responseEvent ) { final SnmpServiceReturnMesage snmpServiceReturnMessage = new SnmpServiceReturnMesage(); boolean isResponded = false; if ( null != responseEvent ) { final PDU resultPdu = responseEvent.getResponse(); if ( null != resultPdu ) { //check if there is any error in the SNMP operation and return error immediately if(resultPdu.getErrorStatus()!=SnmpConstants.SNMP_ERROR_SUCCESS){ snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_FAILURE ); snmpServiceReturnMessage.setResult( FAILURE ); snmpServiceReturnMessage.setSnmpErrorCode(resultPdu.getErrorStatus()); snmpServiceReturnMessage.setMessage( resultPdu.getErrorStatusText()); //NOTE: if there is an error we will return from here. return snmpServiceReturnMessage; } final Vector< VariableBinding > variableBindings = resultPdu.getVariableBindings(); if ((null != variableBindings) && !variableBindings.isEmpty()) { // Getting the first VariableBinding, since we are attaching // a single VariableBinding with the set/get PDU. final VariableBinding varBinding = variableBindings .firstElement(); // Getting the variable value associated with the OID if (varBinding != null) { String result = ""; switch (varBinding.getSyntax()) { case SMIConstants.SYNTAX_TIMETICKS: result += varBinding.getVariable().toLong(); logger.debug(result); break; default: result = varBinding.getVariable().toString(); break; } snmpServiceReturnMessage.setResultObject(result); isResponded = true; } } if (!isResponded) { snmpServiceReturnMessage .setServiceCode(SnmpServiceReturnEnum.SNMP_SERVICE_FAILURE); snmpServiceReturnMessage.setResult(FAILURE); snmpServiceReturnMessage .setMessage("Response received from device is not valid"); snmpServiceReturnMessage .setSnmpErrorCode(SnmpConstants.SNMP_ERROR_GENERAL_ERROR); } } else { logger.error( "Request timed out" ); snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_TIME_OUT ); snmpServiceReturnMessage.setResult( FAILURE ); snmpServiceReturnMessage.setMessage( "Request timed out" ); snmpServiceReturnMessage.setSnmpErrorCode(SnmpConstants.SNMP_ERROR_GENERAL_ERROR); } } else { logger.error( "Invalid PDU" ); snmpServiceReturnMessage.setServiceCode( SnmpServiceReturnEnum.SNMP_SERVICE_FAILURE ); snmpServiceReturnMessage.setResult( FAILURE ); snmpServiceReturnMessage.setMessage( "Invalid PDU" ); snmpServiceReturnMessage.setSnmpErrorCode(SnmpConstants.SNMP_ERROR_GENERAL_ERROR); } return snmpServiceReturnMessage; } }