1 11 12 13 package com.sun.jmx.snmp.agent; 14 15 16 17 import java.io.Serializable ; 20 import java.util.Date ; 21 import java.util.Vector ; 22 import java.util.Enumeration ; 23 24 import javax.management.Notification ; 27 import javax.management.ObjectName ; 28 import javax.management.NotificationFilter ; 29 import javax.management.NotificationListener ; 30 import javax.management.NotificationBroadcaster ; 31 import javax.management.MBeanNotificationInfo ; 32 import javax.management.ListenerNotFoundException ; 33 import com.sun.jmx.snmp.SnmpOid; 34 import com.sun.jmx.snmp.SnmpValue; 35 import com.sun.jmx.snmp.SnmpInt; 36 import com.sun.jmx.snmp.SnmpVarBind; 37 import com.sun.jmx.snmp.SnmpStatusException; 38 39 import com.sun.jmx.snmp.EnumRowStatus; 40 import com.sun.jmx.trace.Trace; 41 42 80 81 public abstract class SnmpMibTable extends SnmpMibNode 82 implements NotificationBroadcaster , Serializable { 83 84 90 public SnmpMibTable(SnmpMib mib) { 91 this.theMib= mib; 92 setCreationEnabled(false); 93 } 94 95 99 121 public abstract void createNewEntry(SnmpMibSubRequest req, SnmpOid rowOid, 122 int depth) 123 throws SnmpStatusException; 124 125 139 public abstract boolean isRegistrationRequired(); 140 141 148 public boolean isCreationEnabled() { 149 return creationEnabled; 150 } 151 152 168 public void setCreationEnabled(boolean remoteCreationFlag) { 169 creationEnabled = remoteCreationFlag; 170 } 171 172 209 public boolean hasRowStatus() { 210 return false; 211 } 212 213 262 public void get(SnmpMibSubRequest req, int depth) 263 throws SnmpStatusException { 264 265 final boolean isnew = req.isNewEntry(); 266 final SnmpMibSubRequest r = req; 267 268 if (isnew) { 272 SnmpVarBind var = null; 273 for (Enumeration e= r.getElements(); e.hasMoreElements();) { 274 var = (SnmpVarBind) e.nextElement(); 275 r.registerGetException(var,noSuchInstanceException); 276 } 277 } 278 279 final SnmpOid oid = r.getEntryOid(); 280 281 get(req,oid,depth+1); 285 } 286 287 325 public void check(SnmpMibSubRequest req, int depth) 326 throws SnmpStatusException { 327 final SnmpOid oid = req.getEntryOid(); 328 final int action = getRowAction(req,oid,depth+1); 329 330 final boolean dbg = isDebugOn(); 331 332 if (dbg) debug("check","Calling beginRowAction"); 333 334 beginRowAction(req,oid,depth+1,action); 335 336 if (dbg) debug("check","Calling check for " + req.getSize() + 337 " varbinds."); 338 339 check(req,oid,depth+1); 340 341 if (dbg) debug("check","check finished"); 342 } 343 344 378 public void set(SnmpMibSubRequest req, int depth) 379 throws SnmpStatusException { 380 381 final boolean dbg = isDebugOn(); 382 if (dbg) debug("set","Entering set."); 383 384 final SnmpOid oid = req.getEntryOid(); 385 final int action = getRowAction(req,oid,depth+1); 386 387 if (dbg) debug("set","Calling set for " + req.getSize() + 388 "varbinds."); 389 390 set(req,oid,depth+1); 391 392 if (dbg) debug("set","Calling endRowAction"); 393 394 endRowAction(req,oid,depth+1,action); 395 396 if (dbg) debug("set","RowAction finished"); 397 } 398 399 400 423 public void addEntry(SnmpOid rowOid, Object entry) 425 throws SnmpStatusException { 426 427 addEntry(rowOid, null, entry); 428 } 429 430 451 public synchronized void addEntry(SnmpOid oid, ObjectName name, 454 Object entry) 455 throws SnmpStatusException { 456 457 if (isRegistrationRequired() == true && name == null) 458 throw new SnmpStatusException(SnmpStatusException.badValue); 459 460 if (size == 0) { 461 insertOid(0,oid); 464 if (entries != null) 465 entries.addElement(entry); 466 if (entrynames != null) 467 entrynames.addElement(name); 468 size++; 469 470 if (factory != null) { 473 try { 474 factory.addEntryCb(0,oid,name,entry,this); 475 } catch (SnmpStatusException x) { 476 removeOid(0); 477 if (entries != null) 478 entries.removeElementAt(0); 479 if (entrynames != null) 480 entrynames.removeElementAt(0); 481 throw x; 482 } 483 } 484 485 sendNotification(SnmpTableEntryNotification.SNMP_ENTRY_ADDED, 488 (new Date ()).getTime(), entry, name); 489 return; 490 } 491 492 int pos= 0; 495 pos= getInsertionPoint(oid,true); 499 if (pos == size) { 500 insertOid(tablecount,oid); 505 if (entries != null) 506 entries.addElement(entry); 507 if (entrynames != null) 508 entrynames.addElement(name); 509 size++; 510 } else { 511 try { 514 insertOid(pos,oid); 517 if (entries != null) 518 entries.insertElementAt(entry, pos); 519 if (entrynames != null) 520 entrynames.insertElementAt(name,pos); 521 size++; 522 } catch(ArrayIndexOutOfBoundsException e) { 523 } 524 } 525 526 if (factory != null) { 529 try { 530 factory.addEntryCb(pos,oid,name,entry,this); 531 } catch (SnmpStatusException x) { 532 removeOid(pos); 533 if (entries != null) 534 entries.removeElementAt(pos); 535 if (entrynames != null) 536 entrynames.removeElementAt(pos); 537 throw x; 538 } 539 } 540 541 sendNotification(SnmpTableEntryNotification.SNMP_ENTRY_ADDED, 544 (new Date ()).getTime(), entry, name); 545 } 546 547 565 public synchronized void removeEntry(SnmpOid rowOid, Object entry) 566 throws SnmpStatusException { 567 int pos = findObject(rowOid); 568 if (pos == -1) 569 return; 570 removeEntry(pos,entry); 571 } 572 573 587 public void removeEntry(SnmpOid rowOid) 588 throws SnmpStatusException { 589 int pos = findObject(rowOid); 590 if (pos == -1) 591 return; 592 removeEntry(pos,null); 593 } 594 595 611 public synchronized void removeEntry(int pos, Object entry) 612 throws SnmpStatusException { 613 if (pos == -1) 614 return; 615 if (pos >= size) return; 616 617 Object obj = entry; 618 if (entries != null && entries.size() > pos) { 619 obj = entries.elementAt(pos); 620 entries.removeElementAt(pos); 621 } 622 623 ObjectName name = null; 624 if (entrynames != null && entrynames.size() > pos) { 625 name = (ObjectName ) entrynames.elementAt(pos); 626 entrynames.removeElementAt(pos); 627 } 628 629 final SnmpOid rowOid = tableoids[pos]; 630 removeOid(pos); 631 size --; 632 633 if (obj == null) obj = entry; 634 635 if (factory != null) 636 factory.removeEntryCb(pos,rowOid,name,obj,this); 637 638 sendNotification(SnmpTableEntryNotification.SNMP_ENTRY_REMOVED, 639 (new Date ()).getTime(), obj, name); 640 } 641 642 654 public synchronized Object getEntry(SnmpOid rowOid) 655 throws SnmpStatusException { 656 int pos= findObject(rowOid); 657 if (pos == -1) 658 throw new SnmpStatusException(SnmpStatusException.noSuchInstance); 659 return entries.elementAt(pos); 660 } 661 662 677 public synchronized ObjectName getEntryName(SnmpOid rowOid) 678 throws SnmpStatusException { 679 int pos = findObject(rowOid); 680 if (entrynames == null) return null; 681 if (pos == -1 || pos >= entrynames.size()) 682 throw new SnmpStatusException(SnmpStatusException.noSuchInstance); 683 return (ObjectName ) entrynames.elementAt(pos); 684 } 685 686 699 public Object [] getBasicEntries() { 700 Object [] array= new Object [size]; 701 entries.copyInto(array); 702 return array; 703 } 704 705 710 public int getSize() { 711 return size; 712 } 713 714 717 733 public synchronized void 734 addNotificationListener(NotificationListener listener, 735 NotificationFilter filter, Object handback) { 736 737 if (listener == null) { 740 throw new java.lang.IllegalArgumentException 741 ("Listener can't be null") ; 742 } 743 744 java.util.Vector handbackList = 747 (java.util.Vector ) handbackTable.get(listener) ; 748 java.util.Vector filterList = 749 (java.util.Vector ) filterTable.get(listener) ; 750 if ( handbackList == null ) { 751 handbackList = new java.util.Vector () ; 752 filterList = new java.util.Vector () ; 753 handbackTable.put(listener, handbackList) ; 754 filterTable.put(listener, filterList) ; 755 } 756 757 handbackList.addElement(handback) ; 760 filterList.addElement(filter) ; 761 } 762 763 775 public synchronized void 776 removeNotificationListener(NotificationListener listener) 777 throws ListenerNotFoundException { 778 779 java.util.Vector handbackList = 782 (java.util.Vector ) handbackTable.get(listener) ; 783 java.util.Vector filterList = 784 (java.util.Vector ) filterTable.get(listener) ; 785 if ( handbackList == null ) { 786 throw new ListenerNotFoundException ("listener"); 787 } 788 789 handbackTable.remove(listener) ; 792 filterTable.remove(listener) ; 793 } 794 795 800 public MBeanNotificationInfo [] getNotificationInfo() { 801 802 String [] types = {SnmpTableEntryNotification.SNMP_ENTRY_ADDED, 803 SnmpTableEntryNotification.SNMP_ENTRY_REMOVED}; 804 805 MBeanNotificationInfo [] notifsInfo = { 806 new MBeanNotificationInfo 807 (types, "com.sun.jmx.snmp.agent.SnmpTableEntryNotification", 808 "Notifications sent by the SnmpMibTable") 809 }; 810 811 return notifsInfo; 812 } 813 814 815 825 public void registerEntryFactory(SnmpTableEntryFactory factory) { 826 this.factory = factory; 827 } 828 829 833 861 protected boolean isRowStatus(SnmpOid rowOid, long var, 862 Object userData) { 863 return false; 864 } 865 866 867 903 protected int getRowAction(SnmpMibSubRequest req, SnmpOid rowOid, 904 int depth) 905 throws SnmpStatusException { 906 final boolean isnew = req.isNewEntry(); 907 final SnmpVarBind vb = req.getRowStatusVarBind(); 908 if (vb == null) { 909 if (isnew && ! hasRowStatus()) 910 return EnumRowStatus.createAndGo; 911 else return EnumRowStatus.unspecified; 912 } 913 914 try { 915 return mapRowStatus(rowOid, vb, req.getUserData()); 916 } catch( SnmpStatusException x) { 917 checkRowStatusFail(req, x.getStatus()); 918 } 919 return EnumRowStatus.unspecified; 920 } 921 922 961 protected int mapRowStatus(SnmpOid rowOid, SnmpVarBind vbstatus, 962 Object userData) 963 throws SnmpStatusException { 964 final SnmpValue rsvalue = vbstatus.value; 965 966 if (rsvalue instanceof SnmpInt) 967 return ((SnmpInt)rsvalue).intValue(); 968 else 969 throw new SnmpStatusException( 970 SnmpStatusException.snmpRspInconsistentValue); 971 } 972 973 1019 protected SnmpValue setRowStatus(SnmpOid rowOid, int newStatus, 1020 Object userData) 1021 throws SnmpStatusException { 1022 return null; 1023 } 1024 1025 1071 protected boolean isRowReady(SnmpOid rowOid, Object userData) 1072 throws SnmpStatusException { 1073 return true; 1074 } 1075 1076 1110 protected void checkRowStatusChange(SnmpMibSubRequest req, 1111 SnmpOid rowOid, int depth, 1112 int newStatus) 1113 throws SnmpStatusException { 1114 1115 } 1116 1117 1141 protected void checkRemoveTableRow(SnmpMibSubRequest req, SnmpOid rowOid, 1142 int depth) 1143 throws SnmpStatusException { 1144 1145 } 1146 1147 1183 protected void removeTableRow(SnmpMibSubRequest req, SnmpOid rowOid, 1184 int depth) 1185 throws SnmpStatusException { 1186 1187 removeEntry(rowOid); 1188 } 1189 1190 1237 protected synchronized void beginRowAction(SnmpMibSubRequest req, 1238 SnmpOid rowOid, int depth, int rowAction) 1239 throws SnmpStatusException { 1240 final boolean isnew = req.isNewEntry(); 1241 final SnmpOid oid = rowOid; 1242 final int action = rowAction; 1243 1244 switch (action) { 1245 case EnumRowStatus.unspecified: 1246 if (isnew) { 1247 if (isDebugOn()) 1248 debug("beginRowAction","Failed to create row[" + rowOid + 1249 "] : RowStatus = unspecified"); 1250 checkRowStatusFail(req,SnmpStatusException.snmpRspNoAccess); 1251 } 1252 break; 1253 case EnumRowStatus.createAndGo: 1254 case EnumRowStatus.createAndWait: 1255 if (isnew) { 1256 if (isCreationEnabled()) { 1257 if (isDebugOn()) 1258 debug("beginRowAction","Creating row[" + rowOid + 1259 "] : RowStatus = createAndGo | createAndWait"); 1260 createNewEntry(req,oid,depth); 1261 } else { 1262 if (isDebugOn()) 1263 debug("beginRowAction","Can't create row[" + rowOid + 1264 "] : RowStatus = createAndGo | createAndWait" + 1265 " but creation is disabled"); 1266 checkRowStatusFail(req, 1267 SnmpStatusException.snmpRspNoAccess); 1268 } 1269 } else { 1270 if (isDebugOn()) 1271 debug("beginRowAction","Can't create row[" + rowOid + 1272 "] : RowStatus = createAndGo | createAndWait" + 1273 " but row already exists"); 1274 checkRowStatusFail(req, 1275 SnmpStatusException.snmpRspInconsistentValue); 1276 } 1277 break; 1278 case EnumRowStatus.destroy: 1279 if (isnew) { 1280 if (isDebugOn()) 1281 debug("beginRowAction","Warning: can't destroy row[" + 1282 rowOid + "] : RowStatus = destroy" + 1283 " but row does not exist"); 1284 } else if (!isCreationEnabled()) { 1285 if (isDebugOn()) 1286 debug("beginRowAction","Can't destroy row[" + rowOid + 1287 "] : RowStatus = destroy " + 1288 " but creation is disabled"); 1289 checkRowStatusFail(req,SnmpStatusException.snmpRspNoAccess); 1290 } 1291 checkRemoveTableRow(req,rowOid,depth); 1292 break; 1293 case EnumRowStatus.active: 1294 case EnumRowStatus.notInService: 1295 if (isnew) { 1296 if (isDebugOn()) 1297 debug("beginRowAction","Can't switch state of row[" + 1298 rowOid + 1299 "] : specified RowStatus = active | notInService" + 1300 " but row does not exist"); 1301 checkRowStatusFail(req, 1302 SnmpStatusException.snmpRspInconsistentValue); 1303 } 1304 checkRowStatusChange(req,rowOid,depth,action); 1305 break; 1306 case EnumRowStatus.notReady: 1307 default: 1308 if (isDebugOn()) 1309 debug("beginRowAction","Invalid RowStatus value for row[" + 1310 rowOid + "] : specified RowStatus = " + action); 1311 checkRowStatusFail(req, 1312 SnmpStatusException.snmpRspInconsistentValue); 1313 } 1314 } 1315 1316 1364 protected void endRowAction(SnmpMibSubRequest req, SnmpOid rowOid, 1365 int depth, int rowAction) 1366 throws SnmpStatusException { 1367 final boolean isnew = req.isNewEntry(); 1368 final SnmpOid oid = rowOid; 1369 final int action = rowAction; 1370 final Object data = req.getUserData(); 1371 SnmpValue value = null; 1372 1373 switch (action) { 1374 case EnumRowStatus.unspecified: 1375 break; 1376 case EnumRowStatus.createAndGo: 1377 if (isDebugOn()) 1378 debug("endRowAction","Setting RowStatus to `active'" + 1379 " for row[" + rowOid + "] : requested RowStatus = " 1380 + "createAndGo"); 1381 value = setRowStatus(oid,EnumRowStatus.active,data); 1382 break; 1383 case EnumRowStatus.createAndWait: 1384 if (isRowReady(oid,data)) { 1385 if (isDebugOn()) 1386 debug("endRowAction", 1387 "Setting RowStatus to `notInService'" + 1388 " for row[" + rowOid + "] : requested RowStatus = " 1389 + "createAndWait"); 1390 value = setRowStatus(oid,EnumRowStatus.notInService,data); 1391 } else { 1392 if (isDebugOn()) 1393 debug("endRowAction", 1394 "Setting RowStatus to `notReady'" + 1395 " for row[" + rowOid + "] : requested RowStatus = " 1396 + "createAndWait"); 1397 value = setRowStatus(oid,EnumRowStatus.notReady,data); 1398 } 1399 break; 1400 case EnumRowStatus.destroy: 1401 if (isnew) { 1402 if (isDebugOn()) 1403 debug("endRowAction", 1404 "Warning: " + " requested RowStatus = destroy," + 1405 "but row[" + rowOid + "] does not exist."); 1406 } else { 1407 if (isDebugOn()) 1408 debug("endRowAction", 1409 "destroying row[" + rowOid + 1410 "] : requested RowStatus = destroy"); 1411 } 1412 removeTableRow(req,oid,depth); 1413 break; 1414 case EnumRowStatus.active: 1415 if (isDebugOn()) 1416 debug("endRowAction", 1417 "Setting RowStatus to `active'" + 1418 " for row[" + rowOid + "] : requested RowStatus = " 1419 + "active"); 1420 value = setRowStatus(oid,EnumRowStatus.active,data); 1421 break; 1422 case EnumRowStatus.notInService: 1423 if (isDebugOn()) 1424 debug("endRowAction", 1425 "Setting RowStatus to `notInService'" + 1426 " for row[" + rowOid + "] : requested RowStatus = " 1427 + "notInService"); 1428 value = setRowStatus(oid,EnumRowStatus.notInService,data); 1429 break; 1430 case EnumRowStatus.notReady: 1431 default: 1432 if (isDebugOn()) 1433 debug("endRowAction","Invalid RowStatus value for row[" + 1434 rowOid + "] : specified RowStatus = " + action); 1435 setRowStatusFail(req, 1436 SnmpStatusException.snmpRspInconsistentValue); 1437 } 1438 if (value != null) { 1439 final SnmpVarBind vb = req.getRowStatusVarBind(); 1440 if (vb != null) vb.value = value; 1441 } 1442 } 1443 1444 1448 1476 protected long getNextVarEntryId(SnmpOid rowOid, 1477 long var, 1478 Object userData, 1479 int pduVersion) 1480 throws SnmpStatusException { 1481 1482 long varid=var; 1483 do { 1484 varid = getNextVarEntryId(rowOid,varid,userData); 1485 } while (skipEntryVariable(rowOid,varid,userData,pduVersion)); 1486 1487 return varid; 1488 } 1489 1490 1514 protected boolean skipEntryVariable(SnmpOid rowOid, 1515 long var, 1516 Object userData, 1517 int pduVersion) { 1518 return false; 1519 } 1520 1521 1539 protected SnmpOid getNextOid(SnmpOid oid, Object userData) 1540 throws SnmpStatusException { 1541 1542 if (size == 0) 1543 throw noSuchInstanceException; 1544 1545 final SnmpOid resOid = oid; 1546 1547 SnmpOid last= tableoids[tablecount-1]; 1551 if (last.equals(resOid)) { 1552 throw noSuchInstanceException; 1555 } 1556 1557 1563 final int newPos = getInsertionPoint(resOid,false); 1567 1568 if (newPos > -1 && newPos < size) { 1572 try { 1573 last = tableoids[newPos]; 1575 } catch(ArrayIndexOutOfBoundsException e) { 1576 throw noSuchInstanceException; 1577 } 1578 } else { 1579 throw noSuchInstanceException; 1582 } 1583 1584 1585 return last; 1586 } 1587 1588 1601 protected SnmpOid getNextOid(Object userData) 1602 throws SnmpStatusException { 1603 if (size == 0) 1604 throw noSuchInstanceException; 1605 return tableoids[0]; 1607 } 1608 1609 1613 1635 abstract protected long getNextVarEntryId(SnmpOid rowOid, long var, 1636 Object userData) 1637 throws SnmpStatusException; 1638 1639 1656 abstract protected void validateVarEntryId(SnmpOid rowOid, long var, 1657 Object userData) 1658 throws SnmpStatusException; 1659 1660 1678 abstract protected boolean isReadableEntryId(SnmpOid rowOid, long var, 1679 Object userData) 1680 throws SnmpStatusException; 1681 1682 1686 abstract protected void get(SnmpMibSubRequest req, 1687 SnmpOid rowOid, int depth) 1688 throws SnmpStatusException; 1689 1690 1694 abstract protected void check(SnmpMibSubRequest req, 1695 SnmpOid rowOid, int depth) 1696 throws SnmpStatusException; 1697 1698 1702 abstract protected void set(SnmpMibSubRequest req, 1703 SnmpOid rowOid, int depth) 1704 throws SnmpStatusException; 1705 1706 1710 1731 SnmpOid getNextOid(long[] oid, int pos, Object userData) 1732 throws SnmpStatusException { 1733 1734 final SnmpOid resOid = new SnmpEntryOid(oid,pos); 1739 1740 return getNextOid(resOid,userData); 1741 } 1742 1743 1749 final static void checkRowStatusFail(SnmpMibSubRequest req, 1750 int errorStatus) 1751 throws SnmpStatusException { 1752 final SnmpVarBind statusvb = req.getRowStatusVarBind(); 1753 final SnmpStatusException x = new SnmpStatusException(errorStatus); 1754 req.registerCheckException(statusvb,x); 1755 } 1756 1757 1763 final static void setRowStatusFail(SnmpMibSubRequest req, 1764 int errorStatus) 1765 throws SnmpStatusException { 1766 final SnmpVarBind statusvb = req.getRowStatusVarBind(); 1767 final SnmpStatusException x = new SnmpStatusException(errorStatus); 1768 req.registerSetException(statusvb,x); 1769 } 1770 1771 final synchronized void findHandlingNode(SnmpVarBind varbind, 1777 long[] oid, int depth, 1778 SnmpRequestTree handlers) 1779 throws SnmpStatusException { 1780 1781 final int length = oid.length; 1782 1783 if (handlers == null) 1784 throw new SnmpStatusException(SnmpStatusException.snmpRspGenErr); 1785 1786 if (depth >= length) 1787 throw new SnmpStatusException(SnmpStatusException.noAccess); 1788 1789 if (oid[depth] != nodeId) 1790 throw new SnmpStatusException(SnmpStatusException.noAccess); 1791 1792 if (depth+2 >= length) 1793 throw new SnmpStatusException(SnmpStatusException.noAccess); 1794 1795 1798 final SnmpOid entryoid = new SnmpEntryOid(oid, depth+2); 1800 1801 final Object data = handlers.getUserData(); 1803 final boolean hasEntry = contains(entryoid, data); 1804 1805 if (!hasEntry) { 1809 if (!handlers.isCreationAllowed()) 1810 throw noSuchInstanceException; 1812 else if (!isCreationEnabled()) 1813 throw new 1815 SnmpStatusException(SnmpStatusException.snmpRspNoAccess); 1816 } 1817 1818 final long var = oid[depth+1]; 1819 1820 if (hasEntry) { 1822 validateVarEntryId(entryoid,var,data); 1824 } 1825 1826 if (handlers.isSetRequest() && isRowStatus(entryoid,var,data)) 1829 1830 handlers.add(this,depth,entryoid,varbind,(!hasEntry),varbind); 1833 1834 else 1835 handlers.add(this,depth,entryoid,varbind,(!hasEntry)); 1836 } 1837 1838 1839 final synchronized long[] findNextHandlingNode(SnmpVarBind varbind, 1846 long[] oid, int pos, int depth, 1847 SnmpRequestTree handlers, 1848 AcmChecker checker) 1849 throws SnmpStatusException { 1850 int length = oid.length; 1851 1852 if (handlers == null) 1853 throw noSuchObjectException; 1858 1859 final Object data = handlers.getUserData(); 1860 final int pduVersion = handlers.getRequestPduVersion(); 1861 1862 long var= -1; 1863 1864 if (pos >= length) { 1873 oid = new long[1]; 1882 oid[0] = nodeId; 1883 pos = 0; 1884 length = 1; 1885 } else if (oid[pos] > nodeId) { 1886 throw noSuchObjectException; 1892 } else if (oid[pos] < nodeId) { 1893 oid = new long[1]; 1899 oid[0] = nodeId; 1900 pos = 0; 1901 length = 0; 1902 } else if ((pos + 1) < length) { 1903 var = oid[pos+1]; 1907 } 1908 1909 SnmpOid entryoid = null ; 1911 1912 if (pos == (length - 1)) { 1913 entryoid = getNextOid(data); 1926 var = getNextVarEntryId(entryoid,var,data,pduVersion); 1927 } else if ( pos == (length-2)) { 1928 entryoid = getNextOid(data); 1938 1939 if (skipEntryVariable(entryoid,var,data,pduVersion)) { 1946 var = getNextVarEntryId(entryoid,var,data,pduVersion); 1947 } 1948 } else { 1949 1950 1960 try { 1971 entryoid = getNextOid(oid, pos + 2, data); 1972 1973 if (skipEntryVariable(entryoid,var,data,pduVersion)) 1982 throw noSuchObjectException; 1983 } catch(SnmpStatusException se) { 1984 entryoid = getNextOid(data); 1985 var = getNextVarEntryId(entryoid,var,data,pduVersion); 1986 } 1987 } 1988 1989 return findNextAccessibleOid(entryoid, 1990 varbind, 1991 oid, 1992 depth, 1993 handlers, 1994 checker, 1995 data, 1996 var); 1997 } 1998 1999 private long[] findNextAccessibleOid(SnmpOid entryoid, 2000 SnmpVarBind varbind,long[] oid, 2001 int depth, SnmpRequestTree handlers, 2002 AcmChecker checker, Object data, 2003 long var) 2004 throws SnmpStatusException { 2005 final int pduVersion = handlers.getRequestPduVersion(); 2006 2007 while(true) { 2009 if (entryoid == null || var == -1 ) throw noSuchObjectException; 2016 2017 2018 2021 try { 2022 if (!isReadableEntryId(entryoid,var,data)) 2028 throw noSuchObjectException; 2029 2030 final long[] etable = entryoid.longValue(false); 2033 final int elength = etable.length; 2034 final long[] result = new long[depth + 2 + elength]; 2035 result[0] = -1 ; 2037 java.lang.System.arraycopy(etable, 0, result, 2040 depth+2, elength); 2041 2042 result[depth] = nodeId; 2045 result[depth+1] = var; 2046 2047 checker.add(depth,result,depth,elength+2); 2050 2051 try { 2053 checker.checkCurrentOid(); 2054 2055 handlers.add(this,depth,entryoid,varbind,false); 2060 return result; 2061 } catch(SnmpStatusException e) { 2062 entryoid = getNextOid(entryoid, data); 2067 } finally { 2068 checker.remove(depth,elength+2); 2071 } 2072 } catch(SnmpStatusException e) { 2073 entryoid = getNextOid(data); 2078 2079 var = getNextVarEntryId(entryoid,var,data,pduVersion); 2082 2083 } 2084 2085 if (entryoid == null || var == -1 ) 2092 throw noSuchObjectException; 2093 } 2094 } 2095 2096 2097 2107 final void validateOid(long[] oid, int pos) throws SnmpStatusException { 2108 final int length= oid.length; 2109 2110 if (pos +2 >= length) 2113 throw noSuchInstanceException; 2114 2115 if (oid[pos] != nodeId) 2118 throw noSuchObjectException; 2119 2120 } 2121 2122 2126 2132 private synchronized void sendNotification(Notification notification) { 2133 2134 for(java.util.Enumeration k = handbackTable.keys(); 2137 k.hasMoreElements(); ) { 2138 2139 NotificationListener listener = 2140 (NotificationListener ) k.nextElement(); 2141 2142 java.util.Vector handbackList = 2145 (java.util.Vector ) handbackTable.get(listener) ; 2146 java.util.Vector filterList = 2147 (java.util.Vector ) filterTable.get(listener) ; 2148 2149 java.util.Enumeration f = filterList.elements(); 2152 for(java.util.Enumeration h = handbackList.elements(); 2153 h.hasMoreElements(); ) { 2154 2155 Object handback = h.nextElement(); 2156 NotificationFilter filter = 2157 (NotificationFilter )f.nextElement(); 2158 2159 if ((filter == null) || 2160 ((filter != null) && 2161 (filter.isNotificationEnabled(notification)))) { 2162 2163 listener.handleNotification(notification,handback) ; 2164 } 2165 } 2166 } 2167 } 2168 2169 2181 private void sendNotification(String type, long timeStamp, 2182 Object entry, ObjectName name) { 2183 2184 synchronized(this) { 2185 sequenceNumber = sequenceNumber + 1; 2186 } 2187 2188 SnmpTableEntryNotification notif = 2189 new SnmpTableEntryNotification(type, this, sequenceNumber, 2190 timeStamp, entry, name); 2191 2192 this.sendNotification(notif) ; 2193 } 2194 2195 2222 protected boolean contains(SnmpOid oid, Object userData) { 2223 return (findObject(oid) > -1); 2224 } 2225 2226 2237 private final int findObject(SnmpOid oid) { 2238 int low= 0; 2239 int max= size - 1; 2240 SnmpOid pos; 2241 int comp; 2242 int curr= low + (max-low)/2; 2243 while (low <= max) { 2245 2246 pos = tableoids[curr]; 2248 2249 comp = oid.compareTo(pos); 2253 if (comp == 0) 2254 return curr; 2255 2256 if (oid.equals(pos) == true) { 2257 return curr; 2258 } 2259 if (comp > 0) { 2260 low = curr + 1; 2261 } else { 2262 max = curr - 1; 2263 } 2264 curr = low + (max-low)/2; 2265 } 2266 return -1; 2267 } 2268 2269 2283 private final int getInsertionPoint(SnmpOid oid) 2284 throws SnmpStatusException { 2285 return getInsertionPoint(oid, true); 2286 } 2287 2288 2308 private final int getInsertionPoint(SnmpOid oid, boolean fail) 2309 throws SnmpStatusException { 2310 2311 final int failStatus = SnmpStatusException.snmpRspNotWritable; 2312 int low= 0; 2313 int max= size - 1; 2314 SnmpOid pos; 2315 int comp; 2316 int curr= low + (max-low)/2; 2317 while (low <= max) { 2318 2319 pos= tableoids[curr]; 2321 2322 comp= oid.compareTo(pos); 2325 2326 if (comp == 0) { 2327 if (fail) 2328 throw new SnmpStatusException(failStatus,curr); 2329 else 2330 return curr+1; 2331 } 2332 2333 if (comp>0) { 2334 low= curr +1; 2335 } else { 2336 max= curr -1; 2337 } 2338 curr= low + (max-low)/2; 2339 } 2340 return curr; 2341 } 2342 2343 2350 private final void removeOid(int pos) { 2351 if (pos >= tablecount) return; 2352 if (pos < 0) return; 2353 final int l1 = --tablecount-pos; 2354 tableoids[pos] = null; 2355 if (l1 > 0) 2356 java.lang.System.arraycopy(tableoids,pos+1,tableoids,pos,l1); 2357 tableoids[tablecount] = null; 2358 } 2359 2360 2368 private final void insertOid(int pos, SnmpOid oid) { 2369 if (pos >= tablesize || tablecount == tablesize) { 2370 2372 final SnmpOid[] olde = tableoids; 2374 2375 tablesize += Delta; 2377 tableoids = new SnmpOid[tablesize]; 2378 2379 if (pos > tablecount) pos = tablecount; 2381 if (pos < 0) pos = 0; 2382 2383 final int l1 = pos; 2384 final int l2 = tablecount - pos; 2385 2386 if (l1 > 0) 2388 java.lang.System.arraycopy(olde,0,tableoids,0,l1); 2389 2390 if (l2 > 0) 2393 java.lang.System.arraycopy(olde,l1,tableoids, 2394 l1+1,l2); 2395 2396 } else if (pos < tablecount) { 2397 2402 java.lang.System.arraycopy(tableoids,pos,tableoids, 2403 pos+1,tablecount-pos); 2404 } 2405 2406 tableoids[pos] = oid; 2408 tablecount++; 2409 } 2410 2411 2412 private final static boolean isDebugOn() { 2414 return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP); 2415 } 2416 2417 private final void debug(String func, String info) { 2419 Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP, 2420 getClass().getName(), func, info); 2421 } 2422 2423 2427 2431 protected int nodeId=1; 2432 2433 2437 protected SnmpMib theMib; 2438 2439 2445 protected boolean creationEnabled = false; 2446 2447 2450 protected SnmpTableEntryFactory factory = null; 2451 2452 2456 2460 private int size=0; 2461 2462 2466 2468 2472 private final static int Delta = 16; 2474 private int tablecount = 0; 2475 private int tablesize = Delta; 2476 private SnmpOid tableoids[] = new SnmpOid[tablesize]; 2477 2478 2482 private final Vector entries= new Vector (); 2483 2484 2488 private final Vector entrynames= new Vector (); 2489 2490 2493 2495 2498 private java.util.Hashtable handbackTable = new java.util.Hashtable (); 2499 2500 2503 private java.util.Hashtable filterTable = new java.util.Hashtable (); 2504 2505 2511 transient long sequenceNumber = 0; 2512} 2513 | Popular Tags |