KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > snmp > SNMPBERCodec


1 /*
2  * SNMP Package
3  *
4  * Copyright (C) 2004, Jonathan Sevy <jsevy@mcs.drexel.edu>
5  *
6  * This is free software. Redistribution and use in source and binary forms, with
7  * or without modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice, this
11  * list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  * derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
19  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
21  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
23  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */

29
30
31 package snmp;
32
33
34 import java.io.*;
35
36
37 /**
38 * SNMPBERCodec defines methods for converting from ASN.1 BER encoding to SNMPObject subclasses. The extraction
39 * process usually produces a tree structure of objects with an SNMPSequence object at the root; this
40 * is the usual behavior when a received encoded message is received from an SNMP device.
41 */

42
43
44
45 public class SNMPBERCodec
46 {
47     
48     public static final byte SNMPINTEGER = 0x02;
49     public static final byte SNMPBITSTRING = 0x03;
50     public static final byte SNMPOCTETSTRING = 0x04;
51     public static final byte SNMPNULL = 0x05;
52     public static final byte SNMPOBJECTIDENTIFIER = 0x06;
53     public static final byte SNMPSEQUENCE = 0x30;
54     
55     public static final byte SNMPIPADDRESS = (byte)0x40;
56     public static final byte SNMPCOUNTER32 = (byte)0x41;
57     public static final byte SNMPGAUGE32 = (byte)0x42;
58     public static final byte SNMPTIMETICKS = (byte)0x43;
59     public static final byte SNMPOPAQUE = (byte)0x44;
60     public static final byte SNMPNSAPADDRESS = (byte)0x45;
61     public static final byte SNMPCOUNTER64 = (byte)0x46;
62     public static final byte SNMPUINTEGER32 = (byte)0x47;
63     
64     public static final byte SNMPGETREQUEST = (byte)0xA0;
65     public static final byte SNMPGETNEXTREQUEST = (byte)0xA1;
66     public static final byte SNMPGETRESPONSE = (byte)0xA2;
67     public static final byte SNMPSETREQUEST = (byte)0xA3;
68     public static final byte SNMPTRAP = (byte)0xA4;
69     
70     
71     // SNMPv2 constants
72
public static final byte SNMPv2pCOMMUNICATION = (byte)0xA2;
73     public static final byte SNMPv2pAUTHORIZEDMESSAGE = (byte)0xA1;
74     public static final byte SNMPv2pENCRYPTEDMESSAGE = (byte)0xA1;
75     public static final byte SNMPv2BULKREQUEST = (byte)0xA5;
76     public static final byte SNMPv2INFORMREQUEST = (byte)0xA6;
77     public static final byte SNMPv2TRAP = (byte)0xA7;
78     
79     public static final byte SNMPv2pENCRYPTEDDATA = (byte)0xA1;
80     
81     
82     public static final byte SNMPUNKNOWNOBJECT = 0x00;
83     
84     
85     
86     
87     
88     
89     /**
90     * Extracts an SNMP object given its type, length, value triple as an SNMPTLV object.
91     * Called by SNMPObject subclass constructors.
92     * @throws SNMPBadValueException Indicates byte array in value field is uninterprettable for
93     * specified SNMP object type.
94     */

95     public static SNMPObject extractEncoding(SNMPTLV theTLV)
96         throws SNMPBadValueException
97     {
98     
99         
100         switch (theTLV.tag)
101         {
102             case SNMPINTEGER:
103             {
104                 return new SNMPInteger(theTLV.value);
105             }
106             
107             case SNMPSEQUENCE:
108             {
109                 return new SNMPSequence(theTLV.value);
110             }
111             
112             case SNMPOBJECTIDENTIFIER:
113             {
114                 return new SNMPObjectIdentifier(theTLV.value);
115             }
116             
117             case SNMPOCTETSTRING:
118             {
119                 return new SNMPOctetString(theTLV.value);
120             }
121             
122             case SNMPBITSTRING:
123             {
124                 return new SNMPBitString(theTLV.value);
125             }
126             
127             case SNMPIPADDRESS:
128             {
129                 return new SNMPIPAddress(theTLV.value);
130             }
131             
132             case SNMPCOUNTER32:
133             {
134                 return new SNMPCounter32(theTLV.value);
135             }
136             
137             case SNMPGAUGE32:
138             {
139                 return new SNMPGauge32(theTLV.value);
140             }
141             
142             case SNMPTIMETICKS:
143             {
144                 return new SNMPTimeTicks(theTLV.value);
145             }
146             
147             case SNMPNSAPADDRESS:
148             {
149                 return new SNMPNSAPAddress(theTLV.value);
150             }
151             
152             case SNMPCOUNTER64:
153             {
154                 return new SNMPCounter64(theTLV.value);
155             }
156             
157             case SNMPUINTEGER32:
158             {
159                 return new SNMPUInteger32(theTLV.value);
160             }
161                 
162             case SNMPGETREQUEST:
163             case SNMPGETNEXTREQUEST:
164             case SNMPGETRESPONSE:
165             case SNMPSETREQUEST:
166             {
167                 return new SNMPPDU(theTLV.value, theTLV.tag);
168             }
169             
170             case SNMPTRAP:
171             {
172                 return new SNMPv1TrapPDU(theTLV.value);
173             }
174             
175             case SNMPv2TRAP:
176             {
177                 return new SNMPv2TrapPDU(theTLV.value);
178             }
179             
180             case SNMPv2INFORMREQUEST:
181             {
182                 return new SNMPv2InformRequestPDU(theTLV.value);
183             }
184             
185             case SNMPNULL:
186             case SNMPOPAQUE:
187             {
188                 return new SNMPNull();
189             }
190             
191             default:
192             {
193                 //System.out.println("Unrecognized tag");
194
//return new SNMPOctetString(theTLV.value);
195
return new SNMPUnknownObject(theTLV.value);
196             }
197         }
198     
199     }
200     
201     
202     
203     
204     
205     /**
206     * Extracts the type, length and value of the SNMP object whose BER encoding begins at the
207     * specified position in the given byte array. Throws an SNMPBadValueException if there's
208     * any problem with the extraction.
209     */

210     
211     public static SNMPTLV extractNextTLV(byte[] enc, int position)
212         throws SNMPBadValueException
213     {
214         SNMPTLV nextTLV = new SNMPTLV();
215         int currentPos = position;
216         
217         
218         try
219         {
220         
221             // get tag
222

223             /*
224             if ((enc[currentPos] % 32) < 31)
225             {
226                 // single byte tag; extract value
227                 nextTLV.tag = (int)(enc[currentPos]);
228             }
229             else
230             {
231                 // multiple byte tag; for now, just return value in subsequent bytes ...
232                 // but need to think about universal / application fields, etc...
233                 nextTLV.tag = 0;
234                 
235                 do
236                 {
237                     currentPos++;
238                     nextTLV.tag = nextTLV.tag * 128 + (int)(enc[currentPos] % 128);
239                 }
240                 while ((enc[currentPos]/128) >= 1);
241             }
242             */

243             
244             // single byte tag; extract value
245
nextTLV.tag = enc[currentPos];
246             currentPos++; // now at start of length info
247

248             // get length of data
249

250             int dataLength;
251             
252             int unsignedValue = enc[currentPos];
253             if (unsignedValue < 0)
254                 unsignedValue += 256;
255                 
256             if ((unsignedValue / 128) < 1)
257             {
258                 // single byte length; extract value
259
dataLength = unsignedValue;
260             }
261             else
262             {
263                 // multiple byte length; first byte's value (minus first bit) is # of length bytes
264
int numBytes = (unsignedValue % 128);
265                 
266                 dataLength = 0;
267                 
268                 for (int i = 0; i < numBytes; i++)
269                 {
270                     currentPos++;
271                     unsignedValue = enc[currentPos];
272                     if (unsignedValue < 0)
273                         unsignedValue += 256;
274                     dataLength = dataLength * 256 + unsignedValue;
275                 }
276             }
277             
278             
279             currentPos++; // now at start of data
280

281             // set total length
282
nextTLV.totalLength = currentPos - position + dataLength;
283             
284             // extract data portion
285

286             ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
287             outBytes.write(enc, currentPos, dataLength);
288             nextTLV.value = outBytes.toByteArray();
289                     
290             
291             return nextTLV;
292         
293         }
294         catch (IndexOutOfBoundsException JavaDoc e)
295         {
296             // whatever the exception, throw an SNMPBadValueException
297
throw new SNMPBadValueException("Problem while decoding SNMP: packet truncated or corrupt");
298         }
299         catch (Exception JavaDoc e)
300         {
301             // whatever the exception, throw an SNMPBadValueException
302
throw new SNMPBadValueException("Problem while decoding SNMP");
303         }
304             
305     }
306     
307     
308     
309     
310     /**
311     * Utility function for encoding a length as a BER byte sequence
312     */

313     
314     public static byte[] encodeLength(int length)
315     {
316         ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
317         
318         // see if can be represented in single byte
319
// don't forget the first bit is the "long field test" bit!!
320
if (length < 128)
321         {
322             byte[] len = {(byte)length};
323             outBytes.write(len, 0, 1);
324         }
325         else
326         {
327             // too big for one byte
328
// see how many are needed:
329
int numBytes = 0;
330             int temp = length;
331             while (temp > 0)
332             {
333                 ++numBytes;
334                 temp = (int)Math.floor(temp / 256);
335             }
336             
337             byte num = (byte)numBytes;
338             num += 128; // set the "long format" bit
339
outBytes.write(num);
340             
341             byte[] len = new byte[numBytes];
342             for (int i = numBytes-1; i >= 0; --i)
343             {
344                 len[i] = (byte)(length % 256);
345                 length = (int)Math.floor(length / 256);
346             }
347             outBytes.write(len, 0, numBytes);
348             
349         }
350         
351         return outBytes.toByteArray();
352     }
353     
354     
355     
356     
357 }
Popular Tags