KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > snmp > SNMPv1CommunicationInterface


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 import java.io.*;
34 import java.net.*;
35
36
37 /**
38 * The class SNMPv1CommunicationInterface defines methods for communicating with SNMP entities.
39 * The approach is that from version 1 of SNMP, using no encryption of data. Communication occurs
40 * via UDP, using port 161, the standard SNMP port, unless an alternate (non-standard) port is
41 * supplied in the constructor.
42 */

43
44 public class SNMPv1CommunicationInterface
45 {
46     public static final int SNMP_PORT = 161;
47     
48     // port to which requests will be sent
49
private int remotePort = SNMP_PORT;
50     
51     // largest size for datagram packet payload; based on
52
// RFC 1157, need to handle messages of at least 484 bytes
53
private int receiveBufferSize = 512;
54     
55     private int version;
56     private InetAddress hostAddress;
57     private String JavaDoc community;
58     DatagramSocket dSocket;
59     
60     public int requestID = 1;
61             
62     
63     
64     
65     /**
66     * Construct a new communication object to communicate with the specified host using the
67     * given community name. The version setting should be either 0 (version 1) or 1 (version 2,
68     * a la RFC 1157).
69     */

70     
71     public SNMPv1CommunicationInterface(int version, InetAddress hostAddress, String JavaDoc community)
72         throws SocketException
73     {
74         this(version, hostAddress, community, SNMP_PORT);
75     }
76     
77     
78     
79     /**
80      * Construct a new communication object to communicate with the specified host using the
81      * given community name, and sending requests to the specified port. The version setting
82      * should be either 0 (version 1) or 1 (version 2, a la RFC 1157).
83      */

84      
85      public SNMPv1CommunicationInterface(int version, InetAddress hostAddress, String JavaDoc community, int remotePort)
86          throws SocketException
87      {
88          this.remotePort = remotePort;
89          this.version = version;
90          this.hostAddress = hostAddress;
91          this.community = community;
92          
93          dSocket = new DatagramSocket();
94          dSocket.setSoTimeout(15000); //15 seconds
95
}
96     
97     
98     
99     
100     /**
101     * Permits setting timeout value for underlying datagram socket (in milliseconds).
102     */

103     
104     public void setSocketTimeout(int socketTimeout)
105         throws SocketException
106     {
107         dSocket.setSoTimeout(socketTimeout);
108     }
109     
110     
111     
112     /**
113     * Close the "connection" with the device.
114     */

115     
116     public void closeConnection()
117         throws SocketException
118     {
119         dSocket.close();
120     }
121
122     
123     
124     
125     
126     
127     /**
128     * Retrieve all MIB variable values subsequent to the starting object identifier
129     * given in startID (in dotted-integer notation). Return as SNMPVarBindList object.
130     * Uses SNMPGetNextRequests to retrieve variable values in sequence.
131     * @throws IOException Thrown when timeout experienced while waiting for response to request.
132     * @throws SNMPBadValueException
133     */

134     
135     public SNMPVarBindList retrieveAllMIBInfo(String JavaDoc startID)
136         throws IOException, SNMPBadValueException
137     {
138         // send GetNextRequests until receive
139
// an error message or a repeat of the object identifier we sent out
140
SNMPVarBindList retrievedVars = new SNMPVarBindList();
141         
142         
143         int errorStatus = 0;
144         int errorIndex = 0;
145         
146         SNMPObjectIdentifier requestedObjectIdentifier = new SNMPObjectIdentifier(startID);
147         SNMPVariablePair nextPair = new SNMPVariablePair(requestedObjectIdentifier, new SNMPNull());
148         SNMPSequence varList = new SNMPSequence();
149         varList.addSNMPObject(nextPair);
150         SNMPPDU pdu = new SNMPPDU(SNMPBERCodec.SNMPGETNEXTREQUEST, requestID, errorStatus, errorIndex, varList);
151         SNMPMessage message = new SNMPMessage(version, community, pdu);
152         byte[] messageEncoding = message.getBEREncoding();
153         DatagramPacket outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, remotePort);
154         
155         
156         dSocket.send(outPacket);
157         
158         
159         
160         while (errorStatus == 0)
161         {
162             
163             DatagramPacket inPacket = new DatagramPacket(new byte[receiveBufferSize], receiveBufferSize);
164         
165             dSocket.receive(inPacket);
166             
167             byte[] encodedMessage = inPacket.getData();
168             
169             
170             SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value);
171             //errorStatus = ((BigInteger)((SNMPInteger)((receivedMessage.getPDU()).getSNMPObjectAt(1))).getValue()).intValue();
172

173             
174             varList = (receivedMessage.getPDU()).getVarBindList();
175             SNMPSequence newPair = (SNMPSequence)(varList.getSNMPObjectAt(0));
176             
177             SNMPObjectIdentifier newObjectIdentifier = (SNMPObjectIdentifier)(newPair.getSNMPObjectAt(0));
178             SNMPObject newValue = newPair.getSNMPObjectAt(1);
179             
180             retrievedVars.addSNMPObject(newPair);
181             
182             
183             if (requestedObjectIdentifier.equals(newObjectIdentifier))
184                 break;
185                 
186             requestedObjectIdentifier = newObjectIdentifier;
187         
188             requestID++;
189             nextPair = new SNMPVariablePair(requestedObjectIdentifier, new SNMPNull());
190             varList = new SNMPSequence();
191             varList.addSNMPObject(nextPair);
192             pdu = new SNMPPDU(SNMPBERCodec.SNMPGETNEXTREQUEST, requestID, errorStatus, errorIndex, varList);
193             message = new SNMPMessage(version, community, pdu);
194             messageEncoding = message.getBEREncoding();
195             outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, remotePort);
196             
197             dSocket.send(outPacket);
198             
199         }
200             
201         
202         return retrievedVars;
203         
204     }
205     
206     
207     
208     private String JavaDoc hexByte(byte b)
209     {
210         int pos = b;
211         if (pos < 0)
212             pos += 256;
213         String JavaDoc returnString = new String JavaDoc();
214         returnString += Integer.toHexString(pos/16);
215         returnString += Integer.toHexString(pos%16);
216         return returnString;
217     }
218     
219     
220     
221     
222     
223     /**
224     * Retrieve the MIB variable value corresponding to the object identifier
225     * given in itemID (in dotted-integer notation). Return as SNMPVarBindList object; if no
226     * such variable (either due to device not supporting it, or community name having incorrect
227     * access privilege), SNMPGetException thrown
228     * @throws IOException Thrown when timeout experienced while waiting for response to request.
229     * @throws SNMPBadValueException
230     * @throws SNMPGetException Thrown if supplied OID has value that can't be retrieved
231     */

232     
233     public SNMPVarBindList getMIBEntry(String JavaDoc itemID)
234         throws IOException, SNMPBadValueException, SNMPGetException
235     {
236         // send GetRequest to specified host to retrieve specified object identifier
237

238         SNMPVarBindList retrievedVars = new SNMPVarBindList();
239         
240         
241         int errorStatus = 0;
242         int errorIndex = 0;
243         
244         
245         SNMPObjectIdentifier requestedObjectIdentifier = new SNMPObjectIdentifier(itemID);
246         SNMPVariablePair nextPair = new SNMPVariablePair(requestedObjectIdentifier, new SNMPNull());
247         SNMPSequence varList = new SNMPSequence();
248         varList.addSNMPObject(nextPair);
249         SNMPPDU pdu = new SNMPPDU(SNMPBERCodec.SNMPGETREQUEST, requestID, errorStatus, errorIndex, varList);
250         
251         SNMPMessage message = new SNMPMessage(version, community, pdu);
252         
253         byte[] messageEncoding = message.getBEREncoding();
254         
255         
256         /*
257         System.out.println("Request Message bytes:");
258         
259         for (int i = 0; i < messageEncoding.length; ++i)
260             System.out.print(hexByte(messageEncoding[i]) + " ");
261         */

262         
263         DatagramPacket outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, remotePort);
264         
265         dSocket.send(outPacket);
266         
267         
268         while (true) // wait until receive reply for requestID & OID (or error)
269
{
270             
271             DatagramPacket inPacket = new DatagramPacket(new byte[receiveBufferSize], receiveBufferSize);
272             
273             dSocket.receive(inPacket);
274             
275             byte[] encodedMessage = inPacket.getData();
276             
277             /*
278             System.out.println("Message bytes:");
279             
280             for (int i = 0; i < encodedMessage.length; ++i)
281             {
282                 System.out.print(hexByte(encodedMessage[i]) + " ");
283             }
284             */

285             
286             
287             SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value);
288             SNMPPDU receivedPDU = receivedMessage.getPDU();
289             
290             // check request identifier; if incorrect, just ignore packet and continue waiting
291
if (receivedPDU.getRequestID() == requestID)
292             {
293                 
294                 // check error status; if retrieval problem, throw SNMPGetException
295
if (receivedPDU.getErrorStatus() != 0)
296                     throw new SNMPGetException("OID " + itemID + " not available for retrieval", receivedPDU.getErrorIndex(), receivedPDU.getErrorStatus());
297                 
298                 
299                 varList = receivedPDU.getVarBindList();
300                 SNMPSequence newPair = (SNMPSequence)(varList.getSNMPObjectAt(0));
301                 
302                 SNMPObjectIdentifier newObjectIdentifier = (SNMPObjectIdentifier)(newPair.getSNMPObjectAt(0));
303                 SNMPObject newValue = newPair.getSNMPObjectAt(1);
304                 
305                 // check the object identifier to make sure the correct variable has been received;
306
// if not, just continue waiting for receive
307
if (newObjectIdentifier.toString().equals(itemID))
308                 {
309                     // got the right one; add it to retrieved var list and break!
310
retrievedVars.addSNMPObject(newPair);
311                     break;
312                 }
313             
314             }
315             
316         }
317         
318         
319         requestID++;
320         
321         
322         return retrievedVars;
323         
324     }
325     
326     
327     
328     
329     /**
330     * Retrieve the MIB variable values corresponding to the object identifiers
331     * given in the array itemID (in dotted-integer notation). Return as SNMPVarBindList object;
332     * if no such variable (either due to device not supporting it, or community name having incorrect
333     * access privilege), SNMPGetException thrown
334     * @throws IOException Thrown when timeout experienced while waiting for response to request.
335     * @throws SNMPBadValueException
336     * @throws SNMPGetException Thrown if one of supplied OIDs has value that can't be retrieved
337     */

