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 }