/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.protocols.snmp; import java.io.PrintStream; import java.util.ArrayList; /** * This class provides a set of utilities that may be used by other package * members. This class is not accessable to non-package classes. * * The util class maintains a dynamically created list of SnmpSyntax object that * is uses to lookup received messages. The typeId() method of each SnmpSyntax * object provides the comparision data for the received ASN.1 type. * * @see SnmpInt32 * @see SnmpCounter32 * @see SnmpGauge32 * @see SnmpTimeTicks * @see SnmpOctetString * @see SnmpIPAddress * @see SnmpObjectId * * @author <a href="mailto:weave@oculan.com">Brian Weaver </a> */ class SnmpUtil extends Object { /** * The array of dynamically registred SnmpSyntax objects * */ static ArrayList<SnmpSyntax> m_syntaxArray = null; // // when the class is "created" and initiazlied // be sure to create an array to store the // syntax object into. // static { m_syntaxArray = new ArrayList<SnmpSyntax>(); } /** * Used to register a SnmpSyntax object with the SnmpUtil class. Once * registered it can be dynamically found based on it's typeId(). * * @param obj * The SnmpSyntax object to add * * @return True if the object is successfully added * */ static boolean registerSyntax(SnmpSyntax obj) { boolean rc = false; synchronized (m_syntaxArray) { // // verify that the object is not in // the list already // boolean addIt = true; for (int x = 0; x < m_syntaxArray.size(); x++) { SnmpSyntax tmp = m_syntaxArray.get(x); if (obj.typeId() == tmp.typeId()) { addIt = false; break; } } if (addIt == true) rc = m_syntaxArray.add(obj); } return rc; } /** * Used to dynamically lookup registered SnmpSyntax objects. * * Deprecation warnings are suppressed because the SnmpV2PartyClock * is supported for backward compatability and is deprecated. * * @param asnType * The ASN.1 type to search for * * @return A new SnmpSyntax object of the appropiate type * */ @SuppressWarnings("deprecation") static SnmpSyntax getSyntaxObject(byte asnType) { SnmpSyntax obj = null; switch (asnType) { case SnmpInt32.ASNTYPE: obj = new SnmpInt32(); break; case SnmpCounter32.ASNTYPE: obj = new SnmpCounter32(); break; case SnmpGauge32.ASNTYPE: obj = new SnmpGauge32(); break; case SnmpCounter64.ASNTYPE: obj = new SnmpCounter64(); break; case SnmpTimeTicks.ASNTYPE: obj = new SnmpTimeTicks(); break; case SnmpOctetString.ASNTYPE: obj = new SnmpOctetString(); break; case SnmpOpaque.ASNTYPE: obj = new SnmpOpaque(); break; case SnmpIPAddress.ASNTYPE: obj = new SnmpIPAddress(); break; case SnmpObjectId.ASNTYPE: obj = new SnmpObjectId(); break; case SnmpV2PartyClock.ASNTYPE: obj = new SnmpV2PartyClock(); break; case SnmpNoSuchInstance.ASNTYPE: obj = new SnmpNoSuchInstance(); break; case SnmpNoSuchObject.ASNTYPE: obj = new SnmpNoSuchObject(); break; case SnmpEndOfMibView.ASNTYPE: obj = new SnmpEndOfMibView(); break; case SnmpNull.ASNTYPE: obj = new SnmpNull(); break; } // end case // // If the object is null then search // through user registered objects // see the SnmpSession.registerSyntaxObject // method // if (obj == null) { synchronized (m_syntaxArray) { for (int x = m_syntaxArray.size() - 1; x >= 0; --x) { SnmpSyntax o = m_syntaxArray.get(x); if (asnType == o.typeId()) { obj = o.duplicate(); break; // exit the loop } } } } return obj; } /** * Rotates a give buffer area marked by begin, pivot, and end. The pivot * marks the point where the array between [pivot..end) are moved to the * position marked by begin. The bytes between [begin..pivot) are shifted * such that begin is at [begin+(end-pivot)]. * * @param arrayBuf * The buffer containing the data to rotate * @param begin * The start of the rotation * @param pivot * The pivot point for the rotation * @param end * The end of the rotational buffer * */ static void rotate(byte[] arrayBuf, int begin, int pivot, int end) { // The amount of data to move between the pivot point // and the end of the buffer // int pedist = end - pivot; int bpdist = pivot - begin; // Allocate an array to hold half of the moving buffer // byte[] hold = new byte[pedist]; // Copy to the back half of the rotating buffer to the // hold area // System.arraycopy(arrayBuf, // source pivot, // source offset hold, // destination 0, // destination offset pedist); // length // Move the front half to the back half // System.arraycopy(arrayBuf, // source begin, // source offset arrayBuf, // destination begin + pedist,// destination offset bpdist); // length System.arraycopy(hold, // source 0, // source offset arrayBuf, // destination begin, // destination offset pedist); // length } /** * Dumps an array of byte to the output string as a sequence of hexadecimal * digits. * * @param out * The output stream * @param data * The data to dump * @param offset * The start location within the data * @param length * The length of data to dump * */ static void dumpHex(PrintStream out, byte[] data, int offset, int length) { if ((offset + length) > data.length) return; int cnt = 0; while (length > 0) { byte b = data[offset]; out.print("0x"); out.print(Integer.toHexString((b >> 4) & 0xf)); out.print(Integer.toHexString(b & 0xf)); out.print(" "); --length; offset++; if ((cnt++ % 16) == 0 && cnt != 1) out.println(""); } } }