KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jmx > snmp > SnmpMessage


1 /*
2  * @(#)file SnmpMessage.java
3  * @(#)author Sun Microsystems, Inc.
4  * @(#)version 4.31
5  * @(#)date 08/02/09
6  *
7  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
8  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
9  *
10  */

11
12
13 package com.sun.jmx.snmp;
14
15
16 // "@(#)SnmpMessage.java 1.1 98/07/23 SMI"
17

18 // java imports
19
//
20
import java.util.Vector JavaDoc;
21 import java.net.InetAddress JavaDoc;
22
23 // import debug stuff
24
//
25
import com.sun.jmx.trace.Trace;
26
27 /**
28  * Is a partially decoded representation of an SNMP packet.
29  * <P>
30  * You will not normally need to use this class unless you decide to
31  * implement your own {@link com.sun.jmx.snmp.SnmpPduFactory SnmpPduFactory} object.
32  * <P>
33  * The <CODE>SnmpMessage</CODE> class is directly mapped onto the
34  * <CODE>Message</CODE> syntax defined in RFC1157 and RFC1902.
35  * <BLOCKQUOTE>
36  * <PRE>
37  * Message ::= SEQUENCE {
38  * version INTEGER { version(1) }, -- for SNMPv2
39  * community OCTET STRING, -- community name
40  * data ANY -- an SNMPv2 PDU
41  * }
42  * </PRE>
43  * </BLOCKQUOTE>
44  *
45  * <p><b>This API is a Sun Microsystems internal API and is subject
46  * to change without notice.</b></p>
47  * @see SnmpPduFactory
48  * @see SnmpPduPacket
49  *
50  * @version 1.1 07/23/98
51  * @author Sun Microsystems, Inc
52  */

