org.snmp4j.Snmp Maven / Gradle / Ivy
/*_############################################################################
_##
_## SNMP4J - Snmp.java
_##
_## Copyright (C) 2003-2024 Frank Fock (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;
import org.snmp4j.event.CounterEvent;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.event.ResponseEventFactory;
import org.snmp4j.event.ResponseListener;
import org.snmp4j.log.LogAdapter;
import org.snmp4j.log.LogFactory;
import org.snmp4j.mp.*;
import org.snmp4j.security.*;
import org.snmp4j.smi.*;
import org.snmp4j.transport.ConnectionOrientedTransportMapping;
import org.snmp4j.transport.TransportMappings;
import org.snmp4j.util.CommonTimer;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
/**
* The {@code Snmp} class is the core of SNMP4J. It provides functions to send and receive SNMP PDUs. All SNMP PDU types
* can be send. Confirmed PDUs can be sent synchronously and asynchronously.
*
* The {@code Snmp} class is transport protocol independent. Support for a specific {@link TransportMapping} instance is
* added by calling the {@link #addTransportMapping(TransportMapping transportMapping)} method or creating a {@code
* Snmp} instance by using the non-default constructor with the corresponding transport mapping. Transport mappings are
* used for incoming and outgoing messages.
*
* To setup a default SNMP session for UDP transport and with SNMPv3 support the following code snippet can be
* used:
*
*
* Address targetAddress = GenericAddress.parse("udp:127.0.0.1/161");
* TransportMapping transport = new DefaultUdpTransportMapping();
* snmp = new Snmp(transport);
* USM usm = new USM(SecurityProtocols.getInstance(),
* new OctetString(MPv3.createLocalEngineID()), 0);
* SecurityModels.getInstance().addSecurityModel(usm);
* transport.listen();
*
*
* How a synchronous SNMPv3 message with authentication and privacy is then sent illustrates the following code
* snippet:
*
*
* // add user to the USM
* snmp.getUSM().addUser(new OctetString("MD5DES"),
* new UsmUser(new OctetString("MD5DES"),
* AuthMD5.ID,
* new OctetString("MD5DESUserAuthPassword"),
* PrivDES.ID,
* new OctetString("MD5DESUserPrivPassword")));
* // create the target
* UserTarget target = new UserTarget();
* target.setAddress(targetAddress);
* target.setRetries(1);
* target.setTimeout(5000);
* target.setVersion(SnmpConstants.version3);
* target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
* target.setSecurityName(new OctetString("MD5DES"));
*
* // create the PDU
* PDU pdu = new ScopedPDU();
* pdu.add(new VariableBinding(new OID("1.3.6")));
* pdu.setType(PDU.GETNEXT);
*
* // send the PDU
* ResponseEvent response = snmp.send(pdu, target);
* // extract the response PDU (could be null if timed out)
* PDU responsePDU = response.getResponse();
* // extract the address used by the agent to send the response:
* Address peerAddress = response.getPeerAddress();
*
*
*
* An asynchronous SNMPv1 request is sent by the following code:
*
*
*
* // setting up target
* CommunityTarget target = new CommunityTarget();
* target.setCommunity(new OctetString("public"));
* target.setAddress(targetAddress);
* target.setRetries(2);
* target.setTimeout(1500);
* target.setVersion(SnmpConstants.version1);
* // creating PDU
* PDU pdu = new PDU();
* pdu.add(new VariableBinding(new OID(new int[] {1,3,6,1,2,1,1,1})));
* pdu.add(new VariableBinding(new OID(new int[] {1,3,6,1,2,1,1,2})));
* pdu.setType(PDU.GETNEXT);
* // sending request
* ResponseListener listener = new ResponseListener() {
* public void onResponse(ResponseEvent event) {
* // Always cancel async request when response has been received
* // otherwise a memory leak is created! Not canceling a request
* // immediately can be useful when sending a request to a broadcast
* // address.
* ((Snmp)event.getSource()).cancel(event.getRequest(), this);
* System.out.println("Received response PDU is: "+event.getResponse());
* }
* };
* snmp.sendPDU(pdu, target, null, listener);
*
*
* Traps (notifications) and other SNMP PDUs can be received by adding the following code to the first code snippet
* above:
*
*
* CommandResponder trapPrinter = new CommandResponder() {
* public synchronized void processPdu(CommandResponderEvent e) {
* PDU command = e.getPDU();
* if (command != null) {
* System.out.println(command.toString());
* }
* }
* };
* snmp.addCommandResponder(trapPrinter);
*
*
* @author Frank Fock
* @version 3.7.5
*/
public class Snmp implements Session, CommandResponder {
private static final LogAdapter logger = LogFactory.getLogger(Snmp.class);
private static final int DEFAULT_MAX_REQUEST_STATUS = 2;
private static final int ENGINE_ID_DISCOVERY_MAX_REQUEST_STATUS = 0;
// Message processing implementation
private MessageDispatcher messageDispatcher;
/**
* The {@code pendingRequests} table contains pending requests accessed through the key {@code PduHandle}
*/
private final Map> pendingRequests =
Collections.synchronizedMap(new HashMap<>(50));
/**
* The {@code asyncRequests} table contains pending requests accessed trough the key userObject
*/
private final Map