📄 mpv3.java
字号:
/*_############################################################################
_##
_## SNMP4J - MPv3.java
_##
_## Copyright 2003-2005 Frank Fock and Jochen Katz (SNMP4J.org)
_##
_## Licensed under the Apache License, Version 2.0 (the "License");
_## you may not use this file except in compliance with the License.
_## You may obtain a copy of the License at
_##
_## http://www.apache.org/licenses/LICENSE-2.0
_##
_## Unless required by applicable law or agreed to in writing, software
_## distributed under the License is distributed on an "AS IS" BASIS,
_## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
_## See the License for the specific language governing permissions and
_## limitations under the License.
_##
_##########################################################################*/
package org.snmp4j.mp;
import org.snmp4j.log.*;
import org.snmp4j.security.*;
import org.snmp4j.smi.*;
import org.snmp4j.*;
import java.io.*;
import java.util.*;
import org.snmp4j.asn1.*;
import org.snmp4j.MutablePDU;
import org.snmp4j.security.SecurityParameters;
import org.snmp4j.event.*;
import org.snmp4j.PDU;
import org.snmp4j.mp.MPv3.CacheEntry;
import java.util.Random;
import org.snmp4j.smi.OctetString;
import java.net.InetAddress;
import java.net.UnknownHostException;
// for JavaDoc
import org.snmp4j.security.SecurityProtocols;
import java.nio.ByteBuffer;
/**
* The <code>MPv3</code> is the message processing model for SNMPv3.
* @author Frank Fock
* @version 1.0
*/
public class MPv3
implements MessageProcessingModel {
public static final int ID = MessageProcessingModel.MPv3;
public static final int MPv3_REPORTABLE_FLAG = 4;
public static final int MAX_MESSAGE_ID = 2147483647;
public static final int MAXLEN_ENGINE_ID = 32;
public static final int MINLEN_ENGINE_ID = 5;
private static final int MAX_HEADER_PAYLOAD_LENGTH =
// length of msgFlags
new OctetString("\0").getBERLength() +
// length of msgID, msgMaxSize, securityModel
3 * new Integer32(Integer.MAX_VALUE).getBERLength();
private static final int MAX_HEADER_LENGTH =
MAX_HEADER_PAYLOAD_LENGTH +
BER.getBERLengthOfLength(MAX_HEADER_PAYLOAD_LENGTH) + 1;
private SecurityProtocols securityProtocols;
private static final LogAdapter logger = LogFactory.getLogger(MPv3.class);
private SecurityModels securityModels;
private Cache cache;
private Hashtable engineIDs;
private byte[] localEngineID;
private int currentMsgID = new Random().nextInt(MAX_MESSAGE_ID);
// Enterprise ID of AGENT++
private static int enterpriseID = 4976;
private CounterSupport counterSupport;
/**
* Creates a MPv3 with a default local engine ID.
*/
public MPv3() {
engineIDs = new Hashtable();
cache = new Cache();
securityProtocols = SecurityProtocols.getInstance();
securityModels = SecurityModels.getInstance();
localEngineID = createLocalEngineID();
counterSupport = CounterSupport.getInstance();
}
/**
* Creates a MPv3 with a supplied local engine ID.
* @param localEngineID
* the local engine ID. Its length must be >= 5 and <= 32.
*/
public MPv3(byte[] localEngineID) {
this();
setLocalEngineID(localEngineID);
}
/**
* Creates a local engine ID based on the local IP address.
* @return
* a new local engine ID.
*/
public static byte[] createLocalEngineID() {
byte[] engineID = new byte[5];
engineID[0] = (byte)(0x80 | ((enterpriseID >> 24) & 0xFF));
engineID[1] = (byte)((enterpriseID >> 16) & 0xFF);
engineID[2] = (byte)((enterpriseID >> 8) & 0xFF);
engineID[3] = (byte)(enterpriseID & 0xFF);
engineID[4] = 1;
OctetString os = new OctetString();
try {
os.setValue(InetAddress.getLocalHost().getAddress());
}
catch (UnknownHostException ex) {
logger.debug("Local host cannot be determined for creation of local engine ID");
engineID[4] = 4;
os.setValue("SNMP4J".getBytes());
}
OctetString ownEngineID = new OctetString(engineID);
ownEngineID.append(os);
return ownEngineID.getValue();
}
/**
* Creates a local engine ID based on the ID string supplied
* @param id
* an ID string.
* @return
* a new local engine ID.
*/
public static byte[] createLocalEngineID(OctetString id) {
byte[] engineID = new byte[5];
engineID[0] = (byte)(0x80 | ((enterpriseID >> 24) & 0xFF));
engineID[1] = (byte)((enterpriseID >> 16) & 0xFF);
engineID[2] = (byte)((enterpriseID >> 8) & 0xFF);
engineID[3] = (byte)(enterpriseID & 0xFF);
engineID[4] = 4;
OctetString ownEngineID = new OctetString(engineID);
ownEngineID.append(id);
return ownEngineID.getValue();
}
/**
* Sets the local engine ID. This value must not be changed after message
* processing has been started.
* @param engineID
* the local engine ID. Its length must be >= 5 and <= 32.
*/
public void setLocalEngineID(byte[] engineID) {
if ((engineID == null) ||
(engineID.length < MINLEN_ENGINE_ID) ||
(engineID.length > MAXLEN_ENGINE_ID)) {
throw new IllegalArgumentException("Illegal (local) engine ID");
}
this.localEngineID = engineID;
}
/**
* Gets a copy of the local engine ID.
* @return
* a byte array containing the local engine ID.
*/
public byte[] getLocalEngineID() {
byte[] retval = new byte[localEngineID.length];
System.arraycopy(localEngineID, 0, retval, 0, localEngineID.length);
return retval;
}
/**
* Creates and initializes the default security protocols.
* @see SecurityProtocols#addDefaultProtocols()
*/
public void initDefaults() {
securityProtocols.addDefaultProtocols();
}
/**
* Gets an authentication protocol for the supplied ID.
* @param id
* an authentication protocol OID.
* @return
* an <code>AuthenticationProtocol</code> instance if the supplied ID
* is supported, otherwise <code>null</code> is returned.
*/
public AuthenticationProtocol getAuthProtocol(OID id) {
return securityProtocols.getAuthenticationProtocol(id);
}
/**
* Gets an privacy protocol for the supplied ID.
* @param id
* an privacy protocol OID.
* @return
* an <code>PrivacyProtocol</code> instance if the supplied ID
* is supported, otherwise <code>null</code> is returned.
*/
public PrivacyProtocol getPrivProtocol(OID id) {
return securityProtocols.getPrivacyProtocol(id);
}
/**
* Gets the security model for the supplied ID.
* @param id
* a security model ID.
* @return
* a <code>SecurityModel</code> instance if the supplied ID
* is supported, otherwise <code>null</code> is returned.
*/
public SecurityModel getSecurityModel(int id) {
return securityModels.getSecurityModel(new Integer32(id));
}
public int getID() {
return ID;
}
public boolean isProtocolVersionSupported(int version) {
return (version == SnmpConstants.version3);
}
/**
* Adds an engine ID to the internal storage.
* @param address
* the <code>Address</code> of the remote SNMP engine.
* @param engineID
* the engine ID of the remote SNMP engine.
*/
public void addEngineID(Address address, OctetString engineID) {
engineIDs.put(address, engineID);
}
/**
* Gets the engine ID associated with the supplied address from the local
* storage.
* @param address
* the <code>Address</code> of the remote SNMP engine.
* @return
* the engine ID of the remote SNMP engine or <code>null</code> if there
* is no entry for <code>address</code> in the local storage.
*/
public OctetString getEngineID(Address address) {
return (OctetString) engineIDs.get(address);
}
/**
* Removes an engine ID association from the local storage.
* @param address
* the <code>Address</code> of the remote SNMP engine for whose engine ID
* is to be removed.
*/
public void removeEngineID(Address address) {
engineIDs.remove(address);
}
/**
* The <code>CacheEntry</code> class holds state reference information
* for the MPv3 message processing model for a single message.
* @author Frank Fock
* @version 1.0
*/
protected class CacheEntry extends StateReference {
int msgID;
long transactionID;
byte[] secEngineID;
SecurityModel secModel;
byte[] secName;
int secLevel;
byte[] contextEngineID;
byte[] contextName;
SecurityStateReference secStateReference;
int errorCode;
public CacheEntry(int msgID,
long reqID,
byte[] secEngineID,
SecurityModel secModel,
byte[] secName,
int secLevel,
byte[] contextEngineID,
byte[] contextName,
SecurityStateReference secStateReference,
int errorCode) {
this.msgID = msgID;
this.transactionID = reqID;
this.secEngineID = secEngineID;
this.secModel = secModel;
this.secName = secName;
this.secLevel = secLevel;
this.contextEngineID = contextEngineID;
this.contextName = contextName;
this.secStateReference = secStateReference;
this.errorCode = errorCode;
}
}
/**
* The <code>Cache</code> stores state reference information for the MPv3.
* @author Frank Fock
* @version 1.0
*/
protected class Cache {
private Map entries = new WeakHashMap(25);
/**
* Adds a <code>StateReference</code> to the cache.
* The <code>PduHandle</code> of the supplied entry will be set to
* <code>null</code> while the entry is part of the cache, because the
* cache uses a <code>WeakHashMap</code> internally which uses the
* <code>PduHandle</code> as key. When
* @param entry
* the state reference to add.
* @return
* {@link SnmpConstants#SNMP_MP_DOUBLED_MESSAGE} if the entry already
* exists and {@link SnmpConstants#SNMP_MP_OK} on success.
*/
public synchronized int addEntry(StateReference entry) {
StateReference existing =
(StateReference) entries.get(entry.getPduHandle());
if (existing != null) {
if (existing.equals(entry)) {
return SnmpConstants.SNMP_MP_DOUBLED_MESSAGE;
}
}
// add it
PduHandle key = entry.getPduHandle();
// because we are using a weak has map for the cache, we need to null out
// our key from the entry.
entry.setPduHandle(null);
entries.put(key, entry);
return SnmpConstants.SNMP_MP_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -