KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > snmp > SNMPTrapReceiverInterface


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 import java.util.*;
36
37
38 /**
39 * The class SNMPTrapListenerInterface implements a server which listens for trap and inform request
40 * messages sent from remote SNMP entities. The approach is that from version 1 and 2c of SNMP, using no
41 * encryption of data. Communication occurs via UDP, using port 162, the standard SNMP trap port. This interface
42 * can handle both SNMPv1 and SNMPv2 traps (which have different PDU types), and SNMPv2 Inform Requests.
43 *
44 * Applications utilize this class with classes which implement the SNMPTrapListener or SNMPv2TrapListener or
45 * SNMPv2InformRequestListener interfaces. These must provide a processTrap(), processv2Trap() or processInformRequest()
46 * method, and are registered/unregistered with this class through its addv1TrapListener()/removev1TrapListener(),
47 * addv2TrapListener()/removev2TrapListener(), or addv2InformRequestListener()/removev2InformRequestListener()
48 * methods.
49 */

50
51 public class SNMPTrapReceiverInterface
52                         implements Runnable JavaDoc
53 {
54     public static final int SNMP_TRAP_PORT = 162;
55     
56     // largest size for datagram packet payload; based on
57
// RFC 1157, need to handle messages of at least 484 bytes
58
private int receiveBufferSize = 512;
59     
60     private DatagramSocket dSocket;
61     private Thread JavaDoc receiveThread;
62     
63     private Vector v1TrapListenerVector;
64     private Vector v2TrapListenerVector;
65     private Vector v2InformRequestListenerVector;
66     private PrintWriter errorLog;
67     
68     
69     
70     
71     /**
72     * Construct a new trap receiver object to receive traps from remote SNMP hosts.
73     * This version will accept messages from all hosts using any community name.
74     */

75     
76     public SNMPTrapReceiverInterface()
77         throws SocketException
78     {
79         // set System.out as the error writer
80
this(new PrintWriter(System.out));
81     }
82     
83     
84     
85     /**
86     * Construct a new trap receiver object to receive traps from remote SNMP hosts.
87     * This version will accept messages from all hosts using any community name. Uses the
88     * specified Writer to deliver error messages.
89     */

90     
91     public SNMPTrapReceiverInterface(PrintWriter errorReceiver)
92         throws SocketException
93     {
94         dSocket = new DatagramSocket(SNMP_TRAP_PORT);
95         
96         v1TrapListenerVector = new Vector();
97         v2TrapListenerVector = new Vector();
98         v2InformRequestListenerVector = new Vector();
99         
100         receiveThread = new Thread JavaDoc(this);
101         
102         errorLog = errorReceiver;
103         
104     }
105     
106     
107     
108     /**
109     * Set the specified PrintWriter to receive error messages.
110     */

111     
112     public void setErrorReceiver(PrintWriter errorReceiver)
113     {
114         errorLog = errorReceiver;
115     }
116     
117     
118     
119     public void addv1TrapListener(SNMPv1TrapListener listener)
120     {
121         // see if listener already added; if so, ignore
122
for (int i = 0; i < v1TrapListenerVector.size(); i++)
123         {
124             if (listener == v1TrapListenerVector.elementAt(i))
125             {
126                 return;
127             }
128         }
129         
130         // if got here, it's not in the list; add it
131
v1TrapListenerVector.add(listener);
132     }
133     
134     
135     
136     public void removev1TrapListener(SNMPv1TrapListener listener)
137     {
138         // see if listener in list; if so, remove, if not, ignore
139
for (int i = 0; i < v1TrapListenerVector.size(); i++)
140         {
141             if (listener == v1TrapListenerVector.elementAt(i))
142             {
143                 v1TrapListenerVector.removeElementAt(i);
144                 break;
145             }
146         }
147         
148     }
149     
150     
151     
152     public void addv2TrapListener(SNMPv2TrapListener listener)
153     {
154         // see if listener already added; if so, ignore
155
for (int i = 0; i < v2TrapListenerVector.size(); i++)
156         {
157             if (listener == v2TrapListenerVector.elementAt(i))
158             {
159                 return;
160             }
161         }
162         
163         // if got here, it's not in the list; add it
164
v2TrapListenerVector.add(listener);
165     }
166     
167     
168     
169     public void removev2TrapListener(SNMPv2TrapListener listener)
170     {
171         // see if listener in list; if so, remove, if not, ignore
172
for (int i = 0; i < v2TrapListenerVector.size(); i++)
173         {
174             if (listener == v2TrapListenerVector.elementAt(i))
175             {
176                 v2TrapListenerVector.removeElementAt(i);
177                 break;
178             }
179         }
180         
181     }
182     
183     
184     
185     public void addv2InformRequestListener(SNMPv2InformRequestListener listener)
186     {
187         // see if listener already added; if so, ignore
188
for (int i = 0; i < v2InformRequestListenerVector.size(); i++)
189         {
190             if (listener == v2InformRequestListenerVector.elementAt(i))
191             {
192                 return;
193             }
194         }
195         
196         // if got here, it's not in the list; add it
197
v2InformRequestListenerVector.add(listener);
198     }
199     
200     
201     
202     public void removev2InformRequestListener(SNMPv2InformRequestListener listener)
203     {
204         // see if listener in list; if so, remove, if not, ignore
205
for (int i = 0; i < v2InformRequestListenerVector.size(); i++)
206         {
207             if (listener == v2InformRequestListenerVector.elementAt(i))
208             {
209                 v2InformRequestListenerVector.removeElementAt(i);
210                 break;
211             }
212         }
213         
214     }
215
216     
217     
218     /**
219     * Start listening for trap and inform messages.
220     */

221     
222     public void startReceiving()
223     {
224         // if receiveThread not already running, start it
225
if (!receiveThread.isAlive())
226         {
227             receiveThread = new Thread JavaDoc(this);
228             receiveThread.start();
229         }
230     }
231     
232
233     
234     
235     /**
236     * Stop listening for trap and inform messages.
237     */

238     
239     public void stopReceiving()
240         throws SocketException
241     {
242         // interrupt receive thread so it will die a natural death
243
receiveThread.interrupt();
244     }
245
246     
247     
248     
249     
250     /**
251     * The run() method for the trap interface's listener. Just waits for trap or inform messages to
252     * come in on port 162, then dispatches the recieved PDUs to each of the registered
253     * listeners by calling their processTrap() or processInform() methods.
254     */

255     
256     public void run()
257     {
258         
259         int errorStatus = 0;
260         int errorIndex = 0;
261         
262         
263         
264         while (!receiveThread.isInterrupted())
265         {
266             
267             try
268                {
269                 
270                 DatagramPacket inPacket = new DatagramPacket(new byte[receiveBufferSize], receiveBufferSize);
271         
272                 dSocket.receive(inPacket);
273                 
274                 byte[] encodedMessage = inPacket.getData();
275                 
276                 
277                 /*
278                 errorLog.println("Message bytes length (in): " + inPacket.getLength());
279                 
280                 errorLog.println("Message bytes (in):");
281                 for (int i = 0; i < encodedMessage.length; ++i)
282                 {
283                     errorLog.print(hexByte(encodedMessage[i]) + " ");
284                 }
285                 errorLog.println("\n");
286                 */

287                 
288                 
289                 SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value);
290                 
291                 Object JavaDoc receivedPDU = receivedMessage.getPDUAsObject();
292                 
293                 if (!(receivedPDU instanceof SNMPv1TrapPDU) && !(receivedPDU instanceof SNMPv2TrapPDU) && !(receivedPDU instanceof SNMPv2InformRequestPDU))
294                 {
295                     throw new SNMPBadValueException("PDU received that's not a v1 or v2 trap or inform request; message payload of type " + receivedPDU.getClass().toString());
296                 }
297                 
298                 // pass the received trap PDU to the processTrap or procesv2Trap method of any listeners
299
if (receivedPDU instanceof SNMPv1TrapPDU)
300                 {
301                     for (int i = 0; i < v1TrapListenerVector.size(); i++)
302                     {
303                         SNMPv1TrapListener listener = (SNMPv1TrapListener)v1TrapListenerVector.elementAt(i);
304                         
305                         listener.processv1Trap((SNMPv1TrapPDU)receivedPDU);
306                     }
307                 }
308                 else if (receivedPDU instanceof SNMPv2TrapPDU)
309                 {
310                     for (int i = 0; i < v2TrapListenerVector.size(); i++)
311                     {
312                         SNMPv2TrapListener listener = (SNMPv2TrapListener)v2TrapListenerVector.elementAt(i);
313                         
314                         listener.processv2Trap((SNMPv2TrapPDU)receivedPDU);
315                     }
316                 }
317                 else if (receivedPDU instanceof SNMPv2InformRequestPDU)
318                 {
319                     for (int i = 0; i < v2InformRequestListenerVector.size(); i++)
320                     {
321                         SNMPv2InformRequestListener listener = (SNMPv2InformRequestListener)v2InformRequestListenerVector.elementAt(i);
322                         
323                         listener.processv2InformRequest((SNMPv2InformRequestPDU)receivedPDU);
324                     }
325                 }
326                 
327         
328             }
329             catch (IOException e)
330             {
331                 // just report the problem
332
errorLog.println("IOException during request processing: " + e.toString());
333                 errorLog.flush();
334             }
335             catch (SNMPBadValueException e)
336             {
337                 // just report the problem
338
errorLog.println("SNMPBadValueException during request processing: " + e.toString());
339                 errorLog.flush();
340             }
341             catch (Exception JavaDoc e)
342             {
343                 // just report the problem
344
errorLog.println("Exception during request processing: " + e.toString());
345                 errorLog.flush();
346             }
347             
348         }
349                 
350     }
351     
352     
353     
354     private String JavaDoc hexByte(byte b)
355     {
356         int pos = b;
357         if (pos < 0)
358             pos += 256;
359         String JavaDoc returnString = new String JavaDoc();
360         returnString += Integer.toHexString(pos/16);
361         returnString += Integer.toHexString(pos%16);
362         return returnString;
363     }
364     
365     
366     
367     
368     
369     
370     private String JavaDoc getHex(byte theByte)
371     {
372         int b = theByte;
373         
374         if (b < 0)
375             b += 256;
376         
377         String JavaDoc returnString = new String JavaDoc(Integer.toHexString(b));
378         
379         // add leading 0 if needed
380
if (returnString.length()%2 == 1)
381             returnString = "0" + returnString;
382             
383         return returnString;
384     }
385     
386     
387     
388     /**
389     * Set the size of the buffer used to receive response packets. RFC 1157 stipulates that an SNMP
390     * implementation must be able to receive packets of at least 484 bytes, so if you try to set the
391     * size to a value less than this, the receive buffer size will be set to 484 bytes. In addition,
392     * the maximum size of a UDP packet payload is 65535 bytes, so setting the buffer to a larger size
393     * will just waste memory. The default value is 512 bytes. The value may need to be increased if
394     * get-requests are issued for multiple OIDs.
395     */

396     
397     public void setReceiveBufferSize(int receiveBufferSize)
398     {
399         if (receiveBufferSize >= 484)
400         {
401             this.receiveBufferSize = receiveBufferSize;
402         }
403         else
404         {
405             this.receiveBufferSize = 484;
406         }
407     }
408     
409     
410     
411     /**
412     * Returns the current size of the buffer used to receive response packets.
413     */

414     
415     public int getReceiveBufferSize()
416     {
417         return this.receiveBufferSize;
418     }
419     
420     
421     
422 }
Popular Tags