New SNMP4SDN code.
[snmp4sdn.git] / third-party / snmpj / src / main / java / org / snmpj / SNMPPDU.java
1 /*\r
2  * SNMP Package\r
3  *\r
4  * Copyright (C) 2004, Jonathan Sevy <jsevy@mcs.drexel.edu>\r
5  *\r
6  * This is free software. Redistribution and use in source and binary forms, with\r
7  * or without modification, are permitted provided that the following conditions\r
8  * are met:\r
9  *\r
10  *  1. Redistributions of source code must retain the above copyright notice, this\r
11  *     list of conditions and the following disclaimer.\r
12  *  2. Redistributions in binary form must reproduce the above copyright notice,\r
13  *     this list of conditions and the following disclaimer in the documentation\r
14  *     and/or other materials provided with the distribution.\r
15  *  3. The name of the author may not be used to endorse or promote products\r
16  *     derived from this software without specific prior written permission.\r
17  *\r
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
19  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\r
21  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
23  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  *\r
28  */\r
29 \r
30 \r
31 package org.snmpj;\r
32 \r
33 import java.math.BigInteger;\r
34 import java.util.Vector;\r
35 \r
36 import org.snmpj.SNMPBadValueException;\r
37 import org.snmpj.SNMPInteger;\r
38 import org.snmpj.SNMPObject;\r
39 import org.snmpj.SNMPSequence;\r
40 \r
41 \r
42 \r
43 \r
44 /**\r
45 *    The SNMPPDU class represents an SNMP PDU from RFC 1157, as indicated below. This\r
46 *    forms the payload of an SNMP message.\r
47 \r
48 -- protocol data units\r
49 \r
50           PDUs ::=\r
51                   CHOICE {\r
52                               get-request\r
53                                   GetRequest-PDU,\r
54 \r
55                               get-next-request\r
56                                   GetNextRequest-PDU,\r
57 \r
58                               get-response\r
59                                   GetResponse-PDU,\r
60 \r
61                               set-request\r
62                                   SetRequest-PDU,\r
63 \r
64                               trap\r
65                                   Trap-PDU\r
66                           }\r
67 \r
68           -- PDUs\r
69 \r
70           GetRequest-PDU ::=\r
71               [0]\r
72                   IMPLICIT PDU\r
73 \r
74           GetNextRequest-PDU ::=\r
75               [1]\r
76                   IMPLICIT PDU\r
77 \r
78           GetResponse-PDU ::=\r
79               [2]\r
80                   IMPLICIT PDU\r
81 \r
82           SetRequest-PDU ::=\r
83               [3]\r
84                   IMPLICIT PDU\r
85 \r
86           PDU ::=\r
87                   SEQUENCE {\r
88                      request-id\r
89                           INTEGER,\r
90 \r
91                       error-status      -- sometimes ignored\r
92                           INTEGER {\r
93                               noError(0),\r
94                               tooBig(1),\r
95                               noSuchName(2),\r
96                               badValue(3),\r
97                               readOnly(4),\r
98                               genErr(5)\r
99                           },\r
100 \r
101                       error-index       -- sometimes ignored\r
102                          INTEGER,\r
103 \r
104                       variable-bindings -- values are sometimes ignored\r
105                           VarBindList\r
106                   }\r
107 \r
108 \r
109 \r
110           -- variable bindings\r
111 \r
112           VarBind ::=\r
113                   SEQUENCE {\r
114                       name\r
115                           ObjectName,\r
116 \r
117                       value\r
118                           ObjectSyntax\r
119                   }\r
120 \r
121          VarBindList ::=\r
122                   SEQUENCE OF\r
123                      VarBind\r
124 \r
125          END\r
126 \r
127 */\r
128 \r
129 \r
130 public class SNMPPDU extends SNMPSequence\r
131 {\r
132 \r
133 \r
134     /**\r
135     *    Create a new PDU of the specified type, with given request ID, error status, and error index,\r
136     *    and containing the supplied SNMP sequence as data.\r
137     */\r
138 \r
139     public SNMPPDU(byte pduType, int requestID, int errorStatus, int errorIndex, SNMPSequence varList)\r
140         throws SNMPBadValueException\r
141     {\r
142         super();\r
143         Vector contents = new Vector();\r
144         tag = pduType;\r
145         contents.insertElementAt(new SNMPInteger(requestID), 0);\r
146         contents.insertElementAt(new SNMPInteger(errorStatus), 1);\r
147         contents.insertElementAt(new SNMPInteger(errorIndex), 2);\r
148         contents.insertElementAt(varList, 3);\r
149         this.setValue(contents);\r
150     }\r
151 \r
152 \r
153 \r
154 \r
155     /**\r
156     *    Create a new PDU of the specified type from the supplied BER encoding.\r
157     *    @throws SNMPBadValueException Indicates invalid SNMP PDU encoding supplied in enc.\r
158     */\r
159 \r
160     protected SNMPPDU(byte[] enc, byte pduType)\r
161         throws SNMPBadValueException\r
162     {\r
163         tag = pduType;\r
164         extractFromBEREncoding(enc);\r
165 \r
166         // validate the message: make sure we have the appropriate pieces\r
167         Vector contents = (Vector)(this.getValue());\r
168 \r
169         if (contents.size() != 4)\r
170         {\r
171             throw new SNMPBadValueException("Bad PDU");\r
172         }\r
173 \r
174         if (!(contents.elementAt(0) instanceof SNMPInteger))\r
175         {\r
176             throw new SNMPBadValueException("Bad PDU: bad request ID");\r
177         }\r
178 \r
179         if (!(contents.elementAt(1) instanceof SNMPInteger))\r
180         {\r
181             throw new SNMPBadValueException("Bad PDU: bad error status");\r
182         }\r
183 \r
184         if (!(contents.elementAt(2) instanceof SNMPInteger))\r
185         {\r
186             throw new SNMPBadValueException("Bad PDU: bad error index");\r
187         }\r
188 \r
189         if (!(contents.elementAt(3) instanceof SNMPSequence))\r
190         {\r
191             throw new SNMPBadValueException("Bad PDU: bad variable binding list");\r
192         }\r
193 \r
194         // now validate the variable binding list: should be list of sequences which\r
195         // are (OID, value) pairs\r
196         SNMPSequence varBindList = this.getVarBindList();\r
197         for (int i = 0; i < varBindList.size(); i++)\r
198         {\r
199             SNMPObject element = varBindList.getSNMPObjectAt(i);\r
200 \r
201             // must be a two-element sequence\r
202             if (!(element instanceof SNMPSequence))\r
203             {\r
204                 throw new SNMPBadValueException("Bad PDU: bad variable binding at index" + i);\r
205             }\r
206 \r
207             // variable binding sequence must have 2 elements, first of which must be an object identifier\r
208             SNMPSequence varBind = (SNMPSequence)element;\r
209             if ((varBind.size() != 2) || !(varBind.getSNMPObjectAt(0) instanceof SNMPObjectIdentifier))\r
210             {\r
211                 throw new SNMPBadValueException("Bad PDU: bad variable binding at index" + i);\r
212             }\r
213         }\r
214 \r
215 \r
216     }\r
217 \r
218 \r
219 \r
220 \r
221     /**\r
222     *    A utility method that extracts the variable binding list from the pdu. Useful for retrieving\r
223     *    the set of (object identifier, value) pairs returned in response to a request to an SNMP\r
224     *    device. The variable binding list is just an SNMP sequence containing the identifier, value pairs.\r
225     *    @see snmp.SNMPVarBindList\r
226     */\r
227 \r
228     public SNMPSequence getVarBindList()\r
229     {\r
230         Vector contents = (Vector)(this.getValue());\r
231         return (SNMPSequence)(contents.elementAt(3));\r
232     }\r
233 \r
234 \r
235 \r
236     /**\r
237     *    A utility method that extracts the request ID number from this PDU.\r
238     */\r
239 \r
240     public int getRequestID()\r
241     {\r
242         Vector contents = (Vector)(this.getValue());\r
243         return ((BigInteger)((SNMPInteger)(contents.elementAt(0))).getValue()).intValue();\r
244     }\r
245 \r
246 \r
247 \r
248     /**\r
249     *    A utility method that extracts the error status for this PDU; if nonzero, can get index of\r
250     *    problematic variable using getErrorIndex().\r
251     */\r
252 \r
253     public int getErrorStatus()\r
254     {\r
255         Vector contents = (Vector)(this.getValue());\r
256         return ((BigInteger)((SNMPInteger)(contents.elementAt(1))).getValue()).intValue();\r
257     }\r
258 \r
259 \r
260 \r
261     /**\r
262     *    A utility method that returns the error index for this PDU, identifying the problematic variable.\r
263     */\r
264 \r
265     public int getErrorIndex()\r
266     {\r
267         Vector contents = (Vector)(this.getValue());\r
268         return ((BigInteger)((SNMPInteger)(contents.elementAt(2))).getValue()).intValue();\r
269     }\r
270 \r
271 \r
272 \r
273     /**\r
274     *    A utility method that returns the PDU type of this PDU.\r
275     */\r
276 \r
277     public byte getPDUType()\r
278     {\r
279         return tag;\r
280     }\r
281 \r
282 \r
283 }