001: /*_############################################################################
002: _##
003: _## SNMP4J - MPv2c.java
004: _##
005: _## Copyright (C) 2003-2008 Frank Fock and Jochen Katz (SNMP4J.org)
006: _##
007: _## Licensed under the Apache License, Version 2.0 (the "License");
008: _## you may not use this file except in compliance with the License.
009: _## You may obtain a copy of the License at
010: _##
011: _## http://www.apache.org/licenses/LICENSE-2.0
012: _##
013: _## Unless required by applicable law or agreed to in writing, software
014: _## distributed under the License is distributed on an "AS IS" BASIS,
015: _## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: _## See the License for the specific language governing permissions and
017: _## limitations under the License.
018: _##
019: _##########################################################################*/
020:
021: package org.snmp4j.mp;
022:
023: import org.snmp4j.MessageDispatcher;
024: import org.snmp4j.smi.Address;
025: import org.snmp4j.asn1.BERInputStream;
026: import org.snmp4j.smi.Integer32;
027: import org.snmp4j.smi.OctetString;
028: import org.snmp4j.MutablePDU;
029: import java.io.IOException;
030: import org.snmp4j.PDU;
031: import org.snmp4j.log.*;
032: import org.snmp4j.ScopedPDU;
033: import org.snmp4j.asn1.BER;
034: import org.snmp4j.security.SecurityModel;
035: import org.snmp4j.asn1.BER.MutableByte;
036: import org.snmp4j.security.SecurityModels;
037: import org.snmp4j.security.SecurityLevel;
038: import org.snmp4j.asn1.BEROutputStream;
039: import java.nio.ByteBuffer;
040: import org.snmp4j.util.PDUFactory;
041: import org.snmp4j.Target;
042:
043: /**
044: * The <code>MPv2c</code> is the message processing model for SNMPv2c
045: * (community based SNMPv2).
046: *
047: * @author Frank Fock
048: * @version 1.9.1
049: */
050: public class MPv2c implements MessageProcessingModel {
051:
052: public static final int ID = MessageProcessingModel.MPv2c;
053: private static final LogAdapter logger = LogFactory
054: .getLogger(MPv2c.class);
055:
056: protected PDUFactory incomingPDUFactory = new PDUFactory() {
057: public PDU createPDU(Target target) {
058: return new PDU();
059: }
060: };
061:
062: /**
063: * Creates a SNMPv2c message processing model with a PDU factory for incoming
064: * messages that uses {@link PDU}.
065: */
066: public MPv2c() {
067: }
068:
069: /**
070: * Creates a SNMPv2c message processing model with a custom PDU factory that
071: * must ignore the target parameter when creating a PDU for parsing incoming
072: * messages.
073: * @param incomingPDUFactory
074: * a {@link PDUFactory}. If <code>null</code> the default factory will be
075: * used which creates {@link ScopedPDU} instances.
076: */
077: public MPv2c(PDUFactory incomingPDUFactory) {
078: if (incomingPDUFactory != null) {
079: this .incomingPDUFactory = incomingPDUFactory;
080: }
081: }
082:
083: public int getID() {
084: return ID;
085: }
086:
087: public int prepareOutgoingMessage(Address transportAddress,
088: int maxMessageSize, int messageProcessingModel,
089: int securityModel, byte[] securityName, int securityLevel,
090: PDU pdu, boolean expectResponse, PduHandle sendPduHandle,
091: Address destTransportAddress,
092: BEROutputStream outgoingMessage) throws IOException {
093: if ((securityLevel != SecurityLevel.NOAUTH_NOPRIV)
094: || (securityModel != SecurityModel.SECURITY_MODEL_SNMPv2c)) {
095: logger.error("MPv2c used with unsupported security model");
096: return SnmpConstants.SNMP_MP_UNSUPPORTED_SECURITY_MODEL;
097: }
098: if (pdu instanceof ScopedPDU) {
099: String txt = "ScopedPDU must not be used with MPv2c";
100: logger.error(txt);
101: throw new IllegalArgumentException(txt);
102: }
103:
104: if (!isProtocolVersionSupported(messageProcessingModel)) {
105: logger.error("MPv2c used with unsupported SNMP version");
106: return SnmpConstants.SNMP_MP_UNSUPPORTED_SECURITY_MODEL;
107: }
108:
109: OctetString community = new OctetString(securityName);
110: Integer32 version = new Integer32(messageProcessingModel);
111: // compute total length
112: int length = pdu.getBERLength();
113: length += community.getBERLength();
114: length += version.getBERLength();
115:
116: ByteBuffer buf = ByteBuffer.allocate(length
117: + BER.getBERLengthOfLength(length) + 1);
118: // set the buffer of the outgoing message
119: outgoingMessage.setBuffer(buf);
120:
121: // encode the message
122: BER.encodeHeader(outgoingMessage, BER.SEQUENCE, length);
123: version.encodeBER(outgoingMessage);
124:
125: community.encodeBER(outgoingMessage);
126: pdu.encodeBER(outgoingMessage);
127:
128: return SnmpConstants.SNMP_MP_OK;
129: }
130:
131: public int prepareResponseMessage(int messageProcessingModel,
132: int maxMessageSize, int securityModel, byte[] securityName,
133: int securityLevel, PDU pdu, int maxSizeResponseScopedPDU,
134: StateReference stateReference,
135: StatusInformation statusInformation,
136: BEROutputStream outgoingMessage) throws IOException {
137: return prepareOutgoingMessage(stateReference.getAddress(),
138: maxMessageSize, messageProcessingModel, securityModel,
139: securityName, securityLevel, pdu, false, stateReference
140: .getPduHandle(), null, outgoingMessage);
141: }
142:
143: public int prepareDataElements(MessageDispatcher messageDispatcher,
144: Address transportAddress, BERInputStream wholeMsg,
145: Integer32 messageProcessingModel, Integer32 securityModel,
146: OctetString securityName, Integer32 securityLevel,
147: MutablePDU pdu, PduHandle sendPduHandle,
148: Integer32 maxSizeResponseScopedPDU,
149: StatusInformation statusInformation,
150: MutableStateReference stateReference) throws IOException {
151:
152: MutableByte mutableByte = new MutableByte();
153: int length = BER.decodeHeader(wholeMsg, mutableByte);
154: int startPos = (int) wholeMsg.getPosition();
155:
156: if (mutableByte.getValue() != BER.SEQUENCE) {
157: String txt = "SNMPv2c PDU must start with a SEQUENCE";
158: logger.error(txt);
159: throw new IOException(txt);
160: }
161: Integer32 version = new Integer32();
162: version.decodeBER(wholeMsg);
163:
164: securityName.decodeBER(wholeMsg);
165: securityLevel.setValue(SecurityLevel.NOAUTH_NOPRIV);
166: securityModel.setValue(SecurityModel.SECURITY_MODEL_SNMPv2c);
167: messageProcessingModel.setValue(ID);
168:
169: PDU v2cPDU = incomingPDUFactory.createPDU(null);
170: pdu.setPdu(v2cPDU);
171: v2cPDU.decodeBER(wholeMsg);
172:
173: BER.checkSequenceLength(length, (int) wholeMsg.getPosition()
174: - startPos, v2cPDU);
175:
176: sendPduHandle
177: .setTransactionID(v2cPDU.getRequestID().getValue());
178:
179: // create state reference
180: StateReference stateRef = new StateReference(sendPduHandle,
181: transportAddress, null, SecurityModels.getInstance()
182: .getSecurityModel(securityModel), securityName
183: .getValue(), SnmpConstants.SNMP_ERROR_SUCCESS);
184: stateReference.setStateReference(stateRef);
185:
186: return SnmpConstants.SNMP_MP_OK;
187: }
188:
189: public boolean isProtocolVersionSupported(int snmpProtocolVersion) {
190: return (snmpProtocolVersion == SnmpConstants.version2c);
191: }
192:
193: public void releaseStateReference(PduHandle pduHandle) {
194: // we do not cache state information -> do nothing
195: }
196:
197: }
|