338     
339     public SNMPVarBindList getMIBEntry(String JavaDoc[] itemID)
340         throws IOException, SNMPBadValueException, SNMPGetException
341     {
342         // send GetRequest to specified host to retrieve values of specified object identifiers
343

344         SNMPVarBindList retrievedVars = new SNMPVarBindList();
345         SNMPSequence varList = new SNMPSequence();
346         
347         int errorStatus = 0;
348         int errorIndex = 0;
349         
350         for (int i = 0; i < itemID.length; i++)
351         {
352             SNMPObjectIdentifier requestedObjectIdentifier = new SNMPObjectIdentifier(itemID[i]);
353             SNMPVariablePair nextPair = new SNMPVariablePair(requestedObjectIdentifier, new SNMPNull());
354             varList.addSNMPObject(nextPair);
355         }
356         
357         
358         SNMPPDU pdu = new SNMPPDU(SNMPBERCodec.SNMPGETREQUEST, requestID, errorStatus, errorIndex, varList);
359         
360         SNMPMessage message = new SNMPMessage(version, community, pdu);
361         
362         byte[] messageEncoding = message.getBEREncoding();
363         
364         
365         /*
366         System.out.println("Request Message bytes:");
367         
368         for (int i = 0; i < messageEncoding.length; ++i)
369             System.out.print(hexByte(messageEncoding[i]) + " ");
370         */

371         
372         DatagramPacket outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, remotePort);
373         
374         
375         dSocket.send(outPacket);
376         
377         
378         while (true) // wait until receive reply for requestID & OID (or error)
379
{
380             
381             DatagramPacket inPacket = new DatagramPacket(new byte[receiveBufferSize], receiveBufferSize);
382             
383             dSocket.receive(inPacket);
384             
385             byte[] encodedMessage = inPacket.getData();
386             
387             /*
388             System.out.println("Message bytes:");
389             
390             for (int i = 0; i < encodedMessage.length; ++i)
391             {
392                 System.out.print(hexByte(encodedMessage[i]) + " ");
393             }
394             */

395             
396             
397             SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value);
398             SNMPPDU receivedPDU = receivedMessage.getPDU();
399             
400             // check request identifier; if incorrect, just ignore packet and continue waiting
401
if (receivedPDU.getRequestID() == requestID)
402             {
403                 
404                 // check error status; if retrieval problem, throw SNMPGetException
405
if (receivedPDU.getErrorStatus() != 0)
406                 {
407                     // determine error index
408
errorIndex = receivedPDU.getErrorIndex();
409                     throw new SNMPGetException("OID " + itemID[errorIndex - 1] + " not available for retrieval", errorIndex, receivedPDU.getErrorStatus());
410                 }
411                 
412                 // copy info from retrieved sequence to var bind list
413
varList = receivedPDU.getVarBindList();
414                 
415                 for (int i = 0; i < varList.size(); i++)
416                 {
417                     SNMPSequence newPair = (SNMPSequence)(varList.getSNMPObjectAt(i));
418                     
419                     SNMPObjectIdentifier newObjectIdentifier = (SNMPObjectIdentifier)(newPair.getSNMPObjectAt(0));
420                     SNMPObject newValue = newPair.getSNMPObjectAt(1);
421                     
422                     if (newObjectIdentifier.toString().equals(itemID[i]))
423                     {
424                         retrievedVars.addSNMPObject(newPair);
425                     }
426                     else
427                     {
428                         // wrong OID; throw GetException
429
throw new SNMPGetException("OID " + itemID[i] + " expected at index " + i + ", OID " + newObjectIdentifier + " received", i+1, SNMPRequestException.FAILED);
430                     }
431                 }
432                 
433                 break;
434             
435             }
436             
437         }
438         
439         
440         requestID++;
441         
442         
443         return retrievedVars;
444         
445     }
446     
447     
448     
449     
450     
451     /**
452     * Retrieve the MIB variable value corresponding to the object identifier following that
453     * given in itemID (in dotted-integer notation). Return as SNMPVarBindList object; if no
454     * such variable (either due to device not supporting it, or community name having incorrect
455     * access privilege), variable value will be SNMPNull object
456     * @throws IOException Thrown when timeout experienced while waiting for response to request.
457     * @throws SNMPBadValueException
458     * @throws SNMPGetException Thrown if one the OID following the supplied OID has value that can't be retrieved
459     */

460     
461     public SNMPVarBindList getNextMIBEntry(String JavaDoc itemID)
462         throws IOException, SNMPBadValueException, SNMPGetException
463     {
464         // send GetRequest to specified host to retrieve specified object identifier
465

466         SNMPVarBindList retrievedVars = new SNMPVarBindList();
467         
468         
469         int errorStatus = 0;
470         int errorIndex = 0;
471         
472         
473         SNMPObjectIdentifier requestedObjectIdentifier = new SNMPObjectIdentifier(itemID);
474         SNMPVariablePair nextPair = new SNMPVariablePair(requestedObjectIdentifier, new SNMPNull());
475         SNMPSequence varList = new SNMPSequence();
476         varList.addSNMPObject(nextPair);
477         SNMPPDU pdu = new SNMPPDU(SNMPBERCodec.SNMPGETNEXTREQUEST, requestID, errorStatus, errorIndex, varList);
478         
479         SNMPMessage message = new SNMPMessage(version, community, pdu);
480         
481         byte[] messageEncoding = message.getBEREncoding();
482         
483         
484         /*
485         System.out.println("Request Message bytes:");
486         
487         for (int i = 0; i < messageEncoding.length; ++i)
488             System.out.print(hexByte(messageEncoding[i]) + " ");
489         */

490         
491         DatagramPacket outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, remotePort);
492         
493         
494         dSocket.send(outPacket);
495         
496         
497         while (true) // wait until receive reply for requestID & OID (or error)
498
{
499             
500             DatagramPacket inPacket = new DatagramPacket(new byte[receiveBufferSize], receiveBufferSize);
501             
502             dSocket.receive(inPacket);
503             
504             byte[] encodedMessage = inPacket.getData();
505             
506             /*
507             System.out.println("Message bytes:");
508             
509             for (int i = 0; i < encodedMessage.length; ++i)
510             {
511                 System.out.print(hexByte(encodedMessage[i]) + " ");
512             }
513             */

514             
515             
516             SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value);
517             SNMPPDU receivedPDU = receivedMessage.getPDU();
518             
519             // check request identifier; if incorrect, just ignore packet and continue waiting
520
if (receivedPDU.getRequestID() == requestID)
521             {
522                 
523                 // check error status; if retrieval problem, throw SNMPGetException
524
if (receivedPDU.getErrorStatus() != 0)
525                     throw new SNMPGetException("OID " + itemID + " not available for retrieval", receivedPDU.getErrorIndex(), receivedPDU.getErrorStatus());
526                 
527                 
528                 varList = receivedPDU.getVarBindList();
529                 SNMPSequence newPair = (SNMPSequence)(varList.getSNMPObjectAt(0));
530                 
531                 SNMPObjectIdentifier newObjectIdentifier = (SNMPObjectIdentifier)(newPair.getSNMPObjectAt(0));
532                 SNMPObject newValue = newPair.getSNMPObjectAt(1);
533                 
534                 retrievedVars.addSNMPObject(newPair);
535                 
536                 break;
537             
538             }
539             
540         }
541         
542         
543         requestID++;
544         
545         
546         return retrievedVars;
547         
548     }
549     
550     
551     
552     
553     
554     /**
555     * Retrieve the MIB variable value corresponding to the object identifiers following those
556     * given in the itemID array (in dotted-integer notation). Return as SNMPVarBindList object;
557     * if no such variable (either due to device not supporting it, or community name having
558     * incorrect access privilege), SNMPGetException thrown
559     * @throws IOException Thrown when timeout experienced while waiting for response to request.
560     * @throws SNMPBadValueException
561     * @throws SNMPGetException Thrown if OID following one of supplied OIDs has value that can't be retrieved
562     */

563     
564     public SNMPVarBindList getNextMIBEntry(String JavaDoc[] itemID)
565         throws IOException, SNMPBadValueException, SNMPGetException
566     {
567         // send GetRequest to specified host to retrieve values of specified object identifiers
568

569         SNMPVarBindList retrievedVars = new SNMPVarBindList();
570         SNMPSequence varList = new SNMPSequence();
571         
572         int errorStatus = 0;
573         int errorIndex = 0;
574         
575         for (int i = 0; i < itemID.length; i++)
576         {
577             SNMPObjectIdentifier requestedObjectIdentifier = new SNMPObjectIdentifier(itemID[i]);
578             SNMPVariablePair nextPair = new SNMPVariablePair(requestedObjectIdentifier, new SNMPNull());
579             varList.addSNMPObject(nextPair);
580         }
581         
582         SNMPPDU pdu = new SNMPPDU(SNMPBERCodec.SNMPGETNEXTREQUEST, requestID, errorStatus, errorIndex, varList);
583         SNMPMessage message = new SNMPMessage(version, community, pdu);
584         
585         byte[] messageEncoding = message.getBEREncoding();
586         
587         
588         /*
589         System.out.println("Request Message bytes:");
590         
591         for (int i = 0; i < messageEncoding.length; ++i)
592             System.out.print(hexByte(messageEncoding[i]) + " ");
593         */

594         
595         DatagramPacket outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, remotePort);
596         
597         
598         dSocket.send(outPacket);
599         
600         
601         while (true) // wait until receive reply for requestID & OID (or error)
602
{
603             
604             DatagramPacket inPacket = new DatagramPacket(new byte[receiveBufferSize], receiveBufferSize);
605             
606             dSocket.receive(inPacket);
607             
608             byte[] encodedMessage = inPacket.getData();
609             
610             /*
611             System.out.println("Message bytes:");
612             
613             for (int i = 0; i < encodedMessage.length; ++i)
614             {
615                 System.out.print(hexByte(encodedMessage[i]) + " ");
616             }
617             */

618             
619             
620             SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value);
621             SNMPPDU receivedPDU = receivedMessage.getPDU();
622             
623             // check request identifier; if incorrect, just ignore packet and continue waiting
624
if (receivedPDU.getRequestID() == requestID)
625             {
626                 
627                 // check error status; if retrieval problem, throw SNMPGetException
628
if (receivedPDU.getErrorStatus() != 0)
629                 {
630                     // determine error index
631
errorIndex = receivedPDU.getErrorIndex();
632                     throw new SNMPGetException("OID following " + itemID[errorIndex - 1] + " not available for retrieval", errorIndex, receivedPDU.getErrorStatus());
633                 }
634                 
635                 // copy info from retrieved sequence to var bind list
636
varList = receivedPDU.getVarBindList();
637                 
638                 for (int i = 0; i < varList.size(); i++)
639                 {
640                     SNMPSequence newPair = (SNMPSequence)(varList.getSNMPObjectAt(i));
641                     
642                     SNMPObjectIdentifier newObjectIdentifier = (SNMPObjectIdentifier)(newPair.getSNMPObjectAt(0));
643                     SNMPObject newValue = newPair.getSNMPObjectAt(1);
644                     
645                     retrievedVars.addSNMPObject(newPair);
646                     
647                 }
648                 
649                 break;
650             
651             }
652             
653         }
654         
655         
656         requestID++;
657         
658         
659         return retrievedVars;
660         
661     }
662     
663     
664     
665     
666     
667     
668     
669     /**
670     * Set the MIB variable value of the object identifier
671     * given in startID (in dotted-integer notation). Return SNMPVarBindList object returned
672     * by device in its response; can be used to check that setting was successful.
673     * Uses SNMPGetNextRequests to retrieve variable values in sequence.
674     * @throws IOException Thrown when timeout experienced while waiting for response to request.
675     * @throws SNMPBadValueException
676     */

