1 10 package com.sun.jmx.snmp.agent; 11 12 import java.util.Vector ; 13 import java.util.ArrayList ; 14 import java.util.Hashtable ; 15 import java.util.Enumeration ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 import java.util.NoSuchElementException ; 19 import java.util.Arrays ; 20 import com.sun.jmx.snmp.SnmpVarBind; 21 import com.sun.jmx.snmp.SnmpStatusException; 22 import com.sun.jmx.snmp.SnmpDefinitions; 23 import com.sun.jmx.snmp.SnmpOid; 24 import com.sun.jmx.snmp.SnmpPdu; 25 import com.sun.jmx.snmp.SnmpEngine; 26 import com.sun.jmx.trace.Trace; 27 28 44 final class SnmpRequestTree { 45 46 SnmpRequestTree(SnmpMibRequest req, boolean creationflag, int pdutype) { 60 this.request = req; 61 this.version = req.getVersion(); 62 this.creationflag = creationflag; 63 this.hashtable = new Hashtable (); 64 setPduType(pdutype); 65 } 66 67 public static int mapSetException(int errorStatus, int version) 68 throws SnmpStatusException { 69 70 final int errorCode = errorStatus; 71 72 if (version == SnmpDefinitions.snmpVersionOne) 73 return errorCode; 74 75 int mappedErrorCode = errorCode; 76 77 if (errorCode == SnmpStatusException.noSuchObject) 80 mappedErrorCode = SnmpStatusException.snmpRspNotWritable; 82 83 else if (errorCode == SnmpStatusException.noSuchInstance) 84 mappedErrorCode = SnmpStatusException.snmpRspNotWritable; 86 87 return mappedErrorCode; 88 } 89 90 public static int mapGetException(int errorStatus, int version) 91 throws SnmpStatusException { 92 93 final int errorCode = errorStatus; 94 if (version == SnmpDefinitions.snmpVersionOne) 95 return errorCode; 96 97 int mappedErrorCode = errorCode; 98 99 if (errorCode == 102 SnmpStatusException.noSuchObject) 103 mappedErrorCode = errorCode; 105 106 else if (errorCode == 107 SnmpStatusException.noSuchInstance) 108 mappedErrorCode = errorCode; 110 111 119 else if (errorCode == 123 SnmpStatusException.noAccess) 124 mappedErrorCode = SnmpStatusException.noSuchInstance; 126 127 else if (errorCode == SnmpStatusException.snmpRspInconsistentName) 138 mappedErrorCode = SnmpStatusException.noSuchInstance; 140 141 else if ((errorCode >= SnmpStatusException.snmpRspWrongType) && 149 (errorCode <= SnmpStatusException.snmpRspInconsistentValue)) 150 mappedErrorCode = SnmpStatusException.noSuchInstance; 151 152 else if (errorCode == SnmpStatusException.readOnly) 156 mappedErrorCode = SnmpStatusException.noSuchInstance; 157 158 else if (errorCode != SnmpStatusException.snmpRspAuthorizationError && 162 errorCode != SnmpStatusException.snmpRspGenErr) 163 mappedErrorCode = SnmpStatusException.noSuchObject; 164 165 return mappedErrorCode; 169 170 } 171 172 177 static final class Enum implements Enumeration { 178 Enum(SnmpRequestTree hlist,Handler h) { 179 handler = h; 180 this.hlist = hlist; 181 size = h.getSubReqCount(); 182 } 183 private final Handler handler; 184 private final SnmpRequestTree hlist; 185 private int entry = 0; 186 private int iter = 0; 187 private int size = 0; 188 189 public boolean hasMoreElements() { 190 return iter < size; 191 } 192 193 public Object nextElement() throws NoSuchElementException { 194 if (iter == 0) { 195 if (handler.sublist != null) { 196 iter++; 197 return hlist.getSubRequest(handler); 198 } 199 } 200 iter ++; 201 if (iter > size) throw new NoSuchElementException (); 202 Object result = hlist.getSubRequest(handler,entry); 203 entry++; 204 return result; 205 } 206 } 207 208 213 static final class SnmpMibSubRequestImpl implements SnmpMibSubRequest { 214 SnmpMibSubRequestImpl(SnmpMibRequest global, Vector sublist, 215 SnmpOid entryoid, boolean isnew, 216 boolean getnextflag, SnmpVarBind rs) { 217 this.global = global; 218 varbinds = sublist; 219 this.version = global.getVersion(); 220 this.entryoid = entryoid; 221 this.isnew = isnew; 222 this.getnextflag = getnextflag; 223 this.statusvb = rs; 224 } 225 226 final private Vector varbinds; 227 final private SnmpMibRequest global; 228 final private int version; 229 final private boolean isnew; 230 final private SnmpOid entryoid; 231 final private boolean getnextflag; 232 final private SnmpVarBind statusvb; 233 234 public Enumeration getElements() { 239 return varbinds.elements(); 240 } 241 242 public Vector getSubList() { 247 return varbinds; 248 } 249 250 public final int getSize() { 255 if (varbinds == null) return 0; 256 return varbinds.size(); 257 } 258 259 public void addVarBind(SnmpVarBind varbind) { 264 varbinds.addElement(varbind); 268 global.addVarBind(varbind); 269 } 270 271 public boolean isNewEntry() { 276 return isnew; 277 } 278 279 public SnmpOid getEntryOid() { 284 return entryoid; 285 } 286 287 public int getVarIndex(SnmpVarBind varbind) { 292 if (varbind == null) return 0; 293 return global.getVarIndex(varbind); 294 } 295 296 public Object getUserData() { return global.getUserData(); } 301 302 303 308 public void registerGetException(SnmpVarBind var, 309 SnmpStatusException exception) 310 throws SnmpStatusException { 311 if (version == SnmpDefinitions.snmpVersionOne) 315 throw new SnmpStatusException(exception, getVarIndex(var)+1); 316 317 if (var == null) 318 throw exception; 319 320 if (getnextflag) { 322 var.value = SnmpVarBind.endOfMibView; 323 return; 324 } 325 326 final int errorCode = mapGetException(exception.getStatus(), 327 version); 328 329 if (errorCode == 332 SnmpStatusException.noSuchObject) 333 var.value= SnmpVarBind.noSuchObject; 335 336 else if (errorCode == 337 SnmpStatusException.noSuchInstance) 338 var.value= SnmpVarBind.noSuchInstance; 340 341 else 342 throw new SnmpStatusException(errorCode, getVarIndex(var)+1); 343 344 } 345 346 public void registerSetException(SnmpVarBind var, 351 SnmpStatusException exception) 352 throws SnmpStatusException { 353 if (version == SnmpDefinitions.snmpVersionOne) 357 throw new SnmpStatusException(exception, getVarIndex(var)+1); 358 359 throw new SnmpStatusException(SnmpDefinitions.snmpRspUndoFailed, 366 getVarIndex(var)+1); 367 } 368 369 public void registerCheckException(SnmpVarBind var, 374 SnmpStatusException exception) 375 throws SnmpStatusException { 376 final int errorCode = exception.getStatus(); 382 final int mappedErrorCode = mapSetException(errorCode, 383 version); 384 385 if (errorCode != mappedErrorCode) 386 throw new 387 SnmpStatusException(mappedErrorCode, getVarIndex(var)+1); 388 else 389 throw new SnmpStatusException(exception, getVarIndex(var)+1); 390 } 391 392 public int getVersion() { 397 return version; 398 } 399 400 public SnmpVarBind getRowStatusVarBind() { 401 return statusvb; 402 } 403 404 public SnmpPdu getPdu() { 405 return global.getPdu(); 406 } 407 408 public int getRequestPduVersion() { 409 return global.getRequestPduVersion(); 410 } 411 412 public SnmpEngine getEngine() { 413 return global.getEngine(); 414 } 415 416 public String getPrincipal() { 417 return global.getPrincipal(); 418 } 419 420 public int getSecurityLevel() { 421 return global.getSecurityLevel(); 422 } 423 424 public int getSecurityModel() { 425 return global.getSecurityModel(); 426 } 427 428 public byte[] getContextName() { 429 return global.getContextName(); 430 } 431 432 public byte[] getAccessContextName() { 433 return global.getAccessContextName(); 434 } 435 } 436 437 446 static final class Handler { 447 SnmpMibNode meta; int depth; Vector sublist; SnmpOid[] entryoids = null; Vector [] entrylists = null; boolean[] isentrynew = null; SnmpVarBind[] rowstatus = null; int entrycount = 0; 458 int entrysize = 0; 459 460 final int type; final private static int Delta = 10; 462 463 public Handler(int pduType) { 464 this.type = pduType; 465 } 466 467 470 public void addVarbind(SnmpVarBind varbind) { 471 if (sublist == null) sublist = new Vector (); 472 sublist.addElement(varbind); 473 } 474 475 479 void add(int pos,SnmpOid oid, Vector v, boolean isnew, 480 SnmpVarBind statusvb) { 481 482 if (entryoids == null) { 483 485 entryoids = new SnmpOid[Delta]; 486 entrylists = new Vector [Delta]; 487 isentrynew = new boolean[Delta]; 488 rowstatus = new SnmpVarBind[Delta]; 489 entrysize = Delta; 490 pos = 0; 491 492 } else if (pos >= entrysize || entrycount == entrysize) { 493 495 SnmpOid[] olde = entryoids; 497 Vector [] oldl = entrylists; 498 boolean[] oldn = isentrynew; 499 SnmpVarBind[] oldr = rowstatus; 500 501 entrysize += Delta; 503 entryoids = new SnmpOid[entrysize]; 504 entrylists = new Vector [entrysize]; 505 isentrynew = new boolean[entrysize]; 506 rowstatus = new SnmpVarBind[entrysize]; 507 508 if (pos > entrycount) pos = entrycount; 510 if (pos < 0) pos = 0; 511 512 final int l1 = pos; 513 final int l2 = entrycount - pos; 514 515 if (l1 > 0) { 517 java.lang.System.arraycopy(olde,0,entryoids, 518 0,l1); 519 java.lang.System.arraycopy(oldl,0,entrylists, 520 0,l1); 521 java.lang.System.arraycopy(oldn,0,isentrynew, 522 0,l1); 523 java.lang.System.arraycopy(oldr,0,rowstatus, 524 0,l1); 525 } 526 527 if (l2 > 0) { 530 final int l3 = l1+1; 531 java.lang.System.arraycopy(olde,l1,entryoids, 532 l3,l2); 533 java.lang.System.arraycopy(oldl,l1,entrylists, 534 l3,l2); 535 java.lang.System.arraycopy(oldn,l1,isentrynew, 536 l3,l2); 537 java.lang.System.arraycopy(oldr,l1,rowstatus, 538 l3,l2); 539 } 540 541 542 } else if (pos < entrycount) { 543 final int l1 = pos+1; 548 final int l2 = entrycount - pos; 549 550 java.lang.System.arraycopy(entryoids,pos,entryoids, 551 l1,l2); 552 java.lang.System.arraycopy(entrylists,pos,entrylists, 553 l1,l2); 554 java.lang.System.arraycopy(isentrynew,pos,isentrynew, 555 l1,l2); 556 java.lang.System.arraycopy(rowstatus,pos,rowstatus, 557 l1,l2); 558 } 559 560 entryoids[pos] = oid; 562 entrylists[pos] = v; 563 isentrynew[pos] = isnew; 564 rowstatus[pos] = statusvb; 565 entrycount++; 566 } 567 568 public void addVarbind(SnmpVarBind varbind, SnmpOid entryoid, 569 boolean isnew, SnmpVarBind statusvb) 570 throws SnmpStatusException { 571 Vector v = null; 572 SnmpVarBind rs = statusvb; 573 574 if (entryoids == null) { 575 v = new Vector (); 579 add(0,entryoid,v,isnew,rs); 583 } else { 584 final int pos = 587 getInsertionPoint(entryoids,entrycount,entryoid); 588 if (pos > -1 && pos < entrycount && 589 entryoid.compareTo(entryoids[pos]) == 0) { 590 v = entrylists[pos]; 591 rs = rowstatus[pos]; 592 } else { 593 v = new Vector (); 598 add(pos,entryoid,v,isnew,rs); 602 } 603 if (statusvb != null) { 606 if ((rs != null) && (rs != statusvb) && 607 ((type == SnmpDefinitions.pduWalkRequest) || 608 (type == SnmpDefinitions.pduSetRequestPdu))) { 609 throw new SnmpStatusException( 610 SnmpStatusException.snmpRspInconsistentValue); 611 } 612 rowstatus[pos] = statusvb; 613 } 614 } 615 616 if (statusvb != varbind) 620 v.addElement(varbind); 621 } 622 623 public int getSubReqCount() { 624 int count = 0; 625 if (sublist != null) count++; 626 if (entryoids != null) count += entrycount; 628 return count; 629 } 630 631 public Vector getSubList() { 632 return sublist; 633 } 634 635 public int getEntryPos(SnmpOid entryoid) { 636 return findOid(entryoids,entrycount,entryoid); 638 } 639 640 public SnmpOid getEntryOid(int pos) { 641 if (entryoids == null) return null; 642 if (pos == -1 || pos >= entrycount ) return null; 644 return (SnmpOid) entryoids[pos]; 646 } 647 648 public boolean isNewEntry(int pos) { 649 if (entryoids == null) return false; 650 if (pos == -1 || pos >= entrycount ) return false; 652 return isentrynew[pos]; 654 } 655 656 public SnmpVarBind getRowStatusVarBind(int pos) { 657 if (entryoids == null) return null; 658 if (pos == -1 || pos >= entrycount ) return null; 660 return rowstatus[pos]; 662 } 663 664 public Vector getEntrySubList(int pos) { 665 if (entrylists == null) return null; 666 if (pos == -1 || pos >= entrycount ) return null; 668 return entrylists[pos]; 670 } 671 672 public Iterator getEntryOids() { 673 if (entryoids == null) return null; 674 return Arrays.asList(entryoids).iterator(); 676 } 677 678 public int getEntryCount() { 679 if (entryoids == null) return 0; 680 return entrycount; 682 } 683 684 } 685 686 687 693 698 public Object getUserData() { return request.getUserData(); } 699 700 705 public boolean isCreationAllowed() { 706 return creationflag; 707 } 708 709 713 public boolean isSetRequest() { 714 return setreqflag; 715 } 716 717 722 public int getVersion() { 723 return version; 724 } 725 726 730 public int getRequestPduVersion() { 731 return request.getRequestPduVersion(); 732 } 733 734 738 public SnmpMibNode getMetaNode(Handler handler) { 739 return handler.meta; 740 } 741 742 747 public int getOidDepth(Handler handler) { 748 return handler.depth; 749 } 750 751 758 public Enumeration getSubRequests(Handler handler) { 759 return new Enum (this,handler); 760 } 761 762 766 public Enumeration getHandlers() { 767 return hashtable.elements(); 768 } 769 770 774 public void add(SnmpMibNode meta, int depth, SnmpVarBind varbind) 775 throws SnmpStatusException { 776 registerNode(meta,depth,null,varbind,false,null); 777 } 778 779 783 public void add(SnmpMibNode meta, int depth, SnmpOid entryoid, 784 SnmpVarBind varbind, boolean isnew) 785 throws SnmpStatusException { 786 registerNode(meta,depth,entryoid,varbind,isnew,null); 787 } 788 789 794 public void add(SnmpMibNode meta, int depth, SnmpOid entryoid, 795 SnmpVarBind varbind, boolean isnew, 796 SnmpVarBind statusvb) 797 throws SnmpStatusException { 798 registerNode(meta,depth,entryoid,varbind,isnew,statusvb); 799 } 800 801 802 808 812 void setPduType(int pduType) { 813 type = pduType; 814 setreqflag = ((pduType == SnmpDefinitions.pduWalkRequest) || 815 (pduType == SnmpDefinitions.pduSetRequestPdu)); 816 } 817 818 822 void setGetNextFlag() { 823 getnextflag = true; 824 } 825 826 void switchCreationFlag(boolean flag) { 830 creationflag = flag; 831 } 832 833 834 839 SnmpMibSubRequest getSubRequest(Handler handler) { 840 if (handler == null) return null; 841 return new SnmpMibSubRequestImpl(request,handler.getSubList(), 842 null,false,getnextflag,null); 843 } 844 845 850 SnmpMibSubRequest getSubRequest(Handler handler, SnmpOid oid) { 851 if (handler == null) return null; 852 final int pos = handler.getEntryPos(oid); 853 if (pos == -1) return null; 854 return new SnmpMibSubRequestImpl(request, 855 handler.getEntrySubList(pos), 856 handler.getEntryOid(pos), 857 handler.isNewEntry(pos), 858 getnextflag, 859 handler.getRowStatusVarBind(pos)); 860 } 861 862 868 SnmpMibSubRequest getSubRequest(Handler handler, int entry) { 869 if (handler == null) return null; 870 return new 871 SnmpMibSubRequestImpl(request,handler.getEntrySubList(entry), 872 handler.getEntryOid(entry), 873 handler.isNewEntry(entry),getnextflag, 874 handler.getRowStatusVarBind(entry)); 875 } 876 877 883 884 888 private void put(Object key, Handler handler) { 889 if (handler == null) return; 890 if (key == null) return; 891 if (hashtable == null) hashtable = new Hashtable (); 892 hashtable.put(key,handler); 893 } 894 895 899 private Handler get(Object key) { 900 if (key == null) return null; 901 if (hashtable == null) return null; 902 return (Handler) hashtable.get(key); 903 } 904 905 910 private static int findOid(SnmpOid[] oids, int count, SnmpOid oid) { 911 final int size = count; 912 int low= 0; 913 int max= size - 1; 914 int curr= low + (max-low)/2; 915 while (low <= max) { 917 918 final SnmpOid pos = oids[curr]; 919 920 final int comp = oid.compareTo(pos); 924 if (comp == 0) 925 return curr; 926 927 if (oid.equals(pos)) { 928 return curr; 929 } 930 if (comp > 0) { 931 low = curr + 1; 932 } else { 933 max = curr - 1; 934 } 935 curr = low + (max-low)/2; 936 } 937 return -1; 938 } 939 940 945 private static int getInsertionPoint(SnmpOid[] oids, int count, 946 SnmpOid oid) { 947 final SnmpOid[] localoids = oids; 948 final int size = count; 949 int low= 0; 950 int max= size - 1; 951 int curr= low + (max-low)/2; 952 953 954 while (low <= max) { 955 956 final SnmpOid pos = localoids[curr]; 957 958 final int comp= oid.compareTo(pos); 961 962 if (comp == 0) 971 return curr; 972 973 if (comp>0) { 974 low= curr +1; 975 } else { 976 max= curr -1; 977 } 978 curr= low + (max-low)/2; 979 } 980 return curr; 981 } 982 983 987 private void registerNode(SnmpMibNode meta, int depth, SnmpOid entryoid, 988 SnmpVarBind varbind, boolean isnew, 989 SnmpVarBind statusvb) 990 throws SnmpStatusException { 991 if (meta == null) { 992 if (isDebugOn()) 993 debug("registerNode","meta-node is null!!!"); 994 return; 995 } 996 if (varbind == null) { 997 if (isDebugOn()) 998 debug("registerNode","varbind is null!!!"); 999 return ; 1000 } 1001 1002 final Object key = meta; 1003 1004 Handler handler = get(key); 1007 1008 if (handler == null) { 1010 handler = new Handler(type); 1014 handler.meta = meta; 1015 handler.depth = depth; 1016 put(key,handler); 1017 } 1018 1024 if (entryoid == null) 1026 handler.addVarbind(varbind); 1027 else 1028 handler.addVarbind(varbind,entryoid,isnew,statusvb); 1029 return ; 1030 } 1031 1032 private final static boolean isDebugOn() { 1033 return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP); 1034 } 1035 1036 private final static void debug(String func, String info) { 1037 Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP, 1038 "SnmpRequestTree", func, info); 1039 } 1040 1041 1045 private Hashtable hashtable = null; private SnmpMibRequest request = null; private int version = 0; private boolean creationflag = false; private boolean getnextflag = false; private int type = 0; private boolean setreqflag = false; } 1057 | Popular Tags |