KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jmx > snmp > daemon > SnmpAdaptorServer


1 /*
2  * @(#)file SnmpAdaptorServer.java
3  * @(#)author Sun Microsystems, Inc.
4  * @(#)version 4.98
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.daemon;
14
15
16 // java imports
17
//
18
import java.util.Vector JavaDoc;
19 import java.util.Enumeration JavaDoc;
20 import java.net.DatagramSocket JavaDoc;
21 import java.net.DatagramPacket JavaDoc;
22 import java.net.InetAddress JavaDoc;
23 import java.net.SocketException JavaDoc;
24 import java.net.UnknownHostException JavaDoc;
25 import java.io.ObjectInputStream JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InterruptedIOException JavaDoc;
28
29
30 // jmx imports
31
//
32
import javax.management.MBeanServer JavaDoc;
33 import javax.management.MBeanRegistration JavaDoc;
34 import javax.management.ObjectName JavaDoc;
35 import javax.management.InstanceAlreadyExistsException JavaDoc;
36 import com.sun.jmx.snmp.SnmpIpAddress;
37 import com.sun.jmx.snmp.SnmpMessage;
38 import com.sun.jmx.snmp.SnmpOid;
39 import com.sun.jmx.snmp.SnmpPduFactory;
40 import com.sun.jmx.snmp.SnmpPduPacket;
41 import com.sun.jmx.snmp.SnmpPduRequest;
42 import com.sun.jmx.snmp.SnmpPduTrap;
43 import com.sun.jmx.snmp.SnmpTimeticks;
44 import com.sun.jmx.snmp.SnmpVarBind;
45 import com.sun.jmx.snmp.SnmpVarBindList;
46 import com.sun.jmx.snmp.SnmpDefinitions;
47 import com.sun.jmx.snmp.SnmpStatusException;
48 import com.sun.jmx.snmp.SnmpTooBigException;
49 import com.sun.jmx.snmp.InetAddressAcl;
50 import com.sun.jmx.snmp.SnmpPeer;
51 import com.sun.jmx.snmp.SnmpParameters;
52 // SNMP Runtime imports
53
//
54
import com.sun.jmx.snmp.SnmpPduFactoryBER;
55 import com.sun.jmx.snmp.agent.SnmpMibAgent;
56 import com.sun.jmx.snmp.agent.SnmpMibHandler;
57 import com.sun.jmx.snmp.agent.SnmpUserDataFactory;
58 import com.sun.jmx.snmp.agent.SnmpErrorHandlerAgent;
59
60 import com.sun.jmx.snmp.IPAcl.SnmpAcl;
61
62 import com.sun.jmx.snmp.tasks.ThreadService;
63
64 /**
65  * Implements an adaptor on top of the SNMP protocol.
66  * <P>
67  * When this SNMP protocol adaptor is started it creates a datagram socket
68  * and is able to receive requests and send traps or inform requests.
69  * When it is stopped, the socket is closed and neither requests
70  * and nor traps/inform request are processed.
71  * <P>
72  * The default port number of the socket is 161. This default value can be
73  * changed by specifying a port number:
74  * <UL>
75  * <LI>in the object constructor</LI>
76  * <LI>using the {@link com.sun.jmx.snmp.daemon.CommunicatorServer#setPort
77  * setPort} method before starting the adaptor</LI>
78  * </UL>
79  * The default object name is defined by {@link
80  * com.sun.jmx.snmp.ServiceName#DOMAIN com.sun.jmx.snmp.ServiceName.DOMAIN}
81  * and {@link com.sun.jmx.snmp.ServiceName#SNMP_ADAPTOR_SERVER
82  * com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_SERVER}.
83  * <P>
84  * The SNMP protocol adaptor supports versions 1 and 2 of the SNMP protocol
85  * in a stateless way: when it receives a v1 request, it replies with a v1
86  * response, when it receives a v2 request it replies with a v2 response.
87  * <BR>The method {@link #snmpV1Trap snmpV1Trap} sends traps using SNMP v1
88  * format.
89  * The method {@link #snmpV2Trap snmpV2Trap} sends traps using SNMP v2 format.
90  * The method {@link #snmpInformRequest snmpInformRequest} sends inform
91  * requests using SNMP v2 format.
92  * <P>
93  * To receive data packets, the SNMP protocol adaptor uses a buffer
94  * which size can be configured using the property <CODE>bufferSize</CODE>
95  * (default value is 1024).
96  * Packets which do not fit into the buffer are rejected.
97  * Increasing <CODE>bufferSize</CODE> allows the exchange of bigger packets.
98  * However, the underlying networking system may impose a limit on the size
99  * of UDP packets.
100  * Packets which size exceed this limit will be rejected, no matter what
101  * the value of <CODE>bufferSize</CODE> actually is.
102  * <P>
103  * An SNMP protocol adaptor may serve several managers concurrently. The
104  * number of concurrent managers can be limited using the property
105  * <CODE>maxActiveClientCount</CODE>.
106  * <p>
107  * The SNMP protocol adaptor specifies a default value (10) for the
108  * <CODE>maxActiveClientCount</CODE> property. When the adaptor is stopped,
109  * the active requests are interrupted and an error result is sent to
110  * the managers.
111  * <p><b>This API is a Sun Microsystems internal API and is subject
112  * to change without notice.</b></p>
113  */

114
115 public class SnmpAdaptorServer extends CommunicatorServer
116     implements SnmpAdaptorServerMBean, MBeanRegistration JavaDoc, SnmpDefinitions,
117            SnmpMibHandler {
118     
119     // PRIVATE VARIABLES
120
//------------------
121

122     /**
123      * Port number for sending SNMP traps.
124      * <BR>The default value is 162.
125      */

126     private int trapPort = 162;
127     
128     /**
129      * Port number for sending SNMP inform requests.
130      * <BR>The default value is 162.
131      */

132     private int informPort = 162;
133     
134     /**
135      * The <CODE>InetAddress</CODE> used when creating the datagram socket.
136      * <BR>It is specified when creating the SNMP protocol adaptor.
137      * If not specified, the local host machine is used.
138      */

139     InetAddress JavaDoc address = null;
140
141     /**
142      * The IP address based ACL used by this SNMP protocol adaptor.
143      */

144     private Object JavaDoc ipacl = null;
145
146     /**
147      * The factory object.
148      */

149     private SnmpPduFactory pduFactory = null;
150     
151     /**
152      * The user-data factory object.
153      */

154     private SnmpUserDataFactory userDataFactory = null;
155
156     /**
157      * Indicates if the SNMP protocol adaptor sends a response in case
158      * of authentication failure
159      */

160     private boolean authRespEnabled = true;
161
162     /**
163      * Indicates if authentication traps are enabled.
164      */

165     private boolean authTrapEnabled = true;
166     
167     /**
168      * The enterprise OID.
169      * <BR>The default value is "1.3.6.1.4.1.42".
170      */

171     private SnmpOid enterpriseOid = new SnmpOid("1.3.6.1.4.1.42");
172     
173     /**
174      * The buffer size of the SNMP protocol adaptor.
175      * This buffer size is used for both incoming request and outgoing
176      * inform requests.
177      * <BR>The default value is 1024.
178      */

179     int bufferSize = 1024;
180     
181     private transient long startUpTime = 0;
182     private transient DatagramSocket JavaDoc socket = null;
183     transient DatagramSocket JavaDoc trapSocket = null;
184     private transient SnmpSession informSession = null;
185     private transient DatagramPacket JavaDoc packet = null;
186     transient Vector JavaDoc mibs = new Vector JavaDoc();
187     private transient SnmpMibTree root;
188
189     /**
190      * Whether ACL must be used.
191      */

192     private transient boolean useAcl = true;
193
194     
195     // SENDING SNMP INFORMS STUFF
196
//---------------------------
197

198     /**
199      * Number of times to try an inform request before giving up.
200      * The default number is 3.
201      */

202     private int maxTries = 3 ;
203
204     /**
205      * The amount of time to wait for an inform response from the manager.
206      * The default amount of time is 3000 millisec.
207      */

208     private int timeout = 3 * 1000 ;
209         
210     // VARIABLES REQUIRED FOR IMPLEMENTING SNMP GROUP (MIBII)
211
//-------------------------------------------------------
212

213     /**
214      * The <CODE>snmpOutTraps</CODE> value defined in MIB-II.
215      */

216     int snmpOutTraps=0;
217     
218     /**
219      * The <CODE>snmpOutGetResponses</CODE> value defined in MIB-II.
220      */

221     private int snmpOutGetResponses=0;
222
223     /**
224      * The <CODE>snmpOutGenErrs</CODE> value defined in MIB-II.
225      */

226     private int snmpOutGenErrs=0;
227
228     /**
229      * The <CODE>snmpOutBadValues</CODE> value defined in MIB-II.
230      */

231     private int snmpOutBadValues=0;
232
233     /**
234      * The <CODE>snmpOutNoSuchNames</CODE> value defined in MIB-II.
235      */

236     private int snmpOutNoSuchNames=0;
237
238     /**
239      * The <CODE>snmpOutTooBigs</CODE> value defined in MIB-II.
240      */

241     private int snmpOutTooBigs=0;
242
243     /**
244      * The <CODE>snmpOutPkts</CODE> value defined in MIB-II.
245      */

246     int snmpOutPkts=0;
247
248     /**
249      * The <CODE>snmpInASNParseErrs</CODE> value defined in MIB-II.
250      */

251     private int snmpInASNParseErrs=0;
252
253     /**
254      * The <CODE>snmpInBadCommunityUses</CODE> value defined in MIB-II.
255      */

256     private int snmpInBadCommunityUses=0;
257
258     /**
259      * The <CODE>snmpInBadCommunityNames</CODE> value defined in MIB-II.
260      */

261     private int snmpInBadCommunityNames=0;
262
263     /**
264      * The <CODE>snmpInBadVersions</CODE> value defined in MIB-II.
265      */

266     private int snmpInBadVersions=0;
267
268     /**
269      * The <CODE>snmpInGetRequests</CODE> value defined in MIB-II.
270      */

271     private int snmpInGetRequests=0;
272
273     /**
274      * The <CODE>snmpInGetNexts</CODE> value defined in MIB-II.
275      */

276     private int snmpInGetNexts=0;
277
278     /**
279      * The <CODE>snmpInSetRequests</CODE> value defined in MIB-II.
280      */

281     private int snmpInSetRequests=0;
282
283     /**
284      * The <CODE>snmpInPkts</CODE> value defined in MIB-II.
285      */

286     private int snmpInPkts=0;
287
288     /**
289      * The <CODE>snmpInTotalReqVars</CODE> value defined in MIB-II.
290      */

291     private int snmpInTotalReqVars=0;
292
293     /**
294      * The <CODE>snmpInTotalSetVars</CODE> value defined in MIB-II.
295      */

296     private int snmpInTotalSetVars=0;
297
298     /**
299      * The <CODE>snmpInTotalSetVars</CODE> value defined in rfc 1907 MIB-II.
300      */

301     private int snmpSilentDrops=0;
302     
303     private static final String JavaDoc InterruptSysCallMsg =
304     "Interrupted system call";
305     static final SnmpOid sysUpTimeOid = new SnmpOid("1.3.6.1.2.1.1.3.0") ;
306     static final SnmpOid snmpTrapOidOid = new SnmpOid("1.3.6.1.6.3.1.1.4.1.0");
307         
308     private ThreadService threadService;
309
310     private static int threadNumber = 6;
311
312     static {
313     String JavaDoc s = System.getProperty("com.sun.jmx.snmp.threadnumber");
314
315     if (s != null) {
316         try {
317         threadNumber = Integer.parseInt(System.getProperty(s));
318         } catch (Exception JavaDoc e) {
319         // ???
320
System.err.println("Got wrong value for " +
321                    "com.sun.jmx.snmp.threadnumber: "+s);
322         System.err.println("Use the default value: "+threadNumber);
323         }
324     }
325     }
326
327     // PUBLIC CONSTRUCTORS
328
//--------------------
329

330     /**
331      * Initializes this SNMP protocol adaptor using the default port (161).
332      * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
333      * implementation of the <CODE>InetAddressAcl</CODE> interface.
334      */

335     public SnmpAdaptorServer() {
336         this(true, null, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
337          null) ;
338     }
339
340     /**
341      * Initializes this SNMP protocol adaptor using the specified port.
342      * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
343      * implementation of the <CODE>InetAddressAcl</CODE> interface.
344      *
345      * @param port The port number for sending SNMP responses.
346      */

347     public SnmpAdaptorServer(int port) {
348         this(true, null, port, null) ;
349     }
350
351     /**
352      * Initializes this SNMP protocol adaptor using the default port (161)
353      * and the specified IP address based ACL implementation.
354      *
355      * @param acl The <CODE>InetAddressAcl</CODE> implementation.
356      * <code>null</code> means no ACL - everybody is authorized.
357      *
358      * @since 1.5
359      */

360     public SnmpAdaptorServer(InetAddressAcl acl) {
361         this(false, acl, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
362          null) ;
363     }
364
365     /**
366      * Initializes this SNMP protocol adaptor using the default port (161)
367      * and the
368      * specified <CODE>InetAddress</CODE>.
369      * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
370      * implementation of the <CODE>InetAddressAcl</CODE> interface.
371      *
372      * @param addr The IP address to bind.
373      */

374     public SnmpAdaptorServer(InetAddress JavaDoc addr) {
375         this(true, null, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
376          addr) ;
377     }
378     
379     /**
380      * Initializes this SNMP protocol adaptor using the specified port and the
381      * specified IP address based ACL implementation.
382      *
383      * @param acl The <CODE>InetAddressAcl</CODE> implementation.
384      * <code>null</code> means no ACL - everybody is authorized.
385      * @param port The port number for sending SNMP responses.
386      *
387      * @since 1.5
388      */

389     public SnmpAdaptorServer(InetAddressAcl acl, int port) {
390         this(false, acl, port, null) ;
391     }
392
393     /**
394      * Initializes this SNMP protocol adaptor using the specified port and the
395      * specified <CODE>InetAddress</CODE>.
396      * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
397      * implementation of the <CODE>InetAddressAcl</CODE> interface.
398      *
399      * @param port The port number for sending SNMP responses.
400      * @param addr The IP address to bind.
401      */

402     public SnmpAdaptorServer(int port, InetAddress JavaDoc addr) {
403         this(true, null, port, addr) ;
404     }
405       
406     /**
407      * Initializes this SNMP protocol adaptor using the specified IP
408      * address based ACL implementation and the specified
409      * <CODE>InetAddress</CODE>.
410      *
411      * @param acl The <CODE>InetAddressAcl</CODE> implementation.
412      * @param addr The IP address to bind.
413      *
414      * @since 1.5
415      */

416     public SnmpAdaptorServer(InetAddressAcl acl, InetAddress JavaDoc addr) {
417         this(false, acl, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
418          addr) ;
419     }
420
421     /**
422      * Initializes this SNMP protocol adaptor using the specified port, the
423      * specified address based ACL implementation and the specified
424      * <CODE>InetAddress</CODE>.
425      *
426      * @param acl The <CODE>InetAddressAcl</CODE> implementation.
427      * @param port The port number for sending SNMP responses.
428      * @param addr The IP address to bind.
429      *
430      * @since 1.5
431      */

432     public SnmpAdaptorServer(InetAddressAcl acl, int port, InetAddress JavaDoc addr) {
433         this(false, acl, port, addr);
434     }
435
436     /**
437      * Initializes this SNMP protocol adaptor using the specified port and the
438      * specified <CODE>InetAddress</CODE>.
439      * This constructor allows to initialize an SNMP adaptor without using
440      * the ACL mechanism (by setting the <CODE>useAcl</CODE> parameter to
441      * false).
442      * <br>This constructor must be used in particular with a platform that
443      * does not support the <CODE>java.security.acl</CODE> package like pJava.
444      *
445      * @param useAcl Specifies if this new SNMP adaptor uses the ACL mechanism.
446      * If the specified parameter is set to <CODE>true</CODE>, this
447      * constructor is equivalent to
448      * <CODE>SnmpAdaptorServer((int)port,(InetAddress)addr)</CODE>.
449      * @param port The port number for sending SNMP responses.
450      * @param addr The IP address to bind.
451      */

452     public SnmpAdaptorServer(boolean useAcl, int port, InetAddress JavaDoc addr) {
453     this(useAcl,null,port,addr);
454     }
455
456     // If forceAcl is `true' and InetAddressAcl is null, then a default
457
// SnmpAcl object is created.
458
//
459
private SnmpAdaptorServer(boolean forceAcl, InetAddressAcl acl,
460                   int port, InetAddress JavaDoc addr) {
461         super(CommunicatorServer.SNMP_TYPE) ;
462     
463         
464         // Initialize the ACL implementation.
465
//
466
if (acl == null && forceAcl) {
467             try {
468                 acl = (InetAddressAcl)
469             new SnmpAcl("SNMP protocol adaptor IP ACL");
470             } catch (UnknownHostException JavaDoc e) {
471                 if (isDebugOn()) {
472                     debug("constructor",
473               "UnknowHostException when creating ACL");
474                     debug("constructor", e);
475                 }
476             }
477         } else {
478         this.useAcl = (acl!=null) || forceAcl;
479     }
480
481         init(acl, port, addr) ;
482     }
483       
484     // GETTERS AND SETTERS
485
//--------------------
486

487     /**
488      * Gets the number of managers that have been processed by this
489      * SNMP protocol adaptor since its creation.
490      *
491      * @return The number of managers handled by this SNMP protocol adaptor
492      * since its creation. This counter is not reset by the <CODE>stop</CODE>
493      * method.
494      */

495     public int getServedClientCount() {
496         return super.getServedClientCount();
497     }
498
499     /**
500      * Gets the number of managers currently being processed by this
501      * SNMP protocol adaptor.
502      *
503      * @return The number of managers currently being processed by this
504      * SNMP protocol adaptor.
505      */

506     public int getActiveClientCount() {
507         return super.getActiveClientCount();
508     }
509
510     /**
511      * Gets the maximum number of managers that this SNMP protocol adaptor can
512      * process concurrently.
513      *
514      * @return The maximum number of managers that this SNMP protocol adaptor
515      * can process concurrently.
516      */

517     public int getMaxActiveClientCount() {
518         return super.getMaxActiveClientCount();
519     }
520
521     /**
522      * Sets the maximum number of managers this SNMP protocol adaptor can
523      * process concurrently.
524      *
525      * @param c The number of managers.
526      *
527      * @exception java.lang.IllegalStateException This method has been invoked
528      * while the communicator was <CODE>ONLINE</CODE> or <CODE>STARTING</CODE>.
529      */

530     public void setMaxActiveClientCount(int c)
531     throws java.lang.IllegalStateException JavaDoc {
532     super.setMaxActiveClientCount(c);
533     }
534     
535     /**
536      * Returns the Ip address based ACL used by this SNMP protocol adaptor.
537      * @return The <CODE>InetAddressAcl</CODE> implementation.
538      *
539      * @since 1.5
540      */

541     public InetAddressAcl getInetAddressAcl() {
542     return (InetAddressAcl)ipacl;
543     }
544
545     /**
546      * Returns the port used by this SNMP protocol adaptor for sending traps.
547      * By default, port 162 is used.
548      *
549      * @return The port number for sending SNMP traps.
550      */

551     public Integer JavaDoc getTrapPort() {
552         return new Integer JavaDoc(trapPort) ;
553     }
554   
555     /**
556      * Sets the port used by this SNMP protocol adaptor for sending traps.
557      *
558      * @param port The port number for sending SNMP traps.
559      */

560     public void setTrapPort(Integer JavaDoc port) {
561         setTrapPort(port.intValue());
562     }
563   
564     /**
565      * Sets the port used by this SNMP protocol adaptor for sending traps.
566      *
567      * @param port The port number for sending SNMP traps.
568      */

569     public void setTrapPort(int port) {
570         int val= port ;
571         if (val < 0) throw new
572             IllegalArgumentException JavaDoc("Trap port cannot be a negative value");
573         trapPort= val ;
574     }
575   
576     /**
577      * Returns the port used by this SNMP protocol adaptor for sending
578      * inform requests. By default, port 162 is used.
579      *
580      * @return The port number for sending SNMP inform requests.
581      */

582     public int getInformPort() {
583         return informPort;
584     }
585   
586     /**
587      * Sets the port used by this SNMP protocol adaptor for sending
588      * inform requests.
589      *
590      * @param port The port number for sending SNMP inform requests.
591      */

592     public void setInformPort(int port) {
593         if (port < 0)
594             throw new IllegalArgumentException JavaDoc("Inform request port "+
595                            "cannot be a negative value");
596         informPort= port ;
597     }
598     
599     /**
600      * Returns the protocol of this SNMP protocol adaptor.
601      *
602      * @return The string "snmp".
603      */

604     public String JavaDoc getProtocol() {
605         return "snmp";
606     }
607   
608     /**
609      * Returns the buffer size of this SNMP protocol adaptor.
610      * This buffer size is used for both incoming request and outgoing
611      * inform requests.
612      * By default, buffer size 1024 is used.
613      *
614      * @return The buffer size.
615      */

616     public Integer JavaDoc getBufferSize() {
617         return new Integer JavaDoc(bufferSize) ;
618     }
619
620     /**
621      * Sets the buffer size of this SNMP protocol adaptor.
622      * This buffer size is used for both incoming request and outgoing
623      * inform requests.
624      *
625      * @param s The buffer size.
626      *
627      * @exception java.lang.IllegalStateException This method has been invoked
628      * while the communicator was <CODE>ONLINE</CODE> or <CODE>STARTING</CODE>.
629      */

630     public void setBufferSize(Integer JavaDoc s)
631     throws java.lang.IllegalStateException JavaDoc {
632         if ((state == ONLINE) || (state == STARTING)) {
633             throw new IllegalStateException JavaDoc("Stop server before carrying out"+
634                         " this operation");
635         }
636         bufferSize = s.intValue() ;
637     }
638   
639     /**
640      * Gets the number of times to try sending an inform request before
641      * giving up.
642      * By default, a maximum of 3 tries is used.
643      * @return The maximun number of tries.
644      */

645     final public int getMaxTries() {
646         return maxTries;
647     }
648     
649     /**
650      * Changes the maximun number of times to try sending an inform
651      * request before giving up.
652      * @param newMaxTries The maximun number of tries.
653      */

654     final public synchronized void setMaxTries(int newMaxTries) {
655         if (newMaxTries < 0)
656             throw new IllegalArgumentException JavaDoc();
657         maxTries = newMaxTries;
658     }
659     
660     /**
661      * Gets the timeout to wait for an inform response from the manager.
662      * By default, a timeout of 3 seconds is used.
663      * @return The value of the timeout property.
664      */

665     final public int getTimeout() {
666         return timeout;
667     }
668     
669     /**
670      * Changes the timeout to wait for an inform response from the manager.
671      * @param newTimeout The timeout (in milliseconds).
672      */

673     final public synchronized void setTimeout(int newTimeout) {
674         if (newTimeout < 0)
675             throw new IllegalArgumentException JavaDoc();
676         timeout= newTimeout;
677     }
678     
679     /**
680      * Returns the message factory of this SNMP protocol adaptor.
681      *
682      * @return The factory object.
683      */

684     public SnmpPduFactory getPduFactory() {
685         return pduFactory ;
686     }
687     
688     /**
689      * Sets the message factory of this SNMP protocol adaptor.
690      *
691      * @param factory The factory object (null means the default factory).
692      */

693     public void setPduFactory(SnmpPduFactory factory) {
694         if (factory == null)
695             pduFactory = new SnmpPduFactoryBER() ;
696         else
697             pduFactory = factory ;
698     }
699   
700     /**
701      * Set the user-data factory of this SNMP protocol adaptor.
702      *
703      * @param factory The factory object (null means no factory).
704      * @see com.sun.jmx.snmp.agent.SnmpUserDataFactory
705      */

706     public void setUserDataFactory(SnmpUserDataFactory factory) {
707     userDataFactory = factory ;
708     }
709   
710     /**
711      * Get the user-data factory associated with this SNMP protocol adaptor.
712      *
713      * @return The factory object (null means no factory).
714      * @see com.sun.jmx.snmp.agent.SnmpUserDataFactory
715      */

716     public SnmpUserDataFactory getUserDataFactory() {
717     return userDataFactory;
718     }
719   
720     /**
721      * Returns <CODE>true</CODE> if authentication traps are enabled.
722      * <P>
723      * When this feature is enabled, the SNMP protocol adaptor sends
724      * an <CODE>authenticationFailure</CODE> trap each time an
725      * authentication fails.
726      * <P>
727      * The default behaviour is to send authentication traps.
728      *
729      * @return <CODE>true</CODE> if authentication traps are enabled,
730      * <CODE>false</CODE> otherwise.
731      */

732     public boolean getAuthTrapEnabled() {
733         return authTrapEnabled ;
734     }
735   
736     /**
737      * Sets the flag indicating if traps need to be sent in case of
738      * authentication failure.
739      *
740      * @param enabled Flag indicating if traps need to be sent.
741      */

742     public void setAuthTrapEnabled(boolean enabled) {
743         authTrapEnabled = enabled ;
744     }
745
746     /**
747      * Returns <code>true</code> if this SNMP protocol adaptor sends a
748      * response in case of authentication failure.
749      * <P>
750      * When this feature is enabled, the SNMP protocol adaptor sends a
751      * response with <CODE>noSuchName</CODE> or <CODE>readOnly</CODE> when
752      * the authentication failed. If the flag is disabled, the
753      * SNMP protocol adaptor trashes the PDU silently.
754      * <P>
755      * The default behavior is to send responses.
756      *
757      * @return <CODE>true</CODE> if responses are sent.
758      */

759     public boolean getAuthRespEnabled() {
760         return authRespEnabled ;
761     }
762
763     /**
764      * Sets the flag indicating if responses need to be sent in case of
765      * authentication failure.
766      *
767      * @param enabled Flag indicating if responses need to be sent.
768      */

769     public void setAuthRespEnabled(boolean enabled) {
770         authRespEnabled = enabled ;
771     }
772     
773     /**
774      * Returns the enterprise OID. It is used by
775      * {@link #snmpV1Trap snmpV1Trap} to fill the 'enterprise' field of the
776      * trap request.
777      *
778      * @return The OID in string format "x.x.x.x".
779      */

780     public String JavaDoc getEnterpriseOid() {
781         return enterpriseOid.toString() ;
782     }
783
784     /**
785      * Sets the enterprise OID.
786      *
787      * @param oid The OID in string format "x.x.x.x".
788      *
789      * @exception IllegalArgumentException The string format is incorrect
790      */

791     public void setEnterpriseOid(String JavaDoc oid) throws IllegalArgumentException JavaDoc {
792         enterpriseOid = new SnmpOid(oid) ;
793     }
794     
795     /**
796      * Returns the names of the MIBs available in this SNMP protocol adaptor.
797      *
798      * @return An array of MIB names.
799      */

800     public String JavaDoc[] getMibs() {
801         String JavaDoc[] result = new String JavaDoc[mibs.size()] ;
802         int i = 0 ;
803         for (Enumeration JavaDoc e = mibs.elements() ; e.hasMoreElements() ;) {
804             SnmpMibAgent mib = (SnmpMibAgent)e.nextElement() ;
805             result[i++] = mib.getMibName();
806         }
807         return result ;
808     }
809     
810     // GETTERS FOR SNMP GROUP (MIBII)
811
//-------------------------------
812

813     /**
814      * Returns the <CODE>snmpOutTraps</CODE> value defined in MIB-II.
815      *
816      * @return The <CODE>snmpOutTraps</CODE> value.
817      */

818     public Long JavaDoc getSnmpOutTraps() {
819         return new Long JavaDoc(snmpOutTraps);
820     }
821   
822     /**
823      * Returns the <CODE>snmpOutGetResponses</CODE> value defined in MIB-II.
824      *
825      * @return The <CODE>snmpOutGetResponses</CODE> value.
826      */

827     public Long JavaDoc getSnmpOutGetResponses() {
828         return new Long JavaDoc(snmpOutGetResponses);
829     }
830   
831     /**
832      * Returns the <CODE>snmpOutGenErrs</CODE> value defined in MIB-II.
833      *
834      * @return The <CODE>snmpOutGenErrs</CODE> value.
835      */

836     public Long JavaDoc getSnmpOutGenErrs() {
837         return new Long JavaDoc(snmpOutGenErrs);
838     }
839   
840     /**
841      * Returns the <CODE>snmpOutBadValues</CODE> value defined in MIB-II.
842      *
843      * @return The <CODE>snmpOutBadValues</CODE> value.
844      */

845     public Long JavaDoc getSnmpOutBadValues() {
846         return new Long JavaDoc(snmpOutBadValues);
847     }
848   
849     /**
850      * Returns the <CODE>snmpOutNoSuchNames</CODE> value defined in MIB-II.
851      *
852      * @return The <CODE>snmpOutNoSuchNames</CODE> value.
853      */

854     public Long JavaDoc getSnmpOutNoSuchNames() {
855         return new Long JavaDoc(snmpOutNoSuchNames);
856     }
857   
858     /**
859      * Returns the <CODE>snmpOutTooBigs</CODE> value defined in MIB-II.
860      *
861      * @return The <CODE>snmpOutTooBigs</CODE> value.
862      */

863     public Long JavaDoc getSnmpOutTooBigs() {
864         return new Long JavaDoc(snmpOutTooBigs);
865     }
866   
867     /**
868      * Returns the <CODE>snmpInASNParseErrs</CODE> value defined in MIB-II.
869      *
870      * @return The <CODE>snmpInASNParseErrs</CODE> value.
871      */

872     public Long JavaDoc getSnmpInASNParseErrs() {
873         return new Long JavaDoc(snmpInASNParseErrs);
874     }
875   
876     /**
877      * Returns the <CODE>snmpInBadCommunityUses</CODE> value defined in MIB-II.
878      *
879      * @return The <CODE>snmpInBadCommunityUses</CODE> value.
880      */

881     public Long JavaDoc getSnmpInBadCommunityUses() {
882         return new Long JavaDoc(snmpInBadCommunityUses);
883     }
884   
885     /**
886      * Returns the <CODE>snmpInBadCommunityNames</CODE> value defined in
887      * MIB-II.
888      *
889      * @return The <CODE>snmpInBadCommunityNames</CODE> value.
890      */

891     public Long JavaDoc getSnmpInBadCommunityNames() {
892         return new Long JavaDoc(snmpInBadCommunityNames);
893     }
894   
895     /**
896      * Returns the <CODE>snmpInBadVersions</CODE> value defined in MIB-II.
897      *
898      * @return The <CODE>snmpInBadVersions</CODE> value.
899      */

900     public Long JavaDoc getSnmpInBadVersions() {
901         return new Long JavaDoc(snmpInBadVersions);
902     }
903   
904     /**
905      * Returns the <CODE>snmpOutPkts</CODE> value defined in MIB-II.
906      *
907      * @return The <CODE>snmpOutPkts</CODE> value.
908      */

909     public Long JavaDoc getSnmpOutPkts() {
910         return new Long JavaDoc(snmpOutPkts);
911     }
912   
913     /**
914      * Returns the <CODE>snmpInPkts</CODE> value defined in MIB-II.
915      *
916      * @return The <CODE>snmpInPkts</CODE> value.
917      */

918     public Long JavaDoc getSnmpInPkts() {
919         return new Long JavaDoc(snmpInPkts);
920     }
921   
922     /**
923      * Returns the <CODE>snmpInGetRequests</CODE> value defined in MIB-II.
924      *
925      * @return The <CODE>snmpInGetRequests</CODE> value.
926      */

927     public Long JavaDoc getSnmpInGetRequests() {
928         return new Long JavaDoc(snmpInGetRequests);
929     }
930   
931     /**
932      * Returns the <CODE>snmpInGetNexts</CODE> value defined in MIB-II.
933      *
934      * @return The <CODE>snmpInGetNexts</CODE> value.
935      */

936     public Long JavaDoc getSnmpInGetNexts() {
937         return new Long JavaDoc(snmpInGetNexts);
938     }
939   
940     /**
941      * Returns the <CODE>snmpInSetRequests</CODE> value defined in MIB-II.
942      *
943      * @return The <CODE>snmpInSetRequests</CODE> value.
944      */

945     public Long JavaDoc getSnmpInSetRequests() {
946         return new Long JavaDoc(snmpInSetRequests);
947     }
948   
949     /**
950      * Returns the <CODE>snmpInTotalSetVars</CODE> value defined in MIB-II.
951      *
952      * @return The <CODE>snmpInTotalSetVars</CODE> value.
953      */

954     public Long JavaDoc getSnmpInTotalSetVars() {
955         return new Long JavaDoc(snmpInTotalSetVars);
956     }
957   
958     /**
959      * Returns the <CODE>snmpInTotalReqVars</CODE> value defined in MIB-II.
960      *
961      * @return The <CODE>snmpInTotalReqVars</CODE> value.
962      */

963     public Long JavaDoc getSnmpInTotalReqVars() {
964         return new Long JavaDoc(snmpInTotalReqVars);
965     }
966     
967     /**
968      * Returns the <CODE>snmpSilentDrops</CODE> value defined in RFC
969      * 1907 NMPv2-MIB .
970      *
971      * @return The <CODE>snmpSilentDrops</CODE> value.
972      *
973      * @since 1.5
974      */

975     public Long JavaDoc getSnmpSilentDrops() {
976         return new Long JavaDoc(snmpSilentDrops);
977     }
978
979     /**
980      * Returns the <CODE>snmpProxyDrops</CODE> value defined in RFC
981      * 1907 NMPv2-MIB .
982      *
983      * @return The <CODE>snmpProxyDrops</CODE> value.
984      *
985      * @since 1.5
986      */

987     public Long JavaDoc getSnmpProxyDrops() {
988         return new Long JavaDoc(0);
989     }
990     
991     
992     // PUBLIC METHODS
993
//---------------
994

995     /**
996      * Allows the MBean to perform any operations it needs before being
997      * registered in the MBean server.
998      * If the name of the SNMP protocol adaptor MBean is not specified,
999      * it is initialized with the default value:
1000     * {@link com.sun.jmx.snmp.ServiceName#DOMAIN
1001     * com.sun.jmx.snmp.ServiceName.DOMAIN}:{@link
1002     * com.sun.jmx.snmp.ServiceName#SNMP_ADAPTOR_SERVER
1003     * com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_SERVER}.
1004     * If any exception is raised, the SNMP protocol adaptor MBean will
1005     * not be registered in the MBean server.
1006     *
1007     * @param server The MBean server to register the service with.
1008     * @param name The object name.
1009     *
1010     * @return The name of the SNMP protocol adaptor registered.
1011     *
1012     * @exception java.lang.Exception
1013     */

1014    public ObjectName JavaDoc preRegister(MBeanServer JavaDoc server, ObjectName JavaDoc name)
1015    throws java.lang.Exception JavaDoc {
1016
1017        if (name == null) {
1018            name = new ObjectName JavaDoc(server.getDefaultDomain() + ":" +
1019                 com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_SERVER);
1020        }
1021        return (super.preRegister(server, name));
1022    }
1023            
1024    /**
1025     * Not used in this context.
1026     */

1027    public void postRegister (Boolean JavaDoc registrationDone) {
1028        super.postRegister(registrationDone);
1029    }
1030
1031    /**
1032     * Not used in this context.
1033     */

1034    public void preDeregister() throws java.lang.Exception JavaDoc {
1035        super.preDeregister();
1036    }
1037
1038    /**
1039     * Not used in this context.
1040     */

1041    public void postDeregister() {
1042        super.postDeregister();
1043    }
1044
1045    /**
1046     * Adds a new MIB in the SNMP MIB handler.
1047     *
1048     * @param mib The MIB to add.
1049     *
1050     * @return A reference to the SNMP MIB handler.
1051     *
1052     * @exception IllegalArgumentException If the parameter is null.
1053     */

1054    public SnmpMibHandler addMib(SnmpMibAgent mib)
1055    throws IllegalArgumentException JavaDoc {
1056        if (mib == null) {
1057            throw new IllegalArgumentException JavaDoc() ;
1058        }
1059    
1060    if(!mibs.contains(mib))
1061        mibs.addElement(mib);
1062
1063        root.register(mib);
1064    
1065        return this;
1066    }
1067    
1068    /**
1069     * Adds a new MIB in the SNMP MIB handler.
1070     * This method is to be called to set a specific agent to a specific OID.
1071     * This can be useful when dealing with MIB overlapping.
1072     * Some OID can be implemented in more than one MIB. In this case,
1073     * the OID nearer agent will be used on SNMP operations.
1074     *
1075     * @param mib The MIB to add.
1076     * @param oids The set of OIDs this agent implements.
1077     *
1078     * @return A reference to the SNMP MIB handler.
1079     *
1080     * @exception IllegalArgumentException If the parameter is null.
1081     *
1082     * @since 1.5
1083     */

1084    public SnmpMibHandler addMib(SnmpMibAgent mib, SnmpOid[] oids)
1085    throws IllegalArgumentException JavaDoc {
1086    if (mib == null) {
1087        throw new IllegalArgumentException JavaDoc() ;
1088    }
1089    
1090    //If null oid array, just add it to the mib.
1091
if(oids == null)
1092        return addMib(mib);
1093    
1094    if(!mibs.contains(mib))
1095        mibs.addElement(mib);
1096    
1097    for (int i = 0; i < oids.length; i++) {
1098        root.register(mib, oids[i].longValue());
1099    }
1100    return this;
1101    }
1102
1103    /**
1104     * Adds a new MIB in the SNMP MIB handler. In SNMP V1 and V2 the
1105     * <CODE>contextName</CODE> is useless and this method
1106     * is equivalent to <CODE>addMib(SnmpMibAgent mib)</CODE>.
1107     *
1108     * @param mib The MIB to add.
1109     * @param contextName The MIB context name.
1110     * @return A reference on the SNMP MIB handler.
1111     *
1112     * @exception IllegalArgumentException If the parameter is null.
1113     *
1114     * @since 1.5
1115     */

1116    public SnmpMibHandler addMib(SnmpMibAgent mib, String JavaDoc contextName)
1117    throws IllegalArgumentException JavaDoc {
1118    return addMib(mib);
1119    }
1120    
1121    /**
1122     * Adds a new MIB in the SNMP MIB handler. In SNMP V1 and V2 the
1123     * <CODE>contextName</CODE> is useless and this method
1124     * is equivalent to <CODE>addMib(SnmpMibAgent mib, SnmpOid[] oids)</CODE>.
1125     *
1126     * @param mib The MIB to add.
1127     * @param contextName The MIB context. If null is passed, will be
1128     * registered in the default context.
1129     * @param oids The set of OIDs this agent implements.
1130     *
1131     * @return A reference to the SNMP MIB handler.
1132     *
1133     * @exception IllegalArgumentException If the parameter is null.
1134     *
1135     * @since 1.5
1136     */

1137    public SnmpMibHandler addMib(SnmpMibAgent mib,
1138                 String JavaDoc contextName,
1139                 SnmpOid[] oids)
1140        throws IllegalArgumentException JavaDoc {
1141    return addMib(mib, oids);
1142    }
1143    
1144    /**
1145     * Removes the specified MIB from the SNMP protocol adaptor.
1146     * In SNMP V1 and V2 the <CODE>contextName</CODE> is useless and this
1147     * method is equivalent to <CODE>removeMib(SnmpMibAgent mib)</CODE>.
1148     *
1149     * @param mib The MIB to be removed.
1150     * @param contextName The context name used at registration time.
1151     *
1152     * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was
1153     * a MIB included in the SNMP MIB handler, <CODE>false</CODE>
1154     * otherwise.
1155     *
1156     * @since 1.5
1157     */

1158    public boolean removeMib(SnmpMibAgent mib, String JavaDoc contextName) {
1159    return removeMib(mib);
1160    }
1161
1162    /**
1163     * Removes the specified MIB from the SNMP protocol adaptor.
1164     *
1165     * @param mib The MIB to be removed.
1166     *
1167     * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was a MIB
1168     * included in the SNMP MIB handler, <CODE>false</CODE> otherwise.
1169     */

1170    public boolean removeMib(SnmpMibAgent mib) {
1171        root.unregister(mib);
1172        return (mibs.removeElement(mib)) ;
1173    }
1174
1175    /**
1176     * Removes the specified MIB from the SNMP protocol adaptor.
1177     *
1178     * @param mib The MIB to be removed.
1179     * @param oids The oid the MIB was previously registered for.
1180     * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was
1181     * a MIB included in the SNMP MIB handler, <CODE>false</CODE>
1182     * otherwise.
1183     *
1184     * @since 1.5
1185     */

1186    public boolean removeMib(SnmpMibAgent mib, SnmpOid[] oids) {
1187    root.unregister(mib, oids);
1188    return (mibs.removeElement(mib)) ;
1189    }
1190
1191     /**
1192     * Removes the specified MIB from the SNMP protocol adaptor.
1193     *
1194     * @param mib The MIB to be removed.
1195     * @param contextName The context name used at registration time.
1196     * @param oids The oid the MIB was previously registered for.
1197     * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was
1198     * a MIB included in the SNMP MIB handler, <CODE>false</CODE>
1199     * otherwise.
1200     *
1201     * @since 1.5
1202     */

1203    public boolean removeMib(SnmpMibAgent mib,
1204                 String JavaDoc contextName,
1205                 SnmpOid[] oids) {
1206    return removeMib(mib, oids);
1207    }
1208
1209    // SUBCLASSING OF COMMUNICATOR SERVER
1210
//-----------------------------------
1211

1212    /**
1213     * Creates the datagram socket.
1214     */

1215    protected void doBind()
1216    throws CommunicationException, InterruptedException JavaDoc {
1217
1218        try {
1219        synchronized (this) {
1220        socket = new DatagramSocket JavaDoc(port, address) ;
1221        }
1222        dbgTag = makeDebugTag();
1223        } catch (SocketException JavaDoc e) {
1224            if (e.getMessage().equals(InterruptSysCallMsg))
1225                throw new InterruptedException JavaDoc(e.toString()) ;
1226            else {
1227                if (isDebugOn()) {
1228                    debug("doBind", "cannot bind on port " + port);
1229                }
1230                throw new CommunicationException(e) ;
1231            }
1232        }
1233    }
1234
1235    /**
1236     * Return the actual port to which the adaptor is bound.
1237     * Can be different from the port given at construction time if
1238     * that port number was 0.
1239     * @return the actual port to which the adaptor is bound.
1240     **/

1241    public int getPort() {
1242    synchronized (this) {
1243        if (socket != null) return socket.getLocalPort();
1244    }
1245    return super.getPort();
1246    }
1247
1248    /**
1249     * Closes the datagram socket.
1250     */

1251    protected void doUnbind()
1252    throws CommunicationException, InterruptedException JavaDoc {
1253        if (isTraceOn()) {
1254            trace("doUnbind","Finally close the socket");
1255        }
1256    synchronized (this) {
1257        if (socket != null) {
1258        socket.close() ;
1259        socket = null ;
1260        // Important to inform finalize() that the socket is closed...
1261
}
1262    }
1263        closeTrapSocketIfNeeded() ;
1264        closeInformSocketIfNeeded() ;
1265    }
1266    
1267    void createSnmpRequestHandler(SnmpAdaptorServer server, int id,
1268                  DatagramSocket JavaDoc s, DatagramPacket JavaDoc p,
1269                  SnmpMibTree tree, Vector JavaDoc m, Object JavaDoc a,
1270                  SnmpPduFactory factory,
1271                  SnmpUserDataFactory dataFactory,
1272                  MBeanServer JavaDoc f, ObjectName JavaDoc n) {
1273    final SnmpRequestHandler handler =
1274        new SnmpRequestHandler(this, id, s, p, tree, m, a, factory,
1275                   dataFactory, f, n);
1276    threadService.submitTask(handler);
1277    }
1278
1279    /**
1280     * Reads a packet from the datagram socket and creates a request
1281     * handler which decodes and processes the request.
1282     */

1283    protected void doReceive()
1284    throws CommunicationException, InterruptedException JavaDoc {
1285
1286        // Let's wait for something to be received.
1287
//
1288
try {
1289            packet = new DatagramPacket JavaDoc(new byte[bufferSize], bufferSize) ;
1290            socket.receive(packet);
1291        int state = getState();
1292        
1293        if(state != ONLINE) {
1294        if (isTraceOn()) {
1295            trace("doReceive",
1296               "received a message but state not online, returning.");
1297        }
1298        return;
1299        }
1300        
1301        createSnmpRequestHandler(this, servedClientCount, socket,
1302                     packet, root, mibs, ipacl, pduFactory,
1303                     userDataFactory, topMBS, objectName);
1304        } catch (SocketException JavaDoc e) {
1305            // Let's check if we have been interrupted by stop().
1306
//
1307
if (e.getMessage().equals(InterruptSysCallMsg))
1308                throw new InterruptedException JavaDoc(e.toString()) ;
1309            else
1310                throw new CommunicationException(e) ;
1311        } catch (InterruptedIOException JavaDoc e) {
1312            throw new InterruptedException JavaDoc(e.toString()) ;
1313        } catch (CommunicationException e) {
1314            throw e ;
1315        } catch (Exception JavaDoc e) {
1316            throw new CommunicationException(e) ;
1317        }
1318        if (isTraceOn()) {
1319            trace("doReceive", "received a message");
1320        }
1321    }
1322  
1323    protected void doError(Exception JavaDoc e) throws CommunicationException {
1324        return;
1325    }
1326    
1327    /**
1328     * Not used in this context.
1329     */

1330    protected void doProcess()
1331    throws CommunicationException, InterruptedException JavaDoc {
1332    }
1333    
1334
1335    /**
1336     * The number of times the communicator server will attempt
1337     * to bind before giving up.
1338     * We attempt only once...
1339     * @return 1
1340     **/

1341    protected int getBindTries() {
1342    return 1;
1343    }
1344
1345    /**
1346     * Stops this SNMP protocol adaptor.
1347     * Closes the datagram socket.
1348     * <p>
1349     * Has no effect if this SNMP protocol adaptor is <CODE>OFFLINE</CODE> or
1350     * <CODE>STOPPING</CODE>.
1351     */

1352    public void stop(){
1353        
1354    final int port = getPort();
1355        if (isTraceOn()) {
1356            trace("stop", "Stopping: using port " + port);
1357        }
1358        if ((state == ONLINE) || (state == STARTING)){
1359            super.stop();
1360            try {
1361        DatagramSocket JavaDoc sn = new DatagramSocket JavaDoc(0);
1362        try {
1363            byte[] ob = new byte[1];
1364            
1365            DatagramPacket JavaDoc pk;
1366            if (address != null)
1367            pk = new DatagramPacket JavaDoc(ob , 1, address, port);
1368            else
1369            pk = new DatagramPacket JavaDoc(ob , 1,
1370                 java.net.InetAddress.getLocalHost(), port);
1371                                
1372            if (isTraceOn()) {
1373            trace("stop", "Sending: using port " + port);
1374            }
1375            sn.send(pk);
1376        } finally {
1377            sn.close();
1378        }
1379            } catch (Throwable JavaDoc e){
1380                if (isDebugOn()) {
1381                    debug("stop", e);
1382                }
1383            }
1384        }
1385    }
1386    
1387    // SENDING SNMP TRAPS STUFF
1388
//-------------------------
1389

1390    /**
1391     * Sends a trap using SNMP V1 trap format.
1392     * <BR>The trap is sent to each destination defined in the ACL file
1393     * (if available).
1394     * If no ACL file or no destinations are available, the trap is sent
1395     * to the local host.
1396     *
1397     * @param generic The generic number of the trap.
1398     * @param specific The specific number of the trap.
1399     * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
1400     *
1401     * @exception IOException An I/O error occurred while sending the trap.
1402     * @exception SnmpStatusException If the trap exceeds the limit defined
1403     * by <CODE>bufferSize</CODE>.
1404     */

1405    public void snmpV1Trap(int generic, int specific,
1406               SnmpVarBindList varBindList)
1407        throws IOException JavaDoc, SnmpStatusException {
1408
1409        if (isTraceOn()) {
1410            trace("snmpV1Trap", "generic=" + generic +
1411          ", specific=" + specific);
1412        }
1413        
1414        // First, make an SNMP V1 trap pdu
1415
//
1416
SnmpPduTrap pdu = new SnmpPduTrap() ;
1417        pdu.address = null ;
1418        pdu.port = trapPort ;
1419        pdu.type = pduV1TrapPdu ;
1420        pdu.version = snmpVersionOne ;
1421        pdu.community = null ;
1422        pdu.enterprise = enterpriseOid ;
1423        pdu.genericTrap = generic ;
1424        pdu.specificTrap = specific ;
1425        pdu.timeStamp = getSysUpTime();
1426    
1427        if (varBindList != null) {
1428            pdu.varBindList = new SnmpVarBind[varBindList.size()] ;
1429            varBindList.copyInto(pdu.varBindList);
1430        }
1431        else
1432            pdu.varBindList = null ;
1433      
1434        // If the local host cannot be determined, we put 0.0.0.0 in agentAddr
1435
try {
1436            if (address != null)
1437                pdu.agentAddr = handleMultipleIpVersion(address.getAddress());
1438            else pdu.agentAddr =
1439              handleMultipleIpVersion(InetAddress.getLocalHost().getAddress());
1440        } catch (UnknownHostException JavaDoc e) {
1441        byte[] zeroedAddr = new byte[4];
1442            pdu.agentAddr = handleMultipleIpVersion(zeroedAddr) ;
1443        }
1444    
1445        // Next, send the pdu to all destinations defined in ACL
1446
//
1447
sendTrapPdu(pdu) ;
1448    }
1449    
1450    private SnmpIpAddress handleMultipleIpVersion(byte[] address) {
1451    if(address.length == 4)
1452      return new SnmpIpAddress(address);
1453    else {
1454        if(isDebugOn())
1455        debug("handleMultipleIPVersion",
1456              "Not an IPv4 address, return null");
1457        return null;
1458    }
1459    }
1460
1461    /**
1462     * Sends a trap using SNMP V1 trap format.
1463     * <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
1464     * destination using the specified community string (and the ACL file
1465     * is not used).
1466     *
1467     * @param addr The <CODE>InetAddress</CODE> destination of the trap.
1468     * @param cs The community string to be used for the trap.
1469     * @param generic The generic number of the trap.
1470     * @param specific The specific number of the trap.
1471     * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
1472     *
1473     * @exception IOException An I/O error occurred while sending the trap.
1474     * @exception SnmpStatusException If the trap exceeds the limit defined
1475     * by <CODE>bufferSize</CODE>.
1476     */

1477    public void snmpV1Trap(InetAddress JavaDoc addr, String JavaDoc cs, int generic,
1478               int specific, SnmpVarBindList varBindList)
1479        throws IOException JavaDoc, SnmpStatusException {
1480    
1481        if (isTraceOn()) {
1482            trace("snmpV1Trap", "generic=" + generic + ", specific=" +
1483          specific);
1484        }
1485        
1486        // First, make an SNMP V1 trap pdu
1487
//
1488
SnmpPduTrap pdu = new SnmpPduTrap() ;
1489        pdu.address = null ;
1490        pdu.port = trapPort ;
1491        pdu.type = pduV1TrapPdu ;
1492        pdu.version = snmpVersionOne ;
1493    
1494    if(cs != null)
1495        pdu.community = cs.getBytes();
1496    else
1497        pdu.community = null ;
1498    
1499        pdu.enterprise = enterpriseOid ;
1500        pdu.genericTrap = generic ;
1501        pdu.specificTrap = specific ;
1502        pdu.timeStamp = getSysUpTime();
1503    
1504        if (varBindList != null) {
1505            pdu.varBindList = new SnmpVarBind[varBindList.size()] ;
1506            varBindList.copyInto(pdu.varBindList);
1507        }
1508        else
1509            pdu.varBindList = null ;
1510      
1511        // If the local host cannot be determined, we put 0.0.0.0 in agentAddr
1512
try {
1513            if (address != null)
1514                pdu.agentAddr = handleMultipleIpVersion(address.getAddress());
1515            else pdu.agentAddr =
1516          handleMultipleIpVersion(InetAddress.getLocalHost().getAddress());
1517        } catch (UnknownHostException JavaDoc e) {
1518        byte[] zeroedAddr = new byte[4];
1519            pdu.agentAddr = handleMultipleIpVersion(zeroedAddr) ;
1520        }
1521    
1522        // Next, send the pdu to the specified destination
1523
//
1524
if(addr != null)
1525        sendTrapPdu(addr, pdu) ;
1526    else
1527        sendTrapPdu(pdu);
1528    }
1529    
1530    /**
1531     * Sends a trap using SNMP V1 trap format.
1532     * <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
1533     * destination using the specified parameters (and the ACL file is not
1534     * used).
1535     * Note that if the specified <CODE>InetAddress</CODE> destination is null,
1536     * then the ACL file mechanism is used.
1537     *
1538     * @param addr The <CODE>InetAddress</CODE> destination of the trap.
1539     * @param agentAddr The agent address to be used for the trap.
1540     * @param cs The community string to be used for the trap.
1541     * @param enterpOid The enterprise OID to be used for the trap.
1542     * @param generic The generic number of the trap.
1543     * @param specific The specific number of the trap.
1544     * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
1545     * @param time The time stamp (overwrite the current time).
1546     *
1547     * @exception IOException An I/O error occurred while sending the trap.
1548     * @exception SnmpStatusException If the trap exceeds the limit defined
1549     * by <CODE>bufferSize</CODE>.
1550     *
1551     * @since 1.5
1552     */

1553    public void snmpV1Trap(InetAddress JavaDoc addr,
1554                           SnmpIpAddress agentAddr,
1555                           String JavaDoc cs,
1556                           SnmpOid enterpOid,
1557                           int generic,
1558                           int specific,
1559                           SnmpVarBindList varBindList,
1560                           SnmpTimeticks time)
1561        throws IOException JavaDoc, SnmpStatusException {
1562    snmpV1Trap(addr,
1563           trapPort,
1564           agentAddr,
1565           cs,
1566           enterpOid,
1567           generic,
1568           specific,
1569           varBindList,
1570           time);
1571    }
1572
1573    /**
1574     * Sends a trap using SNMP V1 trap format.
1575     * <BR>The trap is sent to the specified <CODE>SnmpPeer</CODE> destination.
1576     * The community string used is the one located in the
1577     * <CODE>SnmpPeer</CODE> parameters
1578     * (<CODE>SnmpParameters.getRdCommunity() </CODE>).
1579     *
1580     * @param peer The <CODE>SnmpPeer</CODE> destination of the trap.
1581     * @param agentAddr The agent address to be used for the trap.
1582     * @param enterpOid The enterprise OID to be used for the trap.
1583     * @param generic The generic number of the trap.
1584     * @param specific The specific number of the trap.
1585     * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
1586     * @param time The time stamp (overwrite the current time).
1587     *
1588     * @exception IOException An I/O error occurred while sending the trap.
1589     * @exception SnmpStatusException If the trap exceeds the limit
1590     * defined by <CODE>bufferSize</CODE>.
1591     *
1592     * @since 1.5
1593     */

1594    public void snmpV1Trap(SnmpPeer peer,
1595               SnmpIpAddress agentAddr,
1596               SnmpOid enterpOid,
1597               int generic,
1598               int specific,
1599               SnmpVarBindList varBindList,
1600               SnmpTimeticks time)
1601    throws IOException JavaDoc, SnmpStatusException {
1602    SnmpParameters p = (SnmpParameters) peer.getParams();
1603    snmpV1Trap(peer.getDestAddr(),
1604           peer.getDestPort(),
1605           agentAddr,
1606           p.getRdCommunity(),
1607           enterpOid,
1608           generic,
1609           specific,
1610           varBindList,
1611           time);
1612    }
1613    
1614    private void snmpV1Trap(InetAddress JavaDoc addr,
1615                int port,
1616                SnmpIpAddress agentAddr,
1617                String JavaDoc cs,
1618                SnmpOid enterpOid,
1619                int generic,
1620                int specific,
1621                SnmpVarBindList varBindList,
1622                SnmpTimeticks time)
1623    throws IOException JavaDoc, SnmpStatusException {
1624    
1625    if (isTraceOn()) {
1626            trace("snmpV1Trap", "generic=" + generic + ", specific=" +
1627          specific);
1628        }
1629        
1630        // First, make an SNMP V1 trap pdu
1631
//
1632
SnmpPduTrap pdu = new SnmpPduTrap() ;
1633        pdu.address = null ;
1634        pdu.port = port ;
1635        pdu.type = pduV1TrapPdu ;
1636        pdu.version = snmpVersionOne ;
1637    
1638        //Diff start
1639
if(cs != null)
1640            pdu.community = cs.getBytes();
1641        else
1642            pdu.community = null ;
1643        //Diff end
1644

1645        // Diff start
1646
if(enterpOid != null)
1647            pdu.enterprise = enterpOid;
1648        else
1649            pdu.enterprise = enterpriseOid ;
1650        //Diff end
1651
pdu.genericTrap = generic ;
1652        pdu.specificTrap = specific ;
1653        //Diff start
1654
if(time != null)
1655            pdu.timeStamp = time.longValue();
1656        else
1657            pdu.timeStamp = getSysUpTime();
1658        //Diff end
1659

1660        if (varBindList != null) {
1661            pdu.varBindList = new SnmpVarBind[varBindList.size()] ;
1662            varBindList.copyInto(pdu.varBindList);
1663        }
1664        else
1665            pdu.varBindList = null ;
1666      
1667        if (agentAddr == null) {
1668            // If the local host cannot be determined,
1669
// we put 0.0.0.0 in agentAddr
1670
try {
1671        final InetAddress JavaDoc inetAddr =
1672            (address!=null)?address:InetAddress.getLocalHost();
1673        agentAddr = handleMultipleIpVersion(inetAddr.getAddress());
1674            } catch (UnknownHostException JavaDoc e) {
1675        byte[] zeroedAddr = new byte[4];
1676        agentAddr = handleMultipleIpVersion(zeroedAddr);
1677            }
1678        }
1679
1680    pdu.agentAddr = agentAddr;
1681    
1682        // Next, send the pdu to the specified destination
1683
//
1684
// Diff start
1685
if(addr != null)
1686            sendTrapPdu(addr, pdu) ;
1687        else
1688            sendTrapPdu(pdu);
1689
1690        //End diff
1691
}
1692                
1693    /**
1694     * Sends a trap using SNMP V2 trap format.
1695     * <BR>The trap is sent to the specified <CODE>SnmpPeer</CODE> destination.
1696     * <BR>The community string used is the one located in the
1697     * <CODE>SnmpPeer</CODE> parameters
1698     * (<CODE>SnmpParameters.getRdCommunity() </CODE>).
1699     * <BR>The variable list included in the outgoing trap is composed of
1700     * the following items:
1701     * <UL>
1702     * <LI><CODE>sysUpTime.0</CODE> with the value specified by
1703     * <CODE>time</CODE></LI>
1704     * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
1705     * <CODE>trapOid</CODE></LI>
1706     * <LI><CODE>all the (oid,values)</CODE> from the specified
1707     * <CODE>varBindList</CODE></LI>
1708     * </UL>
1709     *
1710     * @param peer The <CODE>SnmpPeer</CODE> destination of the trap.
1711     * @param trapOid The OID identifying the trap.
1712     * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
1713     * @param time The time stamp (overwrite the current time).
1714     *
1715     * @exception IOException An I/O error occurred while sending the trap.
1716     * @exception SnmpStatusException If the trap exceeds the limit
1717     * defined by <CODE>bufferSize</CODE>.
1718     *
1719     * @since 1.5
1720     */

1721    public void snmpV2Trap(SnmpPeer peer,
1722               SnmpOid trapOid,
1723               SnmpVarBindList varBindList,
1724               SnmpTimeticks time)
1725    throws IOException JavaDoc, SnmpStatusException {
1726    SnmpParameters p = (SnmpParameters) peer.getParams();
1727    snmpV2Trap(peer.getDestAddr(),
1728           peer.getDestPort(),
1729           p.getRdCommunity(),
1730           trapOid,
1731           varBindList,
1732           time);
1733    }
1734
1735    /**
1736     * Sends a trap using SNMP V2 trap format.
1737     * <BR>The trap is sent to each destination defined in the ACL file
1738     * (if available). If no ACL file or no destinations are available,
1739     * the trap is sent to the local host.
1740     * <BR>The variable list included in the outgoing trap is composed of
1741     * the following items:
1742     * <UL>
1743     * <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
1744     * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
1745     * <CODE>trapOid</CODE></LI>
1746     * <LI><CODE>all the (oid,values)</CODE> from the specified
1747     * <CODE>varBindList</CODE></LI>
1748     * </UL>
1749     *
1750     * @param trapOid The OID identifying the trap.
1751     * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
1752     *
1753     * @exception IOException An I/O error occurred while sending the trap.
1754     * @exception SnmpStatusException If the trap exceeds the limit defined
1755     * by <CODE>bufferSize</CODE>.
1756     */

1757    public void snmpV2Trap(SnmpOid trapOid, SnmpVarBindList varBindList)
1758        throws IOException JavaDoc, SnmpStatusException {
1759
1760        if (isTraceOn()) {
1761            trace("snmpV2Trap", "trapOid=" + trapOid);
1762        }
1763        
1764        // First, make an SNMP V2 trap pdu
1765
// We clone varBindList and insert sysUpTime and snmpTrapOid
1766
//
1767
SnmpPduRequest pdu = new SnmpPduRequest() ;
1768        pdu.address = null ;
1769        pdu.port = trapPort ;
1770        pdu.type = pduV2TrapPdu ;
1771        pdu.version = snmpVersionTwo ;
1772        pdu.community = null ;
1773
1774        SnmpVarBindList fullVbl ;
1775        if (varBindList != null)
1776            fullVbl = (SnmpVarBindList)varBindList.clone() ;
1777        else
1778            fullVbl = new SnmpVarBindList(2) ;
1779        SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
1780        fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
1781        fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
1782                0);
1783        pdu.varBindList = new SnmpVarBind[fullVbl.size()] ;
1784        fullVbl.copyInto(pdu.varBindList) ;
1785      
1786        // Next, send the pdu to all destinations defined in ACL
1787
//
1788
sendTrapPdu(pdu) ;
1789    }
1790
1791    /**
1792     * Sends a trap using SNMP V2 trap format.
1793     * <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
1794     * destination using the specified community string (and the ACL file
1795     * is not used).
1796     * <BR>The variable list included in the outgoing trap is composed of
1797     * the following items:
1798     * <UL>
1799     * <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
1800     * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
1801     * <CODE>trapOid</CODE></LI>
1802     * <LI><CODE>all the (oid,values)</CODE> from the specified
1803     * <CODE>varBindList</CODE></LI>
1804     * </UL>
1805     *
1806     * @param addr The <CODE>InetAddress</CODE> destination of the trap.
1807     * @param cs The community string to be used for the trap.
1808     * @param trapOid The OID identifying the trap.
1809     * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
1810     *
1811     * @exception IOException An I/O error occurred while sending the trap.
1812     * @exception SnmpStatusException If the trap exceeds the limit
1813     * defined by <CODE>bufferSize</CODE>.
1814     */

1815    public void snmpV2Trap(InetAddress JavaDoc addr, String JavaDoc cs, SnmpOid trapOid,
1816               SnmpVarBindList varBindList)
1817        throws IOException JavaDoc, SnmpStatusException {
1818    
1819        if (isTraceOn()) {
1820            trace("snmpV2Trap", "trapOid=" + trapOid);
1821        }
1822        
1823        // First, make an SNMP V2 trap pdu
1824
// We clone varBindList and insert sysUpTime and snmpTrapOid
1825
//
1826
SnmpPduRequest pdu = new SnmpPduRequest() ;
1827        pdu.address = null ;
1828        pdu.port = trapPort ;
1829        pdu.type = pduV2TrapPdu ;
1830        pdu.version = snmpVersionTwo ;
1831
1832    if(cs != null)
1833            pdu.community = cs.getBytes();
1834        else
1835            pdu.community = null;
1836    
1837        SnmpVarBindList fullVbl ;
1838        if (varBindList != null)
1839            fullVbl = (SnmpVarBindList)varBindList.clone() ;
1840        else
1841            fullVbl = new SnmpVarBindList(2) ;
1842        SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
1843        fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
1844        fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
1845                0);
1846        pdu.varBindList = new SnmpVarBind[fullVbl.size()] ;
1847        fullVbl.copyInto(pdu.varBindList) ;
1848      
1849        // Next, send the pdu to the specified destination
1850
//
1851
if(addr != null)
1852        sendTrapPdu(addr, pdu);
1853    else
1854        sendTrapPdu(pdu);
1855    }
1856    
1857    /**
1858     * Sends a trap using SNMP V2 trap format.
1859     * <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
1860     * destination using the specified parameters (and the ACL file is not
1861     * used).
1862     * Note that if the specified <CODE>InetAddress</CODE> destination is null,
1863     * then the ACL file mechanism is used.
1864     * <BR>The variable list included in the outgoing trap is composed of the
1865     * following items:
1866     * <UL>
1867     * <LI><CODE>sysUpTime.0</CODE> with the value specified by
1868     * <CODE>time</CODE></LI>
1869     * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
1870     * <CODE>trapOid</CODE></LI>
1871     * <LI><CODE>all the (oid,values)</CODE> from the specified
1872     * <CODE>varBindList</CODE></LI>
1873     * </UL>
1874     *
1875     * @param addr The <CODE>InetAddress</CODE> destination of the trap.
1876     * @param cs The community string to be used for the trap.
1877     * @param trapOid The OID identifying the trap.
1878     * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
1879     * @param time The time stamp (overwrite the current time).
1880     *
1881     * @exception IOException An I/O error occurred while sending the trap.
1882     * @exception SnmpStatusException If the trap exceeds the limit
1883     * defined by <CODE>bufferSize</CODE>.
1884     *
1885     * @since 1.5
1886     */

1887    public void snmpV2Trap(InetAddress JavaDoc addr,
1888                           String JavaDoc cs,
1889                           SnmpOid trapOid,
1890                           SnmpVarBindList varBindList,
1891                           SnmpTimeticks time)
1892        throws IOException JavaDoc, SnmpStatusException {
1893      
1894    snmpV2Trap(addr,
1895           trapPort,
1896           cs,
1897           trapOid,
1898           varBindList,
1899           time);
1900    }
1901    
1902    private void snmpV2Trap(InetAddress JavaDoc addr,
1903                int port,
1904                String JavaDoc cs,
1905                SnmpOid trapOid,
1906                SnmpVarBindList varBindList,
1907                SnmpTimeticks time)
1908        throws IOException JavaDoc, SnmpStatusException {
1909    
1910        if (isTraceOn()) {
1911            trace("snmpV2Trap", "trapOid=" + trapOid +
1912                  "\ncommunity=" + cs + "\naddr=" + addr +
1913                  "\nvarBindList=" + varBindList + "\ntime=" + time +
1914                  "\ntrapPort=" + port);
1915        }
1916        
1917        // First, make an SNMP V2 trap pdu
1918
// We clone varBindList and insert sysUpTime and snmpTrapOid
1919
//
1920
SnmpPduRequest pdu = new SnmpPduRequest() ;
1921        pdu.address = null ;
1922        pdu.port = port ;
1923        pdu.type = pduV2TrapPdu ;
1924        pdu.version = snmpVersionTwo ;
1925    
1926    if(cs != null)
1927            pdu.community = cs.getBytes();
1928        else
1929            pdu.community = null;
1930
1931        SnmpVarBindList fullVbl ;
1932        if (varBindList != null)
1933            fullVbl = (SnmpVarBindList)varBindList.clone() ;
1934        else
1935            fullVbl = new SnmpVarBindList(2) ;
1936
1937        // Only difference with other
1938
SnmpTimeticks sysUpTimeValue = null;
1939        if(time != null)
1940            sysUpTimeValue = time;
1941        else
1942            sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
1943        //End of diff
1944

1945        fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
1946        fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
1947                0);
1948        pdu.varBindList = new SnmpVarBind[fullVbl.size()] ;
1949        fullVbl.copyInto(pdu.varBindList) ;
1950      
1951        // Next, send the pdu to the specified destination
1952
//
1953
// Diff start
1954
if(addr != null)
1955            sendTrapPdu(addr, pdu) ;
1956        else
1957            sendTrapPdu(pdu);
1958        //End diff
1959
}
1960
1961    /**
1962     * Send the specified trap PDU to the passed <CODE>InetAddress</CODE>.
1963     * @param address The destination address.
1964     * @param pdu The pdu to send.
1965     * @exception IOException An I/O error occurred while sending the trap.
1966     * @exception SnmpStatusException If the trap exceeds the limit
1967     * defined by <CODE>bufferSize</CODE>.
1968     *
1969     * @since 1.5
1970     */

1971    public void snmpPduTrap(InetAddress JavaDoc address, SnmpPduPacket pdu)
1972        throws IOException JavaDoc, SnmpStatusException {
1973
1974        if(address != null)
1975            sendTrapPdu(address, pdu);
1976        else
1977            sendTrapPdu(pdu);
1978    }
1979    
1980    /**
1981     * Send the specified trap PDU to the passed <CODE>SnmpPeer</CODE>.
1982     * @param peer The destination peer. The Read community string is used of
1983     * <CODE>SnmpParameters</CODE> is used as the trap community string.
1984     * @param pdu The pdu to send.
1985     * @exception IOException An I/O error occurred while sending the trap.
1986     * @exception SnmpStatusException If the trap exceeds the limit defined
1987     * by <CODE>bufferSize</CODE>.
1988     * @since 1.5
1989     */

1990    public void snmpPduTrap(SnmpPeer peer,
1991                SnmpPduPacket pdu)
1992        throws IOException JavaDoc, SnmpStatusException {
1993    if(peer != null) {
1994        pdu.port = peer.getDestPort();
1995        sendTrapPdu(peer.getDestAddr(), pdu);
1996    }
1997    else {
1998        pdu.port = getTrapPort().intValue();
1999        sendTrapPdu(pdu);
2000    }
2001    }
2002    
2003    /**
2004     * Send the specified trap PDU to every destinations from the ACL file.
2005     */

2006    private void sendTrapPdu(SnmpPduPacket pdu)
2007     throws SnmpStatusException, IOException JavaDoc {
2008  
2009        // Make an SNMP message from the pdu
2010
//
2011
SnmpMessage msg = null ;
2012        try {
2013            msg = (SnmpMessage)pduFactory.encodeSnmpPdu(pdu, bufferSize) ;
2014            if (msg == null) {
2015                throw new SnmpStatusException(
2016              SnmpDefinitions.snmpRspAuthorizationError) ;
2017            }
2018        }
2019        catch (SnmpTooBigException x) {
2020            if (isDebugOn()) {
2021                debug("sendTrapPdu", "trap pdu is too big");
2022                debug("sendTrapPdu", "trap hasn't been sent to anyone");
2023            }
2024            throw new SnmpStatusException(SnmpDefinitions.snmpRspTooBig) ;
2025            // FIXME: is the right exception to throw ?
2026
// We could simply forward SnmpTooBigException ?
2027
}
2028    
2029        // Now send the SNMP message to each destination
2030
//
2031
int sendingCount = 0 ;
2032        openTrapSocketIfNeeded() ;
2033        if (ipacl != null) {
2034            Enumeration JavaDoc ed = ((InetAddressAcl)ipacl).getTrapDestinations() ;
2035            while (ed.hasMoreElements()) {
2036                msg.address = (InetAddress JavaDoc)ed.nextElement() ;
2037                Enumeration JavaDoc ec = ((InetAddressAcl)ipacl).
2038            getTrapCommunities(msg.address) ;
2039                while (ec.hasMoreElements()) {
2040                    msg.community = ((String JavaDoc)ec.nextElement()).getBytes() ;
2041                    try {
2042                        sendTrapMessage(msg) ;
2043                        sendingCount++ ;
2044                    }
2045                    catch (SnmpTooBigException x) {
2046                        if (isDebugOn()) {
2047                            debug("sendTrapPdu", "trap pdu is too big");
2048                            debug("sendTrapPdu", "trap hasn't been sent to "+
2049                  msg.address);
2050                        }
2051                    }
2052                }
2053            }
2054        }
2055    
2056        // If there is no destination defined or if everything has failed
2057
// we tried to send the trap to the local host (as suggested by
2058
// mister Olivier Reisacher).
2059
//
2060
if (sendingCount == 0) {
2061            try {
2062                msg.address = InetAddress.getLocalHost() ;
2063                sendTrapMessage(msg) ;
2064            } catch (SnmpTooBigException x) {
2065                if (isDebugOn()) {
2066                    debug("sendTrapPdu", "trap pdu is too big");
2067                    debug("sendTrapPdu", "trap hasn't been sent");
2068                }
2069            } catch (UnknownHostException JavaDoc e) {
2070                if (isDebugOn()) {
2071                    debug("sendTrapPdu", "cannot get the local host");
2072                    debug("sendTrapPdu", "trap hasn't been sent");
2073                }
2074            }
2075        }
2076    
2077        closeTrapSocketIfNeeded() ;
2078    }
2079
2080    /**
2081     * Send the specified trap PDU to the specified destination.
2082     */

2083    private void sendTrapPdu(InetAddress JavaDoc addr, SnmpPduPacket pdu)
2084    throws SnmpStatusException, IOException JavaDoc {
2085  
2086        // Make an SNMP message from the pdu
2087
//
2088
SnmpMessage msg = null ;
2089        try {
2090            msg = (SnmpMessage)pduFactory.encodeSnmpPdu(pdu, bufferSize) ;
2091            if (msg == null) {
2092                throw new SnmpStatusException(
2093                          SnmpDefinitions.snmpRspAuthorizationError) ;
2094            }
2095        } catch (SnmpTooBigException x) {
2096            if (isDebugOn()) {
2097                debug("sendTrapPdu", "trap pdu is too big");
2098                debug("sendTrapPdu",
2099              "trap hasn't been sent to the specified host");
2100            }
2101            throw new SnmpStatusException(SnmpDefinitions.snmpRspTooBig) ;
2102            // FIXME: is the right exception to throw ?
2103
// We could simply forward SnmpTooBigException ?
2104
}
2105    
2106        // Now send the SNMP message to specified destination
2107
//
2108
openTrapSocketIfNeeded() ;
2109        if (addr != null) {
2110            msg.address = addr;
2111            try {
2112                sendTrapMessage(msg) ;
2113            } catch (SnmpTooBigException x) {
2114                if (isDebugOn()) {
2115                    debug("sendTrapPdu", "trap pdu is too big");
2116                    debug("sendTrapPdu", "trap hasn't been sent to " +
2117              msg.address);
2118                }
2119            }
2120        }
2121    
2122        closeTrapSocketIfNeeded() ;
2123    }
2124    
2125    /**
2126     * Send the specified message on trapSocket.
2127     */

2128    private void sendTrapMessage(SnmpMessage msg)
2129    throws IOException JavaDoc, SnmpTooBigException {
2130        byte[] buffer = new byte[bufferSize] ;
2131        DatagramPacket JavaDoc packet = new DatagramPacket JavaDoc(buffer, buffer.length) ;
2132        int encodingLength = msg.encodeMessage(buffer) ;
2133        packet.setLength(encodingLength) ;
2134        packet.setAddress(msg.address) ;
2135        packet.setPort(msg.port) ;
2136        if (isTraceOn()) {
2137            trace("sendTrapMessage", "sending trap to " + msg.address + ":" +
2138          msg.port);
2139        }
2140        trapSocket.send(packet) ;
2141        if (isTraceOn()) {
2142            trace("sendTrapMessage", "sent to " + msg.address + ":" +
2143          msg.port);
2144        }
2145        snmpOutTraps++;
2146        snmpOutPkts++;
2147    }
2148  
2149    /**
2150     * Open trapSocket if it's not already done.
2151     */

2152    synchronized void openTrapSocketIfNeeded() throws SocketException JavaDoc {
2153        if (trapSocket == null) {
2154            trapSocket = new DatagramSocket JavaDoc(0, address) ;
2155            if (isTraceOn()) {
2156                trace("openTrapSocketIfNeeded", "using port " +
2157              trapSocket.getLocalPort() + " to send traps");
2158            }
2159        }
2160    }
2161
2162    /**
2163     * Close trapSocket if the SNMP protocol adaptor is not ONLINE.
2164     */

2165    synchronized void closeTrapSocketIfNeeded() {
2166        if ((trapSocket != null) && (state != ONLINE)) {
2167            trapSocket.close() ;
2168            trapSocket = null ;
2169        }
2170    }
2171    
2172    // SENDING SNMP INFORMS STUFF
2173
//---------------------------
2174

2175    /**
2176     * Sends an inform using SNMP V2 inform request format.
2177     * <BR>The inform request is sent to each destination defined in the ACL
2178     * file (if available).
2179     * If no ACL file or no destinations are available, the inform request is
2180     * sent to the local host.
2181     * <BR>The variable list included in the outgoing inform is composed of
2182     * the following items:
2183     * <UL>
2184     * <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
2185     * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
2186     * <CODE>trapOid</CODE></LI>
2187     * <LI><CODE>all the (oid,values)</CODE> from the specified
2188     * <CODE>varBindList</CODE></LI>
2189     * </UL>
2190     * To send an inform request, the SNMP adaptor server must be active.
2191     *
2192     * @param cb The callback that is invoked when a request is complete.
2193     * @param trapOid The OID identifying the trap.
2194     * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
2195     *
2196     * @return A vector of {@link com.sun.jmx.snmp.daemon.SnmpInformRequest}
2197     * objects.
2198     * <P>If there is no destination host for this inform request,
2199     * the returned vector will be empty.
2200     *
2201     * @exception IllegalStateException This method has been invoked while
2202     * the SNMP adaptor server was not active.
2203     * @exception IOException An I/O error occurred while sending the
2204     * inform request.
2205     * @exception SnmpStatusException If the inform request exceeds the
2206     * limit defined by <CODE>bufferSize</CODE>.
2207     */

2208    public Vector JavaDoc snmpInformRequest(SnmpInformHandler cb, SnmpOid trapOid,
2209                    SnmpVarBindList varBindList)
2210        throws IllegalStateException JavaDoc, IOException JavaDoc, SnmpStatusException {
2211    
2212        if (!isActive()) {
2213            throw new IllegalStateException JavaDoc(
2214               "Start SNMP adaptor server before carrying out this operation");
2215        }
2216        if (isTraceOn()) {
2217            trace("snmpInformRequest", "trapOid=" + trapOid);
2218        }
2219        
2220        // First, make an SNMP inform pdu:
2221
// We clone varBindList and insert sysUpTime and snmpTrapOid variables.
2222
//
2223
SnmpVarBindList fullVbl ;
2224        if (varBindList != null)
2225            fullVbl = (SnmpVarBindList)varBindList.clone() ;
2226        else
2227            fullVbl = new SnmpVarBindList(2) ;
2228        SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
2229        fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
2230        fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
2231                0);
2232        
2233        // Next, send the pdu to the specified destination
2234
//
2235
openInformSocketIfNeeded() ;
2236        
2237        // Now send the SNMP message to each destination
2238
//
2239
Vector JavaDoc informReqList = new Vector JavaDoc();
2240        InetAddress JavaDoc addr = null;
2241        String JavaDoc cs = null;
2242        if (ipacl != null) {
2243            Enumeration JavaDoc ed = ((InetAddressAcl)ipacl).getInformDestinations() ;
2244            while (ed.hasMoreElements()) {
2245                addr = (InetAddress JavaDoc)ed.nextElement() ;
2246                Enumeration JavaDoc ec = ((InetAddressAcl)ipacl).
2247            getInformCommunities(addr) ;
2248                while (ec.hasMoreElements()) {
2249                    cs = (String JavaDoc)ec.nextElement() ;
2250                    informReqList.addElement(
2251               informSession.makeAsyncRequest(addr, cs, cb,
2252                          fullVbl,getInformPort())) ;
2253                }
2254            }
2255        }
2256    
2257        return informReqList ;
2258    }
2259    
2260    /**
2261     * Sends an inform using SNMP V2 inform request format.
2262     * <BR>The inform is sent to the specified <CODE>InetAddress</CODE>
2263     * destination
2264     * using the specified community string.
2265     * <BR>The variable list included in the outgoing inform is composed
2266     * of the following items:
2267     * <UL>
2268     * <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
2269     * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
2270     * <CODE>trapOid</CODE></LI>
2271     * <LI><CODE>all the (oid,values)</CODE> from the specified
2272     * <CODE>varBindList</CODE></LI>
2273     * </UL>
2274     * To send an inform request, the SNMP adaptor server must be active.
2275     *
2276     * @param addr The <CODE>InetAddress</CODE> destination for this inform
2277     * request.
2278     * @param cs The community string to be used for the inform request.
2279     * @param cb The callback that is invoked when a request is complete.
2280     * @param trapOid The OID identifying the trap.
2281     * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
2282     *
2283     * @return The inform request object.
2284     *
2285     * @exception IllegalStateException This method has been invoked
2286     * while the SNMP adaptor server was not active.
2287     * @exception IOException An I/O error occurred while sending the
2288     * inform request.
2289     * @exception SnmpStatusException If the inform request exceeds the
2290     * limit defined by <CODE>bufferSize</CODE>.
2291     */

2292    public SnmpInformRequest snmpInformRequest(InetAddress JavaDoc addr,
2293                           String JavaDoc cs,
2294                           SnmpInformHandler cb,
2295                                               SnmpOid trapOid,
2296                           SnmpVarBindList varBindList)
2297        throws IllegalStateException JavaDoc, IOException JavaDoc, SnmpStatusException {
2298    
2299    return snmpInformRequest(addr,
2300                 getInformPort(),
2301                 cs,
2302                 cb,
2303                 trapOid,
2304                 varBindList);
2305    }
2306    
2307    /**
2308     * Sends an inform using SNMP V2 inform request format.
2309     * <BR>The inform is sent to the specified <CODE>SnmpPeer</CODE>
2310     * destination.
2311     * <BR>The community string used is the one located in the
2312     * <CODE>SnmpPeer</CODE> parameters
2313     * (<CODE>SnmpParameters.getInformCommunity() </CODE>).
2314     * <BR>The variable list included in the outgoing inform is composed
2315     * of the following items:
2316     * <UL>
2317     * <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
2318     * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
2319     * <CODE>trapOid</CODE></LI>
2320     * <LI><CODE>all the (oid,values)</CODE> from the specified
2321     * <CODE>varBindList</CODE></LI>
2322     * </UL>
2323     * To send an inform request, the SNMP adaptor server must be active.
2324     *
2325     * @param peer The <CODE>SnmpPeer</CODE> destination for this inform
2326     * request.
2327     * @param cb The callback that is invoked when a request is complete.
2328     * @param trapOid The OID identifying the trap.
2329     * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
2330     *
2331     * @return The inform request object.
2332     *
2333     * @exception IllegalStateException This method has been invoked while
2334     * the SNMP adaptor server was not active.
2335     * @exception IOException An I/O error occurred while sending the
2336     * inform request.
2337     * @exception SnmpStatusException If the inform request exceeds the
2338     * limit defined by <CODE>bufferSize</CODE>.
2339     *
2340     * @since 1.5
2341     */

2342    public SnmpInformRequest snmpInformRequest(SnmpPeer peer,
2343                           SnmpInformHandler cb,
2344                           SnmpOid trapOid,
2345                           SnmpVarBindList varBindList)
2346    throws IllegalStateException JavaDoc, IOException JavaDoc, SnmpStatusException {
2347    SnmpParameters p = (SnmpParameters) peer.getParams();
2348    return snmpInformRequest(peer.getDestAddr(),
2349                 peer.getDestPort(),
2350                 p.getInformCommunity(),
2351                 cb,
2352                 trapOid,
2353                 varBindList);
2354    }
2355    
2356    /**
2357     * Method that maps an SNMP error status in the passed protocolVersion
2358     * according to the provided pdu type.
2359     * @param errorStatus The error status to convert.
2360     * @param protocolVersion The protocol version.
2361     * @param reqPduType The pdu type.
2362     */

2363    public static final int mapErrorStatus(int errorStatus,
2364                       int protocolVersion,
2365                       int reqPduType) {
2366    return SnmpSubRequestHandler.mapErrorStatus(errorStatus,
2367                            protocolVersion,
2368                            reqPduType);
2369    }
2370    
2371    private SnmpInformRequest snmpInformRequest(InetAddress JavaDoc addr,
2372                        int port,
2373                        String JavaDoc cs,
2374                        SnmpInformHandler cb,
2375                        SnmpOid trapOid,
2376                        SnmpVarBindList varBindList)
2377        throws IllegalStateException JavaDoc, IOException JavaDoc, SnmpStatusException {
2378    if (!isActive()) {
2379            throw new IllegalStateException JavaDoc(
2380          "Start SNMP adaptor server before carrying out this operation");
2381        }
2382        if (isTraceOn()) {
2383            trace("snmpInformRequest", "trapOid=" + trapOid);
2384        }
2385        
2386        // First, make an SNMP inform pdu:
2387
// We clone varBindList and insert sysUpTime and snmpTrapOid variables.
2388
//
2389
SnmpVarBindList fullVbl ;
2390        if (varBindList != null)
2391            fullVbl = (SnmpVarBindList)varBindList.clone() ;
2392        else
2393            fullVbl = new SnmpVarBindList(2) ;
2394        SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
2395        fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
2396        fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
2397                0);
2398                
2399        // Next, send the pdu to the specified destination
2400
//
2401
openInformSocketIfNeeded() ;
2402        return informSession.makeAsyncRequest(addr, cs, cb, fullVbl, port) ;
2403    }
2404
2405    
2406    /**
2407     * Open informSocket if it's not already done.
2408     */

2409    synchronized void openInformSocketIfNeeded() throws SocketException JavaDoc {
2410        if (informSession == null) {
2411            informSession = new SnmpSession(this) ;
2412            if (isTraceOn()) {
2413                trace("openInformSocketIfNeeded",
2414              "to send inform requests and receive inform responses");
2415            }
2416        }
2417    }
2418
2419    /**
2420     * Close informSocket if the SNMP protocol adaptor is not ONLINE.
2421     */

2422    synchronized void closeInformSocketIfNeeded() {
2423        if ((informSession != null) && (state != ONLINE)) {
2424            informSession.destroySession() ;
2425            informSession = null ;
2426        }
2427    }
2428    
2429    /**
2430     * Gets the IP address to bind.
2431     * This getter is used to initialize the DatagramSocket in the
2432     * SnmpSocket object created for the inform request stuff.
2433     */

2434    InetAddress JavaDoc getAddress() {
2435        return address;
2436    }
2437    
2438    
2439    // PROTECTED METHODS
2440
//------------------
2441

2442    /**
2443     * Finalizer of the SNMP protocol adaptor objects.
2444     * This method is called by the garbage collector on an object
2445     * when garbage collection determines that there are no more
2446     * references to the object.
2447     * <P>Closes the datagram socket associated to this SNMP protocol adaptor.
2448     */

2449    protected void finalize() {
2450    try {
2451        if (socket != null) {
2452        socket.close() ;
2453        socket = null ;
2454        }
2455
2456        threadService.terminate();
2457    } catch (Exception JavaDoc e) {
2458        trace("finalize","Exception in finalizer: " +e);
2459    }
2460    }
2461    
2462    // PACKAGE METHODS
2463
//----------------
2464

2465    /**
2466     * Returns the string used in debug traces.
2467     */

2468    String JavaDoc makeDebugTag() {
2469        return "SnmpAdaptorServer["+ getProtocol() + ":" + getPort() + "]";
2470    }
2471    
2472    void updateRequestCounters(int pduType) {
2473        switch(pduType) {
2474            
2475        case pduGetRequestPdu:
2476            snmpInGetRequests++;
2477            break;
2478        case pduGetNextRequestPdu:
2479            snmpInGetNexts++;
2480            break;
2481        case pduSetRequestPdu:
2482            snmpInSetRequests++;
2483            break;
2484        default:
2485            break;
2486        }
2487        snmpInPkts++ ;
2488    }
2489  
2490    void updateErrorCounters(int errorStatus) {
2491        switch(errorStatus) {
2492            
2493        case snmpRspNoError:
2494            snmpOutGetResponses++;
2495            break;
2496        case snmpRspGenErr:
2497            snmpOutGenErrs++;
2498            break;
2499        case snmpRspBadValue:
2500            snmpOutBadValues++;
2501            break;
2502        case snmpRspNoSuchName:
2503            snmpOutNoSuchNames++;
2504            break;
2505        case snmpRspTooBig:
2506            snmpOutTooBigs++;
2507            break;
2508        default:
2509            break;
2510        }
2511        snmpOutPkts++ ;
2512    }
2513  
2514    void updateVarCounters(int pduType, int n) {
2515        switch(pduType) {
2516            
2517        case pduGetRequestPdu:
2518        case pduGetNextRequestPdu:
2519        case pduGetBulkRequestPdu:
2520            snmpInTotalReqVars += n ;
2521            break ;
2522        case pduSetRequestPdu:
2523            snmpInTotalSetVars += n ;
2524            break ;
2525        }
2526    }
2527  
2528    void incSnmpInASNParseErrs(int n) {
2529        snmpInASNParseErrs += n ;
2530    }
2531  
2532    void incSnmpInBadVersions(int n) {
2533        snmpInBadVersions += n ;
2534    }
2535  
2536    void incSnmpInBadCommunityUses(int n) {
2537        snmpInBadCommunityUses += n ;
2538    }
2539  
2540    void incSnmpInBadCommunityNames(int n) {
2541        snmpInBadCommunityNames += n ;
2542    }
2543    
2544    void incSnmpSilentDrops(int n) {
2545        snmpSilentDrops += n ;
2546    }
2547    // PRIVATE METHODS
2548
//----------------
2549

2550    /**
2551     * Returns the time (in hundreths of second) elapsed since the SNMP
2552     * protocol adaptor startup.
2553     */

2554    long getSysUpTime() {
2555        return (System.currentTimeMillis() - startUpTime) / 10 ;
2556    }
2557  
2558    /**
2559     * Control the way the SnmpAdaptorServer service is deserialized.
2560     */

2561    private void readObject(ObjectInputStream JavaDoc stream)
2562        throws IOException JavaDoc, ClassNotFoundException JavaDoc {
2563      
2564        // Call the default deserialization of the object.
2565
//
2566
stream.defaultReadObject();
2567      
2568        // Call the specific initialization for the SnmpAdaptorServer service.
2569
// This is for transient structures to be initialized to specific
2570
// default values.
2571
//
2572
mibs = new Vector JavaDoc() ;
2573    }
2574  
2575    /**
2576     * Common initializations.
2577     */

2578    private void init(Object JavaDoc acl, int p, InetAddress JavaDoc a) {
2579  
2580        root= new SnmpMibTree();
2581
2582    // The default Agent is initialized with a SnmpErrorHandlerAgent agent.
2583
root.setDefaultAgent(new SnmpErrorHandlerAgent());
2584
2585        // For the trap time, use the time the agent started ...
2586
//
2587
startUpTime= java.lang.System.currentTimeMillis();
2588        maxActiveClientCount = 10;
2589    
2590        // Create the default message factory
2591
pduFactory = new SnmpPduFactoryBER() ;
2592
2593        port = p ;
2594        ipacl = acl ;
2595        address = a ;
2596    
2597        if ((ipacl == null) && (useAcl == true))
2598            throw new IllegalArgumentException JavaDoc("ACL object cannot be null") ;
2599
2600    threadService = new ThreadService(threadNumber);
2601    }
2602
2603    SnmpMibAgent getAgentMib(SnmpOid oid) {
2604    return root.getAgentMib(oid);
2605    }
2606
2607    protected Thread JavaDoc createMainThread() {
2608    final Thread JavaDoc t = super.createMainThread();
2609    t.setDaemon(true);
2610    return t;
2611    }
2612
2613}
2614
2615
Popular Tags