677     
678     public SNMPVarBindList setMIBEntry(String JavaDoc itemID, SNMPObject newValue)
679         throws IOException, SNMPBadValueException, SNMPSetException
680     {
681         // send SetRequest to specified host to set value of specified object identifier
682

683         SNMPVarBindList retrievedVars = new SNMPVarBindList();
684         
685         int errorStatus = 0;
686         int errorIndex = 0;
687         
688         SNMPObjectIdentifier requestedObjectIdentifier = new SNMPObjectIdentifier(itemID);
689         SNMPVariablePair nextPair = new SNMPVariablePair(requestedObjectIdentifier, newValue);
690         
691             
692         
693         SNMPSequence varList = new SNMPSequence();
694         varList.addSNMPObject(nextPair);
695         SNMPPDU pdu = new SNMPPDU(SNMPBERCodec.SNMPSETREQUEST, requestID, errorStatus, errorIndex, varList);
696         
697         
698         SNMPMessage message = new SNMPMessage(version, community, pdu);
699         byte[] messageEncoding = message.getBEREncoding();
700         
701         /*
702         System.out.println("Message bytes:");
703         
704         for (int i = 0; i < messageEncoding.length; ++i)
705         {
706             System.out.print(hexByte(messageEncoding[i]) + " ");
707         }
708         */

709         
710         
711         DatagramPacket outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, remotePort);
712         
713         
714         dSocket.send(outPacket);
715         
716         
717         while (true) // wait until receive reply for correct OID (or error)
718
{
719             
720             DatagramPacket inPacket = new DatagramPacket(new byte[receiveBufferSize], receiveBufferSize);
721             
722             dSocket.receive(inPacket);
723             
724             
725             byte[] encodedMessage = inPacket.getData();
726             
727             /*
728             System.out.println("Message bytes:");
729             
730             for (int i = 0; i < encodedMessage.length; ++i)
731             {
732                 System.out.print((encodedMessage[i]) + " ");
733             }
734             */

735         
736         
737             
738             SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value);
739             
740             SNMPPDU receivedPDU = receivedMessage.getPDU();
741             
742             
743             // check request identifier; if incorrect, just ignore packet and continue waiting
744
if (receivedPDU.getRequestID() == requestID)
745             {
746                 
747                 // check error status; if retrieval problem, throw SNMPGetException
748
if (receivedPDU.getErrorStatus() != 0)
749                 {
750                     switch (receivedPDU.getErrorStatus())
751                     {
752                         case 1:
753                             throw new SNMPSetException("Value supplied for OID " + itemID + " too big.", receivedPDU.getErrorIndex(), receivedPDU.getErrorStatus());
754                         
755                         case 2:
756                             throw new SNMPSetException("OID " + itemID + " not available for setting.", receivedPDU.getErrorIndex(), receivedPDU.getErrorStatus());
757                         
758                         case 3:
759                             throw new SNMPSetException("Bad value supplied for OID " + itemID + ".", receivedPDU.getErrorIndex(), receivedPDU.getErrorStatus());
760                             
761                         case 4:
762                             throw new SNMPSetException("OID " + itemID + " read-only.", receivedPDU.getErrorIndex(), receivedPDU.getErrorStatus());
763                             
764                         default:
765                             throw new SNMPSetException("Error setting OID " + itemID + ".", receivedPDU.getErrorIndex(), receivedPDU.getErrorStatus());
766                             
767                     }
768                 }
769                 
770                 
771                 varList = receivedPDU.getVarBindList();
772                 SNMPSequence newPair = (SNMPSequence)(varList.getSNMPObjectAt(0));
773                 
774                 // check the object identifier to make sure the correct variable has been received;
775
// if not, just continue waiting for receive
776
if (((SNMPObjectIdentifier)newPair.getSNMPObjectAt(0)).toString().equals(itemID))
777                 {
778                     // got the right one; add it to retrieved var list and break!
779
retrievedVars.addSNMPObject(newPair);
780                     break;
781                 }
782             
783             }
784             
785         }
786         
787         
788         requestID++;
789     
790         
791         return retrievedVars;
792         
793     }
794     
795     
796     
797     
798     /**
799     * Set the MIB variable values of the supplied object identifiers given in the
800     * itemID array (in dotted-integer notation). Return SNMPVarBindList returned
801     * by device in its response; can be used to check that setting was successful.
802     * Uses SNMPGetNextRequests to retrieve variable values in sequence.
803     * @throws IOException Thrown when timeout experienced while waiting for response to request.
804     * @throws SNMPBadValueException
805     */

