📄 mpv3.java
字号:
/**
* Get the first cache entry with specified message ID.
* @param msgID
* a message ID.
* @return
* a <code>StateReference</code> instance with the given message ID or
* <code>null</code> if such an entry cannot be found.
*/
/*
public StateReference getEntry(int msgID) {
for (Iterator it = entries.iterator(); it.hasNext(); ) {
StateReference e = (StateReference) it.next();
if (e.getMsgID() == msgID) {
return e;
}
}
return null;
}
*/
/**
* Delete the cache entry with the supplied <code>PduHandle</code>.
* @param pduHandle
* a pduHandle.
* @return
* <code>true</code> if an entry has been deleted, <code>false</code>
* otherwise.
*/
public synchronized boolean deleteEntry(PduHandle pduHandle) {
StateReference e = (StateReference) entries.remove(pduHandle);
return (e != null);
}
/**
* Pop the cache entry with the supplied ID from the cache.
* @param msgID
* a message ID.
* @return
* a <code>CacheEntry</code> instance with the given message ID or
* <code>null</code> if such an entry cannot be found. If a cache entry
* is returned, the same is removed from the cache.
*/
public synchronized StateReference popEntry(int msgID) {
for (Iterator it = entries.keySet().iterator(); it.hasNext(); ) {
PduHandle key = (PduHandle) it.next();
StateReference e = (StateReference) entries.get(key);
if ((e != null) && (e.getMsgID() == msgID)) {
it.remove();
e.setPduHandle(key);
return e;
}
}
return null;
}
}
/**
* The <code>HeaderData</code> represents the message header information
* of SNMPv3 message.
* @author Frank Fock
* @version 1.0
*/
protected class HeaderData
implements BERSerializable {
public static final byte FLAG_AUTH = 0x01;
public static final byte FLAG_PRIV = 0x02;
Integer32 msgID = new Integer32(0);
Integer32 msgMaxSize = new Integer32(Integer.MAX_VALUE);
OctetString msgFlags = new OctetString(new byte[1]);
Integer32 securityModel = new Integer32(SecurityModel.SECURITY_MODEL_ANY);
public void setMsgID(int msgID) {
this.msgID.setValue(msgID);
}
public int getMsgID() {
return msgID.getValue();
}
public void setMsgMaxSize(int msgMaxSize) {
this.msgMaxSize.setValue(msgMaxSize);
}
public int getMsgMaxSize() {
return msgMaxSize.getValue();
}
public void setMsgFlags(int flags) {
this.msgFlags.getValue()[0] = (byte) flags;
}
public int getMsgFlags() {
return msgFlags.getValue()[0] & 0xFF;
}
public void setSecurityModel(int model) {
securityModel.setValue(model);
}
public int getSecurityModel() {
return securityModel.getValue();
}
public int getBERPayloadLength() {
int length = msgID.getBERLength();
length += msgMaxSize.getBERLength();
length += msgFlags.getBERLength();
length += securityModel.getBERLength();
return length;
}
public int getBERLength() {
int length = getBERPayloadLength();
length += BER.getBERLengthOfLength(length) + 1;
return length;
}
public void decodeBER(BERInputStream message) throws IOException {
BER.MutableByte type = new BER.MutableByte();
int length = BER.decodeHeader(message, type);
if (type.getValue() != BER.SEQUENCE) {
throw new IOException("Unexpected sequence header type: " +
type.getValue());
}
msgID.decodeBER(message);
msgMaxSize.decodeBER(message);
if (msgMaxSize.getValue() < 484) {
throw new IOException("Invalid msgMaxSize: " + msgMaxSize);
}
msgFlags.decodeBER(message);
if (msgFlags.length() != 1) {
throw new IOException("Message flags length != 1: " + msgFlags.length());
}
securityModel.decodeBER(message);
if (logger.isDebugEnabled()) {
logger.debug("SNMPv3 header decoded: msgId=" + msgID +
", msgMaxSize=" + msgMaxSize +
", msgFlags=" + msgFlags.toHexString() +
", secModel=" + securityModel);
}
BER.checkSequenceLength(length, this);
}
public void encodeBER(OutputStream outputStream) throws IOException {
BER.encodeHeader(outputStream, BER.SEQUENCE, getBERPayloadLength());
msgID.encodeBER(outputStream);
msgMaxSize.encodeBER(outputStream);
msgFlags.encodeBER(outputStream);
securityModel.encodeBER(outputStream);
}
}
/**
* Gets unique message ID.
* @return
* a message ID >= 1 and <= {@link #MAX_MESSAGE_ID}.
*/
public synchronized int getNextMessageID() {
if (currentMsgID >= MAX_MESSAGE_ID) {
currentMsgID = 1;
}
return currentMsgID++;
}
/**
* Gets the security protocols supported by this <code>MPv3</code>.
* @return
* return a <code>SecurityProtocols</code>.
*/
public SecurityProtocols getSecurityProtocols() {
return securityProtocols;
}
/**
* Sets the security protocols for this <code>MPv3</code>.
* @param securityProtocols SecurityProtocols
*/
public void setSecurityProtocols(SecurityProtocols securityProtocols) {
this.securityProtocols = securityProtocols;
}
/**
* Gets the default security model to be used for engine ID discovery.
* @return
* a security model ID.
* @see USM#getID()
*/
protected int getDefaultSecurityModel() {
return SecurityModel.SECURITY_MODEL_USM;
}
public void releaseStateReference(PduHandle pduHandle) {
cache.deleteEntry(pduHandle);
}
public int prepareOutgoingMessage(Address transportAddress,
int maxMessageSize,
int messageProcessingModel,
int securityModel,
byte[] securityName,
int securityLevel,
PDU pdu,
boolean expectResponse,
PduHandle sendPduHandle,
Address destTransportAddress,
BEROutputStream outgoingMessage) throws
IOException {
if (!(pdu instanceof ScopedPDU)) {
throw new IllegalArgumentException(
"MPv3 only accepts ScopedPDU instances as pdu parameter");
}
ScopedPDU scopedPDU = (ScopedPDU) pdu;
// lookup engine ID
byte[] secEngineID = null;
OctetString securityEngineID =
(OctetString) engineIDs.get(transportAddress);
if (securityEngineID != null) {
secEngineID = securityEngineID.getValue();
if (scopedPDU.getContextEngineID().length() == 0) {
if (logger.isDebugEnabled()) {
logger.debug("Context engine ID of scoped PDU is empty! Setting it to authoritative engine ID: "+
securityEngineID.toHexString());
}
scopedPDU.setContextEngineID(new OctetString(secEngineID));
}
}
else {
secEngineID = new byte[0];
}
// determine request type
if (pdu.isConfirmedPdu()) {
if (secEngineID.length == 0) {
securityLevel = SecurityLevel.NOAUTH_NOPRIV;
securityModel = getDefaultSecurityModel();
// do not send any management information
scopedPDU = (ScopedPDU) scopedPDU.clone();
scopedPDU.clear();
}
}
else {
if (scopedPDU.getContextEngineID().length() == 0) {
if (logger.isDebugEnabled()) {
logger.debug("Context engine ID of unconfirmed scoped PDU is empty! "+
"Setting it to local engine ID");
}
scopedPDU.setContextEngineID(new OctetString(localEngineID));
}
}
// get length of scoped PDU
int scopedPDULength = pdu.getBERLength();
BEROutputStream scopedPdu =
new BEROutputStream(ByteBuffer.allocate(scopedPDULength));
scopedPDU.encodeBER(scopedPdu);
HeaderData headerData = new HeaderData();
int flags = 0;
switch (securityLevel) {
case SecurityLevel.NOAUTH_NOPRIV:
flags = 0;
break;
case SecurityLevel.AUTH_NOPRIV:
flags = 1;
break;
case SecurityLevel.AUTH_PRIV:
flags = 3;
break;
}
if (scopedPDU.isConfirmedPdu()) {
flags |= MPv3_REPORTABLE_FLAG;
}
else {
secEngineID = localEngineID;
}
int msgID = getNextMessageID();
headerData.setMsgFlags(flags);
headerData.setMsgID(msgID);
headerData.setMsgMaxSize(maxMessageSize);
headerData.setSecurityModel(securityModel);
ByteBuffer globalDataBuffer =
ByteBuffer.allocate(headerData.getBERLength());
BEROutputStream globalDataOutputStream =
new BEROutputStream(globalDataBuffer);
headerData.encodeBER(globalDataOutputStream);
BERInputStream scopedPDUInput = new BERInputStream(scopedPdu.rewind());
SecurityModel secModel =
securityModels.getSecurityModel(new Integer32(securityModel));
if (secModel == null) {
return SnmpConstants.SNMP_MP_UNSUPPORTED_SECURITY_MODEL;
}
// output data
SecurityParameters securityParameters =
secModel.newSecurityParametersInstance();
int status =
secModel.generateRequestMessage(messageProcessingModel,
globalDataBuffer.array(),
maxMessageSize,
securityModel,
secEngineID,
securityName,
securityLevel,
scopedPDUInput,
securityParameters,
outgoingMessage);
if (status == SnmpConstants.SNMPv3_USM_OK) {
if (expectResponse) {
cache.addEntry(new StateReference(msgID,
flags,
maxMessageSize,
sendPduHandle,
transportAddress,
null,
secEngineID, secModel,
securityName, securityLevel,
scopedPDU.getContextEngineID().
getValue(),
scopedPDU.getContextName().getValue(),
null,
status));
}
}
return status;
}
public int prepareResponseMessage(int messageProcessingModel,
int maxMessageSize,
int securityModel,
byte[] securityName,
int securityLevel,
PDU pdu,
int maxSizeResponseScopedPDU,
StateReference stateReference,
StatusInformation statusInformation,
BEROutputStream outgoingMessage) throws
IOException {
/**@todo Leave entry in cache or remove it? RFC3414
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -