KickJava   Java API By Example, From Geeks To Geeks.

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


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

11 package com.sun.jmx.snmp;
12
13 // java imports
14
//
15
import java.util.Vector JavaDoc;
16 import java.net.InetAddress JavaDoc;
17
18 // import debug stuff
19
//
20
import com.sun.jmx.trace.Trace;
21 import com.sun.jmx.snmp.internal.SnmpMsgProcessingSubSystem;
22 import com.sun.jmx.snmp.internal.SnmpSecurityModel;
23 import com.sun.jmx.snmp.internal.SnmpDecryptedPdu;
24 import com.sun.jmx.snmp.internal.SnmpSecurityCache;
25
26 import com.sun.jmx.snmp.SnmpMsg;
27 import com.sun.jmx.snmp.SnmpPdu;
28 import com.sun.jmx.snmp.SnmpStatusException;
29 import com.sun.jmx.snmp.SnmpTooBigException;
30 import com.sun.jmx.snmp.SnmpScopedPduBulk;
31 import com.sun.jmx.snmp.BerException;
32 import com.sun.jmx.snmp.SnmpScopedPduRequest;
33 import com.sun.jmx.snmp.BerDecoder;
34 import com.sun.jmx.snmp.SnmpDefinitions;
35 import com.sun.jmx.snmp.SnmpEngineId;
36 import com.sun.jmx.snmp.SnmpScopedPduPacket;
37 import com.sun.jmx.snmp.BerEncoder;
38 import com.sun.jmx.snmp.SnmpPduRequestType;
39 import com.sun.jmx.snmp.SnmpPduBulkType;
40
41 /**
42  * Is a partially decoded representation of an SNMP V3 packet.
43  * <P>
44  * This class can be used when developing customized manager or agent.
45  * <P>
46  * The <CODE>SnmpV3Message</CODE> class is directly mapped onto the
47  * message syntax defined in RFC 2572.
48  * <BLOCKQUOTE>
49  * <PRE>
50  * SNMPv3Message ::= SEQUENCE {
51  * msgVersion INTEGER ( 0 .. 2147483647 ),
52  * -- administrative parameters
53  * msgGlobalData HeaderData,
54  * -- security model-specific parameters
55  * -- format defined by Security Model
56  * msgSecurityParameters OCTET STRING,
57  * msgData ScopedPduData
58  * }
59  * HeaderData ::= SEQUENCE {
60  * msgID INTEGER (0..2147483647),
61  * msgMaxSize INTEGER (484..2147483647),
62  *
63  * msgFlags OCTET STRING (SIZE(1)),
64  * -- .... ...1 authFlag
65  * -- .... ..1. privFlag
66  * -- .... .1.. reportableFlag
67  * -- Please observe:
68  * -- .... ..00 is OK, means noAuthNoPriv
69  * -- .... ..01 is OK, means authNoPriv
70  * -- .... ..10 reserved, must NOT be used.
71  * -- .... ..11 is OK, means authPriv
72  *
73  * msgSecurityModel INTEGER (1..2147483647)
74  * }
75  * </BLOCKQUOTE>
76  * </PRE>
77  * <p><b>This API is a Sun Microsystems internal API and is subject
78  * to change without notice.</b></p>
79  * @since 1.5
80  */