806     
807     public SNMPVarBindList setMIBEntry(String JavaDoc[] itemID, SNMPObject[] newValue)
808         throws IOException, SNMPBadValueException, SNMPSetException
809     {
810         // check that OID and value arrays have same size
811
if (itemID.length != newValue.length)
812         {
813             throw new SNMPSetException("OID and value arrays must have same size", 0, SNMPRequestException.FAILED);
814         }
815         
816         
817         // send SetRequest to specified host to set values of specified object identifiers
818

819         SNMPVarBindList retrievedVars = new SNMPVarBindList();
820         SNMPSequence varList = new SNMPSequence();
821         
822         int errorStatus = 0;
823         int errorIndex = 0;
824         
825         
826         for (int i = 0; i < itemID.length; i++)
827         {
828             SNMPObjectIdentifier requestedObjectIdentifier = new SNMPObjectIdentifier(itemID[i]);
829             SNMPVariablePair nextPair = new SNMPVariablePair(requestedObjectIdentifier, newValue[i]);
830             varList.addSNMPObject(nextPair);
831         }
832         
833         SNMPPDU pdu = new SNMPPDU(SNMPBERCodec.SNMPSETREQUEST, requestID, errorStatus, errorIndex, varList);
834         SNMPMessage message = new SNMPMessage(version, community, pdu);
835         
836         byte[] messageEncoding = message.getBEREncoding();
837         
838         /*
839         System.out.println("Message bytes:");
840         
841         for (int i = 0; i < messageEncoding.length; ++i)
842         {
843             System.out.print(getHex(messageEncoding[i]) + " ");
844         }
845         */

846         
847         
848         DatagramPacket outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, remotePort);
849         
850         dSocket.send(outPacket);
851         
852         
853         while (true) // wait until receive reply for correct OID (or error)
854
{
855             
856             DatagramPacket inPacket = new DatagramPacket(new byte[receiveBufferSize], receiveBufferSize);
857             
858             dSocket.receive(inPacket);
859             
860             byte[] encodedMessage = inPacket.getData();
861             
862             /*
863             System.out.println("Message bytes:");
864             
865             for (int i = 0; i < encodedMessage.length; ++i)
866             {
867                 System.out.print((encodedMessage[i]) + " ");
868             }
869             */

870         
871         
872             
873             SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value);
874             
875             SNMPPDU receivedPDU = receivedMessage.getPDU();
876             
877             
878             // check request identifier; if incorrect, just ignore packet and continue waiting
879
if (receivedPDU.getRequestID() == requestID)
880             {
881                 
882                 // check error status; if retrieval problem, throw SNMPGetException
883
if (receivedPDU.getErrorStatus() != 0)
884                 {
885                     errorIndex = receivedPDU.getErrorIndex();
886                     
887                     switch (receivedPDU.getErrorStatus())
888                     {
889                         case 1:
890                             throw new SNMPSetException("Value supplied for OID " + itemID[errorIndex - 1] + " too big.", receivedPDU.getErrorIndex(), receivedPDU.getErrorStatus());
891                         
892                         case 2:
893                             throw new SNMPSetException("OID " + itemID[errorIndex - 1] + " not available for setting.", receivedPDU.getErrorIndex(), receivedPDU.getErrorStatus());
894                         
895                         case 3:
896                             throw new SNMPSetException("Bad value supplied for OID " + itemID[errorIndex - 1] + ".", receivedPDU.getErrorIndex(), receivedPDU.getErrorStatus());
897                             
898                         case 4:
899                             throw new SNMPSetException("OID " + itemID[errorIndex - 1] + " read-only.", receivedPDU.getErrorIndex(), receivedPDU.getErrorStatus());
900                             
901                         default:
902                             throw new SNMPSetException("Error setting OID " + itemID[errorIndex - 1] + ".", receivedPDU.getErrorIndex(), receivedPDU.getErrorStatus());
903                             
904                     }
905                 }
906                 
907                 
908                 // copy info from retrieved sequence to var bind list
909
varList = receivedPDU.getVarBindList();
910                 
911                 for (int i = 0; i < varList.size(); i++)
912                 {
913                     SNMPSequence newPair = (SNMPSequence)(varList.getSNMPObjectAt(i));
914                     
915                     SNMPObjectIdentifier newObjectIdentifier = (SNMPObjectIdentifier)(newPair.getSNMPObjectAt(0));
916                     //SNMPObject receivedValue = newPair.getSNMPObjectAt(1);
917

918                     if (newObjectIdentifier.toString().equals(itemID[i]))
919                     {
920                         retrievedVars.addSNMPObject(newPair);
921                     }
922                     else
923                     {
924                         // wrong OID; throw GetException
925
throw new SNMPSetException("OID " + itemID[i] + " expected at index " + i + ", OID " + newObjectIdentifier + " received", i+1, SNMPRequestException.FAILED);
926                     }
927                 }
928                 
929                 break;
930             
931             }
932             
933         }
934         
935         
936         requestID++;
937     
938         
939         return retrievedVars;
940         
941     }
942     
943     
944     
945     
946     /**
947     * Retrieve all MIB variable values whose OIDs start with the supplied baseID. Since the entries of
948     * an SNMP table have the form <baseID>.<tableEntry>.<index>, this will retrieve all of the table
949     * data as an SNMPVarBindList object consisting of sequence of SNMPVariablePairs.
950     * Uses SNMPGetNextRequests to retrieve variable values in sequence.
951     * @throws IOException Thrown when timeout experienced while waiting for response to request.
952     * @throws SNMPBadValueException
953     */