53
54 public class SnmpMessage extends SnmpMsg implements SnmpDefinitions {
55     /**
56      * Community name.
57      */

58     public byte[] community ;
59   
60     /**
61      * Encodes this message and puts the result in the specified byte array.
62      * For internal use only.
63      *
64      * @param outputBytes An array to receive the resulting encoding.
65      *
66      * @exception ArrayIndexOutOfBoundsException If the result does not fit
67      * into the specified array.
68      */

69     public int encodeMessage(byte[] outputBytes) throws SnmpTooBigException {
70         int encodingLength = 0 ;
71         if (data == null)
72             throw new IllegalArgumentException JavaDoc("Data field is null") ;
73
74         //
75
// Reminder: BerEncoder does backward encoding !
76
//
77
try {
78             BerEncoder benc = new BerEncoder(outputBytes) ;
79             benc.openSequence() ;
80             benc.putAny(data, dataLength) ;
81             benc.putOctetString((community != null) ? community : new byte[0]) ;
82             benc.putInteger(version) ;
83             benc.closeSequence() ;
84             encodingLength = benc.trim() ;
85         }
86         catch(ArrayIndexOutOfBoundsException JavaDoc x) {
87             throw new SnmpTooBigException() ;
88         }
89     
90         return encodingLength ;
91     }
92     /**
93      * Returns the associated request ID.
94      * @param inputBytes The flat message.
95      * @return The request ID.
96      *
97      * @since 1.5
98      */

99     public int getRequestId(byte[] inputBytes) throws SnmpStatusException {
100     int requestId = 0;
101     BerDecoder bdec = null;
102     BerDecoder bdec2 = null;
103     byte[] any = null;
104     try {
105         bdec = new BerDecoder(inputBytes);
106         bdec.openSequence();
107         bdec.fetchInteger();
108             bdec.fetchOctetString();
109         any = bdec.fetchAny();
110         bdec2 = new BerDecoder(any);
111             int type = bdec2.getTag();
112             bdec2.openSequence(type);
113         requestId = bdec2.fetchInteger();
114     }
115         catch(BerException x) {
116             throw new SnmpStatusException("Invalid encoding") ;
117         }
118     try {
119         bdec.closeSequence();
120     }
121         catch(BerException x) {
122         }
123     try {
124         bdec2.closeSequence();
125     }
126         catch(BerException x) {
127         }
128     return requestId;
129     }
130     /**
131      * Decodes the specified bytes and initializes this message.
132      * For internal use only.
133      *
134      * @param inputBytes The bytes to be decoded.
135      *
136      * @exception SnmpStatusException If the specified bytes are not a valid encoding.
137      */

138     public void decodeMessage(byte[] inputBytes, int byteCount)
139         throws SnmpStatusException {
140         try {
141             BerDecoder bdec = new BerDecoder(inputBytes/*, byteCount */) ; // FIXME
142
bdec.openSequence() ;
143             version = bdec.fetchInteger() ;
144             community = bdec.fetchOctetString() ;
145             data = bdec.fetchAny() ;
146             dataLength = data.length ;
147             bdec.closeSequence() ;
148         }
149         catch(BerException x) {
150             throw new SnmpStatusException("Invalid encoding") ;
151         }
152     }
153   
154     /**
155      * Initializes this message with the specified <CODE>pdu</CODE>.
156      * <P>
157      * This method initializes the data field with an array of
158      * <CODE>maxDataLength</CODE> bytes. It encodes the <CODE>pdu</CODE>.
159      * The resulting encoding is stored in the data field
160      * and the length of the encoding is stored in <CODE>dataLength</CODE>.
161      * <p>
162      * If the encoding length exceeds <CODE>maxDataLength</CODE>,
163      * the method throws an exception.
164      *
165      * @param pdu The PDU to be encoded.
166      * @param maxDataLength The maximum length permitted for the data field.
167      *
168      * @exception SnmpStatusException If the specified <CODE>pdu</CODE> is not valid.
169      * @exception SnmpTooBigException If the resulting encoding does not fit
170      * into <CODE>maxDataLength</CODE> bytes.
171      * @exception ArrayIndexOutOfBoundsException If the encoding exceeds <CODE>maxDataLength</CODE>.
172      *
173      * @since 1.5
174      */

175     public void encodeSnmpPdu(SnmpPdu pdu, int maxDataLength)
176         throws SnmpStatusException, SnmpTooBigException {
177     //
178
// The easy work
179
//
180
SnmpPduPacket pdupacket = (SnmpPduPacket) pdu;
181         version = pdupacket.version ;
182         community = pdupacket.community ;
183         address = pdupacket.address ;
184         port = pdupacket.port ;
185     
186         //
187
// Allocate the array to receive the encoding.
188
//
189
data = new byte[maxDataLength] ;
190     
191         //
192
// Encode the pdupacket
193
// Reminder: BerEncoder does backward encoding !
194
//
195

196         try {
197             BerEncoder benc = new BerEncoder(data) ;
198             benc.openSequence() ;
199             encodeVarBindList(benc, pdupacket.varBindList) ;
200
201             switch(pdupacket.type) {
202
203             case pduGetRequestPdu :
204             case pduGetNextRequestPdu :
205             case pduInformRequestPdu :
206             case pduGetResponsePdu :
207             case pduSetRequestPdu :
208             case pduV2TrapPdu :
209             case pduReportPdu :
210                 SnmpPduRequest reqPdu = (SnmpPduRequest)pdupacket ;
211                 benc.putInteger(reqPdu.errorIndex) ;
212                 benc.putInteger(reqPdu.errorStatus) ;
213                 benc.putInteger(reqPdu.requestId) ;
214                 break ;
215
216             case pduGetBulkRequestPdu :
217                 SnmpPduBulk bulkPdu = (SnmpPduBulk)pdupacket ;
218                 benc.putInteger(bulkPdu.maxRepetitions) ;
219                 benc.putInteger(bulkPdu.nonRepeaters) ;
220                 benc.putInteger(bulkPdu.requestId) ;
221                 break ;
222
223             case pduV1TrapPdu :
224                 SnmpPduTrap trapPdu = (SnmpPduTrap)pdupacket ;
225                 benc.putInteger(trapPdu.timeStamp, SnmpValue.TimeticksTag) ;
226                 benc.putInteger(trapPdu.specificTrap) ;
227                 benc.putInteger(trapPdu.genericTrap) ;
228         if(trapPdu.agentAddr != null)
229             benc.putOctetString(trapPdu.agentAddr.byteValue(), SnmpValue.IpAddressTag) ;
230         else
231             benc.putOctetString(new byte[0], SnmpValue.IpAddressTag);
232                 benc.putOid(trapPdu.enterprise.longValue()) ;
233                 break ;
234
235             default:
236                 throw new SnmpStatusException("Invalid pdu type " + String.valueOf(pdupacket.type)) ;
237             }
238             benc.closeSequence(pdupacket.type) ;
239             dataLength = benc.trim() ;
240         }
241         catch(ArrayIndexOutOfBoundsException JavaDoc x) {
242             throw new SnmpTooBigException() ;
243         }
244     }
245     /**
246      * Gets the PDU encoded in this message.
247      * <P>
248      * This method decodes the data field and returns the resulting PDU.
249      *
250      * @return The resulting PDU.
251      * @exception SnmpStatusException If the encoding is not valid.
252      *
253      * @since 1.5
254      */

255     public SnmpPdu decodeSnmpPdu()
256         throws SnmpStatusException {
257     //
258
// Decode the pdu
259
//
260
SnmpPduPacket pdu = null ;
261         BerDecoder bdec = new BerDecoder(data) ;
262         try {
263             int type = bdec.getTag() ;
264             bdec.openSequence(type) ;
265             switch(type) {
266         
267             case pduGetRequestPdu :
268             case pduGetNextRequestPdu :
269             case pduInformRequestPdu :
270             case pduGetResponsePdu :
271             case pduSetRequestPdu :
272             case pduV2TrapPdu :
273             case pduReportPdu :
274                 SnmpPduRequest reqPdu = new SnmpPduRequest() ;
275                 reqPdu.requestId = bdec.fetchInteger() ;
276                 reqPdu.errorStatus = bdec.fetchInteger() ;
277                 reqPdu.errorIndex = bdec.fetchInteger() ;
278                 pdu = reqPdu ;
279                 break ;
280
281             case pduGetBulkRequestPdu :
282                 SnmpPduBulk bulkPdu = new SnmpPduBulk() ;
283                 bulkPdu.requestId = bdec.fetchInteger() ;
284                 bulkPdu.nonRepeaters = bdec.fetchInteger() ;
285                 bulkPdu.maxRepetitions = bdec.fetchInteger() ;
286                 pdu = bulkPdu ;
287                 break ;
288
289             case pduV1TrapPdu :
290                 SnmpPduTrap trapPdu = new SnmpPduTrap() ;
291                 trapPdu.enterprise = new SnmpOid(bdec.fetchOid()) ;
292         byte []b = bdec.fetchOctetString(SnmpValue.IpAddressTag);
293         if(b.length != 0)
294             trapPdu.agentAddr = new SnmpIpAddress(b) ;
295         else
296             trapPdu.agentAddr = null;
297                 trapPdu.genericTrap = bdec.fetchInteger() ;
298                 trapPdu.specificTrap = bdec.fetchInteger() ;
299                 trapPdu.timeStamp = bdec.fetchInteger(SnmpValue.TimeticksTag) ;
300                 pdu = trapPdu ;
301                 break ;
302
303             default:
304                 throw new SnmpStatusException(snmpRspWrongEncoding) ;
305             }
306             pdu.type = type ;
307             pdu.varBindList = decodeVarBindList(bdec) ;
308             bdec.closeSequence() ;
309         } catch(BerException e) {
310             if (isDebugOn()) {
311                 debug("decodeSnmpPdu", e);
312             }
313             throw new SnmpStatusException(snmpRspWrongEncoding);
314         } catch(IllegalArgumentException JavaDoc e) {
315         // bug id 4654066
316
if (isDebugOn()) {
317                 debug("decodeSnmpPdu", e);
318             }
319             throw new SnmpStatusException(snmpRspWrongEncoding);
320         }
321     
322         //
323
// The easy work
324
//
325
pdu.version = version ;
326         pdu.community = community ;
327         pdu.address = address ;
328         pdu.port = port ;
329     
330         return pdu;
331     }
332     /**
333      * Dumps this message in a string.
334      *
335      * @return The string containing the dump.
336      */

337     public String JavaDoc printMessage() {
338     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
339     if (community == null) {
340             sb.append("Community: null") ;
341         }
342         else {
343             sb.append("Community: {\n") ;
344             sb.append(dumpHexBuffer(community, 0, community.length)) ;
345             sb.append("\n}\n") ;
346         }
347     return sb.append(super.printMessage()).toString();
348     }
349     // TRACES & DEBUG
350
//---------------
351

352     boolean isTraceOn() {
353         return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_SNMP);
354     }
355
356     void trace(String JavaDoc clz, String JavaDoc func, String JavaDoc info) {
357         Trace.send(Trace.LEVEL_TRACE, Trace.INFO_SNMP, clz, func, info);
358     }
359
360     void trace(String JavaDoc func, String JavaDoc info) {
361         trace(dbgTag, func, info);
362     }
363     
364     boolean isDebugOn() {
365         return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_SNMP);
366     }
367
368     void debug(String JavaDoc clz, String JavaDoc func, String JavaDoc info) {
369         Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_SNMP, clz, func, info);
370     }
371
372     void debug(String JavaDoc clz, String JavaDoc func, Throwable JavaDoc exception) {
373         Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_SNMP, clz, func, exception);
374     }
375
376     void debug(String JavaDoc func, String JavaDoc info) {
377         debug(dbgTag, func, info);
378     }
379     
380     void debug(String JavaDoc func, Throwable JavaDoc exception) {
381         debug(dbgTag, func, exception);
382     }
383     
384     String JavaDoc dbgTag = "SnmpMessage";
385 }
386
387
388
389
390
Popular Tags