|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
package com.sun.jmx.snmp; |
|
|
|
// java imports |
|
|
|
import java.util.Vector; |
|
import java.util.logging.Level; |
|
import java.net.InetAddress; |
|
|
|
// import debug stuff |
|
|
|
import static com.sun.jmx.defaults.JmxProperties.SNMP_LOGGER; |
|
import com.sun.jmx.snmp.internal.SnmpMsgProcessingSubSystem; |
|
import com.sun.jmx.snmp.internal.SnmpSecurityModel; |
|
import com.sun.jmx.snmp.internal.SnmpDecryptedPdu; |
|
import com.sun.jmx.snmp.internal.SnmpSecurityCache; |
|
|
|
import com.sun.jmx.snmp.SnmpMsg; |
|
import com.sun.jmx.snmp.SnmpPdu; |
|
import com.sun.jmx.snmp.SnmpStatusException; |
|
import com.sun.jmx.snmp.SnmpTooBigException; |
|
import com.sun.jmx.snmp.SnmpScopedPduBulk; |
|
import com.sun.jmx.snmp.BerException; |
|
import com.sun.jmx.snmp.SnmpScopedPduRequest; |
|
import com.sun.jmx.snmp.BerDecoder; |
|
import com.sun.jmx.snmp.SnmpDefinitions; |
|
import com.sun.jmx.snmp.SnmpEngineId; |
|
import com.sun.jmx.snmp.SnmpScopedPduPacket; |
|
import com.sun.jmx.snmp.BerEncoder; |
|
import com.sun.jmx.snmp.SnmpPduRequestType; |
|
import com.sun.jmx.snmp.SnmpPduBulkType; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public class SnmpV3Message extends SnmpMsg { |
|
|
|
|
|
|
|
*/ |
|
public int msgId = 0; |
|
|
|
|
|
|
|
*/ |
|
public int msgMaxSize = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public byte msgFlags = 0; |
|
|
|
|
|
*/ |
|
public int msgSecurityModel = 0; |
|
|
|
|
|
*/ |
|
public byte[] msgSecurityParameters = null; |
|
|
|
|
|
*/ |
|
public byte[] contextEngineId = null; |
|
|
|
|
|
*/ |
|
public byte[] contextName = null; |
|
|
|
*/ |
|
public byte[] encryptedPdu = null; |
|
|
|
|
|
|
|
|
|
*/ |
|
public SnmpV3Message() { |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public int encodeMessage(byte[] outputBytes) |
|
throws SnmpTooBigException { |
|
int encodingLength = 0; |
|
if (SNMP_LOGGER.isLoggable(Level.FINER)) { |
|
SNMP_LOGGER.logp(Level.FINER, SnmpV3Message.class.getName(), |
|
"encodeMessage", |
|
"Can't encode directly V3Message! Need a SecuritySubSystem"); |
|
} |
|
throw new IllegalArgumentException("Can't encode"); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void decodeMessage(byte[] inputBytes, int byteCount) |
|
throws SnmpStatusException { |
|
|
|
try { |
|
BerDecoder bdec = new BerDecoder(inputBytes); |
|
bdec.openSequence(); |
|
version = bdec.fetchInteger(); |
|
bdec.openSequence(); |
|
msgId = bdec.fetchInteger(); |
|
msgMaxSize = bdec.fetchInteger(); |
|
msgFlags = bdec.fetchOctetString()[0]; |
|
msgSecurityModel =bdec.fetchInteger(); |
|
bdec.closeSequence(); |
|
msgSecurityParameters = bdec.fetchOctetString(); |
|
if( (msgFlags & SnmpDefinitions.privMask) == 0 ) { |
|
bdec.openSequence(); |
|
contextEngineId = bdec.fetchOctetString(); |
|
contextName = bdec.fetchOctetString(); |
|
data = bdec.fetchAny(); |
|
dataLength = data.length; |
|
bdec.closeSequence(); |
|
} |
|
else { |
|
encryptedPdu = bdec.fetchOctetString(); |
|
} |
|
bdec.closeSequence() ; |
|
} |
|
catch(BerException x) { |
|
x.printStackTrace(); |
|
throw new SnmpStatusException("Invalid encoding") ; |
|
} |
|
|
|
if (SNMP_LOGGER.isLoggable(Level.FINER)) { |
|
final StringBuilder strb = new StringBuilder() |
|
.append("Unmarshalled message : \n") |
|
.append("version : ").append(version) |
|
.append("\n") |
|
.append("msgId : ").append(msgId) |
|
.append("\n") |
|
.append("msgMaxSize : ").append(msgMaxSize) |
|
.append("\n") |
|
.append("msgFlags : ").append(msgFlags) |
|
.append("\n") |
|
.append("msgSecurityModel : ").append(msgSecurityModel) |
|
.append("\n") |
|
.append("contextEngineId : ").append(contextEngineId == null ? null : |
|
SnmpEngineId.createEngineId(contextEngineId)) |
|
.append("\n") |
|
.append("contextName : ").append(contextName) |
|
.append("\n") |
|
.append("data : ").append(data) |
|
.append("\n") |
|
.append("dat len : ").append((data == null) ? 0 : data.length) |
|
.append("\n") |
|
.append("encryptedPdu : ").append(encryptedPdu) |
|
.append("\n"); |
|
SNMP_LOGGER.logp(Level.FINER, SnmpV3Message.class.getName(), |
|
"decodeMessage", strb.toString()); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public int getRequestId(byte[] data) throws SnmpStatusException { |
|
BerDecoder bdec = null; |
|
int msgId = 0; |
|
try { |
|
bdec = new BerDecoder(data); |
|
bdec.openSequence(); |
|
bdec.fetchInteger(); |
|
bdec.openSequence(); |
|
msgId = bdec.fetchInteger(); |
|
}catch(BerException x) { |
|
throw new SnmpStatusException("Invalid encoding") ; |
|
} |
|
try { |
|
bdec.closeSequence(); |
|
} |
|
catch(BerException x) { |
|
} |
|
|
|
return msgId; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void encodeSnmpPdu(SnmpPdu p, |
|
int maxDataLength) |
|
throws SnmpStatusException, SnmpTooBigException { |
|
|
|
SnmpScopedPduPacket pdu = (SnmpScopedPduPacket) p; |
|
|
|
if (SNMP_LOGGER.isLoggable(Level.FINER)) { |
|
final StringBuilder strb = new StringBuilder() |
|
.append("PDU to marshall: \n") |
|
.append("security parameters : ").append(pdu.securityParameters) |
|
.append("\n") |
|
.append("type : ").append(pdu.type) |
|
.append("\n") |
|
.append("version : ").append(pdu.version) |
|
.append("\n") |
|
.append("requestId : ").append(pdu.requestId) |
|
.append("\n") |
|
.append("msgId : ").append(pdu.msgId) |
|
.append("\n") |
|
.append("msgMaxSize : ").append(pdu.msgMaxSize) |
|
.append("\n") |
|
.append("msgFlags : ").append(pdu.msgFlags) |
|
.append("\n") |
|
.append("msgSecurityModel : ").append(pdu.msgSecurityModel) |
|
.append("\n") |
|
.append("contextEngineId : ").append(pdu.contextEngineId) |
|
.append("\n") |
|
.append("contextName : ").append(pdu.contextName) |
|
.append("\n"); |
|
SNMP_LOGGER.logp(Level.FINER, SnmpV3Message.class.getName(), |
|
"encodeSnmpPdu", strb.toString()); |
|
} |
|
|
|
version = pdu.version; |
|
address = pdu.address; |
|
port = pdu.port; |
|
msgId = pdu.msgId; |
|
msgMaxSize = pdu.msgMaxSize; |
|
msgFlags = pdu.msgFlags; |
|
msgSecurityModel = pdu.msgSecurityModel; |
|
|
|
contextEngineId = pdu.contextEngineId; |
|
contextName = pdu.contextName; |
|
|
|
securityParameters = pdu.securityParameters; |
|
|
|
// |
|
// Allocate the array to receive the encoding. |
|
|
|
data = new byte[maxDataLength]; |
|
|
|
// |
|
// Encode the pdu |
|
// Reminder: BerEncoder does backward encoding ! |
|
// |
|
|
|
try { |
|
BerEncoder benc = new BerEncoder(data) ; |
|
benc.openSequence() ; |
|
encodeVarBindList(benc, pdu.varBindList) ; |
|
|
|
switch(pdu.type) { |
|
|
|
case pduGetRequestPdu : |
|
case pduGetNextRequestPdu : |
|
case pduInformRequestPdu : |
|
case pduGetResponsePdu : |
|
case pduSetRequestPdu : |
|
case pduV2TrapPdu : |
|
case pduReportPdu : |
|
SnmpPduRequestType reqPdu = (SnmpPduRequestType) pdu; |
|
benc.putInteger(reqPdu.getErrorIndex()); |
|
benc.putInteger(reqPdu.getErrorStatus()); |
|
benc.putInteger(pdu.requestId); |
|
break; |
|
|
|
case pduGetBulkRequestPdu : |
|
SnmpPduBulkType bulkPdu = (SnmpPduBulkType) pdu; |
|
benc.putInteger(bulkPdu.getMaxRepetitions()); |
|
benc.putInteger(bulkPdu.getNonRepeaters()); |
|
benc.putInteger(pdu.requestId); |
|
break ; |
|
|
|
default: |
|
throw new SnmpStatusException("Invalid pdu type " + String.valueOf(pdu.type)) ; |
|
} |
|
benc.closeSequence(pdu.type) ; |
|
dataLength = benc.trim() ; |
|
} |
|
catch(ArrayIndexOutOfBoundsException x) { |
|
throw new SnmpTooBigException() ; |
|
} |
|
} |
|
|
|
|
|
/** |
|
* Gets the PDU encoded in this message. |
|
* <P> |
|
* This method decodes the data field and returns the resulting PDU. |
|
* |
|
* @return The resulting PDU. |
|
* @exception SnmpStatusException If the encoding is not valid. |
|
*/ |
|
|
|
public SnmpPdu decodeSnmpPdu() |
|
throws SnmpStatusException { |
|
|
|
SnmpScopedPduPacket pdu = null; |
|
|
|
BerDecoder bdec = new BerDecoder(data) ; |
|
try { |
|
int type = bdec.getTag() ; |
|
bdec.openSequence(type) ; |
|
switch(type) { |
|
|
|
case pduGetRequestPdu : |
|
case pduGetNextRequestPdu : |
|
case pduInformRequestPdu : |
|
case pduGetResponsePdu : |
|
case pduSetRequestPdu : |
|
case pduV2TrapPdu : |
|
case pduReportPdu : |
|
SnmpScopedPduRequest reqPdu = new SnmpScopedPduRequest() ; |
|
reqPdu.requestId = bdec.fetchInteger() ; |
|
reqPdu.setErrorStatus(bdec.fetchInteger()); |
|
reqPdu.setErrorIndex(bdec.fetchInteger()); |
|
pdu = reqPdu ; |
|
break ; |
|
|
|
case pduGetBulkRequestPdu : |
|
SnmpScopedPduBulk bulkPdu = new SnmpScopedPduBulk() ; |
|
bulkPdu.requestId = bdec.fetchInteger() ; |
|
bulkPdu.setNonRepeaters(bdec.fetchInteger()); |
|
bulkPdu.setMaxRepetitions(bdec.fetchInteger()); |
|
pdu = bulkPdu ; |
|
break ; |
|
default: |
|
throw new SnmpStatusException(snmpRspWrongEncoding) ; |
|
} |
|
pdu.type = type; |
|
pdu.varBindList = decodeVarBindList(bdec); |
|
bdec.closeSequence() ; |
|
} catch(BerException e) { |
|
if (SNMP_LOGGER.isLoggable(Level.FINEST)) { |
|
SNMP_LOGGER.logp(Level.FINEST, SnmpV3Message.class.getName(), |
|
"decodeSnmpPdu", "BerException", e); |
|
} |
|
throw new SnmpStatusException(snmpRspWrongEncoding); |
|
} |
|
|
|
// |
|
// The easy work. |
|
|
|
pdu.address = address; |
|
pdu.port = port; |
|
pdu.msgFlags = msgFlags; |
|
pdu.version = version; |
|
pdu.msgId = msgId; |
|
pdu.msgMaxSize = msgMaxSize; |
|
pdu.msgSecurityModel = msgSecurityModel; |
|
pdu.contextEngineId = contextEngineId; |
|
pdu.contextName = contextName; |
|
|
|
pdu.securityParameters = securityParameters; |
|
|
|
if (SNMP_LOGGER.isLoggable(Level.FINER)) { |
|
final StringBuilder strb = new StringBuilder() |
|
.append("Unmarshalled PDU : \n") |
|
.append("type : ").append(pdu.type) |
|
.append("\n") |
|
.append("version : ").append(pdu.version) |
|
.append("\n") |
|
.append("requestId : ").append(pdu.requestId) |
|
.append("\n") |
|
.append("msgId : ").append(pdu.msgId) |
|
.append("\n") |
|
.append("msgMaxSize : ").append(pdu.msgMaxSize) |
|
.append("\n") |
|
.append("msgFlags : ").append(pdu.msgFlags) |
|
.append("\n") |
|
.append("msgSecurityModel : ").append(pdu.msgSecurityModel) |
|
.append("\n") |
|
.append("contextEngineId : ").append(pdu.contextEngineId) |
|
.append("\n") |
|
.append("contextName : ").append(pdu.contextName) |
|
.append("\n"); |
|
SNMP_LOGGER.logp(Level.FINER, SnmpV3Message.class.getName(), |
|
"decodeSnmpPdu", strb.toString()); |
|
} |
|
return pdu ; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public String printMessage() { |
|
StringBuffer sb = new StringBuffer(); |
|
sb.append("msgId : " + msgId + "\n"); |
|
sb.append("msgMaxSize : " + msgMaxSize + "\n"); |
|
sb.append("msgFlags : " + msgFlags + "\n"); |
|
sb.append("msgSecurityModel : " + msgSecurityModel + "\n"); |
|
|
|
if (contextEngineId == null) { |
|
sb.append("contextEngineId : null"); |
|
} |
|
else { |
|
sb.append("contextEngineId : {\n"); |
|
sb.append(dumpHexBuffer(contextEngineId, |
|
0, |
|
contextEngineId.length)); |
|
sb.append("\n}\n"); |
|
} |
|
|
|
if (contextName == null) { |
|
sb.append("contextName : null"); |
|
} |
|
else { |
|
sb.append("contextName : {\n"); |
|
sb.append(dumpHexBuffer(contextName, |
|
0, |
|
contextName.length)); |
|
sb.append("\n}\n"); |
|
} |
|
return sb.append(super.printMessage()).toString(); |
|
} |
|
|
|
} |