1 /* 2 * Copyright (c) 1997, 2013, 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 package com.sun.jmx.snmp.agent; 27 28 import java.io.Serializable; 29 import java.util.Enumeration; 30 import java.util.logging.Level; 31 import java.util.Vector; 32 33 import javax.management.ObjectName; 34 import javax.management.MBeanServer; 35 import javax.management.MalformedObjectNameException; 36 import javax.management.InstanceAlreadyExistsException; 37 import javax.management.MBeanRegistrationException; 38 import javax.management.NotCompliantMBeanException; 39 40 import static com.sun.jmx.defaults.JmxProperties.SNMP_ADAPTOR_LOGGER; 41 import com.sun.jmx.snmp.SnmpOid; 42 import com.sun.jmx.snmp.SnmpVarBind; 43 import com.sun.jmx.snmp.SnmpDefinitions; 44 import com.sun.jmx.snmp.SnmpStatusException; 45 46 /** 47 * Abstract class for representing an SNMP MIB. 48 * <P> 49 * When compiling a SNMP MIB, among all the classes generated by 50 * <CODE>mibgen</CODE>, there is one which extends <CODE>SnmpMib</CODE> 51 * for representing a whole MIB. 52 * <BR>The class is used by the SNMP protocol adaptor as the entry point in 53 * the MIB. 54 * 55 * <p>This generated class can be subclassed in your code in order to 56 * plug in your own specific behaviour. 57 * </p> 58 * 59 * <p><b>This API is a Sun Microsystems internal API and is subject 60 * to change without notice.</b></p> 61 */ 62 public abstract class SnmpMib extends SnmpMibAgent implements Serializable { 63 64 /** 65 * Default constructor. 66 * Initializes the OID tree. 67 */ SnmpMib()68 public SnmpMib() { 69 root= new SnmpMibOid(); 70 } 71 72 73 // -------------------------------------------------------------------- 74 // POLYMORHIC METHODS 75 // -------------------------------------------------------------------- 76 77 /** 78 * <p> 79 * This callback should return the OID associated to the group 80 * identified by the given <code>groupName</code>. 81 * </p> 82 * 83 * <p> 84 * This method is provided as a hook to plug-in some custom 85 * specific behavior. Although doing so is discouraged you might 86 * want to subclass this method in order to store & provide more metadata 87 * information (mapping OID <-> symbolic name) within the agent, 88 * or to "change" the root of the MIB OID by prefixing the 89 * defaultOid by an application dependant OID string, for instance. 90 * </p> 91 * 92 * <p> 93 * The default implementation of this method is to return the given 94 * <code>defaultOid</code> 95 * </p> 96 * 97 * @param groupName The java-ized name of the SNMP group. 98 * @param defaultOid The OID defined in the MIB for that group 99 * (in dot notation). 100 * 101 * @return The OID of the group identified by <code>groupName</code>, 102 * in dot-notation. 103 */ getGroupOid(String groupName, String defaultOid)104 protected String getGroupOid(String groupName, String defaultOid) { 105 return defaultOid; 106 } 107 108 /** 109 * <p> 110 * This callback should return the ObjectName associated to the 111 * group identified by the given <code>groupName</code>. 112 * </p> 113 * 114 * <p> 115 * This method is provided as a hook to plug-in some custom 116 * specific behavior. You might want to override this method 117 * in order to provide a different object naming scheme than 118 * that proposed by default by <code>mibgen</code>. 119 * </p> 120 * 121 * <p> 122 * This method is only meaningful if the MIB is registered 123 * in the MBeanServer, otherwise, it will not be called. 124 * </p> 125 * 126 * <p> 127 * The default implementation of this method is to return an ObjectName 128 * built from the given <code>defaultName</code>. 129 * </p> 130 * 131 * @param name The java-ized name of the SNMP group. 132 * @param oid The OID returned by getGroupOid() - in dot notation. 133 * @param defaultName The name by default generated by <code> 134 * mibgen</code> 135 * 136 * @return The ObjectName of the group identified by <code>name</code> 137 */ getGroupObjectName(String name, String oid, String defaultName)138 protected ObjectName getGroupObjectName(String name, String oid, 139 String defaultName) 140 throws MalformedObjectNameException { 141 return new ObjectName(defaultName); 142 } 143 144 /** 145 * <p> 146 * Register an SNMP group and its metadata node in the MIB. 147 * </p> 148 * 149 * <p> 150 * This method is provided as a hook to plug-in some custom 151 * specific behavior. You might want to override this method 152 * if you want to set special links between the MBean, its metadata 153 * node, its OID or ObjectName etc.. 154 * </p> 155 * 156 * <p> 157 * If the MIB is not registered in the MBeanServer, the <code> 158 * server</code> and <code>groupObjName</code> parameters will be 159 * <code>null</code>.<br> 160 * If the given group MBean is not <code>null</code>, and if the 161 * <code>server</code> and <code>groupObjName</code> parameters are 162 * not null, then this method will also automatically register the 163 * group MBean with the given MBeanServer <code>server</code>. 164 * </p> 165 * 166 * @param groupName The java-ized name of the SNMP group. 167 * @param groupOid The OID as returned by getGroupOid() - in dot 168 * notation. 169 * @param groupObjName The ObjectName as returned by getGroupObjectName(). 170 * This parameter may be <code>null</code> if the 171 * MIB is not registered in the MBeanServer. 172 * @param node The metadata node, as returned by the metadata 173 * factory method for this group. 174 * @param group The MBean for this group, as returned by the 175 * MBean factory method for this group. 176 * @param server The MBeanServer in which the groups are to be 177 * registered. This parameter will be <code>null</code> 178 * if the MIB is not registered, otherwise it is a 179 * reference to the MBeanServer in which the MIB is 180 * registered. 181 * 182 */ registerGroupNode(String groupName, String groupOid, ObjectName groupObjName, SnmpMibNode node, Object group, MBeanServer server)183 protected void registerGroupNode(String groupName, String groupOid, 184 ObjectName groupObjName, SnmpMibNode node, 185 Object group, MBeanServer server) 186 throws NotCompliantMBeanException, MBeanRegistrationException, 187 InstanceAlreadyExistsException, IllegalAccessException { 188 root.registerNode(groupOid,node); 189 if (server != null && groupObjName != null && group != null) 190 server.registerMBean(group,groupObjName); 191 } 192 193 /** 194 * <p> 195 * Register an SNMP Table metadata node in the MIB. 196 * </p> 197 * 198 * <p> 199 * <b><i> 200 * This method is used internally and you should never need to 201 * call it directly.</i></b><br> It is used to establish the link 202 * between an SNMP table metadata node and its bean-like counterpart. 203 * <br> 204 * The group metadata nodes will create and register their 205 * underlying table metadata nodes in the MIB using this 206 * method. <br> 207 * The metadata nodes will be later retrieved from the MIB by the 208 * bean-like table objects using the getRegisterTableMeta() method. 209 * </p> 210 * 211 * @param name The java-ized name of the SNMP table. 212 * @param table The SNMP table metadata node - usually this 213 * corresponds to a <code>mibgen</code> generated 214 * object. 215 */ registerTableMeta(String name, SnmpMibTable table)216 public abstract void registerTableMeta(String name, SnmpMibTable table); 217 218 /** 219 * Returns a registered SNMP Table metadata node. 220 * 221 * <p><b><i> 222 * This method is used internally and you should never need to 223 * call it directly. 224 * </i></b></p> 225 * 226 */ getRegisteredTableMeta(String name)227 public abstract SnmpMibTable getRegisteredTableMeta(String name); 228 229 // -------------------------------------------------------------------- 230 // PUBLIC METHODS 231 // -------------------------------------------------------------------- 232 233 /** 234 * Processes a <CODE>get</CODE> operation. 235 * 236 **/ 237 // Implements the method defined in SnmpMibAgent. See SnmpMibAgent 238 // for java-doc 239 // 240 @Override get(SnmpMibRequest req)241 public void get(SnmpMibRequest req) throws SnmpStatusException { 242 243 // Builds the request tree: creation is not allowed, operation 244 // is not atomic. 245 246 final int reqType = SnmpDefinitions.pduGetRequestPdu; 247 SnmpRequestTree handlers = getHandlers(req,false,false,reqType); 248 249 SnmpRequestTree.Handler h = null; 250 SnmpMibNode meta = null; 251 252 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 253 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(), 254 "get", "Processing handlers for GET... "); 255 } 256 257 // For each sub-request stored in the request-tree, invoke the 258 // get() method. 259 for (Enumeration<SnmpRequestTree.Handler> eh=handlers.getHandlers();eh.hasMoreElements();) { 260 h = eh.nextElement(); 261 262 // Gets the Meta node. It can be either a Group Meta or a 263 // Table Meta. 264 // 265 meta = handlers.getMetaNode(h); 266 267 // Gets the depth of the Meta node in the OID tree 268 final int depth = handlers.getOidDepth(h); 269 270 for (Enumeration<SnmpMibSubRequest> rqs=handlers.getSubRequests(h); 271 rqs.hasMoreElements();) { 272 273 // Invoke the get() operation. 274 meta.get(rqs.nextElement(),depth); 275 } 276 } 277 } 278 279 /** 280 * Processes a <CODE>set</CODE> operation. 281 * 282 */ 283 // Implements the method defined in SnmpMibAgent. See SnmpMibAgent 284 // for java-doc 285 // 286 @Override set(SnmpMibRequest req)287 public void set(SnmpMibRequest req) throws SnmpStatusException { 288 289 SnmpRequestTree handlers = null; 290 291 // Optimization: we're going to get the whole SnmpRequestTree 292 // built in the "check" method, so that we don't have to rebuild 293 // it here. 294 // 295 if (req instanceof SnmpMibRequestImpl) 296 handlers = ((SnmpMibRequestImpl)req).getRequestTree(); 297 298 // Optimization didn't work: we have to rebuild the tree. 299 // 300 // Builds the request tree: creation is not allowed, operation 301 // is atomic. 302 // 303 final int reqType = SnmpDefinitions.pduSetRequestPdu; 304 if (handlers == null) handlers = getHandlers(req,false,true,reqType); 305 handlers.switchCreationFlag(false); 306 handlers.setPduType(reqType); 307 308 SnmpRequestTree.Handler h; 309 SnmpMibNode meta; 310 311 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 312 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(), 313 "set", "Processing handlers for SET... "); 314 } 315 316 // For each sub-request stored in the request-tree, invoke the 317 // get() method. 318 for (Enumeration<SnmpRequestTree.Handler> eh=handlers.getHandlers();eh.hasMoreElements();) { 319 h = eh.nextElement(); 320 321 // Gets the Meta node. It can be either a Group Meta or a 322 // Table Meta. 323 // 324 meta = handlers.getMetaNode(h); 325 326 // Gets the depth of the Meta node in the OID tree 327 final int depth = handlers.getOidDepth(h); 328 329 for (Enumeration<SnmpMibSubRequest> rqs=handlers.getSubRequests(h); 330 rqs.hasMoreElements();) { 331 332 // Invoke the set() operation 333 meta.set(rqs.nextElement(),depth); 334 } 335 } 336 } 337 338 /** 339 * Checks if a <CODE>set</CODE> operation can be performed. 340 * If the operation cannot be performed, the method will raise a 341 * <CODE>SnmpStatusException</CODE>. 342 * 343 */ 344 // Implements the method defined in SnmpMibAgent. See SnmpMibAgent 345 // for java-doc 346 // 347 @Override check(SnmpMibRequest req)348 public void check(SnmpMibRequest req) throws SnmpStatusException { 349 350 final int reqType = SnmpDefinitions.pduWalkRequest; 351 // Builds the request tree: creation is allowed, operation 352 // is atomic. 353 SnmpRequestTree handlers = getHandlers(req,true,true,reqType); 354 355 SnmpRequestTree.Handler h; 356 SnmpMibNode meta; 357 358 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 359 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(), 360 "check", "Processing handlers for CHECK... "); 361 } 362 363 // For each sub-request stored in the request-tree, invoke the 364 // check() method. 365 for (Enumeration<SnmpRequestTree.Handler> eh=handlers.getHandlers();eh.hasMoreElements();) { 366 h = eh.nextElement(); 367 368 // Gets the Meta node. It can be either a Group Meta or a 369 // Table Meta. 370 // 371 meta = handlers.getMetaNode(h); 372 373 // Gets the depth of the Meta node in the OID tree 374 final int depth = handlers.getOidDepth(h); 375 376 for (Enumeration<SnmpMibSubRequest> rqs=handlers.getSubRequests(h); 377 rqs.hasMoreElements();) { 378 379 // Invoke the check() operation 380 meta.check(rqs.nextElement(),depth); 381 } 382 } 383 384 // Optimization: we're going to pass the whole SnmpRequestTree 385 // to the "set" method, so that we don't have to rebuild it there. 386 // 387 if (req instanceof SnmpMibRequestImpl) { 388 ((SnmpMibRequestImpl)req).setRequestTree(handlers); 389 } 390 391 } 392 393 /** 394 * Processes a <CODE>getNext</CODE> operation. 395 * 396 */ 397 // Implements the method defined in SnmpMibAgent. See SnmpMibAgent 398 // for java-doc 399 // 400 @Override getNext(SnmpMibRequest req)401 public void getNext(SnmpMibRequest req) throws SnmpStatusException { 402 // Build the request tree for the operation 403 // The subrequest stored in the request tree are valid GET requests 404 SnmpRequestTree handlers = getGetNextHandlers(req); 405 406 SnmpRequestTree.Handler h; 407 SnmpMibNode meta; 408 409 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 410 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(), 411 "getNext", "Processing handlers for GET-NEXT... "); 412 } 413 414 // Now invoke get() for each subrequest of the request tree. 415 for (Enumeration<SnmpRequestTree.Handler> eh=handlers.getHandlers();eh.hasMoreElements();) { 416 h = eh.nextElement(); 417 418 // Gets the Meta node. It can be either a Group Meta or a 419 // Table Meta. 420 // 421 meta = handlers.getMetaNode(h); 422 423 // Gets the depth of the Meta node in the OID tree 424 int depth = handlers.getOidDepth(h); 425 426 for (Enumeration<SnmpMibSubRequest> rqs=handlers.getSubRequests(h); 427 rqs.hasMoreElements();) { 428 429 // Invoke the get() operation 430 meta.get(rqs.nextElement(),depth); 431 } 432 } 433 } 434 435 436 /** 437 * Processes a <CODE>getBulk</CODE> operation. 438 * The method implements the <CODE>getBulk</CODE> operation by calling 439 * appropriately the <CODE>getNext</CODE> method. 440 * 441 */ 442 // Implements the method defined in SnmpMibAgent. See SnmpMibAgent 443 // for java-doc 444 // 445 @Override getBulk(SnmpMibRequest req, int nonRepeat, int maxRepeat)446 public void getBulk(SnmpMibRequest req, int nonRepeat, int maxRepeat) 447 throws SnmpStatusException { 448 449 getBulkWithGetNext(req, nonRepeat, maxRepeat); 450 } 451 452 /** 453 * Gets the root object identifier of the MIB. 454 * <P>In order to be accurate, the method should be called once the 455 * MIB is fully initialized (that is, after a call to <CODE>init</CODE> 456 * or <CODE>preRegister</CODE>). 457 * 458 * @return The root object identifier. 459 */ 460 @Override getRootOid()461 public long[] getRootOid() { 462 463 if( rootOid == null) { 464 Vector<Integer> list= new Vector<>(10); 465 466 // Ask the tree to do the job ! 467 // 468 root.getRootOid(list); 469 470 // Now format the result 471 // 472 rootOid= new long[list.size()]; 473 int i=0; 474 for(Enumeration<Integer> e= list.elements(); e.hasMoreElements(); ) { 475 Integer val= e.nextElement(); 476 rootOid[i++]= val.longValue(); 477 } 478 } 479 return rootOid.clone(); 480 } 481 482 // -------------------------------------------------------------------- 483 // PRIVATE METHODS 484 //--------------------------------------------------------------------- 485 486 /** 487 * This method builds the temporary request-tree that will be used to 488 * perform the SNMP request associated with the given vector of varbinds 489 * `list'. 490 * 491 * @param req The SnmpMibRequest object holding the varbind list 492 * concerning this MIB. 493 * @param createflag Indicates whether the operation allow for creation 494 * of new instances (ie: it is a SET). 495 * @param atomic Indicates whether the operation is atomic or not. 496 * @param type Request type (from SnmpDefinitions). 497 * 498 * @return The request-tree where the original varbind list has been 499 * dispatched to the appropriate nodes. 500 */ getHandlers(SnmpMibRequest req, boolean createflag, boolean atomic, int type)501 private SnmpRequestTree getHandlers(SnmpMibRequest req, 502 boolean createflag, boolean atomic, 503 int type) 504 throws SnmpStatusException { 505 506 // Build an empty request tree 507 SnmpRequestTree handlers = 508 new SnmpRequestTree(req,createflag,type); 509 510 int index=0; 511 SnmpVarBind var; 512 final int ver= req.getVersion(); 513 514 // For each varbind in the list finds its handling node. 515 for (Enumeration<SnmpVarBind> e= req.getElements(); e.hasMoreElements(); index++) { 516 517 var= e.nextElement(); 518 519 try { 520 // Find the handling node for this varbind. 521 root.findHandlingNode(var,var.oid.longValue(false), 522 0,handlers); 523 } catch(SnmpStatusException x) { 524 525 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 526 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, 527 SnmpMib.class.getName(), 528 "getHandlers", 529 "Couldn't find a handling node for " + 530 var.oid.toString()); 531 } 532 533 // If the operation is atomic (Check/Set) or the version 534 // is V1 we must generate an exception. 535 // 536 if (ver == SnmpDefinitions.snmpVersionOne) { 537 538 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 539 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, 540 SnmpMib.class.getName(), 541 "getHandlers", "\tV1: Throwing exception"); 542 } 543 544 // The index in the exception must correspond to the 545 // SNMP index ... 546 // 547 final SnmpStatusException sse = 548 new SnmpStatusException(x, index + 1); 549 sse.initCause(x); 550 throw sse; 551 } else if ((type == SnmpDefinitions.pduWalkRequest) || 552 (type == SnmpDefinitions.pduSetRequestPdu)) { 553 final int status = 554 SnmpRequestTree.mapSetException(x.getStatus(),ver); 555 556 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 557 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, 558 SnmpMib.class.getName(), 559 "getHandlers", "\tSET: Throwing exception"); 560 } 561 562 final SnmpStatusException sse = 563 new SnmpStatusException(status, index + 1); 564 sse.initCause(x); 565 throw sse; 566 } else if (atomic) { 567 568 // Should never come here... 569 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 570 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, 571 SnmpMib.class.getName(), 572 "getHandlers", "\tATOMIC: Throwing exception"); 573 } 574 575 final SnmpStatusException sse = 576 new SnmpStatusException(x, index + 1); 577 sse.initCause(x); 578 throw sse; 579 } 580 581 final int status = 582 SnmpRequestTree.mapGetException(x.getStatus(),ver); 583 584 if (status == SnmpStatusException.noSuchInstance) { 585 586 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 587 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, 588 SnmpMib.class.getName(), 589 "getHandlers", 590 "\tGET: Registering noSuchInstance"); 591 } 592 593 var.value= SnmpVarBind.noSuchInstance; 594 595 } else if (status == SnmpStatusException.noSuchObject) { 596 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 597 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, 598 SnmpMib.class.getName(), 599 "getHandlers", 600 "\tGET: Registering noSuchObject"); 601 } 602 603 var.value= SnmpVarBind.noSuchObject; 604 605 } else { 606 607 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 608 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, 609 SnmpMib.class.getName(), 610 "getHandlers", 611 "\tGET: Registering global error: " + status); 612 } 613 614 final SnmpStatusException sse = 615 new SnmpStatusException(status, index + 1); 616 sse.initCause(x); 617 throw sse; 618 } 619 } 620 } 621 return handlers; 622 } 623 624 /** 625 * This method builds the temporary request-tree that will be used to 626 * perform the SNMP GET-NEXT request associated with the given vector 627 * of varbinds `list'. 628 * 629 * @param req The SnmpMibRequest object holding the varbind list 630 * concerning this MIB. 631 * 632 * @return The request-tree where the original varbind list has been 633 * dispatched to the appropriate nodes, and where the original 634 * OIDs have been replaced with the correct "next" OID. 635 */ getGetNextHandlers(SnmpMibRequest req)636 private SnmpRequestTree getGetNextHandlers(SnmpMibRequest req) 637 throws SnmpStatusException { 638 639 // Creates an empty request tree, no entry creation is allowed (false) 640 SnmpRequestTree handlers = new 641 SnmpRequestTree(req,false,SnmpDefinitions.pduGetNextRequestPdu); 642 643 // Sets the getNext flag: if version=V2, status exception are 644 // transformed in endOfMibView 645 handlers.setGetNextFlag(); 646 647 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 648 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(), 649 "getGetNextHandlers", "Received MIB request : " + req); 650 } 651 AcmChecker checker = new AcmChecker(req); 652 int index=0; 653 SnmpVarBind var = null; 654 final int ver= req.getVersion(); 655 SnmpOid original = null; 656 // For each varbind, finds the handling node. 657 // This function has the side effect of transforming a GET-NEXT 658 // request into a valid GET request, replacing the OIDs in the 659 // original GET-NEXT request with the OID of the first leaf that 660 // follows. 661 for (Enumeration<SnmpVarBind> e= req.getElements(); e.hasMoreElements(); index++) { 662 663 var = e.nextElement(); 664 SnmpOid result; 665 try { 666 // Find the node handling the OID that follows the varbind 667 // OID. `result' contains this next leaf OID. 668 //ACM loop. 669 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 670 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, 671 SnmpMib.class.getName(), 672 "getGetNextHandlers", " Next OID of : " + var.oid); 673 } 674 result = new SnmpOid(root.findNextHandlingNode 675 (var,var.oid.longValue(false),0, 676 0,handlers, checker)); 677 678 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 679 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, 680 SnmpMib.class.getName(), 681 "getGetNextHandlers", " is : " + result); 682 } 683 // We replace the varbind original OID with the OID of the 684 // leaf object we have to return. 685 var.oid = result; 686 } catch(SnmpStatusException x) { 687 688 // if (isDebugOn()) 689 // debug("getGetNextHandlers", 690 // "Couldn't find a handling node for " 691 // + var.oid.toString()); 692 693 if (ver == SnmpDefinitions.snmpVersionOne) { 694 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 695 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, 696 SnmpMib.class.getName(), 697 "getGetNextHandlers", 698 "\tThrowing exception " + x.toString()); 699 } 700 // The index in the exception must correspond to the 701 // SNMP index ... 702 // 703 throw new SnmpStatusException(x, index + 1); 704 } 705 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { 706 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, 707 SnmpMib.class.getName(), 708 "getGetNextHandlers", 709 "Exception : " + x.getStatus()); 710 } 711 712 var.setSnmpValue(SnmpVarBind.endOfMibView); 713 } 714 } 715 return handlers; 716 } 717 718 // -------------------------------------------------------------------- 719 // PROTECTED VARIABLES 720 // -------------------------------------------------------------------- 721 722 /** 723 * The top element in the Mib tree. 724 * @serial 725 */ 726 protected SnmpMibOid root; 727 728 729 // -------------------------------------------------------------------- 730 // PRIVATE VARIABLES 731 // -------------------------------------------------------------------- 732 733 /** 734 * The root object identifier of the MIB. 735 */ 736 private transient long[] rootOid= null; 737 } 738