1 11 12 13 package com.sun.jmx.snmp; 14 15 16 17 18 38 39 public class BerDecoder { 40 41 46 47 public BerDecoder(byte b[]) { 48 bytes = b ; 49 reset() ; 50 } 51 52 public void reset() { 53 next = 0 ; 54 stackTop = 0 ; 55 } 56 57 64 65 public int fetchInteger() throws BerException { 66 return fetchInteger(IntegerTag) ; 67 } 68 69 70 80 81 public int fetchInteger(int tag) throws BerException { 82 int result = 0 ; 83 final int backup = next ; 84 try { 85 if (fetchTag() != tag) { 86 throw new BerException() ; 87 } 88 result = fetchIntegerValue() ; 89 } 90 catch(BerException e) { 91 next = backup ; 92 throw e ; 93 } 94 95 return result ; 96 } 97 98 99 100 107 108 public long fetchIntegerAsLong() throws BerException { 109 return fetchIntegerAsLong(IntegerTag) ; 110 } 111 112 113 123 124 public long fetchIntegerAsLong(int tag) throws BerException { 125 long result = 0 ; 126 final int backup = next ; 127 try { 128 if (fetchTag() != tag) { 129 throw new BerException() ; 130 } 131 result = fetchIntegerValueAsLong() ; 132 } 133 catch(BerException e) { 134 next = backup ; 135 throw e ; 136 } 137 138 return result ; 139 } 140 141 142 143 150 151 public byte[] fetchOctetString() throws BerException { 152 return fetchOctetString(OctetStringTag) ; 153 } 154 155 156 166 167 public byte[] fetchOctetString(int tag) throws BerException { 168 byte[] result = null ; 169 final int backup = next ; 170 try { 171 if (fetchTag() != tag) { 172 throw new BerException() ; 173 } 174 result = fetchStringValue() ; 175 } 176 catch(BerException e) { 177 next = backup ; 178 throw e ; 179 } 180 181 return result ; 182 } 183 184 185 190 191 public long[] fetchOid() throws BerException { 192 return fetchOid(OidTag) ; 193 } 194 195 196 206 207 public long[] fetchOid(int tag) throws BerException { 208 long[] result = null ; 209 final int backup = next ; 210 try { 211 if (fetchTag() != tag) { 212 throw new BerException() ; 213 } 214 result = fetchOidValue() ; 215 } 216 catch(BerException e) { 217 next = backup ; 218 throw e ; 219 } 220 221 return result ; 222 } 223 224 225 230 231 public void fetchNull() throws BerException { 232 fetchNull(NullTag) ; 233 } 234 235 236 244 245 public void fetchNull(int tag) throws BerException { 246 final int backup = next ; 247 try { 248 if (fetchTag() != tag) { 249 throw new BerException() ; 250 } 251 final int length = fetchLength(); 252 if (length != 0) throw new BerException(); 253 } 254 catch(BerException e) { 255 next = backup ; 256 throw e ; 257 } 258 } 259 260 261 262 270 271 public byte[] fetchAny() throws BerException { 272 byte[] result = null ; 273 final int backup = next ; 274 try { 275 final int tag = fetchTag() ; 276 final int contentLength = fetchLength() ; 277 if (contentLength < 0) throw new BerException() ; 278 final int tlvLength = next + contentLength - backup ; 279 if (contentLength > (bytes.length - next)) 280 throw new IndexOutOfBoundsException ("Decoded length exceeds buffer"); 281 final byte[] data = new byte[tlvLength] ; 282 java.lang.System.arraycopy(bytes,backup,data,0,tlvLength); 283 next = next + contentLength ; 287 result = data; 288 } 289 catch(IndexOutOfBoundsException e) { 290 next = backup ; 291 throw new BerException() ; 292 } 293 298 return result ; 299 } 300 301 302 311 312 public byte[] fetchAny(int tag) throws BerException { 313 if (getTag() != tag) { 314 throw new BerException() ; 315 } 316 return fetchAny() ; 317 } 318 319 320 321 328 329 public void openSequence() throws BerException { 330 openSequence(SequenceTag) ; 331 } 332 333 334 342 343 public void openSequence(int tag) throws BerException { 344 final int backup = next ; 345 try { 346 if (fetchTag() != tag) { 347 throw new BerException() ; 348 } 349 final int l = fetchLength() ; 350 if (l < 0) throw new BerException(); 351 if (l > (bytes.length - next)) throw new BerException(); 352 stackBuf[stackTop++] = next + l ; 353 } 354 catch(BerException e) { 355 next = backup ; 356 throw e ; 357 } 358 } 359 360 361 369 370 public void closeSequence() throws BerException { 371 if (stackBuf[stackTop - 1] == next) { 372 stackTop-- ; 373 } 374 else { 375 throw new BerException() ; 376 } 377 } 378 379 380 387 388 public boolean cannotCloseSequence() { 389 return (next < stackBuf[stackTop - 1]) ; 390 } 391 392 393 399 400 public int getTag() throws BerException { 401 int result = 0 ; 402 final int backup = next ; 403 try { 404 result = fetchTag() ; 405 } 406 finally { 407 next = backup ; 408 } 409 410 return result ; 411 } 412 413 414 415 public String toString() { 416 final StringBuffer result = new StringBuffer (bytes.length * 2) ; 417 for (int i = 0 ; i < bytes.length ; i++) { 418 final int b = (bytes[i] > 0) ? bytes[i] : bytes[i] + 256 ; 419 if (i == next) { 420 result.append("(") ; 421 } 422 result.append(Character.forDigit(b / 16, 16)) ; 423 result.append(Character.forDigit(b % 16, 16)) ; 424 if (i == next) { 425 result.append(")") ; 426 } 427 } 428 if (bytes.length == next) { 429 result.append("()") ; 430 } 431 432 return new String (result) ; 433 } 434 435 436 public final static int BooleanTag = 1 ; 440 public final static int IntegerTag = 2 ; 441 public final static int OctetStringTag = 4 ; 442 public final static int NullTag = 5 ; 443 public final static int OidTag = 6 ; 444 public final static int SequenceTag = 0x30 ; 445 446 447 448 449 451 452 453 458 459 private final int fetchTag() throws BerException { 460 int result = 0 ; 461 final int backup = next ; 462 463 try { 464 final byte b0 = bytes[next++] ; 465 result = (b0 >= 0) ? b0 : b0 + 256 ; 466 if ((result & 31) == 31) { 467 while ((bytes[next] & 128) != 0) { 468 result = result << 7 ; 469 result = result | (bytes[next++] & 127); 470 } 471 } 472 } 473 catch(IndexOutOfBoundsException e) { 474 next = backup ; 475 throw new BerException() ; 476 } 477 478 return result ; 479 } 480 481 482 487 488 private final int fetchLength() throws BerException { 489 int result = 0 ; 490 final int backup = next ; 491 492 try { 493 final byte b0 = bytes[next++] ; 494 if (b0 >= 0) { 495 result = b0 ; 496 } 497 else { 498 for (int c = 128 + b0 ; c > 0 ; c--) { 499 final byte bX = bytes[next++] ; 500 result = result << 8 ; 501 result = result | ((bX >= 0) ? bX : bX+256) ; 502 } 503 } 504 } 505 catch(IndexOutOfBoundsException e) { 506 next = backup ; 507 throw new BerException() ; 508 } 509 510 return result ; 511 } 512 513 514 519 520 private int fetchIntegerValue() throws BerException { 521 int result = 0 ; 522 final int backup = next ; 523 524 try { 525 final int length = fetchLength() ; 526 if (length <= 0) throw new BerException() ; 527 if (length > (bytes.length - next)) throw 528 new IndexOutOfBoundsException ("Decoded length exceeds buffer"); 529 final int end = next + length ; 530 result = bytes[next++] ; 531 while (next < end) { 532 final byte b = bytes[next++] ; 533 if (b < 0) { 534 result = (result << 8) | (256 + b) ; 535 } 536 else { 537 result = (result << 8) | b ; 538 } 539 } 540 } 541 catch(BerException e) { 542 next = backup ; 543 throw e ; 544 } 545 catch(IndexOutOfBoundsException e) { 546 next = backup ; 547 throw new BerException() ; 548 } 549 catch(ArithmeticException e) { 550 next = backup ; 551 throw new BerException() ; 552 } 553 return result ; 554 } 555 556 557 564 565 private final long fetchIntegerValueAsLong() throws BerException { 566 long result = 0 ; 567 final int backup = next ; 568 569 try { 570 final int length = fetchLength() ; 571 if (length <= 0) throw new BerException() ; 572 if (length > (bytes.length - next)) throw 573 new IndexOutOfBoundsException ("Decoded length exceeds buffer"); 574 575 final int end = next + length ; 576 result = bytes[next++] ; 577 while (next < end) { 578 final byte b = bytes[next++] ; 579 if (b < 0) { 580 result = (result << 8) | (256 + b) ; 581 } 582 else { 583 result = (result << 8) | b ; 584 } 585 } 586 } 587 catch(BerException e) { 588 next = backup ; 589 throw e ; 590 } 591 catch(IndexOutOfBoundsException e) { 592 next = backup ; 593 throw new BerException() ; 594 } 595 catch(ArithmeticException e) { 596 next = backup ; 597 throw new BerException() ; 598 } 599 return result ; 600 } 601 602 603 608 609 private byte[] fetchStringValue() throws BerException { 610 byte[] result = null ; 611 final int backup = next ; 612 613 try { 614 final int length = fetchLength() ; 615 if (length < 0) throw new BerException() ; 616 if (length > (bytes.length - next)) 617 throw new IndexOutOfBoundsException ("Decoded length exceeds buffer"); 618 final byte data[] = new byte[length] ; 619 java.lang.System.arraycopy(bytes,next,data,0,length); 620 next += length; 621 result = data; 626 } 627 catch(BerException e) { 628 next = backup ; 629 throw e ; 630 } 631 catch(IndexOutOfBoundsException e) { 632 next = backup ; 633 throw new BerException() ; 634 } 635 catch(ArithmeticException e) { 636 next = backup ; 637 throw new BerException() ; 638 } 639 644 return result ; 645 } 646 647 648 649 654 655 private final long[] fetchOidValue() throws BerException { 656 long[] result = null ; 657 final int backup = next ; 658 659 try { 660 final int length = fetchLength() ; 661 if (length <= 0) throw new BerException() ; 662 if (length > (bytes.length - next)) 663 throw new IndexOutOfBoundsException ("Decoded length exceeds buffer"); 664 int subidCount = 2 ; 667 for (int i = 1 ; i < length ; i++) { 668 if ((bytes[next + i] & 0x80) == 0) { 669 subidCount++ ; 670 } 671 } 672 final int datalen = subidCount; 673 final long[] data = new long[datalen]; 674 final byte b0 = bytes[next++] ; 675 676 if (b0 < 0) throw new BerException(); 679 680 final long lb0 = b0 / 40 ; 683 if (lb0 > 2) throw new BerException(); 684 685 final long lb1 = b0 % 40; 686 data[0] = lb0 ; 687 data[1] = lb1 ; 688 int i = 2 ; 689 while (i < datalen) { 690 long subid = 0 ; 691 byte b = bytes[next++] ; 692 while ((b & 0x80) != 0) { 693 subid = (subid << 7) | (b & 0x7f) ; 694 if (subid < 0) throw new BerException(); 696 b = bytes[next++] ; 697 } 698 subid = (subid << 7) | b ; 699 if (subid < 0) throw new BerException(); 701 data[i++] = subid ; 702 } 703 result = data; 704 } 705 catch(BerException e) { 706 next = backup ; 707 throw e ; 708 } 709 catch(IndexOutOfBoundsException e) { 710 next = backup ; 711 throw new BerException() ; 712 } 713 718 return result ; 719 } 720 721 725 private final byte bytes[]; 729 730 private int next = 0 ; 735 736 private final int stackBuf[] = new int[200] ; 743 private int stackTop = 0 ; 744 745 } 746 747 748 | Popular Tags |