954     
955     public SNMPVarBindList retrieveMIBTable(String JavaDoc baseID)
956         throws IOException, SNMPBadValueException, SNMPGetException
957     {
958         // send GetNextRequests until receive
959
// an error message or a repeat of the object identifier we sent out
960
SNMPVarBindList retrievedVars = new SNMPVarBindList();
961         
962         
963         int errorStatus = 0;
964         int errorIndex = 0;
965         
966         String JavaDoc currentID = baseID;
967         SNMPObjectIdentifier requestedObjectIdentifier = new SNMPObjectIdentifier(currentID);
968         
969         
970         while (errorStatus == 0)
971         {
972             
973             SNMPVariablePair nextPair = new SNMPVariablePair(requestedObjectIdentifier, new SNMPNull());
974             SNMPSequence varList = new SNMPSequence();
975             varList.addSNMPObject(nextPair);
976             SNMPPDU pdu = new SNMPPDU(SNMPBERCodec.SNMPGETNEXTREQUEST, requestID, errorStatus, errorIndex, varList);
977             SNMPMessage message = new SNMPMessage(version, community, pdu);
978             byte[] messageEncoding = message.getBEREncoding();
979             DatagramPacket outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, remotePort);
980             
981             /*
982             System.out.println("Request bytes:");
983             
984             for (int i = 0; i < messageEncoding.length; ++i)
985             {
986                 System.out.print(getHex(messageEncoding[i]) + " ");
987             }
988             */

989             
990             dSocket.send(outPacket);
991             
992             
993             DatagramPacket inPacket = new DatagramPacket(new byte[receiveBufferSize], receiveBufferSize);
994         
995             dSocket.receive(inPacket);
996             
997             byte[] encodedMessage = inPacket.getData();
998             
999             
1000            SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value);
1001            SNMPPDU receivedPDU = receivedMessage.getPDU();
1002            
1003            // check request identifier; if incorrect, just ignore packet and continue waiting
1004
if (receivedPDU.getRequestID() == requestID)
1005            {
1006                
1007                // check error status; if retrieval problem, just break - could be there are no additional OIDs
1008
if (receivedPDU.getErrorStatus() != 0)
1009                {
1010                    break;
1011                    //throw new SNMPGetException("OID following " + requestedObjectIdentifier + " not available for retrieval");
1012
}
1013                
1014                varList = receivedPDU.getVarBindList();
1015                SNMPSequence newPair = (SNMPSequence)(varList.getSNMPObjectAt(0));
1016                
1017                SNMPObjectIdentifier newObjectIdentifier = (SNMPObjectIdentifier)(newPair.getSNMPObjectAt(0));
1018                SNMPObject newValue = newPair.getSNMPObjectAt(1);
1019                
1020                // now see if retrieved ID starts with table base; if not, done with table - break
1021
String JavaDoc newOIDString = (String JavaDoc)newObjectIdentifier.toString();
1022                if (!newOIDString.startsWith(baseID))
1023                    break;
1024                
1025                retrievedVars.addSNMPObject(newPair);
1026                    
1027                requestedObjectIdentifier = newObjectIdentifier;
1028            
1029                requestID++;
1030            
1031            }
1032            
1033            
1034        }
1035            
1036        
1037        return retrievedVars;
1038        
1039    }
1040    
1041    
1042    
1043    
1044    /**
1045    * Retrieve all MIB variable values whose OIDs start with the supplied baseIDs. The normal way for
1046    * this to be used is for the base OID array to consist of the base OIDs of the columns of a table.
1047    * This method will then retrieve all of the entries of the table corresponding to these columns, one
1048    * row at a time (i.e., the entries for each row will be retrieved in a single SNMP request). This
1049    * will retrieve the table data as an SNMPVarBindList object consisting of sequence of SNMPVariablePairs,
1050    * with the entries for each row grouped together. This may provide a more convenient arrangement of
1051    * the table data than the simpler retrieveMIBTable method taking a single OID as argument; in addition,
1052    * it's more efficient, requiring one SNMP request per row rather than one request per entry.
1053    * Uses SNMPGetNextRequests to retrieve variable values for each row in sequence.
1054    * @throws IOException Thrown when timeout experienced while waiting for response to request.
1055    * @throws SNMPBadValueException
1056    * @throws SNMPGetException Thrown if incomplete row retrieved
1057    */