81 public class SnmpV3Message extends SnmpMsg {
82   
83     /**
84      * Message identifier.
85      */

86     public int msgId = 0;
87
88     /**
89      * Message max size the pdu sender can deal with.
90      */

91     public int msgMaxSize = 0;
92     /**
93      * Message flags. Reportable flag and security level.</P>
94      *<PRE>
95      * -- .... ...1 authFlag
96      * -- .... ..1. privFlag
97      * -- .... .1.. reportableFlag
98      * -- Please observe:
99      * -- .... ..00 is OK, means noAuthNoPriv
100      * -- .... ..01 is OK, means authNoPriv
101      * -- .... ..10 reserved, must NOT be used.
102      * -- .... ..11 is OK, means authPriv
103      *</PRE>
104      */

105     public byte msgFlags = 0;
106     /**
107      * The security model the security sub system MUST use in order to deal with this pdu (eg: User based Security Model Id = 3).
108      */

109     public int msgSecurityModel = 0;
110     /**
111      * The unmarshalled security parameters.
112      */

113     public byte[] msgSecurityParameters = null;
114     /**
115      * The context engine Id in which the pdu must be handled (Generaly the local engine Id).
116      */

117     public byte[] contextEngineId = null;
118     /**
119      * The context name in which the OID has to be interpreted.
120      */

121     public byte[] contextName = null;
122     /** The encrypted form of the scoped pdu (Only relevant when dealing with privacy).
123      */

124     public byte[] encryptedPdu = null;
125
126     /**
127      * Constructor.
128      *
129      */

130     public SnmpV3Message() {
131     }
132     /**
133      * Encodes this message and puts the result in the specified byte array.
134      * For internal use only.
135      *
136      * @param outputBytes An array to receive the resulting encoding.
137      *
138      * @exception ArrayIndexOutOfBoundsException If the result does not fit
139      * into the specified array.
140      */

141     public int encodeMessage(byte[] outputBytes)
142     throws SnmpTooBigException {
143         int encodingLength = 0;
144     if(isTraceOn()) {
145         trace("encodeMessage", "Can't encode directly V3Message!!!!! Need a SecuritySubSystem");
146     }
147     throw new IllegalArgumentException JavaDoc("Can't encode");
148     }
149
150     /**
151      * Decodes the specified bytes and initializes this message.
152      * For internal use only.
153      *
154      * @param inputBytes The bytes to be decoded.
155      *
156      * @exception SnmpStatusException If the specified bytes are not a valid encoding.
157      */

158     public void decodeMessage(byte[] inputBytes, int byteCount)
159         throws SnmpStatusException {
160     
161         try {
162             BerDecoder bdec = new BerDecoder(inputBytes);
163             bdec.openSequence();
164             version = bdec.fetchInteger();
165         bdec.openSequence();
166         msgId = bdec.fetchInteger();
167         msgMaxSize = bdec.fetchInteger();
168         msgFlags = bdec.fetchOctetString()[0];
169         msgSecurityModel =bdec.fetchInteger();
170         bdec.closeSequence();
171         msgSecurityParameters = bdec.fetchOctetString();
172         if( (msgFlags & SnmpDefinitions.privMask) == 0 ) {
173         bdec.openSequence();
174         contextEngineId = bdec.fetchOctetString();
175         contextName = bdec.fetchOctetString();
176         data = bdec.fetchAny();
177         dataLength = data.length;
178         bdec.closeSequence();
179         }
180         else {
181         encryptedPdu = bdec.fetchOctetString();
182         }
183             bdec.closeSequence() ;
184         }
185         catch(BerException x) {
186         x.printStackTrace();
187             throw new SnmpStatusException("Invalid encoding") ;
188         }
189     
190     if(isTraceOn()) {
191         trace("decodeMessage", "Unmarshalled message : \n" +
192           "version :" + version + "\n" +
193           "msgId :" + msgId + "\n" +
194           "msgMaxSize :" + msgMaxSize + "\n" +
195           "msgFlags :" + msgFlags + "\n" +
196           "msgSecurityModel :" + msgSecurityModel + "\n" +
197           "contextEngineId :" + (contextEngineId == null ? null : SnmpEngineId.createEngineId(contextEngineId)) + "\n" +
198           "contextName :" + (contextName == null ? null : new String JavaDoc(contextName)) + "\n" +
199           "data :" + data + "\n" +
200           "dat len :" + ((data == null) ? 0 : data.length) + "\n" +
201           "encryptedPdu :" + encryptedPdu + "\n");
202     }
203     }
204
205     /**
206      * Returns the associated request Id.
207      * @param data The flat message.
208      * @return The request Id.
209      */

210     public int getRequestId(byte[] data) throws SnmpStatusException {
211     BerDecoder bdec = null;
212     int msgId = 0;
213     try {
214             bdec = new BerDecoder(data);
215             bdec.openSequence();
216             bdec.fetchInteger();
217         bdec.openSequence();
218         msgId = bdec.fetchInteger();
219     }catch(BerException x) {
220         throw new SnmpStatusException("Invalid encoding") ;
221     }
222     try {
223         bdec.closeSequence();
224     }
225     catch(BerException x) {
226     }
227     
228     return msgId;
229     }
230
231     /**
232      * Initializes this message with the specified <CODE>pdu</CODE>.
233      * <P>
234      * This method initializes the data field with an array of
235      * <CODE>maxDataLength</CODE> bytes. It encodes the <CODE>pdu</CODE>.
236      * The resulting encoding is stored in the data field
237      * and the length of the encoding is stored in <CODE>dataLength</CODE>.
238      * <p>
239      * If the encoding length exceeds <CODE>maxDataLength</CODE>,
240      * the method throws an exception.
241      *
242      * @param p The PDU to be encoded.
243      * @param maxDataLength The maximum length permitted for the data field.
244      *
245      * @exception SnmpStatusException If the specified <CODE>pdu</CODE>
246      * is not valid.
247      * @exception SnmpTooBigException If the resulting encoding does not fit
248      * into <CODE>maxDataLength</CODE> bytes.
249      * @exception ArrayIndexOutOfBoundsException If the encoding exceeds
250      * <CODE>maxDataLength</CODE>.
251      */

252     public void encodeSnmpPdu(SnmpPdu p,
253                   int maxDataLength)
254         throws SnmpStatusException, SnmpTooBigException {
255     
256     SnmpScopedPduPacket pdu = (SnmpScopedPduPacket) p;
257
258     if(isTraceOn()) {
259         trace("encodeSnmpPdu", "Pdu to marshall: \n" +
260           "security parameters : " + pdu.securityParameters + "\n" +
261           "type :" + pdu.type + "\n" +
262           "version :" + pdu.version + "\n" +
263           "requestId :" + pdu.requestId + "\n" +
264           "msgId :" + pdu.msgId + "\n" +
265           "msgMaxSize :" + pdu.msgMaxSize + "\n" +
266           "msgFlags :" + pdu.msgFlags + "\n" +
267           "msgSecurityModel :" + pdu.msgSecurityModel + "\n" +
268           "contextEngineId :" + pdu.contextEngineId + "\n" +
269           "contextName :" + pdu.contextName + "\n");
270     }
271
272         version = pdu.version;
273         address = pdu.address;
274         port = pdu.port;
275     msgId = pdu.msgId;
276     msgMaxSize = pdu.msgMaxSize;
277     msgFlags = pdu.msgFlags;
278     msgSecurityModel = pdu.msgSecurityModel;
279
280     contextEngineId = pdu.contextEngineId;
281     contextName = pdu.contextName;
282
283     securityParameters = pdu.securityParameters;
284
285         //
286
// Allocate the array to receive the encoding.
287
//
288
data = new byte[maxDataLength];
289     
290         //
291
// Encode the pdu
292
// Reminder: BerEncoder does backward encoding !
293
//
294

295         try {
296             BerEncoder benc = new BerEncoder(data) ;
297             benc.openSequence() ;
298             encodeVarBindList(benc, pdu.varBindList) ;
299
300             switch(pdu.type) {
301
302             case pduGetRequestPdu :
303             case pduGetNextRequestPdu :
304             case pduInformRequestPdu :
305             case pduGetResponsePdu :
306             case pduSetRequestPdu :
307             case pduV2TrapPdu :
308             case pduReportPdu :
309                 SnmpPduRequestType reqPdu = (SnmpPduRequestType) pdu;
310                 benc.putInteger(reqPdu.getErrorIndex());
311                 benc.putInteger(reqPdu.getErrorStatus());
312                 benc.putInteger(pdu.requestId);
313                 break;
314
315             case pduGetBulkRequestPdu :
316                 SnmpPduBulkType bulkPdu = (SnmpPduBulkType) pdu;
317                 benc.putInteger(bulkPdu.getMaxRepetitions());
318                 benc.putInteger(bulkPdu.getNonRepeaters());
319                 benc.putInteger(pdu.requestId);
320                 break ;
321
322             default:
323                 throw new SnmpStatusException("Invalid pdu type " + String.valueOf(pdu.type)) ;
324             }
325             benc.closeSequence(pdu.type) ;
326             dataLength = benc.trim() ;
327         }
328         catch(ArrayIndexOutOfBoundsException JavaDoc x) {
329             throw new SnmpTooBigException() ;
330         }
331     }
332   
333   
334     /**
335      * Gets the PDU encoded in this message.
336      * <P>
337      * This method decodes the data field and returns the resulting PDU.
338      *
339      * @return The resulting PDU.
340      * @exception SnmpStatusException If the encoding is not valid.
341      */

342
343     public SnmpPdu decodeSnmpPdu()
344     throws SnmpStatusException {
345   
346     SnmpScopedPduPacket pdu = null;
347
348         BerDecoder bdec = new BerDecoder(data) ;
349         try {
350             int type = bdec.getTag() ;
351             bdec.openSequence(type) ;
352             switch(type) {
353       
354             case pduGetRequestPdu :
355             case pduGetNextRequestPdu :
356             case pduInformRequestPdu :
357             case pduGetResponsePdu :
358             case pduSetRequestPdu :
359             case pduV2TrapPdu :
360             case pduReportPdu :
361                 SnmpScopedPduRequest reqPdu = new SnmpScopedPduRequest() ;
362                 reqPdu.requestId = bdec.fetchInteger() ;
363                 reqPdu.setErrorStatus(bdec.fetchInteger());
364                 reqPdu.setErrorIndex(bdec.fetchInteger());
365                 pdu = reqPdu ;
366                 break ;
367
368             case pduGetBulkRequestPdu :
369                 SnmpScopedPduBulk bulkPdu = new SnmpScopedPduBulk() ;
370                 bulkPdu.requestId = bdec.fetchInteger() ;
371                 bulkPdu.setNonRepeaters(bdec.fetchInteger());
372                 bulkPdu.setMaxRepetitions(bdec.fetchInteger());
373                 pdu = bulkPdu ;
374                 break ;
375             default:
376                 throw new SnmpStatusException(snmpRspWrongEncoding) ;
377             }
378             pdu.type = type;
379             pdu.varBindList = decodeVarBindList(bdec);
380             bdec.closeSequence() ;
381         } catch(BerException e) {
382             if (isDebugOn()) {
383                 debug("decodeSnmpPdu", e);
384             }
385             throw new SnmpStatusException(snmpRspWrongEncoding);
386         }
387     
388         //
389
// The easy work.
390
//
391
pdu.address = address;
392         pdu.port = port;
393     pdu.msgFlags = msgFlags;
394         pdu.version = version;
395     pdu.msgId = msgId;
396     pdu.msgMaxSize = msgMaxSize;
397     pdu.msgSecurityModel = msgSecurityModel;
398     pdu.contextEngineId = contextEngineId;
399     pdu.contextName = contextName;
400     
401     pdu.securityParameters = securityParameters;
402
403     if(isTraceOn()) {
404         trace("decodeSnmpPdu", "Unmarshalled pdu : \n" +
405           "type :" + pdu.type + "\n" +
406           "version :" + pdu.version + "\n" +
407           "requestId :" + pdu.requestId + "\n" +
408           "msgId :" + pdu.msgId + "\n" +
409           "msgMaxSize :" + pdu.msgMaxSize + "\n" +
410           "msgFlags :" + pdu.msgFlags + "\n" +
411           "msgSecurityModel :" + pdu.msgSecurityModel + "\n" +
412           "contextEngineId :" + pdu.contextEngineId + "\n" +
413           "contextName :" + pdu.contextName + "\n");
414     }
415         return pdu ;
416     }
417     
418     /**
419      * Dumps this message in a string.
420      *
421      * @return The string containing the dump.
422      */

423     public String JavaDoc printMessage() {
424     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
425     sb.append("msgId : " + msgId + "\n");
426     sb.append("msgMaxSize : " + msgMaxSize + "\n");
427     sb.append("msgFlags : " + msgFlags + "\n");
428     sb.append("msgSecurityModel : " + msgSecurityModel + "\n");
429
430     if (contextEngineId == null) {
431             sb.append("contextEngineId : null");
432         }
433         else {
434             sb.append("contextEngineId : {\n");
435             sb.append(dumpHexBuffer(contextEngineId,
436                     0,
437                     contextEngineId.length));
438             sb.append("\n}\n");
439         }
440
441     if (contextName == null) {
442             sb.append("contextName : null");
443         }
444         else {
445             sb.append("contextName : {\n");
446             sb.append(dumpHexBuffer(contextName,
447                     0,
448                     contextName.length));
449             sb.append("\n}\n");
450         }
451     return sb.append(super.printMessage()).toString();
452     }
453
454     // TRACES & DEBUG
455
//---------------
456

457     boolean isTraceOn() {
458         return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_SNMP);
459     }
460
461     void trace(String JavaDoc clz, String JavaDoc func, String JavaDoc info) {
462         Trace.send(Trace.LEVEL_TRACE, Trace.INFO_SNMP, clz, func, info);
463     }
464
465     void trace(String JavaDoc func, String JavaDoc info) {
466         trace(dbgTag, func, info);
467     }
468     
469     boolean isDebugOn() {
470         return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_SNMP);
471     }
472
473     void debug(String JavaDoc clz, String JavaDoc func, String JavaDoc info) {
474         Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_SNMP, clz, func, info);
475     }
476
477     void debug(String JavaDoc clz, String JavaDoc func, Throwable JavaDoc exception) {
478         Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_SNMP, clz, func, exception);
479     }
480
481     void debug(String JavaDoc func, String JavaDoc info) {
482         debug(dbgTag, func, info);
483     }
484     
485     void debug(String JavaDoc func, Throwable JavaDoc exception) {
486         debug(dbgTag, func, exception);
487     }
488     
489     String JavaDoc dbgTag = "SnmpV3Message";
490 }
491
Popular Tags