📄 snmp.java
字号:
transport);
if (logger.isDebugEnabled()) {
logger.debug("New pending request with handle " + handle);
}
pendingRequests.put(handle, request);
long delay =
timeoutModel.getRetryTimeout(0, target.getRetries(),
target.getTimeout());
timer.schedule(request, delay);
}
try {
syncResponse.wait();
}
catch (InterruptedException iex) {
logger.warn(iex);
// ignore
}
}
return syncResponse.response;
}
public void send(PDU pdu, Target target,
Object userHandle,
ResponseListener listener) throws IOException {
send(pdu, target, null, userHandle, listener);
}
public void send(PDU pdu, Target target,
TransportMapping transport,
Object userHandle,
ResponseListener listener) throws IOException {
if (!pdu.isConfirmedPdu()) {
sendMessage(pdu, target, transport);
return;
}
synchronized (sync) {
PduHandle handle = sendMessage(pdu, target, null);
PendingRequest request =
new PendingRequest(handle, listener, userHandle,
pdu, target, transport);
logger.debug("New pending async request with handle " + handle);
pendingRequests.put(handle, request);
asyncRequests.put(new AsyncRequestKey(pdu, listener), handle);
long delay =
timeoutModel.getRetryTimeout(0, target.getRetries(),
target.getTimeout());
timer.schedule(request, delay);
}
}
/**
* Sends a <code>PDU</code> to the given target and returns the received
* response <code>PDU</code>.
* @param pdu
* a <code>PDU</code> instance. When sending a SNMPv1 trap PDU, the
* supplied PDU instance must be a <code>PDUv1</code>. For all types of
* SNMPv3 messages, the supplied PDU instance has to be a
* <code>ScopedPDU</code> instance.
* @param target
* the Target instance representing the target SNMP engine where to send
* the <code>pdu</code>.
* @return
* the received response <code>PDU</code> or <code>null</code>
* if the request timed out and if the PDU type of <code>pdu</code>
* is an unconfirmed PDU (i.e., trap or notification).
* @throws IOException
* if the message could not be sent.
* @see PDU
* @see ScopedPDU
* @see PDUv1
* @deprecated This method has been deprecated because it does not return
* the transport address of the entity (target) that sent the response.
* Please use {@link #send(PDU pdu, Target target)} instead. It returns
* a {@link ResponseEvent} object holding the response PDU and transport
* address of a successfully received response. This method will be supported
* until v2.0.
*/
public PDU sendPDU(PDU pdu, Target target) throws IOException {
ResponseEvent e = send(pdu, target);
if (e != null) {
return e.getResponse();
}
// pdu sent is unconfirmed one
return null;
}
/**
* Asynchronously sends a <code>PDU</code> to the given target. The response
* is then returned by calling the supplied <code>ResponseListener</code>
* instance.
*
* @param pdu
* the PDU instance to send.
* @param target
* the Target instance representing the target SNMP engine where to send
* the <code>pdu</code>.
* @param userHandle
* an user defined handle that is returned when the request is returned
* via the <code>listener</code> object.
* @param listener
* a <code>ResponseListener</code> instance that is called when
* <code>pdu</code> is a confirmed PDU and the request is either answered
* or timed out.
* @deprecated Please use {@link #send(PDU pdu, Target target, Object
* userHandle, ResponseListener listener)} instead. It has exactly
* the same function but follows the new namong scheme. This method
* will be supported until v2.0.
* @throws IOException
* if the PDU could not be sent to the specified target.
*/
public void sendPDU(PDU pdu, Target target, Object userHandle,
ResponseListener listener) throws IOException {
send(pdu, target, userHandle, listener);
}
/**
* Actually sends a PDU to a target and returns a handle for the sent PDU.
* @param pdu
* the <code>PDU</code> instance to be sent.
* @param target
* a <code>Target</code> instance denoting the target SNMP entity.
* @param transport
* the (optional) transport mapping to be used to send the request.
* If <code>transport</code> is <code>null</code> a suitable transport
* mapping is determined from the <code>target</code> address.
* @throws IOException
* if the transport fails to send the PDU or the if the message cannot
* be BER encoded.
* @return PduHandle
* that uniquely identifies the sent PDU for further reference.
*/
protected PduHandle sendMessage(PDU pdu, Target target,
TransportMapping transport)
throws IOException
{
PduHandle handle = null;
if (target instanceof SecureTarget) {
SecureTarget secureTarget = (SecureTarget) target;
handle = messageDispatcher.sendPdu(transport,
secureTarget.getAddress(),
secureTarget.getVersion(),
secureTarget.getSecurityModel(),
secureTarget.getSecurityName().
getValue(),
secureTarget.getSecurityLevel(),
pdu, true);
}
else if (target instanceof CommunityTarget) {
CommunityTarget communityTarget = (CommunityTarget) target;
int securityModel = SecurityModel.SECURITY_MODEL_SNMPv2c;
if (communityTarget.getVersion() == SnmpConstants.version1) {
securityModel = SecurityModel.SECURITY_MODEL_SNMPv1;
}
handle = messageDispatcher.sendPdu(transport,
communityTarget.getAddress(),
communityTarget.getVersion(),
securityModel,
communityTarget.getCommunity().
getValue(),
SecurityLevel.NOAUTH_NOPRIV,
pdu, true);
}
return handle;
}
public void cancel(PDU request, ResponseListener listener) {
AsyncRequestKey key = new AsyncRequestKey(request, listener);
PduHandle pending = (PduHandle) asyncRequests.remove(key);
logger.debug("Removing pending request with handle " + pending);
if (pending != null) {
PendingRequest pendingRequest =
(PendingRequest) pendingRequests.remove(pending);
if (pendingRequest != null) {
pendingRequest.cancel();
}
}
}
/**
* Sets the local engine ID for the SNMP entity represented by this
* <code>Snmp</code> instance. This is a convenience method that sets
* the local engine ID in the associated <code>MPv3</code> and
* <code>USM</code>.
* @param engineID
* a byte array containing the local engine ID. The length and content
* has to comply with the constraints defined in the SNMP-FRAMEWORK-MIB.
* @param engineBoots
* the number of boots of this SNMP engine (zero based).
* @param engineTime
* the number of seconds since the value of engineBoots last changed.
* @see MPv3
* @see USM
*/
public void setLocalEngine(byte[] engineID,
int engineBoots,
int engineTime) {
MPv3 mpv3 = getMPv3();
mpv3.setLocalEngineID(engineID);
USM usm = (USM) mpv3.getSecurityModel(SecurityModel.SECURITY_MODEL_USM);
usm.setLocalEngine(new OctetString(engineID), engineBoots, engineTime);
}
/**
* Gets the local engine ID if the MPv3 is available, otherwise a runtime
* exception is thrown.
* @return byte[]
* the local engine ID.
*/
public byte[] getLocalEngineID() {
return getMPv3().getLocalEngineID();
}
private MPv3 getMPv3() {
MPv3 mpv3 = (MPv3) getMessageProcessingModel(MessageProcessingModel.MPv3);
if (mpv3 == null) {
throw new NoSuchElementException("MPv3 not available");
}
return mpv3;
}
/**
* Discovers the engine ID of the SNMPv3 entity denoted by the supplied
* address. This method does not need to be called for normal operation,
* because SNMP4J automatically discovers authoritative engine IDs and
* also automatically synchronize engine time values.
* <p>
* <em>For this method to operate succesfully, the discover engine IDs
* flag in {@link USM} must be <code>true</code> (which is the default).
* </em>
* @param address
* an Address instance representing the transport address of the SNMPv3
* entity for which its authoritative engine ID should be discovered.
* @param timeout
* the maximum time in milliseconds to wait for a response.
* @return
* a byte array containing the authoritative engine ID or <code>null</code>
* if it could not be discovered.
* @see USM#setEngineDiscoveryEnabled(boolean enableEngineDiscovery)
*/
public byte[] discoverAuthoritativeEngineID(Address address, long timeout) {
MPv3 mpv3 = getMPv3();
// do we need to remove the engine ID explicitly to be sure that it is
// updated?
mpv3.removeEngineID(address);
ScopedPDU scopedPDU = new ScopedPDU();
scopedPDU.setType(PDU.GET);
SecureTarget target = new UserTarget();
target.setTimeout(timeout);
target.setAddress(address);
try {
sendPDU(scopedPDU, target);
OctetString authoritativeEngineID = mpv3.getEngineID(address);
if (authoritativeEngineID == null) {
return null;
}
// we copy the byte array here, so we are sure nobody can modify the
// internal cache.
return new OctetString(authoritativeEngineID.getValue()).getValue();
}
catch (IOException ex) {
logger.error(
"IO error while trying to discover authoritative engine ID: " +
ex);
return null;
}
}
/**
* Gets the User Based Security Model (USM). This is a convenience method
* that uses the <code>SecurityModels</code> singleton to get the USM.
* @return
* an <code>USM</code> instance if available in the current SNMP4J
* configuration, <code>null</code> otherwise.
*/
public USM getUSM() {
return (USM) SecurityModels.getInstance().getSecurityModel(
new Integer32(SecurityModel.SECURITY_MODEL_USM));
}
/**
* Gets the message processing model for the supplied ID.
* @param messageProcessingModel
* a mesage processing model ID as defined in {@link MessageProcessingModel}.
* @return MessageProcessingModel
* a <code>MessageProcessingModel</code> if
* <code>messageProcessingModel</code> has been registered with the
* message dispatcher associated with this SNMP session.
*/
public MessageProcessingModel getMessageProcessingModel(int
messageProcessingModel) {
return messageDispatcher.getMessageProcessingModel(messageProcessingModel);
}
/**
* Process an incoming request or notification PDU.
*
* @param event
* a <code>CommandResponderEvent</code> with the decoded incoming PDU as
* dispatched to this method call by the associated message dispatcher.
*/
public void processPdu(CommandResponderEvent event) {
PduHandle handle = event.getPduHandle();
PDU pdu = event.getPDU();
if (pdu.getType() == PDU.RESPONSE) {
event.setProcessed(true);
PendingRequest request;
boolean intime = true;
synchronized (sync) {
if (logger.isDebugEnabled()) {
logger.debug("Removing pending request with handle " + handle);
}
request = (PendingRequest) pendingRequests.remove(handle);
if (request == null) {
if (logger.isWarnEnabled()) {
logger.warn("Received response that cannot be matched to any " +
"outstanding request, address=" +
event.getPeerAddress() +
", requestID=" + pdu.getRequestID());
}
}
else {
intime = request.cancel();
}
}
if (request == null) {
logger.warn("Received response that cannot be matched to any " +
"outstanding request, address=" +
event.getPeerAddress() +
", requestID=" + pdu.getRequestID());
}
else {
if (intime || (!request.setFinished())) {
// return response
request.listener.onResponse(new ResponseEvent(this,
event.getPeerAddress(),
request.pdu,
pdu,
request.userObject));
}
else {
// silently drop late response
if (logger.isInfoEnabled()) {
logger.info("Received late response from " +
event.getPeerAddress() +
" with request ID " + pdu.getRequestID());
}
}
}
}
else if (pdu.getType() == PDU.REPORT) {
event.setProcessed(true);
processReport(handle, event);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Fire process PDU event: " + event.toString());
}
fireProcessPdu(event);
}
}
private void processReport(PduHandle handle, CommandResponderEvent e) {
PDU pdu = e.getPDU();
logger.debug("Searching pending request with handle" + handle);
PendingRequest request;
synchronized (sync) {
request = (PendingRequest) pendingRequests.get(handle);
}
if (request == null) {
logger.warn("Unmatched report PDU received from " + e.getPeerAddress());
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -