1 /* |
|
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 |
|
27 package com.sun.jmx.snmp.daemon; |
|
28 |
|
29 |
|
30 // java imports |
|
31 // |
|
32 import java.util.Vector; |
|
33 import java.util.Enumeration; |
|
34 import java.util.logging.Level; |
|
35 import java.net.DatagramSocket; |
|
36 import java.net.DatagramPacket; |
|
37 import java.net.InetAddress; |
|
38 import java.net.SocketException; |
|
39 import java.net.UnknownHostException; |
|
40 import java.io.ObjectInputStream; |
|
41 import java.io.IOException; |
|
42 import java.io.InterruptedIOException; |
|
43 |
|
44 |
|
45 // jmx imports |
|
46 // |
|
47 import javax.management.MBeanServer; |
|
48 import javax.management.MBeanRegistration; |
|
49 import javax.management.ObjectName; |
|
50 import static com.sun.jmx.defaults.JmxProperties.SNMP_ADAPTOR_LOGGER; |
|
51 import com.sun.jmx.snmp.SnmpIpAddress; |
|
52 import com.sun.jmx.snmp.SnmpMessage; |
|
53 import com.sun.jmx.snmp.SnmpOid; |
|
54 import com.sun.jmx.snmp.SnmpPduFactory; |
|
55 import com.sun.jmx.snmp.SnmpPduPacket; |
|
56 import com.sun.jmx.snmp.SnmpPduRequest; |
|
57 import com.sun.jmx.snmp.SnmpPduTrap; |
|
58 import com.sun.jmx.snmp.SnmpTimeticks; |
|
59 import com.sun.jmx.snmp.SnmpVarBind; |
|
60 import com.sun.jmx.snmp.SnmpVarBindList; |
|
61 import com.sun.jmx.snmp.SnmpDefinitions; |
|
62 import com.sun.jmx.snmp.SnmpStatusException; |
|
63 import com.sun.jmx.snmp.SnmpTooBigException; |
|
64 import com.sun.jmx.snmp.InetAddressAcl; |
|
65 import com.sun.jmx.snmp.SnmpPeer; |
|
66 import com.sun.jmx.snmp.SnmpParameters; |
|
67 // SNMP Runtime imports |
|
68 // |
|
69 import com.sun.jmx.snmp.SnmpPduFactoryBER; |
|
70 import com.sun.jmx.snmp.agent.SnmpMibAgent; |
|
71 import com.sun.jmx.snmp.agent.SnmpMibHandler; |
|
72 import com.sun.jmx.snmp.agent.SnmpUserDataFactory; |
|
73 import com.sun.jmx.snmp.agent.SnmpErrorHandlerAgent; |
|
74 |
|
75 import com.sun.jmx.snmp.IPAcl.SnmpAcl; |
|
76 |
|
77 import com.sun.jmx.snmp.tasks.ThreadService; |
|
78 |
|
79 /** |
|
80 * Implements an adaptor on top of the SNMP protocol. |
|
81 * <P> |
|
82 * When this SNMP protocol adaptor is started it creates a datagram socket |
|
83 * and is able to receive requests and send traps or inform requests. |
|
84 * When it is stopped, the socket is closed and neither requests |
|
85 * and nor traps/inform request are processed. |
|
86 * <P> |
|
87 * The default port number of the socket is 161. This default value can be |
|
88 * changed by specifying a port number: |
|
89 * <UL> |
|
90 * <LI>in the object constructor</LI> |
|
91 * <LI>using the {@link com.sun.jmx.snmp.daemon.CommunicatorServer#setPort |
|
92 * setPort} method before starting the adaptor</LI> |
|
93 * </UL> |
|
94 * The default object name is defined by {@link |
|
95 * com.sun.jmx.snmp.ServiceName#DOMAIN com.sun.jmx.snmp.ServiceName.DOMAIN} |
|
96 * and {@link com.sun.jmx.snmp.ServiceName#SNMP_ADAPTOR_SERVER |
|
97 * com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_SERVER}. |
|
98 * <P> |
|
99 * The SNMP protocol adaptor supports versions 1 and 2 of the SNMP protocol |
|
100 * in a stateless way: when it receives a v1 request, it replies with a v1 |
|
101 * response, when it receives a v2 request it replies with a v2 response. |
|
102 * <BR>The method {@link #snmpV1Trap snmpV1Trap} sends traps using SNMP v1 |
|
103 * format. |
|
104 * The method {@link #snmpV2Trap snmpV2Trap} sends traps using SNMP v2 format. |
|
105 * The method {@link #snmpInformRequest snmpInformRequest} sends inform |
|
106 * requests using SNMP v2 format. |
|
107 * <P> |
|
108 * To receive data packets, the SNMP protocol adaptor uses a buffer |
|
109 * which size can be configured using the property <CODE>bufferSize</CODE> |
|
110 * (default value is 1024). |
|
111 * Packets which do not fit into the buffer are rejected. |
|
112 * Increasing <CODE>bufferSize</CODE> allows the exchange of bigger packets. |
|
113 * However, the underlying networking system may impose a limit on the size |
|
114 * of UDP packets. |
|
115 * Packets which size exceed this limit will be rejected, no matter what |
|
116 * the value of <CODE>bufferSize</CODE> actually is. |
|
117 * <P> |
|
118 * An SNMP protocol adaptor may serve several managers concurrently. The |
|
119 * number of concurrent managers can be limited using the property |
|
120 * <CODE>maxActiveClientCount</CODE>. |
|
121 * <p> |
|
122 * The SNMP protocol adaptor specifies a default value (10) for the |
|
123 * <CODE>maxActiveClientCount</CODE> property. When the adaptor is stopped, |
|
124 * the active requests are interrupted and an error result is sent to |
|
125 * the managers. |
|
126 * <p><b>This API is a Sun Microsystems internal API and is subject |
|
127 * to change without notice.</b></p> |
|
128 */ |
|
129 |
|
130 public class SnmpAdaptorServer extends CommunicatorServer |
|
131 implements SnmpAdaptorServerMBean, MBeanRegistration, SnmpDefinitions, |
|
132 SnmpMibHandler { |
|
133 |
|
134 // PRIVATE VARIABLES |
|
135 //------------------ |
|
136 |
|
137 /** |
|
138 * Port number for sending SNMP traps. |
|
139 * <BR>The default value is 162. |
|
140 */ |
|
141 private int trapPort = 162; |
|
142 |
|
143 /** |
|
144 * Port number for sending SNMP inform requests. |
|
145 * <BR>The default value is 162. |
|
146 */ |
|
147 private int informPort = 162; |
|
148 |
|
149 /** |
|
150 * The <CODE>InetAddress</CODE> used when creating the datagram socket. |
|
151 * <BR>It is specified when creating the SNMP protocol adaptor. |
|
152 * If not specified, the local host machine is used. |
|
153 */ |
|
154 InetAddress address = null; |
|
155 |
|
156 /** |
|
157 * The IP address based ACL used by this SNMP protocol adaptor. |
|
158 */ |
|
159 private InetAddressAcl ipacl = null; |
|
160 |
|
161 /** |
|
162 * The factory object. |
|
163 */ |
|
164 private SnmpPduFactory pduFactory = null; |
|
165 |
|
166 /** |
|
167 * The user-data factory object. |
|
168 */ |
|
169 private SnmpUserDataFactory userDataFactory = null; |
|
170 |
|
171 /** |
|
172 * Indicates if the SNMP protocol adaptor sends a response in case |
|
173 * of authentication failure |
|
174 */ |
|
175 private boolean authRespEnabled = true; |
|
176 |
|
177 /** |
|
178 * Indicates if authentication traps are enabled. |
|
179 */ |
|
180 private boolean authTrapEnabled = true; |
|
181 |
|
182 /** |
|
183 * The enterprise OID. |
|
184 * <BR>The default value is "1.3.6.1.4.1.42". |
|
185 */ |
|
186 private SnmpOid enterpriseOid = new SnmpOid("1.3.6.1.4.1.42"); |
|
187 |
|
188 /** |
|
189 * The buffer size of the SNMP protocol adaptor. |
|
190 * This buffer size is used for both incoming request and outgoing |
|
191 * inform requests. |
|
192 * <BR>The default value is 1024. |
|
193 */ |
|
194 int bufferSize = 1024; |
|
195 |
|
196 private transient long startUpTime = 0; |
|
197 private transient DatagramSocket socket = null; |
|
198 transient DatagramSocket trapSocket = null; |
|
199 private transient SnmpSession informSession = null; |
|
200 private transient DatagramPacket packet = null; |
|
201 transient Vector<SnmpMibAgent> mibs = new Vector<>(); |
|
202 private transient SnmpMibTree root; |
|
203 |
|
204 /** |
|
205 * Whether ACL must be used. |
|
206 */ |
|
207 private transient boolean useAcl = true; |
|
208 |
|
209 |
|
210 // SENDING SNMP INFORMS STUFF |
|
211 //--------------------------- |
|
212 |
|
213 /** |
|
214 * Number of times to try an inform request before giving up. |
|
215 * The default number is 3. |
|
216 */ |
|
217 private int maxTries = 3 ; |
|
218 |
|
219 /** |
|
220 * The amount of time to wait for an inform response from the manager. |
|
221 * The default amount of time is 3000 millisec. |
|
222 */ |
|
223 private int timeout = 3 * 1000 ; |
|
224 |
|
225 // VARIABLES REQUIRED FOR IMPLEMENTING SNMP GROUP (MIBII) |
|
226 //------------------------------------------------------- |
|
227 |
|
228 /** |
|
229 * The <CODE>snmpOutTraps</CODE> value defined in MIB-II. |
|
230 */ |
|
231 int snmpOutTraps=0; |
|
232 |
|
233 /** |
|
234 * The <CODE>snmpOutGetResponses</CODE> value defined in MIB-II. |
|
235 */ |
|
236 private int snmpOutGetResponses=0; |
|
237 |
|
238 /** |
|
239 * The <CODE>snmpOutGenErrs</CODE> value defined in MIB-II. |
|
240 */ |
|
241 private int snmpOutGenErrs=0; |
|
242 |
|
243 /** |
|
244 * The <CODE>snmpOutBadValues</CODE> value defined in MIB-II. |
|
245 */ |
|
246 private int snmpOutBadValues=0; |
|
247 |
|
248 /** |
|
249 * The <CODE>snmpOutNoSuchNames</CODE> value defined in MIB-II. |
|
250 */ |
|
251 private int snmpOutNoSuchNames=0; |
|
252 |
|
253 /** |
|
254 * The <CODE>snmpOutTooBigs</CODE> value defined in MIB-II. |
|
255 */ |
|
256 private int snmpOutTooBigs=0; |
|
257 |
|
258 /** |
|
259 * The <CODE>snmpOutPkts</CODE> value defined in MIB-II. |
|
260 */ |
|
261 int snmpOutPkts=0; |
|
262 |
|
263 /** |
|
264 * The <CODE>snmpInASNParseErrs</CODE> value defined in MIB-II. |
|
265 */ |
|
266 private int snmpInASNParseErrs=0; |
|
267 |
|
268 /** |
|
269 * The <CODE>snmpInBadCommunityUses</CODE> value defined in MIB-II. |
|
270 */ |
|
271 private int snmpInBadCommunityUses=0; |
|
272 |
|
273 /** |
|
274 * The <CODE>snmpInBadCommunityNames</CODE> value defined in MIB-II. |
|
275 */ |
|
276 private int snmpInBadCommunityNames=0; |
|
277 |
|
278 /** |
|
279 * The <CODE>snmpInBadVersions</CODE> value defined in MIB-II. |
|
280 */ |
|
281 private int snmpInBadVersions=0; |
|
282 |
|
283 /** |
|
284 * The <CODE>snmpInGetRequests</CODE> value defined in MIB-II. |
|
285 */ |
|
286 private int snmpInGetRequests=0; |
|
287 |
|
288 /** |
|
289 * The <CODE>snmpInGetNexts</CODE> value defined in MIB-II. |
|
290 */ |
|
291 private int snmpInGetNexts=0; |
|
292 |
|
293 /** |
|
294 * The <CODE>snmpInSetRequests</CODE> value defined in MIB-II. |
|
295 */ |
|
296 private int snmpInSetRequests=0; |
|
297 |
|
298 /** |
|
299 * The <CODE>snmpInPkts</CODE> value defined in MIB-II. |
|
300 */ |
|
301 private int snmpInPkts=0; |
|
302 |
|
303 /** |
|
304 * The <CODE>snmpInTotalReqVars</CODE> value defined in MIB-II. |
|
305 */ |
|
306 private int snmpInTotalReqVars=0; |
|
307 |
|
308 /** |
|
309 * The <CODE>snmpInTotalSetVars</CODE> value defined in MIB-II. |
|
310 */ |
|
311 private int snmpInTotalSetVars=0; |
|
312 |
|
313 /** |
|
314 * The <CODE>snmpInTotalSetVars</CODE> value defined in rfc 1907 MIB-II. |
|
315 */ |
|
316 private int snmpSilentDrops=0; |
|
317 |
|
318 private static final String InterruptSysCallMsg = |
|
319 "Interrupted system call"; |
|
320 static final SnmpOid sysUpTimeOid = new SnmpOid("1.3.6.1.2.1.1.3.0") ; |
|
321 static final SnmpOid snmpTrapOidOid = new SnmpOid("1.3.6.1.6.3.1.1.4.1.0"); |
|
322 |
|
323 private ThreadService threadService; |
|
324 |
|
325 private static int threadNumber = 6; |
|
326 |
|
327 static { |
|
328 String s = System.getProperty("com.sun.jmx.snmp.threadnumber"); |
|
329 |
|
330 if (s != null) { |
|
331 try { |
|
332 threadNumber = Integer.parseInt(System.getProperty(s)); |
|
333 } catch (Exception e) { |
|
334 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, |
|
335 SnmpAdaptorServer.class.getName(), |
|
336 "<static init>", |
|
337 "Got wrong value for com.sun.jmx.snmp.threadnumber: " + |
|
338 s + ". Use the default value: " + threadNumber); |
|
339 } |
|
340 } |
|
341 } |
|
342 |
|
343 // PUBLIC CONSTRUCTORS |
|
344 //-------------------- |
|
345 |
|
346 /** |
|
347 * Initializes this SNMP protocol adaptor using the default port (161). |
|
348 * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default |
|
349 * implementation of the <CODE>InetAddressAcl</CODE> interface. |
|
350 */ |
|
351 public SnmpAdaptorServer() { |
|
352 this(true, null, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT, |
|
353 null) ; |
|
354 } |
|
355 |
|
356 /** |
|
357 * Initializes this SNMP protocol adaptor using the specified port. |
|
358 * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default |
|
359 * implementation of the <CODE>InetAddressAcl</CODE> interface. |
|
360 * |
|
361 * @param port The port number for sending SNMP responses. |
|
362 */ |
|
363 public SnmpAdaptorServer(int port) { |
|
364 this(true, null, port, null) ; |
|
365 } |
|
366 |
|
367 /** |
|
368 * Initializes this SNMP protocol adaptor using the default port (161) |
|
369 * and the specified IP address based ACL implementation. |
|
370 * |
|
371 * @param acl The <CODE>InetAddressAcl</CODE> implementation. |
|
372 * <code>null</code> means no ACL - everybody is authorized. |
|
373 * |
|
374 * @since 1.5 |
|
375 */ |
|
376 public SnmpAdaptorServer(InetAddressAcl acl) { |
|
377 this(false, acl, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT, |
|
378 null) ; |
|
379 } |
|
380 |
|
381 /** |
|
382 * Initializes this SNMP protocol adaptor using the default port (161) |
|
383 * and the |
|
384 * specified <CODE>InetAddress</CODE>. |
|
385 * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default |
|
386 * implementation of the <CODE>InetAddressAcl</CODE> interface. |
|
387 * |
|
388 * @param addr The IP address to bind. |
|
389 */ |
|
390 public SnmpAdaptorServer(InetAddress addr) { |
|
391 this(true, null, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT, |
|
392 addr) ; |
|
393 } |
|
394 |
|
395 /** |
|
396 * Initializes this SNMP protocol adaptor using the specified port and the |
|
397 * specified IP address based ACL implementation. |
|
398 * |
|
399 * @param acl The <CODE>InetAddressAcl</CODE> implementation. |
|
400 * <code>null</code> means no ACL - everybody is authorized. |
|
401 * @param port The port number for sending SNMP responses. |
|
402 * |
|
403 * @since 1.5 |
|
404 */ |
|
405 public SnmpAdaptorServer(InetAddressAcl acl, int port) { |
|
406 this(false, acl, port, null) ; |
|
407 } |
|
408 |
|
409 /** |
|
410 * Initializes this SNMP protocol adaptor using the specified port and the |
|
411 * specified <CODE>InetAddress</CODE>. |
|
412 * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default |
|
413 * implementation of the <CODE>InetAddressAcl</CODE> interface. |
|
414 * |
|
415 * @param port The port number for sending SNMP responses. |
|
416 * @param addr The IP address to bind. |
|
417 */ |
|
418 public SnmpAdaptorServer(int port, InetAddress addr) { |
|
419 this(true, null, port, addr) ; |
|
420 } |
|
421 |
|
422 /** |
|
423 * Initializes this SNMP protocol adaptor using the specified IP |
|
424 * address based ACL implementation and the specified |
|
425 * <CODE>InetAddress</CODE>. |
|
426 * |
|
427 * @param acl The <CODE>InetAddressAcl</CODE> implementation. |
|
428 * @param addr The IP address to bind. |
|
429 * |
|
430 * @since 1.5 |
|
431 */ |
|
432 public SnmpAdaptorServer(InetAddressAcl acl, InetAddress addr) { |
|
433 this(false, acl, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT, |
|
434 addr) ; |
|
435 } |
|
436 |
|
437 /** |
|
438 * Initializes this SNMP protocol adaptor using the specified port, the |
|
439 * specified address based ACL implementation and the specified |
|
440 * <CODE>InetAddress</CODE>. |
|
441 * |
|
442 * @param acl The <CODE>InetAddressAcl</CODE> implementation. |
|
443 * @param port The port number for sending SNMP responses. |
|
444 * @param addr The IP address to bind. |
|
445 * |
|
446 * @since 1.5 |
|
447 */ |
|
448 public SnmpAdaptorServer(InetAddressAcl acl, int port, InetAddress addr) { |
|
449 this(false, acl, port, addr); |
|
450 } |
|
451 |
|
452 /** |
|
453 * Initializes this SNMP protocol adaptor using the specified port and the |
|
454 * specified <CODE>InetAddress</CODE>. |
|
455 * This constructor allows to initialize an SNMP adaptor without using |
|
456 * the ACL mechanism (by setting the <CODE>useAcl</CODE> parameter to |
|
457 * false). |
|
458 * <br>This constructor must be used in particular with a platform that |
|
459 * does not support the <CODE>java.security.acl</CODE> package like pJava. |
|
460 * |
|
461 * @param useAcl Specifies if this new SNMP adaptor uses the ACL mechanism. |
|
462 * If the specified parameter is set to <CODE>true</CODE>, this |
|
463 * constructor is equivalent to |
|
464 * <CODE>SnmpAdaptorServer((int)port,(InetAddress)addr)</CODE>. |
|
465 * @param port The port number for sending SNMP responses. |
|
466 * @param addr The IP address to bind. |
|
467 */ |
|
468 public SnmpAdaptorServer(boolean useAcl, int port, InetAddress addr) { |
|
469 this(useAcl,null,port,addr); |
|
470 } |
|
471 |
|
472 // If forceAcl is `true' and InetAddressAcl is null, then a default |
|
473 // SnmpAcl object is created. |
|
474 // |
|
475 private SnmpAdaptorServer(boolean forceAcl, InetAddressAcl acl, |
|
476 int port, InetAddress addr) { |
|
477 super(CommunicatorServer.SNMP_TYPE) ; |
|
478 |
|
479 |
|
480 // Initialize the ACL implementation. |
|
481 // |
|
482 if (acl == null && forceAcl) { |
|
483 try { |
|
484 acl = new SnmpAcl("SNMP protocol adaptor IP ACL"); |
|
485 } catch (UnknownHostException e) { |
|
486 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { |
|
487 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag, |
|
488 "constructor", "UnknowHostException when creating ACL",e); |
|
489 } |
|
490 } |
|
491 } else { |
|
492 this.useAcl = (acl!=null) || forceAcl; |
|
493 } |
|
494 |
|
495 init(acl, port, addr) ; |
|
496 } |
|
497 |
|
498 // GETTERS AND SETTERS |
|
499 //-------------------- |
|
500 |
|
501 /** |
|
502 * Gets the number of managers that have been processed by this |
|
503 * SNMP protocol adaptor since its creation. |
|
504 * |
|
505 * @return The number of managers handled by this SNMP protocol adaptor |
|
506 * since its creation. This counter is not reset by the <CODE>stop</CODE> |
|
507 * method. |
|
508 */ |
|
509 @Override |
|
510 public int getServedClientCount() { |
|
511 return super.getServedClientCount(); |
|
512 } |
|
513 |
|
514 /** |
|
515 * Gets the number of managers currently being processed by this |
|
516 * SNMP protocol adaptor. |
|
517 * |
|
518 * @return The number of managers currently being processed by this |
|
519 * SNMP protocol adaptor. |
|
520 */ |
|
521 @Override |
|
522 public int getActiveClientCount() { |
|
523 return super.getActiveClientCount(); |
|
524 } |
|
525 |
|
526 /** |
|
527 * Gets the maximum number of managers that this SNMP protocol adaptor can |
|
528 * process concurrently. |
|
529 * |
|
530 * @return The maximum number of managers that this SNMP protocol adaptor |
|
531 * can process concurrently. |
|
532 */ |
|
533 @Override |
|
534 public int getMaxActiveClientCount() { |
|
535 return super.getMaxActiveClientCount(); |
|
536 } |
|
537 |
|
538 /** |
|
539 * Sets the maximum number of managers this SNMP protocol adaptor can |
|
540 * process concurrently. |
|
541 * |
|
542 * @param c The number of managers. |
|
543 * |
|
544 * @exception java.lang.IllegalStateException This method has been invoked |
|
545 * while the communicator was <CODE>ONLINE</CODE> or <CODE>STARTING</CODE>. |
|
546 */ |
|
547 @Override |
|
548 public void setMaxActiveClientCount(int c) |
|
549 throws java.lang.IllegalStateException { |
|
550 super.setMaxActiveClientCount(c); |
|
551 } |
|
552 |
|
553 /** |
|
554 * Returns the Ip address based ACL used by this SNMP protocol adaptor. |
|
555 * @return The <CODE>InetAddressAcl</CODE> implementation. |
|
556 * |
|
557 * @since 1.5 |
|
558 */ |
|
559 @Override |
|
560 public InetAddressAcl getInetAddressAcl() { |
|
561 return ipacl; |
|
562 } |
|
563 |
|
564 /** |
|
565 * Returns the port used by this SNMP protocol adaptor for sending traps. |
|
566 * By default, port 162 is used. |
|
567 * |
|
568 * @return The port number for sending SNMP traps. |
|
569 */ |
|
570 @Override |
|
571 public Integer getTrapPort() { |
|
572 return trapPort; |
|
573 } |
|
574 |
|
575 /** |
|
576 * Sets the port used by this SNMP protocol adaptor for sending traps. |
|
577 * |
|
578 * @param port The port number for sending SNMP traps. |
|
579 */ |
|
580 @Override |
|
581 public void setTrapPort(Integer port) { |
|
582 setTrapPort(port.intValue()); |
|
583 } |
|
584 |
|
585 /** |
|
586 * Sets the port used by this SNMP protocol adaptor for sending traps. |
|
587 * |
|
588 * @param port The port number for sending SNMP traps. |
|
589 */ |
|
590 public void setTrapPort(int port) { |
|
591 int val= port ; |
|
592 if (val < 0) throw new |
|
593 IllegalArgumentException("Trap port cannot be a negative value"); |
|
594 trapPort= val ; |
|
595 } |
|
596 |
|
597 /** |
|
598 * Returns the port used by this SNMP protocol adaptor for sending |
|
599 * inform requests. By default, port 162 is used. |
|
600 * |
|
601 * @return The port number for sending SNMP inform requests. |
|
602 */ |
|
603 @Override |
|
604 public int getInformPort() { |
|
605 return informPort; |
|
606 } |
|
607 |
|
608 /** |
|
609 * Sets the port used by this SNMP protocol adaptor for sending |
|
610 * inform requests. |
|
611 * |
|
612 * @param port The port number for sending SNMP inform requests. |
|
613 */ |
|
614 @Override |
|
615 public void setInformPort(int port) { |
|
616 if (port < 0) |
|
617 throw new IllegalArgumentException("Inform request port "+ |
|
618 "cannot be a negative value"); |
|
619 informPort= port ; |
|
620 } |
|
621 |
|
622 /** |
|
623 * Returns the protocol of this SNMP protocol adaptor. |
|
624 * |
|
625 * @return The string "snmp". |
|
626 */ |
|
627 @Override |
|
628 public String getProtocol() { |
|
629 return "snmp"; |
|
630 } |
|
631 |
|
632 /** |
|
633 * Returns the buffer size of this SNMP protocol adaptor. |
|
634 * This buffer size is used for both incoming request and outgoing |
|
635 * inform requests. |
|
636 * By default, buffer size 1024 is used. |
|
637 * |
|
638 * @return The buffer size. |
|
639 */ |
|
640 @Override |
|
641 public Integer getBufferSize() { |
|
642 return bufferSize; |
|
643 } |
|
644 |
|
645 /** |
|
646 * Sets the buffer size of this SNMP protocol adaptor. |
|
647 * This buffer size is used for both incoming request and outgoing |
|
648 * inform requests. |
|
649 * |
|
650 * @param s The buffer size. |
|
651 * |
|
652 * @exception java.lang.IllegalStateException This method has been invoked |
|
653 * while the communicator was <CODE>ONLINE</CODE> or <CODE>STARTING</CODE>. |
|
654 */ |
|
655 @Override |
|
656 public void setBufferSize(Integer s) |
|
657 throws java.lang.IllegalStateException { |
|
658 if ((state == ONLINE) || (state == STARTING)) { |
|
659 throw new IllegalStateException("Stop server before carrying out"+ |
|
660 " this operation"); |
|
661 } |
|
662 bufferSize = s.intValue() ; |
|
663 } |
|
664 |
|
665 /** |
|
666 * Gets the number of times to try sending an inform request before |
|
667 * giving up. |
|
668 * By default, a maximum of 3 tries is used. |
|
669 * @return The maximun number of tries. |
|
670 */ |
|
671 @Override |
|
672 final public int getMaxTries() { |
|
673 return maxTries; |
|
674 } |
|
675 |
|
676 /** |
|
677 * Changes the maximun number of times to try sending an inform |
|
678 * request before giving up. |
|
679 * @param newMaxTries The maximun number of tries. |
|
680 */ |
|
681 @Override |
|
682 final public synchronized void setMaxTries(int newMaxTries) { |
|
683 if (newMaxTries < 0) |
|
684 throw new IllegalArgumentException(); |
|
685 maxTries = newMaxTries; |
|
686 } |
|
687 |
|
688 /** |
|
689 * Gets the timeout to wait for an inform response from the manager. |
|
690 * By default, a timeout of 3 seconds is used. |
|
691 * @return The value of the timeout property. |
|
692 */ |
|
693 @Override |
|
694 final public int getTimeout() { |
|
695 return timeout; |
|
696 } |
|
697 |
|
698 /** |
|
699 * Changes the timeout to wait for an inform response from the manager. |
|
700 * @param newTimeout The timeout (in milliseconds). |
|
701 */ |
|
702 @Override |
|
703 final public synchronized void setTimeout(int newTimeout) { |
|
704 if (newTimeout < 0) |
|
705 throw new IllegalArgumentException(); |
|
706 timeout= newTimeout; |
|
707 } |
|
708 |
|
709 /** |
|
710 * Returns the message factory of this SNMP protocol adaptor. |
|
711 * |
|
712 * @return The factory object. |
|
713 */ |
|
714 @Override |
|
715 public SnmpPduFactory getPduFactory() { |
|
716 return pduFactory ; |
|
717 } |
|
718 |
|
719 /** |
|
720 * Sets the message factory of this SNMP protocol adaptor. |
|
721 * |
|
722 * @param factory The factory object (null means the default factory). |
|
723 */ |
|
724 @Override |
|
725 public void setPduFactory(SnmpPduFactory factory) { |
|
726 if (factory == null) |
|
727 pduFactory = new SnmpPduFactoryBER() ; |
|
728 else |
|
729 pduFactory = factory ; |
|
730 } |
|
731 |
|
732 /** |
|
733 * Set the user-data factory of this SNMP protocol adaptor. |
|
734 * |
|
735 * @param factory The factory object (null means no factory). |
|
736 * @see com.sun.jmx.snmp.agent.SnmpUserDataFactory |
|
737 */ |
|
738 @Override |
|
739 public void setUserDataFactory(SnmpUserDataFactory factory) { |
|
740 userDataFactory = factory ; |
|
741 } |
|
742 |
|
743 /** |
|
744 * Get the user-data factory associated with this SNMP protocol adaptor. |
|
745 * |
|
746 * @return The factory object (null means no factory). |
|
747 * @see com.sun.jmx.snmp.agent.SnmpUserDataFactory |
|
748 */ |
|
749 @Override |
|
750 public SnmpUserDataFactory getUserDataFactory() { |
|
751 return userDataFactory; |
|
752 } |
|
753 |
|
754 /** |
|
755 * Returns <CODE>true</CODE> if authentication traps are enabled. |
|
756 * <P> |
|
757 * When this feature is enabled, the SNMP protocol adaptor sends |
|
758 * an <CODE>authenticationFailure</CODE> trap each time an |
|
759 * authentication fails. |
|
760 * <P> |
|
761 * The default behaviour is to send authentication traps. |
|
762 * |
|
763 * @return <CODE>true</CODE> if authentication traps are enabled, |
|
764 * <CODE>false</CODE> otherwise. |
|
765 */ |
|
766 @Override |
|
767 public boolean getAuthTrapEnabled() { |
|
768 return authTrapEnabled ; |
|
769 } |
|
770 |
|
771 /** |
|
772 * Sets the flag indicating if traps need to be sent in case of |
|
773 * authentication failure. |
|
774 * |
|
775 * @param enabled Flag indicating if traps need to be sent. |
|
776 */ |
|
777 @Override |
|
778 public void setAuthTrapEnabled(boolean enabled) { |
|
779 authTrapEnabled = enabled ; |
|
780 } |
|
781 |
|
782 /** |
|
783 * Returns <code>true</code> if this SNMP protocol adaptor sends a |
|
784 * response in case of authentication failure. |
|
785 * <P> |
|
786 * When this feature is enabled, the SNMP protocol adaptor sends a |
|
787 * response with <CODE>noSuchName</CODE> or <CODE>readOnly</CODE> when |
|
788 * the authentication failed. If the flag is disabled, the |
|
789 * SNMP protocol adaptor trashes the PDU silently. |
|
790 * <P> |
|
791 * The default behavior is to send responses. |
|
792 * |
|
793 * @return <CODE>true</CODE> if responses are sent. |
|
794 */ |
|
795 @Override |
|
796 public boolean getAuthRespEnabled() { |
|
797 return authRespEnabled ; |
|
798 } |
|
799 |
|
800 /** |
|
801 * Sets the flag indicating if responses need to be sent in case of |
|
802 * authentication failure. |
|
803 * |
|
804 * @param enabled Flag indicating if responses need to be sent. |
|
805 */ |
|
806 @Override |
|
807 public void setAuthRespEnabled(boolean enabled) { |
|
808 authRespEnabled = enabled ; |
|
809 } |
|
810 |
|
811 /** |
|
812 * Returns the enterprise OID. It is used by |
|
813 * {@link #snmpV1Trap snmpV1Trap} to fill the 'enterprise' field of the |
|
814 * trap request. |
|
815 * |
|
816 * @return The OID in string format "x.x.x.x". |
|
817 */ |
|
818 @Override |
|
819 public String getEnterpriseOid() { |
|
820 return enterpriseOid.toString() ; |
|
821 } |
|
822 |
|
823 /** |
|
824 * Sets the enterprise OID. |
|
825 * |
|
826 * @param oid The OID in string format "x.x.x.x". |
|
827 * |
|
828 * @exception IllegalArgumentException The string format is incorrect |
|
829 */ |
|
830 @Override |
|
831 public void setEnterpriseOid(String oid) throws IllegalArgumentException { |
|
832 enterpriseOid = new SnmpOid(oid) ; |
|
833 } |
|
834 |
|
835 /** |
|
836 * Returns the names of the MIBs available in this SNMP protocol adaptor. |
|
837 * |
|
838 * @return An array of MIB names. |
|
839 */ |
|
840 @Override |
|
841 public String[] getMibs() { |
|
842 String[] result = new String[mibs.size()] ; |
|
843 int i = 0 ; |
|
844 for (Enumeration<SnmpMibAgent> e = mibs.elements() ; e.hasMoreElements() ;) { |
|
845 SnmpMibAgent mib = e.nextElement() ; |
|
846 result[i++] = mib.getMibName(); |
|
847 } |
|
848 return result ; |
|
849 } |
|
850 |
|
851 // GETTERS FOR SNMP GROUP (MIBII) |
|
852 //------------------------------- |
|
853 |
|
854 /** |
|
855 * Returns the <CODE>snmpOutTraps</CODE> value defined in MIB-II. |
|
856 * |
|
857 * @return The <CODE>snmpOutTraps</CODE> value. |
|
858 */ |
|
859 @Override |
|
860 public Long getSnmpOutTraps() { |
|
861 return (long)snmpOutTraps; |
|
862 } |
|
863 |
|
864 /** |
|
865 * Returns the <CODE>snmpOutGetResponses</CODE> value defined in MIB-II. |
|
866 * |
|
867 * @return The <CODE>snmpOutGetResponses</CODE> value. |
|
868 */ |
|
869 @Override |
|
870 public Long getSnmpOutGetResponses() { |
|
871 return (long)snmpOutGetResponses; |
|
872 } |
|
873 |
|
874 /** |
|
875 * Returns the <CODE>snmpOutGenErrs</CODE> value defined in MIB-II. |
|
876 * |
|
877 * @return The <CODE>snmpOutGenErrs</CODE> value. |
|
878 */ |
|
879 @Override |
|
880 public Long getSnmpOutGenErrs() { |
|
881 return (long)snmpOutGenErrs; |
|
882 } |
|
883 |
|
884 /** |
|
885 * Returns the <CODE>snmpOutBadValues</CODE> value defined in MIB-II. |
|
886 * |
|
887 * @return The <CODE>snmpOutBadValues</CODE> value. |
|
888 */ |
|
889 @Override |
|
890 public Long getSnmpOutBadValues() { |
|
891 return (long)snmpOutBadValues; |
|
892 } |
|
893 |
|
894 /** |
|
895 * Returns the <CODE>snmpOutNoSuchNames</CODE> value defined in MIB-II. |
|
896 * |
|
897 * @return The <CODE>snmpOutNoSuchNames</CODE> value. |
|
898 */ |
|
899 @Override |
|
900 public Long getSnmpOutNoSuchNames() { |
|
901 return (long)snmpOutNoSuchNames; |
|
902 } |
|
903 |
|
904 /** |
|
905 * Returns the <CODE>snmpOutTooBigs</CODE> value defined in MIB-II. |
|
906 * |
|
907 * @return The <CODE>snmpOutTooBigs</CODE> value. |
|
908 */ |
|
909 @Override |
|
910 public Long getSnmpOutTooBigs() { |
|
911 return (long)snmpOutTooBigs; |
|
912 } |
|
913 |
|
914 /** |
|
915 * Returns the <CODE>snmpInASNParseErrs</CODE> value defined in MIB-II. |
|
916 * |
|
917 * @return The <CODE>snmpInASNParseErrs</CODE> value. |
|
918 */ |
|
919 @Override |
|
920 public Long getSnmpInASNParseErrs() { |
|
921 return (long)snmpInASNParseErrs; |
|
922 } |
|
923 |
|
924 /** |
|
925 * Returns the <CODE>snmpInBadCommunityUses</CODE> value defined in MIB-II. |
|
926 * |
|
927 * @return The <CODE>snmpInBadCommunityUses</CODE> value. |
|
928 */ |
|
929 @Override |
|
930 public Long getSnmpInBadCommunityUses() { |
|
931 return (long)snmpInBadCommunityUses; |
|
932 } |
|
933 |
|
934 /** |
|
935 * Returns the <CODE>snmpInBadCommunityNames</CODE> value defined in |
|
936 * MIB-II. |
|
937 * |
|
938 * @return The <CODE>snmpInBadCommunityNames</CODE> value. |
|
939 */ |
|
940 @Override |
|
941 public Long getSnmpInBadCommunityNames() { |
|
942 return (long)snmpInBadCommunityNames; |
|
943 } |
|
944 |
|
945 /** |
|
946 * Returns the <CODE>snmpInBadVersions</CODE> value defined in MIB-II. |
|
947 * |
|
948 * @return The <CODE>snmpInBadVersions</CODE> value. |
|
949 */ |
|
950 @Override |
|
951 public Long getSnmpInBadVersions() { |
|
952 return (long)snmpInBadVersions; |
|
953 } |
|
954 |
|
955 /** |
|
956 * Returns the <CODE>snmpOutPkts</CODE> value defined in MIB-II. |
|
957 * |
|
958 * @return The <CODE>snmpOutPkts</CODE> value. |
|
959 */ |
|
960 @Override |
|
961 public Long getSnmpOutPkts() { |
|
962 return (long)snmpOutPkts; |
|
963 } |
|
964 |
|
965 /** |
|
966 * Returns the <CODE>snmpInPkts</CODE> value defined in MIB-II. |
|
967 * |
|
968 * @return The <CODE>snmpInPkts</CODE> value. |
|
969 */ |
|
970 @Override |
|
971 public Long getSnmpInPkts() { |
|
972 return (long)snmpInPkts; |
|
973 } |
|
974 |
|
975 /** |
|
976 * Returns the <CODE>snmpInGetRequests</CODE> value defined in MIB-II. |
|
977 * |
|
978 * @return The <CODE>snmpInGetRequests</CODE> value. |
|
979 */ |
|
980 @Override |
|
981 public Long getSnmpInGetRequests() { |
|
982 return (long)snmpInGetRequests; |
|
983 } |
|
984 |
|
985 /** |
|
986 * Returns the <CODE>snmpInGetNexts</CODE> value defined in MIB-II. |
|
987 * |
|
988 * @return The <CODE>snmpInGetNexts</CODE> value. |
|
989 */ |
|
990 @Override |
|
991 public Long getSnmpInGetNexts() { |
|
992 return (long)snmpInGetNexts; |
|
993 } |
|
994 |
|
995 /** |
|
996 * Returns the <CODE>snmpInSetRequests</CODE> value defined in MIB-II. |
|
997 * |
|
998 * @return The <CODE>snmpInSetRequests</CODE> value. |
|
999 */ |
|
1000 @Override |
|
1001 public Long getSnmpInSetRequests() { |
|
1002 return (long)snmpInSetRequests; |
|
1003 } |
|
1004 |
|
1005 /** |
|
1006 * Returns the <CODE>snmpInTotalSetVars</CODE> value defined in MIB-II. |
|
1007 * |
|
1008 * @return The <CODE>snmpInTotalSetVars</CODE> value. |
|
1009 */ |
|
1010 @Override |
|
1011 public Long getSnmpInTotalSetVars() { |
|
1012 return (long)snmpInTotalSetVars; |
|
1013 } |
|
1014 |
|
1015 /** |
|
1016 * Returns the <CODE>snmpInTotalReqVars</CODE> value defined in MIB-II. |
|
1017 * |
|
1018 * @return The <CODE>snmpInTotalReqVars</CODE> value. |
|
1019 */ |
|
1020 @Override |
|
1021 public Long getSnmpInTotalReqVars() { |
|
1022 return (long)snmpInTotalReqVars; |
|
1023 } |
|
1024 |
|
1025 /** |
|
1026 * Returns the <CODE>snmpSilentDrops</CODE> value defined in RFC |
|
1027 * 1907 NMPv2-MIB . |
|
1028 * |
|
1029 * @return The <CODE>snmpSilentDrops</CODE> value. |
|
1030 * |
|
1031 * @since 1.5 |
|
1032 */ |
|
1033 @Override |
|
1034 public Long getSnmpSilentDrops() { |
|
1035 return (long)snmpSilentDrops; |
|
1036 } |
|
1037 |
|
1038 /** |
|
1039 * Returns the <CODE>snmpProxyDrops</CODE> value defined in RFC |
|
1040 * 1907 NMPv2-MIB . |
|
1041 * |
|
1042 * @return The <CODE>snmpProxyDrops</CODE> value. |
|
1043 * |
|
1044 * @since 1.5 |
|
1045 */ |
|
1046 @Override |
|
1047 public Long getSnmpProxyDrops() { |
|
1048 return 0L; |
|
1049 } |
|
1050 |
|
1051 |
|
1052 // PUBLIC METHODS |
|
1053 //--------------- |
|
1054 |
|
1055 /** |
|
1056 * Allows the MBean to perform any operations it needs before being |
|
1057 * registered in the MBean server. |
|
1058 * If the name of the SNMP protocol adaptor MBean is not specified, |
|
1059 * it is initialized with the default value: |
|
1060 * {@link com.sun.jmx.snmp.ServiceName#DOMAIN |
|
1061 * com.sun.jmx.snmp.ServiceName.DOMAIN}:{@link |
|
1062 * com.sun.jmx.snmp.ServiceName#SNMP_ADAPTOR_SERVER |
|
1063 * com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_SERVER}. |
|
1064 * If any exception is raised, the SNMP protocol adaptor MBean will |
|
1065 * not be registered in the MBean server. |
|
1066 * |
|
1067 * @param server The MBean server to register the service with. |
|
1068 * @param name The object name. |
|
1069 * |
|
1070 * @return The name of the SNMP protocol adaptor registered. |
|
1071 * |
|
1072 * @exception java.lang.Exception |
|
1073 */ |
|
1074 @Override |
|
1075 public ObjectName preRegister(MBeanServer server, ObjectName name) |
|
1076 throws java.lang.Exception { |
|
1077 |
|
1078 if (name == null) { |
|
1079 name = new ObjectName(server.getDefaultDomain() + ":" + |
|
1080 com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_SERVER); |
|
1081 } |
|
1082 return (super.preRegister(server, name)); |
|
1083 } |
|
1084 |
|
1085 /** |
|
1086 * Not used in this context. |
|
1087 */ |
|
1088 @Override |
|
1089 public void postRegister (Boolean registrationDone) { |
|
1090 super.postRegister(registrationDone); |
|
1091 } |
|
1092 |
|
1093 /** |
|
1094 * Not used in this context. |
|
1095 */ |
|
1096 @Override |
|
1097 public void preDeregister() throws java.lang.Exception { |
|
1098 super.preDeregister(); |
|
1099 } |
|
1100 |
|
1101 /** |
|
1102 * Not used in this context. |
|
1103 */ |
|
1104 @Override |
|
1105 public void postDeregister() { |
|
1106 super.postDeregister(); |
|
1107 } |
|
1108 |
|
1109 /** |
|
1110 * Adds a new MIB in the SNMP MIB handler. |
|
1111 * |
|
1112 * @param mib The MIB to add. |
|
1113 * |
|
1114 * @return A reference to the SNMP MIB handler. |
|
1115 * |
|
1116 * @exception IllegalArgumentException If the parameter is null. |
|
1117 */ |
|
1118 @Override |
|
1119 public SnmpMibHandler addMib(SnmpMibAgent mib) |
|
1120 throws IllegalArgumentException { |
|
1121 if (mib == null) { |
|
1122 throw new IllegalArgumentException() ; |
|
1123 } |
|
1124 |
|
1125 if(!mibs.contains(mib)) |
|
1126 mibs.addElement(mib); |
|
1127 |
|
1128 root.register(mib); |
|
1129 |
|
1130 return this; |
|
1131 } |
|
1132 |
|
1133 /** |
|
1134 * Adds a new MIB in the SNMP MIB handler. |
|
1135 * This method is to be called to set a specific agent to a specific OID. |
|
1136 * This can be useful when dealing with MIB overlapping. |
|
1137 * Some OID can be implemented in more than one MIB. In this case, |
|
1138 * the OID nearer agent will be used on SNMP operations. |
|
1139 * |
|
1140 * @param mib The MIB to add. |
|
1141 * @param oids The set of OIDs this agent implements. |
|
1142 * |
|
1143 * @return A reference to the SNMP MIB handler. |
|
1144 * |
|
1145 * @exception IllegalArgumentException If the parameter is null. |
|
1146 * |
|
1147 * @since 1.5 |
|
1148 */ |
|
1149 @Override |
|
1150 public SnmpMibHandler addMib(SnmpMibAgent mib, SnmpOid[] oids) |
|
1151 throws IllegalArgumentException { |
|
1152 if (mib == null) { |
|
1153 throw new IllegalArgumentException() ; |
|
1154 } |
|
1155 |
|
1156 //If null oid array, just add it to the mib. |
|
1157 if(oids == null) |
|
1158 return addMib(mib); |
|
1159 |
|
1160 if(!mibs.contains(mib)) |
|
1161 mibs.addElement(mib); |
|
1162 |
|
1163 for (int i = 0; i < oids.length; i++) { |
|
1164 root.register(mib, oids[i].longValue()); |
|
1165 } |
|
1166 return this; |
|
1167 } |
|
1168 |
|
1169 /** |
|
1170 * Adds a new MIB in the SNMP MIB handler. In SNMP V1 and V2 the |
|
1171 * <CODE>contextName</CODE> is useless and this method |
|
1172 * is equivalent to <CODE>addMib(SnmpMibAgent mib)</CODE>. |
|
1173 * |
|
1174 * @param mib The MIB to add. |
|
1175 * @param contextName The MIB context name. |
|
1176 * @return A reference on the SNMP MIB handler. |
|
1177 * |
|
1178 * @exception IllegalArgumentException If the parameter is null. |
|
1179 * |
|
1180 * @since 1.5 |
|
1181 */ |
|
1182 @Override |
|
1183 public SnmpMibHandler addMib(SnmpMibAgent mib, String contextName) |
|
1184 throws IllegalArgumentException { |
|
1185 return addMib(mib); |
|
1186 } |
|
1187 |
|
1188 /** |
|
1189 * Adds a new MIB in the SNMP MIB handler. In SNMP V1 and V2 the |
|
1190 * <CODE>contextName</CODE> is useless and this method |
|
1191 * is equivalent to <CODE>addMib(SnmpMibAgent mib, SnmpOid[] oids)</CODE>. |
|
1192 * |
|
1193 * @param mib The MIB to add. |
|
1194 * @param contextName The MIB context. If null is passed, will be |
|
1195 * registered in the default context. |
|
1196 * @param oids The set of OIDs this agent implements. |
|
1197 * |
|
1198 * @return A reference to the SNMP MIB handler. |
|
1199 * |
|
1200 * @exception IllegalArgumentException If the parameter is null. |
|
1201 * |
|
1202 * @since 1.5 |
|
1203 */ |
|
1204 @Override |
|
1205 public SnmpMibHandler addMib(SnmpMibAgent mib, |
|
1206 String contextName, |
|
1207 SnmpOid[] oids) |
|
1208 throws IllegalArgumentException { |
|
1209 |
|
1210 return addMib(mib, oids); |
|
1211 } |
|
1212 |
|
1213 /** |
|
1214 * Removes the specified MIB from the SNMP protocol adaptor. |
|
1215 * In SNMP V1 and V2 the <CODE>contextName</CODE> is useless and this |
|
1216 * method is equivalent to <CODE>removeMib(SnmpMibAgent mib)</CODE>. |
|
1217 * |
|
1218 * @param mib The MIB to be removed. |
|
1219 * @param contextName The context name used at registration time. |
|
1220 * |
|
1221 * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was |
|
1222 * a MIB included in the SNMP MIB handler, <CODE>false</CODE> |
|
1223 * otherwise. |
|
1224 * |
|
1225 * @since 1.5 |
|
1226 */ |
|
1227 @Override |
|
1228 public boolean removeMib(SnmpMibAgent mib, String contextName) { |
|
1229 return removeMib(mib); |
|
1230 } |
|
1231 |
|
1232 /** |
|
1233 * Removes the specified MIB from the SNMP protocol adaptor. |
|
1234 * |
|
1235 * @param mib The MIB to be removed. |
|
1236 * |
|
1237 * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was a MIB |
|
1238 * included in the SNMP MIB handler, <CODE>false</CODE> otherwise. |
|
1239 */ |
|
1240 @Override |
|
1241 public boolean removeMib(SnmpMibAgent mib) { |
|
1242 root.unregister(mib); |
|
1243 return (mibs.removeElement(mib)) ; |
|
1244 } |
|
1245 |
|
1246 /** |
|
1247 * Removes the specified MIB from the SNMP protocol adaptor. |
|
1248 * |
|
1249 * @param mib The MIB to be removed. |
|
1250 * @param oids The oid the MIB was previously registered for. |
|
1251 * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was |
|
1252 * a MIB included in the SNMP MIB handler, <CODE>false</CODE> |
|
1253 * otherwise. |
|
1254 * |
|
1255 * @since 1.5 |
|
1256 */ |
|
1257 @Override |
|
1258 public boolean removeMib(SnmpMibAgent mib, SnmpOid[] oids) { |
|
1259 root.unregister(mib, oids); |
|
1260 return (mibs.removeElement(mib)) ; |
|
1261 } |
|
1262 |
|
1263 /** |
|
1264 * Removes the specified MIB from the SNMP protocol adaptor. |
|
1265 * |
|
1266 * @param mib The MIB to be removed. |
|
1267 * @param contextName The context name used at registration time. |
|
1268 * @param oids The oid the MIB was previously registered for. |
|
1269 * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was |
|
1270 * a MIB included in the SNMP MIB handler, <CODE>false</CODE> |
|
1271 * otherwise. |
|
1272 * |
|
1273 * @since 1.5 |
|
1274 */ |
|
1275 @Override |
|
1276 public boolean removeMib(SnmpMibAgent mib, |
|
1277 String contextName, |
|
1278 SnmpOid[] oids) { |
|
1279 return removeMib(mib, oids); |
|
1280 } |
|
1281 |
|
1282 // SUBCLASSING OF COMMUNICATOR SERVER |
|
1283 //----------------------------------- |
|
1284 |
|
1285 /** |
|
1286 * Creates the datagram socket. |
|
1287 */ |
|
1288 @Override |
|
1289 protected void doBind() |
|
1290 throws CommunicationException, InterruptedException { |
|
1291 |
|
1292 try { |
|
1293 synchronized (this) { |
|
1294 socket = new DatagramSocket(port, address) ; |
|
1295 } |
|
1296 dbgTag = makeDebugTag(); |
|
1297 } catch (SocketException e) { |
|
1298 if (e.getMessage().equals(InterruptSysCallMsg)) |
|
1299 throw new InterruptedException(e.toString()) ; |
|
1300 else { |
|
1301 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { |
|
1302 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag, |
|
1303 "doBind", "cannot bind on port " + port); |
|
1304 } |
|
1305 throw new CommunicationException(e) ; |
|
1306 } |
|
1307 } |
|
1308 } |
|
1309 |
|
1310 /** |
|
1311 * Return the actual port to which the adaptor is bound. |
|
1312 * Can be different from the port given at construction time if |
|
1313 * that port number was 0. |
|
1314 * @return the actual port to which the adaptor is bound. |
|
1315 **/ |
|
1316 @Override |
|
1317 public int getPort() { |
|
1318 synchronized (this) { |
|
1319 if (socket != null) return socket.getLocalPort(); |
|
1320 } |
|
1321 return super.getPort(); |
|
1322 } |
|
1323 |
|
1324 /** |
|
1325 * Closes the datagram socket. |
|
1326 */ |
|
1327 @Override |
|
1328 protected void doUnbind() |
|
1329 throws CommunicationException, InterruptedException { |
|
1330 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
1331 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
1332 "doUnbind","Finally close the socket"); |
|
1333 } |
|
1334 synchronized (this) { |
|
1335 if (socket != null) { |
|
1336 socket.close() ; |
|
1337 socket = null ; |
|
1338 // Important to inform finalize() that the socket is closed... |
|
1339 } |
|
1340 } |
|
1341 closeTrapSocketIfNeeded() ; |
|
1342 closeInformSocketIfNeeded() ; |
|
1343 } |
|
1344 |
|
1345 private void createSnmpRequestHandler(SnmpAdaptorServer server, |
|
1346 int id, |
|
1347 DatagramSocket s, |
|
1348 DatagramPacket p, |
|
1349 SnmpMibTree tree, |
|
1350 Vector<SnmpMibAgent> m, |
|
1351 InetAddressAcl a, |
|
1352 SnmpPduFactory factory, |
|
1353 SnmpUserDataFactory dataFactory, |
|
1354 MBeanServer f, |
|
1355 ObjectName n) { |
|
1356 final SnmpRequestHandler handler = |
|
1357 new SnmpRequestHandler(this, id, s, p, tree, m, a, factory, |
|
1358 dataFactory, f, n); |
|
1359 threadService.submitTask(handler); |
|
1360 } |
|
1361 |
|
1362 /** |
|
1363 * Reads a packet from the datagram socket and creates a request |
|
1364 * handler which decodes and processes the request. |
|
1365 */ |
|
1366 @Override |
|
1367 protected void doReceive() |
|
1368 throws CommunicationException, InterruptedException { |
|
1369 |
|
1370 // Let's wait for something to be received. |
|
1371 // |
|
1372 try { |
|
1373 packet = new DatagramPacket(new byte[bufferSize], bufferSize) ; |
|
1374 socket.receive(packet); |
|
1375 int state = getState(); |
|
1376 |
|
1377 if(state != ONLINE) { |
|
1378 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
1379 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
1380 "doReceive","received a message but state not online, returning."); |
|
1381 } |
|
1382 return; |
|
1383 } |
|
1384 |
|
1385 createSnmpRequestHandler(this, servedClientCount, socket, |
|
1386 packet, root, mibs, ipacl, pduFactory, |
|
1387 userDataFactory, topMBS, objectName); |
|
1388 } catch (SocketException e) { |
|
1389 // Let's check if we have been interrupted by stop(). |
|
1390 // |
|
1391 if (e.getMessage().equals(InterruptSysCallMsg)) |
|
1392 throw new InterruptedException(e.toString()) ; |
|
1393 else |
|
1394 throw new CommunicationException(e) ; |
|
1395 } catch (InterruptedIOException e) { |
|
1396 throw new InterruptedException(e.toString()) ; |
|
1397 } catch (CommunicationException e) { |
|
1398 throw e ; |
|
1399 } catch (Exception e) { |
|
1400 throw new CommunicationException(e) ; |
|
1401 } |
|
1402 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
1403 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
1404 "doReceive", "received a message"); |
|
1405 } |
|
1406 } |
|
1407 |
|
1408 @Override |
|
1409 protected void doError(Exception e) throws CommunicationException { |
|
1410 } |
|
1411 |
|
1412 /** |
|
1413 * Not used in this context. |
|
1414 */ |
|
1415 @Override |
|
1416 protected void doProcess() |
|
1417 throws CommunicationException, InterruptedException { |
|
1418 } |
|
1419 |
|
1420 |
|
1421 /** |
|
1422 * The number of times the communicator server will attempt |
|
1423 * to bind before giving up. |
|
1424 * We attempt only once... |
|
1425 * @return 1 |
|
1426 **/ |
|
1427 @Override |
|
1428 protected int getBindTries() { |
|
1429 return 1; |
|
1430 } |
|
1431 |
|
1432 /** |
|
1433 * Stops this SNMP protocol adaptor. |
|
1434 * Closes the datagram socket. |
|
1435 * <p> |
|
1436 * Has no effect if this SNMP protocol adaptor is <CODE>OFFLINE</CODE> or |
|
1437 * <CODE>STOPPING</CODE>. |
|
1438 */ |
|
1439 @Override |
|
1440 public void stop(){ |
|
1441 |
|
1442 final int port = getPort(); |
|
1443 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
1444 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
1445 "stop", "Stopping: using port " + port); |
|
1446 } |
|
1447 if ((state == ONLINE) || (state == STARTING)){ |
|
1448 super.stop(); |
|
1449 try { |
|
1450 DatagramSocket sn = new DatagramSocket(0); |
|
1451 try { |
|
1452 byte[] ob = new byte[1]; |
|
1453 |
|
1454 DatagramPacket pk; |
|
1455 if (address != null) |
|
1456 pk = new DatagramPacket(ob , 1, address, port); |
|
1457 else |
|
1458 pk = new DatagramPacket(ob , 1, |
|
1459 java.net.InetAddress.getLocalHost(), port); |
|
1460 |
|
1461 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
1462 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
1463 "stop", "Sending: using port " + port); |
|
1464 } |
|
1465 sn.send(pk); |
|
1466 } finally { |
|
1467 sn.close(); |
|
1468 } |
|
1469 } catch (Throwable e){ |
|
1470 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { |
|
1471 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag, |
|
1472 "stop", "Got unexpected Throwable", e); |
|
1473 } |
|
1474 } |
|
1475 } |
|
1476 } |
|
1477 |
|
1478 // SENDING SNMP TRAPS STUFF |
|
1479 //------------------------- |
|
1480 |
|
1481 /** |
|
1482 * Sends a trap using SNMP V1 trap format. |
|
1483 * <BR>The trap is sent to each destination defined in the ACL file |
|
1484 * (if available). |
|
1485 * If no ACL file or no destinations are available, the trap is sent |
|
1486 * to the local host. |
|
1487 * |
|
1488 * @param generic The generic number of the trap. |
|
1489 * @param specific The specific number of the trap. |
|
1490 * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null. |
|
1491 * |
|
1492 * @exception IOException An I/O error occurred while sending the trap. |
|
1493 * @exception SnmpStatusException If the trap exceeds the limit defined |
|
1494 * by <CODE>bufferSize</CODE>. |
|
1495 */ |
|
1496 @Override |
|
1497 public void snmpV1Trap(int generic, int specific, |
|
1498 SnmpVarBindList varBindList) |
|
1499 throws IOException, SnmpStatusException { |
|
1500 |
|
1501 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
1502 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
1503 "snmpV1Trap", "generic=" + generic + |
|
1504 ", specific=" + specific); |
|
1505 } |
|
1506 |
|
1507 // First, make an SNMP V1 trap pdu |
|
1508 // |
|
1509 SnmpPduTrap pdu = new SnmpPduTrap() ; |
|
1510 pdu.address = null ; |
|
1511 pdu.port = trapPort ; |
|
1512 pdu.type = pduV1TrapPdu ; |
|
1513 pdu.version = snmpVersionOne ; |
|
1514 pdu.community = null ; |
|
1515 pdu.enterprise = enterpriseOid ; |
|
1516 pdu.genericTrap = generic ; |
|
1517 pdu.specificTrap = specific ; |
|
1518 pdu.timeStamp = getSysUpTime(); |
|
1519 |
|
1520 if (varBindList != null) { |
|
1521 pdu.varBindList = new SnmpVarBind[varBindList.size()] ; |
|
1522 varBindList.copyInto(pdu.varBindList); |
|
1523 } |
|
1524 else |
|
1525 pdu.varBindList = null ; |
|
1526 |
|
1527 // If the local host cannot be determined, we put 0.0.0.0 in agentAddr |
|
1528 try { |
|
1529 if (address != null) |
|
1530 pdu.agentAddr = handleMultipleIpVersion(address.getAddress()); |
|
1531 else pdu.agentAddr = |
|
1532 handleMultipleIpVersion(InetAddress.getLocalHost().getAddress()); |
|
1533 } catch (UnknownHostException e) { |
|
1534 byte[] zeroedAddr = new byte[4]; |
|
1535 pdu.agentAddr = handleMultipleIpVersion(zeroedAddr) ; |
|
1536 } |
|
1537 |
|
1538 // Next, send the pdu to all destinations defined in ACL |
|
1539 // |
|
1540 sendTrapPdu(pdu) ; |
|
1541 } |
|
1542 |
|
1543 private SnmpIpAddress handleMultipleIpVersion(byte[] address) { |
|
1544 if(address.length == 4) |
|
1545 return new SnmpIpAddress(address); |
|
1546 else { |
|
1547 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { |
|
1548 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag, |
|
1549 "handleMultipleIPVersion", |
|
1550 "Not an IPv4 address, return null"); |
|
1551 } |
|
1552 return null; |
|
1553 } |
|
1554 } |
|
1555 |
|
1556 /** |
|
1557 * Sends a trap using SNMP V1 trap format. |
|
1558 * <BR>The trap is sent to the specified <CODE>InetAddress</CODE> |
|
1559 * destination using the specified community string (and the ACL file |
|
1560 * is not used). |
|
1561 * |
|
1562 * @param addr The <CODE>InetAddress</CODE> destination of the trap. |
|
1563 * @param cs The community string to be used for the trap. |
|
1564 * @param generic The generic number of the trap. |
|
1565 * @param specific The specific number of the trap. |
|
1566 * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null. |
|
1567 * |
|
1568 * @exception IOException An I/O error occurred while sending the trap. |
|
1569 * @exception SnmpStatusException If the trap exceeds the limit defined |
|
1570 * by <CODE>bufferSize</CODE>. |
|
1571 */ |
|
1572 @Override |
|
1573 public void snmpV1Trap(InetAddress addr, String cs, int generic, |
|
1574 int specific, SnmpVarBindList varBindList) |
|
1575 throws IOException, SnmpStatusException { |
|
1576 |
|
1577 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
1578 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
1579 "snmpV1Trap", "generic=" + generic + ", specific=" + |
|
1580 specific); |
|
1581 } |
|
1582 |
|
1583 // First, make an SNMP V1 trap pdu |
|
1584 // |
|
1585 SnmpPduTrap pdu = new SnmpPduTrap() ; |
|
1586 pdu.address = null ; |
|
1587 pdu.port = trapPort ; |
|
1588 pdu.type = pduV1TrapPdu ; |
|
1589 pdu.version = snmpVersionOne ; |
|
1590 |
|
1591 if(cs != null) |
|
1592 pdu.community = cs.getBytes(); |
|
1593 else |
|
1594 pdu.community = null ; |
|
1595 |
|
1596 pdu.enterprise = enterpriseOid ; |
|
1597 pdu.genericTrap = generic ; |
|
1598 pdu.specificTrap = specific ; |
|
1599 pdu.timeStamp = getSysUpTime(); |
|
1600 |
|
1601 if (varBindList != null) { |
|
1602 pdu.varBindList = new SnmpVarBind[varBindList.size()] ; |
|
1603 varBindList.copyInto(pdu.varBindList); |
|
1604 } |
|
1605 else |
|
1606 pdu.varBindList = null ; |
|
1607 |
|
1608 // If the local host cannot be determined, we put 0.0.0.0 in agentAddr |
|
1609 try { |
|
1610 if (address != null) |
|
1611 pdu.agentAddr = handleMultipleIpVersion(address.getAddress()); |
|
1612 else pdu.agentAddr = |
|
1613 handleMultipleIpVersion(InetAddress.getLocalHost().getAddress()); |
|
1614 } catch (UnknownHostException e) { |
|
1615 byte[] zeroedAddr = new byte[4]; |
|
1616 pdu.agentAddr = handleMultipleIpVersion(zeroedAddr) ; |
|
1617 } |
|
1618 |
|
1619 // Next, send the pdu to the specified destination |
|
1620 // |
|
1621 if(addr != null) |
|
1622 sendTrapPdu(addr, pdu) ; |
|
1623 else |
|
1624 sendTrapPdu(pdu); |
|
1625 } |
|
1626 |
|
1627 /** |
|
1628 * Sends a trap using SNMP V1 trap format. |
|
1629 * <BR>The trap is sent to the specified <CODE>InetAddress</CODE> |
|
1630 * destination using the specified parameters (and the ACL file is not |
|
1631 * used). |
|
1632 * Note that if the specified <CODE>InetAddress</CODE> destination is null, |
|
1633 * then the ACL file mechanism is used. |
|
1634 * |
|
1635 * @param addr The <CODE>InetAddress</CODE> destination of the trap. |
|
1636 * @param agentAddr The agent address to be used for the trap. |
|
1637 * @param cs The community string to be used for the trap. |
|
1638 * @param enterpOid The enterprise OID to be used for the trap. |
|
1639 * @param generic The generic number of the trap. |
|
1640 * @param specific The specific number of the trap. |
|
1641 * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null. |
|
1642 * @param time The time stamp (overwrite the current time). |
|
1643 * |
|
1644 * @exception IOException An I/O error occurred while sending the trap. |
|
1645 * @exception SnmpStatusException If the trap exceeds the limit defined |
|
1646 * by <CODE>bufferSize</CODE>. |
|
1647 * |
|
1648 * @since 1.5 |
|
1649 */ |
|
1650 public void snmpV1Trap(InetAddress addr, |
|
1651 SnmpIpAddress agentAddr, |
|
1652 String cs, |
|
1653 SnmpOid enterpOid, |
|
1654 int generic, |
|
1655 int specific, |
|
1656 SnmpVarBindList varBindList, |
|
1657 SnmpTimeticks time) |
|
1658 throws IOException, SnmpStatusException { |
|
1659 snmpV1Trap(addr, |
|
1660 trapPort, |
|
1661 agentAddr, |
|
1662 cs, |
|
1663 enterpOid, |
|
1664 generic, |
|
1665 specific, |
|
1666 varBindList, |
|
1667 time); |
|
1668 } |
|
1669 |
|
1670 /** |
|
1671 * Sends a trap using SNMP V1 trap format. |
|
1672 * <BR>The trap is sent to the specified <CODE>SnmpPeer</CODE> destination. |
|
1673 * The community string used is the one located in the |
|
1674 * <CODE>SnmpPeer</CODE> parameters |
|
1675 * (<CODE>SnmpParameters.getRdCommunity() </CODE>). |
|
1676 * |
|
1677 * @param peer The <CODE>SnmpPeer</CODE> destination of the trap. |
|
1678 * @param agentAddr The agent address to be used for the trap. |
|
1679 * @param enterpOid The enterprise OID to be used for the trap. |
|
1680 * @param generic The generic number of the trap. |
|
1681 * @param specific The specific number of the trap. |
|
1682 * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null. |
|
1683 * @param time The time stamp (overwrite the current time). |
|
1684 * |
|
1685 * @exception IOException An I/O error occurred while sending the trap. |
|
1686 * @exception SnmpStatusException If the trap exceeds the limit |
|
1687 * defined by <CODE>bufferSize</CODE>. |
|
1688 * |
|
1689 * @since 1.5 |
|
1690 */ |
|
1691 @Override |
|
1692 public void snmpV1Trap(SnmpPeer peer, |
|
1693 SnmpIpAddress agentAddr, |
|
1694 SnmpOid enterpOid, |
|
1695 int generic, |
|
1696 int specific, |
|
1697 SnmpVarBindList varBindList, |
|
1698 SnmpTimeticks time) |
|
1699 throws IOException, SnmpStatusException { |
|
1700 |
|
1701 SnmpParameters p = (SnmpParameters) peer.getParams(); |
|
1702 snmpV1Trap(peer.getDestAddr(), |
|
1703 peer.getDestPort(), |
|
1704 agentAddr, |
|
1705 p.getRdCommunity(), |
|
1706 enterpOid, |
|
1707 generic, |
|
1708 specific, |
|
1709 varBindList, |
|
1710 time); |
|
1711 } |
|
1712 |
|
1713 private void snmpV1Trap(InetAddress addr, |
|
1714 int port, |
|
1715 SnmpIpAddress agentAddr, |
|
1716 String cs, |
|
1717 SnmpOid enterpOid, |
|
1718 int generic, |
|
1719 int specific, |
|
1720 SnmpVarBindList varBindList, |
|
1721 SnmpTimeticks time) |
|
1722 throws IOException, SnmpStatusException { |
|
1723 |
|
1724 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
1725 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
1726 "snmpV1Trap", "generic=" + generic + ", specific=" + |
|
1727 specific); |
|
1728 } |
|
1729 |
|
1730 // First, make an SNMP V1 trap pdu |
|
1731 // |
|
1732 SnmpPduTrap pdu = new SnmpPduTrap() ; |
|
1733 pdu.address = null ; |
|
1734 pdu.port = port ; |
|
1735 pdu.type = pduV1TrapPdu ; |
|
1736 pdu.version = snmpVersionOne ; |
|
1737 |
|
1738 //Diff start |
|
1739 if(cs != null) |
|
1740 pdu.community = cs.getBytes(); |
|
1741 else |
|
1742 pdu.community = null ; |
|
1743 //Diff end |
|
1744 |
|
1745 // Diff start |
|
1746 if(enterpOid != null) |
|
1747 pdu.enterprise = enterpOid; |
|
1748 else |
|
1749 pdu.enterprise = enterpriseOid ; |
|
1750 //Diff end |
|
1751 pdu.genericTrap = generic ; |
|
1752 pdu.specificTrap = specific ; |
|
1753 //Diff start |
|
1754 if(time != null) |
|
1755 pdu.timeStamp = time.longValue(); |
|
1756 else |
|
1757 pdu.timeStamp = getSysUpTime(); |
|
1758 //Diff end |
|
1759 |
|
1760 if (varBindList != null) { |
|
1761 pdu.varBindList = new SnmpVarBind[varBindList.size()] ; |
|
1762 varBindList.copyInto(pdu.varBindList); |
|
1763 } |
|
1764 else |
|
1765 pdu.varBindList = null ; |
|
1766 |
|
1767 if (agentAddr == null) { |
|
1768 // If the local host cannot be determined, |
|
1769 // we put 0.0.0.0 in agentAddr |
|
1770 try { |
|
1771 final InetAddress inetAddr = |
|
1772 (address!=null)?address:InetAddress.getLocalHost(); |
|
1773 agentAddr = handleMultipleIpVersion(inetAddr.getAddress()); |
|
1774 } catch (UnknownHostException e) { |
|
1775 byte[] zeroedAddr = new byte[4]; |
|
1776 agentAddr = handleMultipleIpVersion(zeroedAddr); |
|
1777 } |
|
1778 } |
|
1779 |
|
1780 pdu.agentAddr = agentAddr; |
|
1781 |
|
1782 // Next, send the pdu to the specified destination |
|
1783 // |
|
1784 // Diff start |
|
1785 if(addr != null) |
|
1786 sendTrapPdu(addr, pdu) ; |
|
1787 else |
|
1788 sendTrapPdu(pdu); |
|
1789 |
|
1790 //End diff |
|
1791 } |
|
1792 |
|
1793 /** |
|
1794 * Sends a trap using SNMP V2 trap format. |
|
1795 * <BR>The trap is sent to the specified <CODE>SnmpPeer</CODE> destination. |
|
1796 * <BR>The community string used is the one located in the |
|
1797 * <CODE>SnmpPeer</CODE> parameters |
|
1798 * (<CODE>SnmpParameters.getRdCommunity() </CODE>). |
|
1799 * <BR>The variable list included in the outgoing trap is composed of |
|
1800 * the following items: |
|
1801 * <UL> |
|
1802 * <LI><CODE>sysUpTime.0</CODE> with the value specified by |
|
1803 * <CODE>time</CODE></LI> |
|
1804 * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by |
|
1805 * <CODE>trapOid</CODE></LI> |
|
1806 * <LI><CODE>all the (oid,values)</CODE> from the specified |
|
1807 * <CODE>varBindList</CODE></LI> |
|
1808 * </UL> |
|
1809 * |
|
1810 * @param peer The <CODE>SnmpPeer</CODE> destination of the trap. |
|
1811 * @param trapOid The OID identifying the trap. |
|
1812 * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null. |
|
1813 * @param time The time stamp (overwrite the current time). |
|
1814 * |
|
1815 * @exception IOException An I/O error occurred while sending the trap. |
|
1816 * @exception SnmpStatusException If the trap exceeds the limit |
|
1817 * defined by <CODE>bufferSize</CODE>. |
|
1818 * |
|
1819 * @since 1.5 |
|
1820 */ |
|
1821 @Override |
|
1822 public void snmpV2Trap(SnmpPeer peer, |
|
1823 SnmpOid trapOid, |
|
1824 SnmpVarBindList varBindList, |
|
1825 SnmpTimeticks time) |
|
1826 throws IOException, SnmpStatusException { |
|
1827 |
|
1828 SnmpParameters p = (SnmpParameters) peer.getParams(); |
|
1829 snmpV2Trap(peer.getDestAddr(), |
|
1830 peer.getDestPort(), |
|
1831 p.getRdCommunity(), |
|
1832 trapOid, |
|
1833 varBindList, |
|
1834 time); |
|
1835 } |
|
1836 |
|
1837 /** |
|
1838 * Sends a trap using SNMP V2 trap format. |
|
1839 * <BR>The trap is sent to each destination defined in the ACL file |
|
1840 * (if available). If no ACL file or no destinations are available, |
|
1841 * the trap is sent to the local host. |
|
1842 * <BR>The variable list included in the outgoing trap is composed of |
|
1843 * the following items: |
|
1844 * <UL> |
|
1845 * <LI><CODE>sysUpTime.0</CODE> with its current value</LI> |
|
1846 * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by |
|
1847 * <CODE>trapOid</CODE></LI> |
|
1848 * <LI><CODE>all the (oid,values)</CODE> from the specified |
|
1849 * <CODE>varBindList</CODE></LI> |
|
1850 * </UL> |
|
1851 * |
|
1852 * @param trapOid The OID identifying the trap. |
|
1853 * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null. |
|
1854 * |
|
1855 * @exception IOException An I/O error occurred while sending the trap. |
|
1856 * @exception SnmpStatusException If the trap exceeds the limit defined |
|
1857 * by <CODE>bufferSize</CODE>. |
|
1858 */ |
|
1859 @Override |
|
1860 public void snmpV2Trap(SnmpOid trapOid, SnmpVarBindList varBindList) |
|
1861 throws IOException, SnmpStatusException { |
|
1862 |
|
1863 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
1864 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
1865 "snmpV2Trap", "trapOid=" + trapOid); |
|
1866 } |
|
1867 |
|
1868 // First, make an SNMP V2 trap pdu |
|
1869 // We clone varBindList and insert sysUpTime and snmpTrapOid |
|
1870 // |
|
1871 SnmpPduRequest pdu = new SnmpPduRequest() ; |
|
1872 pdu.address = null ; |
|
1873 pdu.port = trapPort ; |
|
1874 pdu.type = pduV2TrapPdu ; |
|
1875 pdu.version = snmpVersionTwo ; |
|
1876 pdu.community = null ; |
|
1877 |
|
1878 SnmpVarBindList fullVbl ; |
|
1879 if (varBindList != null) |
|
1880 fullVbl = varBindList.clone() ; |
|
1881 else |
|
1882 fullVbl = new SnmpVarBindList(2) ; |
|
1883 SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ; |
|
1884 fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ; |
|
1885 fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue), |
|
1886 0); |
|
1887 pdu.varBindList = new SnmpVarBind[fullVbl.size()] ; |
|
1888 fullVbl.copyInto(pdu.varBindList) ; |
|
1889 |
|
1890 // Next, send the pdu to all destinations defined in ACL |
|
1891 // |
|
1892 sendTrapPdu(pdu) ; |
|
1893 } |
|
1894 |
|
1895 /** |
|
1896 * Sends a trap using SNMP V2 trap format. |
|
1897 * <BR>The trap is sent to the specified <CODE>InetAddress</CODE> |
|
1898 * destination using the specified community string (and the ACL file |
|
1899 * is not used). |
|
1900 * <BR>The variable list included in the outgoing trap is composed of |
|
1901 * the following items: |
|
1902 * <UL> |
|
1903 * <LI><CODE>sysUpTime.0</CODE> with its current value</LI> |
|
1904 * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by |
|
1905 * <CODE>trapOid</CODE></LI> |
|
1906 * <LI><CODE>all the (oid,values)</CODE> from the specified |
|
1907 * <CODE>varBindList</CODE></LI> |
|
1908 * </UL> |
|
1909 * |
|
1910 * @param addr The <CODE>InetAddress</CODE> destination of the trap. |
|
1911 * @param cs The community string to be used for the trap. |
|
1912 * @param trapOid The OID identifying the trap. |
|
1913 * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null. |
|
1914 * |
|
1915 * @exception IOException An I/O error occurred while sending the trap. |
|
1916 * @exception SnmpStatusException If the trap exceeds the limit |
|
1917 * defined by <CODE>bufferSize</CODE>. |
|
1918 */ |
|
1919 @Override |
|
1920 public void snmpV2Trap(InetAddress addr, String cs, SnmpOid trapOid, |
|
1921 SnmpVarBindList varBindList) |
|
1922 throws IOException, SnmpStatusException { |
|
1923 |
|
1924 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
1925 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
1926 "snmpV2Trap", "trapOid=" + trapOid); |
|
1927 } |
|
1928 |
|
1929 // First, make an SNMP V2 trap pdu |
|
1930 // We clone varBindList and insert sysUpTime and snmpTrapOid |
|
1931 // |
|
1932 SnmpPduRequest pdu = new SnmpPduRequest() ; |
|
1933 pdu.address = null ; |
|
1934 pdu.port = trapPort ; |
|
1935 pdu.type = pduV2TrapPdu ; |
|
1936 pdu.version = snmpVersionTwo ; |
|
1937 |
|
1938 if(cs != null) |
|
1939 pdu.community = cs.getBytes(); |
|
1940 else |
|
1941 pdu.community = null; |
|
1942 |
|
1943 SnmpVarBindList fullVbl ; |
|
1944 if (varBindList != null) |
|
1945 fullVbl = varBindList.clone() ; |
|
1946 else |
|
1947 fullVbl = new SnmpVarBindList(2) ; |
|
1948 SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ; |
|
1949 fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ; |
|
1950 fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue), |
|
1951 0); |
|
1952 pdu.varBindList = new SnmpVarBind[fullVbl.size()] ; |
|
1953 fullVbl.copyInto(pdu.varBindList) ; |
|
1954 |
|
1955 // Next, send the pdu to the specified destination |
|
1956 // |
|
1957 if(addr != null) |
|
1958 sendTrapPdu(addr, pdu); |
|
1959 else |
|
1960 sendTrapPdu(pdu); |
|
1961 } |
|
1962 |
|
1963 /** |
|
1964 * Sends a trap using SNMP V2 trap format. |
|
1965 * <BR>The trap is sent to the specified <CODE>InetAddress</CODE> |
|
1966 * destination using the specified parameters (and the ACL file is not |
|
1967 * used). |
|
1968 * Note that if the specified <CODE>InetAddress</CODE> destination is null, |
|
1969 * then the ACL file mechanism is used. |
|
1970 * <BR>The variable list included in the outgoing trap is composed of the |
|
1971 * following items: |
|
1972 * <UL> |
|
1973 * <LI><CODE>sysUpTime.0</CODE> with the value specified by |
|
1974 * <CODE>time</CODE></LI> |
|
1975 * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by |
|
1976 * <CODE>trapOid</CODE></LI> |
|
1977 * <LI><CODE>all the (oid,values)</CODE> from the specified |
|
1978 * <CODE>varBindList</CODE></LI> |
|
1979 * </UL> |
|
1980 * |
|
1981 * @param addr The <CODE>InetAddress</CODE> destination of the trap. |
|
1982 * @param cs The community string to be used for the trap. |
|
1983 * @param trapOid The OID identifying the trap. |
|
1984 * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null. |
|
1985 * @param time The time stamp (overwrite the current time). |
|
1986 * |
|
1987 * @exception IOException An I/O error occurred while sending the trap. |
|
1988 * @exception SnmpStatusException If the trap exceeds the limit |
|
1989 * defined by <CODE>bufferSize</CODE>. |
|
1990 * |
|
1991 * @since 1.5 |
|
1992 */ |
|
1993 public void snmpV2Trap(InetAddress addr, |
|
1994 String cs, |
|
1995 SnmpOid trapOid, |
|
1996 SnmpVarBindList varBindList, |
|
1997 SnmpTimeticks time) |
|
1998 throws IOException, SnmpStatusException { |
|
1999 |
|
2000 snmpV2Trap(addr, |
|
2001 trapPort, |
|
2002 cs, |
|
2003 trapOid, |
|
2004 varBindList, |
|
2005 time); |
|
2006 } |
|
2007 |
|
2008 private void snmpV2Trap(InetAddress addr, |
|
2009 int port, |
|
2010 String cs, |
|
2011 SnmpOid trapOid, |
|
2012 SnmpVarBindList varBindList, |
|
2013 SnmpTimeticks time) |
|
2014 throws IOException, SnmpStatusException { |
|
2015 |
|
2016 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
2017 final StringBuilder strb = new StringBuilder() |
|
2018 .append("trapOid=").append(trapOid) |
|
2019 .append("\ncommunity=").append(cs) |
|
2020 .append("\naddr=").append(addr) |
|
2021 .append("\nvarBindList=").append(varBindList) |
|
2022 .append("\ntime=").append(time) |
|
2023 .append("\ntrapPort=").append(port); |
|
2024 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
2025 "snmpV2Trap", strb.toString()); |
|
2026 } |
|
2027 |
|
2028 // First, make an SNMP V2 trap pdu |
|
2029 // We clone varBindList and insert sysUpTime and snmpTrapOid |
|
2030 // |
|
2031 SnmpPduRequest pdu = new SnmpPduRequest() ; |
|
2032 pdu.address = null ; |
|
2033 pdu.port = port ; |
|
2034 pdu.type = pduV2TrapPdu ; |
|
2035 pdu.version = snmpVersionTwo ; |
|
2036 |
|
2037 if(cs != null) |
|
2038 pdu.community = cs.getBytes(); |
|
2039 else |
|
2040 pdu.community = null; |
|
2041 |
|
2042 SnmpVarBindList fullVbl ; |
|
2043 if (varBindList != null) |
|
2044 fullVbl = varBindList.clone() ; |
|
2045 else |
|
2046 fullVbl = new SnmpVarBindList(2) ; |
|
2047 |
|
2048 // Only difference with other |
|
2049 SnmpTimeticks sysUpTimeValue; |
|
2050 if(time != null) |
|
2051 sysUpTimeValue = time; |
|
2052 else |
|
2053 sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ; |
|
2054 //End of diff |
|
2055 |
|
2056 fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ; |
|
2057 fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue), |
|
2058 0); |
|
2059 pdu.varBindList = new SnmpVarBind[fullVbl.size()] ; |
|
2060 fullVbl.copyInto(pdu.varBindList) ; |
|
2061 |
|
2062 // Next, send the pdu to the specified destination |
|
2063 // |
|
2064 // Diff start |
|
2065 if(addr != null) |
|
2066 sendTrapPdu(addr, pdu) ; |
|
2067 else |
|
2068 sendTrapPdu(pdu); |
|
2069 //End diff |
|
2070 } |
|
2071 |
|
2072 /** |
|
2073 * Send the specified trap PDU to the passed <CODE>InetAddress</CODE>. |
|
2074 * @param address The destination address. |
|
2075 * @param pdu The pdu to send. |
|
2076 * @exception IOException An I/O error occurred while sending the trap. |
|
2077 * @exception SnmpStatusException If the trap exceeds the limit |
|
2078 * defined by <CODE>bufferSize</CODE>. |
|
2079 * |
|
2080 * @since 1.5 |
|
2081 */ |
|
2082 @Override |
|
2083 public void snmpPduTrap(InetAddress address, SnmpPduPacket pdu) |
|
2084 throws IOException, SnmpStatusException { |
|
2085 |
|
2086 if(address != null) |
|
2087 sendTrapPdu(address, pdu); |
|
2088 else |
|
2089 sendTrapPdu(pdu); |
|
2090 } |
|
2091 |
|
2092 /** |
|
2093 * Send the specified trap PDU to the passed <CODE>SnmpPeer</CODE>. |
|
2094 * @param peer The destination peer. The Read community string is used of |
|
2095 * <CODE>SnmpParameters</CODE> is used as the trap community string. |
|
2096 * @param pdu The pdu to send. |
|
2097 * @exception IOException An I/O error occurred while sending the trap. |
|
2098 * @exception SnmpStatusException If the trap exceeds the limit defined |
|
2099 * by <CODE>bufferSize</CODE>. |
|
2100 * @since 1.5 |
|
2101 */ |
|
2102 @Override |
|
2103 public void snmpPduTrap(SnmpPeer peer, |
|
2104 SnmpPduPacket pdu) |
|
2105 throws IOException, SnmpStatusException { |
|
2106 if(peer != null) { |
|
2107 pdu.port = peer.getDestPort(); |
|
2108 sendTrapPdu(peer.getDestAddr(), pdu); |
|
2109 } |
|
2110 else { |
|
2111 pdu.port = getTrapPort().intValue(); |
|
2112 sendTrapPdu(pdu); |
|
2113 } |
|
2114 } |
|
2115 |
|
2116 /** |
|
2117 * Send the specified trap PDU to every destinations from the ACL file. |
|
2118 */ |
|
2119 private void sendTrapPdu(SnmpPduPacket pdu) |
|
2120 throws SnmpStatusException, IOException { |
|
2121 |
|
2122 // Make an SNMP message from the pdu |
|
2123 // |
|
2124 SnmpMessage msg = null ; |
|
2125 try { |
|
2126 msg = (SnmpMessage)pduFactory.encodeSnmpPdu(pdu, bufferSize) ; |
|
2127 if (msg == null) { |
|
2128 throw new SnmpStatusException( |
|
2129 SnmpDefinitions.snmpRspAuthorizationError) ; |
|
2130 } |
|
2131 } |
|
2132 catch (SnmpTooBigException x) { |
|
2133 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { |
|
2134 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag, |
|
2135 "sendTrapPdu", "Trap pdu is too big. " + |
|
2136 "Trap hasn't been sent to anyone" ); |
|
2137 } |
|
2138 throw new SnmpStatusException(SnmpDefinitions.snmpRspTooBig) ; |
|
2139 // FIXME: is the right exception to throw ? |
|
2140 // We could simply forward SnmpTooBigException ? |
|
2141 } |
|
2142 |
|
2143 // Now send the SNMP message to each destination |
|
2144 // |
|
2145 int sendingCount = 0 ; |
|
2146 openTrapSocketIfNeeded() ; |
|
2147 if (ipacl != null) { |
|
2148 Enumeration<InetAddress> ed = ipacl.getTrapDestinations() ; |
|
2149 while (ed.hasMoreElements()) { |
|
2150 msg.address = ed.nextElement() ; |
|
2151 Enumeration<String> ec = ipacl.getTrapCommunities(msg.address) ; |
|
2152 while (ec.hasMoreElements()) { |
|
2153 msg.community = ec.nextElement().getBytes() ; |
|
2154 try { |
|
2155 sendTrapMessage(msg) ; |
|
2156 sendingCount++ ; |
|
2157 } |
|
2158 catch (SnmpTooBigException x) { |
|
2159 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { |
|
2160 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag, |
|
2161 "sendTrapPdu", "Trap pdu is too big. " + |
|
2162 "Trap hasn't been sent to "+msg.address); |
|
2163 } |
|
2164 } |
|
2165 } |
|
2166 } |
|
2167 } |
|
2168 |
|
2169 // If there is no destination defined or if everything has failed |
|
2170 // we tried to send the trap to the local host (as suggested by |
|
2171 // mister Olivier Reisacher). |
|
2172 // |
|
2173 if (sendingCount == 0) { |
|
2174 try { |
|
2175 msg.address = InetAddress.getLocalHost() ; |
|
2176 sendTrapMessage(msg) ; |
|
2177 } catch (SnmpTooBigException x) { |
|
2178 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { |
|
2179 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag, |
|
2180 "sendTrapPdu", "Trap pdu is too big. " + |
|
2181 "Trap hasn't been sent."); |
|
2182 } |
|
2183 } catch (UnknownHostException e) { |
|
2184 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { |
|
2185 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag, |
|
2186 "sendTrapPdu", "Trap pdu is too big. " + |
|
2187 "Trap hasn't been sent."); |
|
2188 } |
|
2189 } |
|
2190 } |
|
2191 |
|
2192 closeTrapSocketIfNeeded() ; |
|
2193 } |
|
2194 |
|
2195 /** |
|
2196 * Send the specified trap PDU to the specified destination. |
|
2197 */ |
|
2198 private void sendTrapPdu(InetAddress addr, SnmpPduPacket pdu) |
|
2199 throws SnmpStatusException, IOException { |
|
2200 |
|
2201 // Make an SNMP message from the pdu |
|
2202 // |
|
2203 SnmpMessage msg = null ; |
|
2204 try { |
|
2205 msg = (SnmpMessage)pduFactory.encodeSnmpPdu(pdu, bufferSize) ; |
|
2206 if (msg == null) { |
|
2207 throw new SnmpStatusException( |
|
2208 SnmpDefinitions.snmpRspAuthorizationError) ; |
|
2209 } |
|
2210 } catch (SnmpTooBigException x) { |
|
2211 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { |
|
2212 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag, |
|
2213 "sendTrapPdu", "Trap pdu is too big. " + |
|
2214 "Trap hasn't been sent to the specified host."); |
|
2215 } |
|
2216 throw new SnmpStatusException(SnmpDefinitions.snmpRspTooBig) ; |
|
2217 // FIXME: is the right exception to throw ? |
|
2218 // We could simply forward SnmpTooBigException ? |
|
2219 } |
|
2220 |
|
2221 // Now send the SNMP message to specified destination |
|
2222 // |
|
2223 openTrapSocketIfNeeded() ; |
|
2224 if (addr != null) { |
|
2225 msg.address = addr; |
|
2226 try { |
|
2227 sendTrapMessage(msg) ; |
|
2228 } catch (SnmpTooBigException x) { |
|
2229 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { |
|
2230 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag, |
|
2231 "sendTrapPdu", "Trap pdu is too big. " + |
|
2232 "Trap hasn't been sent to " + msg.address); |
|
2233 } |
|
2234 } |
|
2235 } |
|
2236 |
|
2237 closeTrapSocketIfNeeded() ; |
|
2238 } |
|
2239 |
|
2240 /** |
|
2241 * Send the specified message on trapSocket. |
|
2242 */ |
|
2243 private void sendTrapMessage(SnmpMessage msg) |
|
2244 throws IOException, SnmpTooBigException { |
|
2245 |
|
2246 byte[] buffer = new byte[bufferSize] ; |
|
2247 DatagramPacket packet = new DatagramPacket(buffer, buffer.length) ; |
|
2248 int encodingLength = msg.encodeMessage(buffer) ; |
|
2249 packet.setLength(encodingLength) ; |
|
2250 packet.setAddress(msg.address) ; |
|
2251 packet.setPort(msg.port) ; |
|
2252 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
2253 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
2254 "sendTrapMessage", "sending trap to " + msg.address + ":" + |
|
2255 msg.port); |
|
2256 } |
|
2257 trapSocket.send(packet) ; |
|
2258 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
2259 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
2260 "sendTrapMessage", "sent to " + msg.address + ":" + |
|
2261 msg.port); |
|
2262 } |
|
2263 snmpOutTraps++; |
|
2264 snmpOutPkts++; |
|
2265 } |
|
2266 |
|
2267 /** |
|
2268 * Open trapSocket if it's not already done. |
|
2269 */ |
|
2270 synchronized void openTrapSocketIfNeeded() throws SocketException { |
|
2271 if (trapSocket == null) { |
|
2272 trapSocket = new DatagramSocket(0, address) ; |
|
2273 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
2274 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
2275 "openTrapSocketIfNeeded", "using port " + |
|
2276 trapSocket.getLocalPort() + " to send traps"); |
|
2277 } |
|
2278 } |
|
2279 } |
|
2280 |
|
2281 /** |
|
2282 * Close trapSocket if the SNMP protocol adaptor is not ONLINE. |
|
2283 */ |
|
2284 synchronized void closeTrapSocketIfNeeded() { |
|
2285 if ((trapSocket != null) && (state != ONLINE)) { |
|
2286 trapSocket.close() ; |
|
2287 trapSocket = null ; |
|
2288 } |
|
2289 } |
|
2290 |
|
2291 // SENDING SNMP INFORMS STUFF |
|
2292 //--------------------------- |
|
2293 |
|
2294 /** |
|
2295 * Sends an inform using SNMP V2 inform request format. |
|
2296 * <BR>The inform request is sent to each destination defined in the ACL |
|
2297 * file (if available). |
|
2298 * If no ACL file or no destinations are available, the inform request is |
|
2299 * sent to the local host. |
|
2300 * <BR>The variable list included in the outgoing inform is composed of |
|
2301 * the following items: |
|
2302 * <UL> |
|
2303 * <LI><CODE>sysUpTime.0</CODE> with its current value</LI> |
|
2304 * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by |
|
2305 * <CODE>trapOid</CODE></LI> |
|
2306 * <LI><CODE>all the (oid,values)</CODE> from the specified |
|
2307 * <CODE>varBindList</CODE></LI> |
|
2308 * </UL> |
|
2309 * To send an inform request, the SNMP adaptor server must be active. |
|
2310 * |
|
2311 * @param cb The callback that is invoked when a request is complete. |
|
2312 * @param trapOid The OID identifying the trap. |
|
2313 * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null. |
|
2314 * |
|
2315 * @return A vector of {@link com.sun.jmx.snmp.daemon.SnmpInformRequest} |
|
2316 * objects. |
|
2317 * <P>If there is no destination host for this inform request, |
|
2318 * the returned vector will be empty. |
|
2319 * |
|
2320 * @exception IllegalStateException This method has been invoked while |
|
2321 * the SNMP adaptor server was not active. |
|
2322 * @exception IOException An I/O error occurred while sending the |
|
2323 * inform request. |
|
2324 * @exception SnmpStatusException If the inform request exceeds the |
|
2325 * limit defined by <CODE>bufferSize</CODE>. |
|
2326 */ |
|
2327 @Override |
|
2328 public Vector<SnmpInformRequest> snmpInformRequest(SnmpInformHandler cb, |
|
2329 SnmpOid trapOid, |
|
2330 SnmpVarBindList varBindList) |
|
2331 throws IllegalStateException, IOException, SnmpStatusException { |
|
2332 |
|
2333 if (!isActive()) { |
|
2334 throw new IllegalStateException( |
|
2335 "Start SNMP adaptor server before carrying out this operation"); |
|
2336 } |
|
2337 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
2338 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
2339 "snmpInformRequest", "trapOid=" + trapOid); |
|
2340 } |
|
2341 |
|
2342 // First, make an SNMP inform pdu: |
|
2343 // We clone varBindList and insert sysUpTime and snmpTrapOid variables. |
|
2344 // |
|
2345 SnmpVarBindList fullVbl ; |
|
2346 if (varBindList != null) |
|
2347 fullVbl = varBindList.clone() ; |
|
2348 else |
|
2349 fullVbl = new SnmpVarBindList(2) ; |
|
2350 SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ; |
|
2351 fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ; |
|
2352 fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue), |
|
2353 0); |
|
2354 |
|
2355 // Next, send the pdu to the specified destination |
|
2356 // |
|
2357 openInformSocketIfNeeded() ; |
|
2358 |
|
2359 // Now send the SNMP message to each destination |
|
2360 // |
|
2361 Vector<SnmpInformRequest> informReqList = new Vector<>(); |
|
2362 InetAddress addr; |
|
2363 String cs; |
|
2364 if (ipacl != null) { |
|
2365 Enumeration<InetAddress> ed = ipacl.getInformDestinations() ; |
|
2366 while (ed.hasMoreElements()) { |
|
2367 addr = ed.nextElement() ; |
|
2368 Enumeration<String> ec = ipacl.getInformCommunities(addr) ; |
|
2369 while (ec.hasMoreElements()) { |
|
2370 cs = ec.nextElement() ; |
|
2371 informReqList.addElement( |
|
2372 informSession.makeAsyncRequest(addr, cs, cb, |
|
2373 fullVbl,getInformPort())) ; |
|
2374 } |
|
2375 } |
|
2376 } |
|
2377 |
|
2378 return informReqList ; |
|
2379 } |
|
2380 |
|
2381 /** |
|
2382 * Sends an inform using SNMP V2 inform request format. |
|
2383 * <BR>The inform is sent to the specified <CODE>InetAddress</CODE> |
|
2384 * destination |
|
2385 * using the specified community string. |
|
2386 * <BR>The variable list included in the outgoing inform is composed |
|
2387 * of the following items: |
|
2388 * <UL> |
|
2389 * <LI><CODE>sysUpTime.0</CODE> with its current value</LI> |
|
2390 * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by |
|
2391 * <CODE>trapOid</CODE></LI> |
|
2392 * <LI><CODE>all the (oid,values)</CODE> from the specified |
|
2393 * <CODE>varBindList</CODE></LI> |
|
2394 * </UL> |
|
2395 * To send an inform request, the SNMP adaptor server must be active. |
|
2396 * |
|
2397 * @param addr The <CODE>InetAddress</CODE> destination for this inform |
|
2398 * request. |
|
2399 * @param cs The community string to be used for the inform request. |
|
2400 * @param cb The callback that is invoked when a request is complete. |
|
2401 * @param trapOid The OID identifying the trap. |
|
2402 * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null. |
|
2403 * |
|
2404 * @return The inform request object. |
|
2405 * |
|
2406 * @exception IllegalStateException This method has been invoked |
|
2407 * while the SNMP adaptor server was not active. |
|
2408 * @exception IOException An I/O error occurred while sending the |
|
2409 * inform request. |
|
2410 * @exception SnmpStatusException If the inform request exceeds the |
|
2411 * limit defined by <CODE>bufferSize</CODE>. |
|
2412 */ |
|
2413 @Override |
|
2414 public SnmpInformRequest snmpInformRequest(InetAddress addr, |
|
2415 String cs, |
|
2416 SnmpInformHandler cb, |
|
2417 SnmpOid trapOid, |
|
2418 SnmpVarBindList varBindList) |
|
2419 throws IllegalStateException, IOException, SnmpStatusException { |
|
2420 |
|
2421 return snmpInformRequest(addr, |
|
2422 getInformPort(), |
|
2423 cs, |
|
2424 cb, |
|
2425 trapOid, |
|
2426 varBindList); |
|
2427 } |
|
2428 |
|
2429 /** |
|
2430 * Sends an inform using SNMP V2 inform request format. |
|
2431 * <BR>The inform is sent to the specified <CODE>SnmpPeer</CODE> |
|
2432 * destination. |
|
2433 * <BR>The community string used is the one located in the |
|
2434 * <CODE>SnmpPeer</CODE> parameters |
|
2435 * (<CODE>SnmpParameters.getInformCommunity() </CODE>). |
|
2436 * <BR>The variable list included in the outgoing inform is composed |
|
2437 * of the following items: |
|
2438 * <UL> |
|
2439 * <LI><CODE>sysUpTime.0</CODE> with its current value</LI> |
|
2440 * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by |
|
2441 * <CODE>trapOid</CODE></LI> |
|
2442 * <LI><CODE>all the (oid,values)</CODE> from the specified |
|
2443 * <CODE>varBindList</CODE></LI> |
|
2444 * </UL> |
|
2445 * To send an inform request, the SNMP adaptor server must be active. |
|
2446 * |
|
2447 * @param peer The <CODE>SnmpPeer</CODE> destination for this inform |
|
2448 * request. |
|
2449 * @param cb The callback that is invoked when a request is complete. |
|
2450 * @param trapOid The OID identifying the trap. |
|
2451 * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null. |
|
2452 * |
|
2453 * @return The inform request object. |
|
2454 * |
|
2455 * @exception IllegalStateException This method has been invoked while |
|
2456 * the SNMP adaptor server was not active. |
|
2457 * @exception IOException An I/O error occurred while sending the |
|
2458 * inform request. |
|
2459 * @exception SnmpStatusException If the inform request exceeds the |
|
2460 * limit defined by <CODE>bufferSize</CODE>. |
|
2461 * |
|
2462 * @since 1.5 |
|
2463 */ |
|
2464 @Override |
|
2465 public SnmpInformRequest snmpInformRequest(SnmpPeer peer, |
|
2466 SnmpInformHandler cb, |
|
2467 SnmpOid trapOid, |
|
2468 SnmpVarBindList varBindList) |
|
2469 throws IllegalStateException, IOException, SnmpStatusException { |
|
2470 |
|
2471 SnmpParameters p = (SnmpParameters) peer.getParams(); |
|
2472 return snmpInformRequest(peer.getDestAddr(), |
|
2473 peer.getDestPort(), |
|
2474 p.getInformCommunity(), |
|
2475 cb, |
|
2476 trapOid, |
|
2477 varBindList); |
|
2478 } |
|
2479 |
|
2480 /** |
|
2481 * Method that maps an SNMP error status in the passed protocolVersion |
|
2482 * according to the provided pdu type. |
|
2483 * @param errorStatus The error status to convert. |
|
2484 * @param protocolVersion The protocol version. |
|
2485 * @param reqPduType The pdu type. |
|
2486 */ |
|
2487 public static int mapErrorStatus(int errorStatus, |
|
2488 int protocolVersion, |
|
2489 int reqPduType) { |
|
2490 return SnmpSubRequestHandler.mapErrorStatus(errorStatus, |
|
2491 protocolVersion, |
|
2492 reqPduType); |
|
2493 } |
|
2494 |
|
2495 private SnmpInformRequest snmpInformRequest(InetAddress addr, |
|
2496 int port, |
|
2497 String cs, |
|
2498 SnmpInformHandler cb, |
|
2499 SnmpOid trapOid, |
|
2500 SnmpVarBindList varBindList) |
|
2501 throws IllegalStateException, IOException, SnmpStatusException { |
|
2502 |
|
2503 if (!isActive()) { |
|
2504 throw new IllegalStateException( |
|
2505 "Start SNMP adaptor server before carrying out this operation"); |
|
2506 } |
|
2507 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
2508 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
2509 "snmpInformRequest", "trapOid=" + trapOid); |
|
2510 } |
|
2511 |
|
2512 // First, make an SNMP inform pdu: |
|
2513 // We clone varBindList and insert sysUpTime and snmpTrapOid variables. |
|
2514 // |
|
2515 SnmpVarBindList fullVbl ; |
|
2516 if (varBindList != null) |
|
2517 fullVbl = varBindList.clone() ; |
|
2518 else |
|
2519 fullVbl = new SnmpVarBindList(2) ; |
|
2520 SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ; |
|
2521 fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ; |
|
2522 fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue), |
|
2523 0); |
|
2524 |
|
2525 // Next, send the pdu to the specified destination |
|
2526 // |
|
2527 openInformSocketIfNeeded() ; |
|
2528 return informSession.makeAsyncRequest(addr, cs, cb, fullVbl, port) ; |
|
2529 } |
|
2530 |
|
2531 |
|
2532 /** |
|
2533 * Open informSocket if it's not already done. |
|
2534 */ |
|
2535 synchronized void openInformSocketIfNeeded() throws SocketException { |
|
2536 if (informSession == null) { |
|
2537 informSession = new SnmpSession(this) ; |
|
2538 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
2539 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
2540 "openInformSocketIfNeeded", |
|
2541 "to send inform requests and receive inform responses"); |
|
2542 } |
|
2543 } |
|
2544 } |
|
2545 |
|
2546 /** |
|
2547 * Close informSocket if the SNMP protocol adaptor is not ONLINE. |
|
2548 */ |
|
2549 synchronized void closeInformSocketIfNeeded() { |
|
2550 if ((informSession != null) && (state != ONLINE)) { |
|
2551 informSession.destroySession() ; |
|
2552 informSession = null ; |
|
2553 } |
|
2554 } |
|
2555 |
|
2556 /** |
|
2557 * Gets the IP address to bind. |
|
2558 * This getter is used to initialize the DatagramSocket in the |
|
2559 * SnmpSocket object created for the inform request stuff. |
|
2560 */ |
|
2561 InetAddress getAddress() { |
|
2562 return address; |
|
2563 } |
|
2564 |
|
2565 |
|
2566 // PROTECTED METHODS |
|
2567 //------------------ |
|
2568 |
|
2569 /** |
|
2570 * Finalizer of the SNMP protocol adaptor objects. |
|
2571 * This method is called by the garbage collector on an object |
|
2572 * when garbage collection determines that there are no more |
|
2573 * references to the object. |
|
2574 * <P>Closes the datagram socket associated to this SNMP protocol adaptor. |
|
2575 */ |
|
2576 @Override |
|
2577 protected void finalize() { |
|
2578 try { |
|
2579 if (socket != null) { |
|
2580 socket.close() ; |
|
2581 socket = null ; |
|
2582 } |
|
2583 |
|
2584 threadService.terminate(); |
|
2585 } catch (Exception e) { |
|
2586 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { |
|
2587 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag, |
|
2588 "finalize", "Exception in finalizer", e); |
|
2589 } |
|
2590 } |
|
2591 } |
|
2592 |
|
2593 // PACKAGE METHODS |
|
2594 //---------------- |
|
2595 |
|
2596 /** |
|
2597 * Returns the string used in debug traces. |
|
2598 */ |
|
2599 @Override |
|
2600 String makeDebugTag() { |
|
2601 return "SnmpAdaptorServer["+ getProtocol() + ":" + getPort() + "]"; |
|
2602 } |
|
2603 |
|
2604 void updateRequestCounters(int pduType) { |
|
2605 switch(pduType) { |
|
2606 |
|
2607 case pduGetRequestPdu: |
|
2608 snmpInGetRequests++; |
|
2609 break; |
|
2610 case pduGetNextRequestPdu: |
|
2611 snmpInGetNexts++; |
|
2612 break; |
|
2613 case pduSetRequestPdu: |
|
2614 snmpInSetRequests++; |
|
2615 break; |
|
2616 default: |
|
2617 break; |
|
2618 } |
|
2619 snmpInPkts++ ; |
|
2620 } |
|
2621 |
|
2622 void updateErrorCounters(int errorStatus) { |
|
2623 switch(errorStatus) { |
|
2624 |
|
2625 case snmpRspNoError: |
|
2626 snmpOutGetResponses++; |
|
2627 break; |
|
2628 case snmpRspGenErr: |
|
2629 snmpOutGenErrs++; |
|
2630 break; |
|
2631 case snmpRspBadValue: |
|
2632 snmpOutBadValues++; |
|
2633 break; |
|
2634 case snmpRspNoSuchName: |
|
2635 snmpOutNoSuchNames++; |
|
2636 break; |
|
2637 case snmpRspTooBig: |
|
2638 snmpOutTooBigs++; |
|
2639 break; |
|
2640 default: |
|
2641 break; |
|
2642 } |
|
2643 snmpOutPkts++ ; |
|
2644 } |
|
2645 |
|
2646 void updateVarCounters(int pduType, int n) { |
|
2647 switch(pduType) { |
|
2648 |
|
2649 case pduGetRequestPdu: |
|
2650 case pduGetNextRequestPdu: |
|
2651 case pduGetBulkRequestPdu: |
|
2652 snmpInTotalReqVars += n ; |
|
2653 break ; |
|
2654 case pduSetRequestPdu: |
|
2655 snmpInTotalSetVars += n ; |
|
2656 break ; |
|
2657 } |
|
2658 } |
|
2659 |
|
2660 void incSnmpInASNParseErrs(int n) { |
|
2661 snmpInASNParseErrs += n ; |
|
2662 } |
|
2663 |
|
2664 void incSnmpInBadVersions(int n) { |
|
2665 snmpInBadVersions += n ; |
|
2666 } |
|
2667 |
|
2668 void incSnmpInBadCommunityUses(int n) { |
|
2669 snmpInBadCommunityUses += n ; |
|
2670 } |
|
2671 |
|
2672 void incSnmpInBadCommunityNames(int n) { |
|
2673 snmpInBadCommunityNames += n ; |
|
2674 } |
|
2675 |
|
2676 void incSnmpSilentDrops(int n) { |
|
2677 snmpSilentDrops += n ; |
|
2678 } |
|
2679 // PRIVATE METHODS |
|
2680 //---------------- |
|
2681 |
|
2682 /** |
|
2683 * Returns the time (in hundreths of second) elapsed since the SNMP |
|
2684 * protocol adaptor startup. |
|
2685 */ |
|
2686 long getSysUpTime() { |
|
2687 return (System.currentTimeMillis() - startUpTime) / 10 ; |
|
2688 } |
|
2689 |
|
2690 /** |
|
2691 * Control the way the SnmpAdaptorServer service is deserialized. |
|
2692 */ |
|
2693 private void readObject(ObjectInputStream stream) |
|
2694 throws IOException, ClassNotFoundException { |
|
2695 |
|
2696 // Call the default deserialization of the object. |
|
2697 // |
|
2698 stream.defaultReadObject(); |
|
2699 |
|
2700 // Call the specific initialization for the SnmpAdaptorServer service. |
|
2701 // This is for transient structures to be initialized to specific |
|
2702 // default values. |
|
2703 // |
|
2704 mibs = new Vector<>() ; |
|
2705 } |
|
2706 |
|
2707 /** |
|
2708 * Common initializations. |
|
2709 */ |
|
2710 private void init(InetAddressAcl acl, int p, InetAddress a) { |
|
2711 |
|
2712 root= new SnmpMibTree(); |
|
2713 |
|
2714 // The default Agent is initialized with a SnmpErrorHandlerAgent agent. |
|
2715 root.setDefaultAgent(new SnmpErrorHandlerAgent()); |
|
2716 |
|
2717 // For the trap time, use the time the agent started ... |
|
2718 // |
|
2719 startUpTime= java.lang.System.currentTimeMillis(); |
|
2720 maxActiveClientCount = 10; |
|
2721 |
|
2722 // Create the default message factory |
|
2723 pduFactory = new SnmpPduFactoryBER() ; |
|
2724 |
|
2725 port = p ; |
|
2726 ipacl = acl ; |
|
2727 address = a ; |
|
2728 |
|
2729 if ((ipacl == null) && (useAcl == true)) |
|
2730 throw new IllegalArgumentException("ACL object cannot be null") ; |
|
2731 |
|
2732 threadService = new ThreadService(threadNumber); |
|
2733 } |
|
2734 |
|
2735 SnmpMibAgent getAgentMib(SnmpOid oid) { |
|
2736 return root.getAgentMib(oid); |
|
2737 } |
|
2738 |
|
2739 @Override |
|
2740 protected Thread createMainThread() { |
|
2741 final Thread t = super.createMainThread(); |
|
2742 t.setDaemon(true); |
|
2743 return t; |
|
2744 } |
|
2745 |
|
2746 } |
|