1058    
1059    public SNMPVarBindList retrieveMIBTable(String JavaDoc[] baseID)
1060        throws IOException, SNMPBadValueException, SNMPGetException
1061    {
1062        // send GetNextRequests until receive
1063
// an error message or a repeat of the object identifier we sent out
1064
SNMPVarBindList retrievedVars = new SNMPVarBindList();
1065        
1066        int errorStatus = 0;
1067        int errorIndex = 0;
1068        
1069        SNMPObjectIdentifier[] requestedObjectIdentifier = new SNMPObjectIdentifier[baseID.length];
1070        for (int i = 0; i < baseID.length; i++)
1071        {
1072               requestedObjectIdentifier[i] = new SNMPObjectIdentifier(baseID[i]);
1073        }
1074        
1075
1076retrievalLoop:
1077        
1078        while (errorStatus == 0)
1079        {
1080            
1081            SNMPSequence varList = new SNMPSequence();
1082            
1083            for (int i = 0; i < requestedObjectIdentifier.length; i++)
1084            {
1085                SNMPVariablePair nextPair = new SNMPVariablePair(requestedObjectIdentifier[i], new SNMPNull());
1086                varList.addSNMPObject(nextPair);
1087            }
1088            
1089            SNMPPDU pdu = new SNMPPDU(SNMPBERCodec.SNMPGETNEXTREQUEST, requestID, errorStatus, errorIndex, varList);
1090            SNMPMessage message = new SNMPMessage(version, community, pdu);
1091            
1092            byte[] messageEncoding = message.getBEREncoding();
1093            
1094            DatagramPacket outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, remotePort);
1095            
1096            /*
1097            System.out.println("Request bytes:");
1098            
1099            for (int i = 0; i < messageEncoding.length; ++i)
1100            {
1101                System.out.print(getHex(messageEncoding[i]) + " ");
1102            }
1103            */

1104            
1105            dSocket.send(outPacket);
1106            
1107            
1108            DatagramPacket inPacket = new DatagramPacket(new byte[receiveBufferSize], receiveBufferSize);
1109        
1110            dSocket.receive(inPacket);
1111            
1112            byte[] encodedMessage = inPacket.getData();
1113            
1114            
1115            SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value);
1116            SNMPPDU receivedPDU = receivedMessage.getPDU();
1117            
1118            // check request identifier; if incorrect, just ignore packet and continue waiting
1119
if (receivedPDU.getRequestID() == requestID)
1120            {
1121                
1122                // check error status; if retrieval problem for error index 1, just break - assume there are no additional OIDs
1123
// to retrieve. If index is other than 1, throw exception
1124
if (receivedPDU.getErrorStatus() != 0)
1125                {
1126                    int retrievedErrorIndex = receivedPDU.getErrorIndex();
1127                    
1128                    if (retrievedErrorIndex == 1)
1129                    {
1130                        break retrievalLoop;
1131                    }
1132                    else
1133                    {
1134                        throw new SNMPGetException("OID following " + requestedObjectIdentifier[retrievedErrorIndex - 1] + " not available for retrieval", retrievedErrorIndex, receivedPDU.getErrorStatus());
1135                    }
1136                }
1137                
1138                // copy info from retrieved sequence to var bind list
1139
varList = receivedPDU.getVarBindList();
1140                
1141                // make sure got the right number of vars in reply; if not, throw GetException
1142
if(varList.size() != requestedObjectIdentifier.length)
1143                {
1144                    throw new SNMPGetException("Incomplete row of table received", 0, SNMPRequestException.FAILED);
1145                }
1146                
1147                // copy the retrieved variable pairs into retrievedVars
1148
for (int i = 0; i < varList.size(); i++)
1149                {
1150                    SNMPSequence newPair = (SNMPSequence)(varList.getSNMPObjectAt(i));
1151                    
1152                    SNMPObjectIdentifier newObjectIdentifier = (SNMPObjectIdentifier)(newPair.getSNMPObjectAt(0));
1153                    SNMPObject newValue = newPair.getSNMPObjectAt(1);
1154                    
1155                    // now see if retrieved ID starts with table base; if not, done with table - break
1156
String JavaDoc newOIDString = (String JavaDoc)newObjectIdentifier.toString();
1157                    if (!newOIDString.startsWith(baseID[i]))
1158                    {
1159                        if (i == 0)
1160                        {
1161                            // it's the first element of the row; just break
1162
break retrievalLoop;
1163                        }
1164                        else
1165                        {
1166                            // it's a subsequent row element; throw exception
1167
throw new SNMPGetException("Incomplete row of table received", i+1, SNMPRequestException.FAILED);
1168                        }
1169                    }
1170                        
1171                    retrievedVars.addSNMPObject(newPair);
1172                    
1173                    // set requested identifiers array to current identifiers to do get-next for next row
1174
requestedObjectIdentifier[i] = newObjectIdentifier;
1175                }
1176                
1177                
1178                requestID++;
1179            
1180            }
1181            
1182            
1183        }
1184            
1185        
1186        return retrievedVars;
1187        
1188    }
1189    
1190    
1191    
1192    
1193    
1194    
1195    /**
1196    * Set the size of the buffer used to receive response packets. RFC 1157 stipulates that an SNMP
1197    * implementation must be able to receive packets of at least 484 bytes, so if you try to set the
1198    * size to a value less than this, the receive buffer size will be set to 484 bytes. In addition,
1199    * the maximum size of a UDP packet payload is 65535 bytes, so setting the buffer to a larger size
1200    * will just waste memory. The default value is 512 bytes. The value may need to be increased if
1201    * get-requests are issued for multiple OIDs.
1202    */

1203    
1204    public void setReceiveBufferSize(int receiveBufferSize)
1205    {
1206        if (receiveBufferSize >= 484)
1207        {
1208            this.receiveBufferSize = receiveBufferSize;
1209        }
1210        else
1211        {
1212            this.receiveBufferSize = 484;
1213        }
1214    }
1215    
1216    
1217    
1218    /**
1219    * Returns the current size of the buffer used to receive response packets.
1220    */

1221    
1222    public int getReceiveBufferSize()
1223    {
1224        return this.receiveBufferSize;
1225    }
1226    
1227    
1228    
1229}
1230
Popular Tags