/*_############################################################################
_##
_## SNMP4J - PDUv1.java
_##
_## Copyright (C) 2003-2008 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;
import java.io.*;
import java.util.*;
import org.snmp4j.asn1.*;
import org.snmp4j.asn1.BER.*;
import org.snmp4j.smi.*;
import org.snmp4j.smi.OID;
// for JavaDoc
import org.snmp4j.mp.SnmpConstants;
/**
* The <code>PDUv1</class> represents SNMPv1 PDUs. The behavior of this class
* is identical to its superclass {@link PDU} for the PDU type {@link PDU#GET},
* {@link PDU#GETNEXT}, and {@link PDU#SET}. The other SNMPv2 PDU types
* implemented by <code>PDU</code> are not supported. In contrast to its super
* class, <code>PDUv1</code> implements the {@link PDU#V1TRAP} type.
*
* <p>To support this type, access methods are provided to get and set the
* enterprise <code>OID</code>, generic, specific, and timestamp of a SNMPv1
* trap PDU.
*
* <p>The constants defined for generic SNMPv1 traps are included in this class.
* The descriptions are taken from the SNMPv2-MIB (RFC 3418). The corresponding
* OIDs are defined in {@link SnmpConstants}.
*
* @author Frank Fock
* @version 1.7.3
*/
public class PDUv1 extends PDU {
private static final long serialVersionUID = -6478805117911347898L;
/**
* A coldStart(0) trap signifies that the SNMP entity,
* supporting a notification originator application, is
* reinitializing itself and that its configuration may
* have been altered.
*/
public static final int COLDSTART = 0;
/**
* A warmStart(1) trap signifies that the SNMP entity,
* supporting a notification originator application,
* is reinitializing itself such that its configuration
* is unaltered.
*/
public static final int WARMSTART = 1;
/**
* A linkDown(2) trap signifies that the SNMP entity, acting in
* an agent role, has detected that the ifOperStatus object for
* one of its communication links is about to enter the down
* state from some other state (but not from the notPresent
* state). This other state is indicated by the included value
* of ifOperStatus.
*/
public static final int LINKDOWN = 2;
/**
* A linkUp(3) trap signifies that the SNMP entity, acting in an
* agent role, has detected that the ifOperStatus object for
* one of its communication links left the down state and
* transitioned into some other state (but not into the
* notPresent state). This other state is indicated by the
* included value of ifOperStatus.
*/
public static final int LINKUP = 3;
/**
* An authenticationFailure(4) trap signifies that the SNMP
* entity has received a protocol message that is not
* properly authenticated. While all implementations
* of SNMP entities MAY be capable of generating this
* trap, the snmpEnableAuthenTraps object indicates
* whether this trap will be generated.
*/
public static final int AUTHENTICATIONFAILURE = 4;
/**
* If the generic trap identifier is <code>ENTERPRISE_SPECIFIC</code>(6), then
* the enterprise specific trap ID is given by the specificTrap member field.
*/
public static final int ENTERPRISE_SPECIFIC = 6;
private static final String OPERATION_NOT_SUPPORTED =
"Operation not supported for SNMPv1 PDUs";
private OID enterprise = new OID();
private IpAddress agentAddress = new IpAddress("0.0.0.0");
private Integer32 genericTrap = new Integer32(0);
private Integer32 specificTrap = new Integer32(0);
private TimeTicks timestamp = new TimeTicks(0);
public PDUv1() {
setType(V1TRAP);
}
/**
* Decodes a <code>Variable</code> from an <code>InputStream</code>.
*
* @param inputStream an <code>InputStream</code> containing a BER encoded
* byte stream.
* @throws IOException
*/
public void decodeBER(BERInputStream inputStream) throws IOException {
MutableByte pduType = new MutableByte();
int length = BER.decodeHeader(inputStream, pduType);
int pduStartPos = (int)inputStream.getPosition();
switch (pduType.getValue()) {
case PDU.SET:
case PDU.GET:
case PDU.GETNEXT:
case PDU.V1TRAP:
case PDU.RESPONSE:
break;
default:
throw new IOException("Unsupported PDU type: "+pduType.getValue());
}
this.setType(pduType.getValue());
if (getType() == PDU.V1TRAP) {
enterprise.decodeBER(inputStream);
agentAddress.decodeBER(inputStream);
genericTrap.decodeBER(inputStream);
specificTrap.decodeBER(inputStream);
timestamp.decodeBER(inputStream);
}
else {
requestID.decodeBER(inputStream);
errorStatus.decodeBER(inputStream);
errorIndex.decodeBER(inputStream);
}
// reusing pduType here to save memory ;-)
pduType = new BER.MutableByte();
int vbLength = BER.decodeHeader(inputStream, pduType);
if (pduType.getValue() != BER.SEQUENCE) {
throw new IOException("Encountered invalid tag, SEQUENCE expected: "+
pduType.getValue());
}
// rest read count
int startPos = (int)inputStream.getPosition();
variableBindings = new Vector();
while (inputStream.getPosition() - startPos < vbLength) {
VariableBinding vb = new VariableBinding();
vb.decodeBER(inputStream);
if (vb.getSyntax() == SMIConstants.SYNTAX_COUNTER64) {
throw new MessageException("Counter64 encountered in SNMPv1 PDU "+
"(RFC 2576 4.1.2.1)");
}
variableBindings.add(vb);
}
if (BER.isCheckSequenceLength()) {
BER.checkSequenceLength(vbLength,
(int) inputStream.getPosition() - startPos, this);
BER.checkSequenceLength(length,
(int) inputStream.getPosition() - pduStartPos, this);
}
}
/**
* Encodes a <code>Variable</code> to an <code>OutputStream</code>.
*
* @param outputStream an <code>OutputStream</code>.
* @throws IOException if an error occurs while writing to the stream.
*/
public void encodeBER(OutputStream outputStream) throws IOException {
BER.encodeHeader(outputStream, type, getBERPayloadLength());
if (type == PDU.V1TRAP) {
enterprise.encodeBER(outputStream);
agentAddress.encodeBER(outputStream);
genericTrap.encodeBER(outputStream);
specificTrap.encodeBER(outputStream);
timestamp.encodeBER(outputStream);
}
else {
requestID.encodeBER(outputStream);
errorStatus.encodeBER(outputStream);
errorIndex.encodeBER(outputStream);
}
int vbLength = 0;
for (int i=0; i<variableBindings.size(); i++) {
vbLength += ((VariableBinding)variableBindings.get(i)).getBERLength();
}
BER.encodeHeader(outputStream, BER.SEQUENCE, vbLength);
for (int i=0; i<variableBindings.size(); i++) {
VariableBinding vb = (VariableBinding)variableBindings.get(i);
if (vb.getVariable() instanceof Counter64) {
throw new IOException("Cannot encode Counter64 into a SNMPv1 PDU");
}
vb.encodeBER(outputStream);
}
}
protected int getBERPayloadLengthPDU() {
if (getType() != PDU.V1TRAP) {
return super.getBERPayloadLengthPDU();
}
else {
int length = 0;
// length for all vbs
for (int i = 0; i < variableBindings.size(); i++) {
length += ((VariableBinding)variableBindings.get(i)).getBERLength();
}
length += BER.getBERLengthOfLength(length) + 1;
length += agentAddress.getBERLength();
length += enterprise.getBERLength();
length += genericTrap.getBERLength();
length += specificTrap.getBERLength();
length += timestamp.getBERLength();
return length;
}
}
/**
* This method is not supported for SNMPv1 PDUs and will throw a
* {@link java.lang.UnsupportedOperationException}
* @return
* nothing
* @throws UnsupportedOperationException
*/
public int getMaxRepetitions() {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
/**
* This method is not supported for SNMPv1 PDUs and will throw a
* {@link java.lang.UnsupportedOperationException}
* @param maxRepetitions int
* @throws UnsupportedOperationException
*/
public void setMaxRepetitions(int maxRepetitions) {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
/**
* This method is not supported for SNMPv1 PDUs and will throw a
* {@link java.lang.UnsupportedOperationException}
*
* @param maxSizeScopedPDU int
* @throws UnsupportedOperationException
*/
public void setMaxSizeScopedPDU(int maxSizeScopedPDU) {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
/**
* This method is not supported for SNMPv1 PDUs and will throw a
* {@link java.lang.UnsupportedOperationException}
*
* @param nonRepeaters int
* @throws UnsupportedOperationException
*/
public void setNonRepeaters(int nonRepeaters) {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
private void checkV1TRAP() {
if (getType() != PDU.V1TRAP) {
throw new UnsupportedOperationException(
"Operation is only supported for SNMPv1 trap PDUs (V1TRAP)");
}
}
/**
* Gets the "enterprise" OID of the SNMPv1 trap. The enterprise OID could be
* any OID although the name could lead to the assumption that the
* enterprise OID has to be an OID under the
* iso(1).org(3).dod(6).internet(1).private(4).enterprises(1) node, but that's
* not true.
*
* @return
* an OID instance.
* @throws UnsupportedOperationException if the type of this PDU is not
* {@link PDU#V1TRAP}.
*/
public OID getEnterprise() {
checkV1TRAP();
return enterprise;
}
/**
* Sets the "enterprise" OID of the SNMPv1 trap. The enterprise OID could be
* any OID although the name could lead to the assumption that the
* enterprise OID has to be an OID under the
* iso(1).org(3).dod(6).internet(1).private(4).enterprises(1) node, but that's
* not true.
*
* @param enterprise
* an OID instance.
* @throws UnsupportedOperationException if the type of this PDU is not
* {@link PDU#V1TRAP}.
*/
public void setEnterprise(org.snmp4j.smi.OID enterprise) {
checkV1TRAP();
checkNull(enterprise);
this.enterprise = (OID) enterprise.clone();
}
/**
* Gets the IP address of the originator system of this SNMPv1 trap.
* If this value is 0.0.0.0 (the recommended default), then the address
* of the peer SNMP entity should be extracted from the {@link Target}
* object associated with this PDU.
*
* @return
* an IpAddress instance.
* @throws UnsupportedOperationException if the type of this PDU is not
* {@link PDU#V1TRAP}.
*/
public org.snmp4j.smi.IpAddress getAgentAddress() {
checkV1TRAP();
return agentAddress;
}
/**
* Sets the IP address of the originator system of this SNMPv1 trap.
* The default value is 0.0.0.0, which should be only overriden in special
* cases, for example when forwarding SNMPv1 traps through a SNMP proxy.
* @param agentAddress
* a <code>IpAddress</code> instance.
* @throws UnsupportedOperationException if the type of this PDU is not
* {@link PDU#V1TRAP}.
*/
public void setAgentAddress(org.snmp4j.smi.IpAddress agentAddress) {
checkV1TRAP();
checkNull(agentAddress);
this.agentAddress = agentAddress;
}
/**
* Gets the generic trap ID. If this value is ENTERPRISE_SPECIFIC(6), then
* {@link #getSpecificTrap()} will return the trap ID of the enterprise
* specific trap.
* @return
* an Integer32 instance with a value between 0 and 6.
* @throws UnsupportedOperationException if the type of this PDU is not
* {@link PDU#V1TRAP}.
*/
public int getGenericTrap() {
checkV1TRAP();
return genericTrap.getValue();
}
/**
* Sets the generic trap ID. If this value is ENTERPRISE_SPECIFIC(6), then
* {@link #setSpecificTrap} must be used to set the trap ID of the enterprise
* specific trap.
* @param genericTrap
* an integer value >= 0 and <= 6.
* @throws UnsupportedOperationException if the type of this PDU is not
* {@link PDU#V1TRAP}.
*/
public void setGenericTrap(int genericTrap) {
checkV1TRAP();
this.genericTrap.setValue(genericTrap);
}
/**
* Gets the specific trap ID. If this value is set,
* {@link #getGenericTrap()} must return ENTERPRISE_SPECIFIC(6).
* @return
* an integer value > 0.
* @throws UnsupportedOperationException if the type of this PDU is not
* {@link PDU#V1TRAP}.
*/
public int getSpecificTrap() {
checkV1TRAP();
return specificTrap.getValue();
}
/**
* Sets the specific trap ID. If this value is set,
* {@link #setGenericTrap(int genericTrap)} must be called with value
* {@link #ENTERPRISE_SPECIFIC}.
*
* @param specificTrap
* an integer value > 0.
* @throws UnsupportedOperationException if the type of this PDU is not
* {@link PDU#V1TRAP}.
*/
public void setSpecificTrap(int specificTrap) {
checkV1TRAP();
this.specificTrap.setValue(specificTrap);
}
/**
* Gets the <code>TimeTicks</code> value of the trap sender's notion of
* its sysUpTime value when this trap has been generated.
*
* @return
* a long value.
* @throws UnsupportedOperationException if the type of this PDU is not
* {@link PDU#V1TRAP}.
*/
public long getTimestamp() {
checkV1TRAP();
return timestamp.getValue();
}
/**
* Sets the <code>TimeTicks</code> value of the trap sender's notion of
* its sysUpTime value when this trap has been generated.
*
* @param timeStamp
* a long value.
*/
public void setTimestamp(long timeStamp) {
checkV1TRAP();
this.timestamp.setValue(timeStamp);
}
/**
* Checks for null parameters.
* @param parameter
* an Object instance.
* @throws NullPointerException if <code>parameter</code> is null.
*/
protected void checkNull(Object parameter) {
if (parameter == null) {
throw new NullPointerException("Members of PDUv1 must not be null");
}
}
public String toString() {
if (type == PDU.V1TRAP) {
StringBuffer buf = new StringBuffer();
buf.append(getTypeString(type));
buf.append("[reqestID=");
buf.append(requestID);
buf.append(",timestamp=");
buf.append(timestamp);
buf.append(",enterprise=");
buf.append(enterprise);
buf.append(",genericTrap=");
buf.append(genericTrap);
buf.append(",specificTrap=");
buf.append(specificTrap);
buf.append(", VBS[");
for (int i = 0; i < variableBindings.size(); i++) {
buf.append(variableBindings.get(i));
if (i + 1 < variableBindings.size()) {
buf.append("; ");
}
}
buf.append("]]");
return buf.toString();
}
return super.toString();
}
}
|