001: /*
002: * SNMP Package
003: *
004: * Copyright (C) 2004, Jonathan Sevy <jsevy@mcs.drexel.edu>
005: *
006: * This is free software. Redistribution and use in source and binary forms, with
007: * or without modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright notice, this
011: * list of conditions and the following disclaimer.
012: * 2. Redistributions in binary form must reproduce the above copyright notice,
013: * this list of conditions and the following disclaimer in the documentation
014: * and/or other materials provided with the distribution.
015: * 3. The name of the author may not be used to endorse or promote products
016: * derived from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
019: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
020: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
021: * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
023: * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
024: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
025: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
026: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: *
028: */
029:
030: package snmp;
031:
032: import java.util.*;
033: import java.math.*;
034:
035: /**
036: * The SNMPPDU class represents an SNMP PDU from RFC 1157, as indicated below. This
037: * forms the payload of an SNMP message.
038:
039: -- protocol data units
040:
041: PDUs ::=
042: CHOICE {
043: get-request
044: GetRequest-PDU,
045:
046: get-next-request
047: GetNextRequest-PDU,
048:
049: get-response
050: GetResponse-PDU,
051:
052: set-request
053: SetRequest-PDU,
054:
055: trap
056: Trap-PDU
057: }
058:
059: -- PDUs
060:
061: GetRequest-PDU ::=
062: [0]
063: IMPLICIT PDU
064:
065: GetNextRequest-PDU ::=
066: [1]
067: IMPLICIT PDU
068:
069: GetResponse-PDU ::=
070: [2]
071: IMPLICIT PDU
072:
073: SetRequest-PDU ::=
074: [3]
075: IMPLICIT PDU
076:
077: PDU ::=
078: SEQUENCE {
079: request-id
080: INTEGER,
081:
082: error-status -- sometimes ignored
083: INTEGER {
084: noError(0),
085: tooBig(1),
086: noSuchName(2),
087: badValue(3),
088: readOnly(4),
089: genErr(5)
090: },
091:
092: error-index -- sometimes ignored
093: INTEGER,
094:
095: variable-bindings -- values are sometimes ignored
096: VarBindList
097: }
098:
099:
100:
101: -- variable bindings
102:
103: VarBind ::=
104: SEQUENCE {
105: name
106: ObjectName,
107:
108: value
109: ObjectSyntax
110: }
111:
112: VarBindList ::=
113: SEQUENCE OF
114: VarBind
115:
116: END
117:
118: */
119:
120: public class SNMPPDU extends SNMPSequence {
121:
122: /**
123: * Create a new PDU of the specified type, with given request ID, error status, and error index,
124: * and containing the supplied SNMP sequence as data.
125: */
126:
127: public SNMPPDU(byte pduType, int requestID, int errorStatus,
128: int errorIndex, SNMPSequence varList)
129: throws SNMPBadValueException {
130: super ();
131: Vector contents = new Vector();
132: tag = pduType;
133: contents.insertElementAt(new SNMPInteger(requestID), 0);
134: contents.insertElementAt(new SNMPInteger(errorStatus), 1);
135: contents.insertElementAt(new SNMPInteger(errorIndex), 2);
136: contents.insertElementAt(varList, 3);
137: this .setValue(contents);
138: }
139:
140: /**
141: * Create a new PDU of the specified type from the supplied BER encoding.
142: * @throws SNMPBadValueException Indicates invalid SNMP PDU encoding supplied in enc.
143: */
144:
145: protected SNMPPDU(byte[] enc, byte pduType)
146: throws SNMPBadValueException {
147: tag = pduType;
148: extractFromBEREncoding(enc);
149:
150: // validate the message: make sure we have the appropriate pieces
151: Vector contents = (Vector) (this .getValue());
152:
153: if (contents.size() != 4) {
154: throw new SNMPBadValueException("Bad PDU");
155: }
156:
157: if (!(contents.elementAt(0) instanceof SNMPInteger)) {
158: throw new SNMPBadValueException("Bad PDU: bad request ID");
159: }
160:
161: if (!(contents.elementAt(1) instanceof SNMPInteger)) {
162: throw new SNMPBadValueException("Bad PDU: bad error status");
163: }
164:
165: if (!(contents.elementAt(2) instanceof SNMPInteger)) {
166: throw new SNMPBadValueException("Bad PDU: bad error index");
167: }
168:
169: if (!(contents.elementAt(3) instanceof SNMPSequence)) {
170: throw new SNMPBadValueException(
171: "Bad PDU: bad variable binding list");
172: }
173:
174: // now validate the variable binding list: should be list of sequences which
175: // are (OID, value) pairs
176: SNMPSequence varBindList = this .getVarBindList();
177: for (int i = 0; i < varBindList.size(); i++) {
178: SNMPObject element = varBindList.getSNMPObjectAt(i);
179:
180: // must be a two-element sequence
181: if (!(element instanceof SNMPSequence)) {
182: throw new SNMPBadValueException(
183: "Bad PDU: bad variable binding at index" + i);
184: }
185:
186: // variable binding sequence must have 2 elements, first of which must be an object identifier
187: SNMPSequence varBind = (SNMPSequence) element;
188: if ((varBind.size() != 2)
189: || !(varBind.getSNMPObjectAt(0) instanceof SNMPObjectIdentifier)) {
190: throw new SNMPBadValueException(
191: "Bad PDU: bad variable binding at index" + i);
192: }
193: }
194:
195: }
196:
197: /**
198: * A utility method that extracts the variable binding list from the pdu. Useful for retrieving
199: * the set of (object identifier, value) pairs returned in response to a request to an SNMP
200: * device. The variable binding list is just an SNMP sequence containing the identifier, value pairs.
201: * @see snmp.SNMPVarBindList
202: */
203:
204: public SNMPSequence getVarBindList() {
205: Vector contents = (Vector) (this .getValue());
206: return (SNMPSequence) (contents.elementAt(3));
207: }
208:
209: /**
210: * A utility method that extracts the request ID number from this PDU.
211: */
212:
213: public int getRequestID() {
214: Vector contents = (Vector) (this .getValue());
215: return ((BigInteger) ((SNMPInteger) (contents.elementAt(0)))
216: .getValue()).intValue();
217: }
218:
219: /**
220: * A utility method that extracts the error status for this PDU; if nonzero, can get index of
221: * problematic variable using getErrorIndex().
222: */
223:
224: public int getErrorStatus() {
225: Vector contents = (Vector) (this .getValue());
226: return ((BigInteger) ((SNMPInteger) (contents.elementAt(1)))
227: .getValue()).intValue();
228: }
229:
230: /**
231: * A utility method that returns the error index for this PDU, identifying the problematic variable.
232: */
233:
234: public int getErrorIndex() {
235: Vector contents = (Vector) (this .getValue());
236: return ((BigInteger) ((SNMPInteger) (contents.elementAt(2)))
237: .getValue()).intValue();
238: }
239:
240: /**
241: * A utility method that returns the PDU type of this PDU.
242: */
243:
244: public byte getPDUType() {
245: return tag;
246: }
247:
248: }
|