Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/jmx/snmp/SnmpMsg.java
38924 views
/*1* Copyright (c) 2001, 2006, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.jmx.snmp;2627import com.sun.jmx.snmp.SnmpSecurityParameters;28// java imports29//30import java.util.Vector;31import java.net.InetAddress;323334import com.sun.jmx.snmp.SnmpStatusException;35/**36* A partially decoded representation of an SNMP packet. It contains37* the information contained in any SNMP message (SNMPv1, SNMPv2 or38* SNMPv3).39* <p><b>This API is a Sun Microsystems internal API and is subject40* to change without notice.</b></p>41* @since 1.542*/43public abstract class SnmpMsg implements SnmpDefinitions {44/**45* The protocol version.46* <P><CODE>decodeMessage</CODE> and <CODE>encodeMessage</CODE> do not47* perform any check on this value.48* <BR><CODE>decodeSnmpPdu</CODE> and <CODE>encodeSnmpPdu</CODE> only49* accept the values 0 (for SNMPv1), 1 (for SNMPv2) and 3 (for SNMPv3).50*/51public int version = 0;5253/**54* Encoding of the PDU.55* <P>This is usually the BER encoding of the PDU's syntax56* defined in RFC1157 and RFC1902. However, this can be authenticated57* or encrypted data (but you need to implemented your own58* <CODE>SnmpPduFactory</CODE> class).59*/60public byte[] data = null;6162/**63* Number of useful bytes in the <CODE>data</CODE> field.64*/65public int dataLength = 0;6667/**68* Source or destination address.69* <BR>For an incoming message it's the source.70* For an outgoing message it's the destination.71*/72public InetAddress address = null;7374/**75* Source or destination port.76* <BR>For an incoming message it's the source.77* For an outgoing message it's the destination.78*/79public int port = 0;80/**81* Security parameters. Contain informations according to Security Model (Usm, community string based, ...).82*/83public SnmpSecurityParameters securityParameters = null;84/**85* Returns the encoded SNMP version present in the passed byte array.86* @param data The unmarshalled SNMP message.87* @return The SNMP version (0, 1 or 3).88*/89public static int getProtocolVersion(byte[] data)90throws SnmpStatusException {91int version = 0;92BerDecoder bdec = null;93try {94bdec = new BerDecoder(data);95bdec.openSequence();96version = bdec.fetchInteger();97}98catch(BerException x) {99throw new SnmpStatusException("Invalid encoding") ;100}101try {102bdec.closeSequence();103}104catch(BerException x) {105}106return version;107}108109/**110* Returns the associated request ID.111* @param data The flat message.112* @return The request ID.113*/114public abstract int getRequestId(byte[] data) throws SnmpStatusException;115116/**117* Encodes this message and puts the result in the specified byte array.118* For internal use only.119*120* @param outputBytes An array to receive the resulting encoding.121*122* @exception ArrayIndexOutOfBoundsException If the result does not fit123* into the specified array.124*/125public abstract int encodeMessage(byte[] outputBytes)126throws SnmpTooBigException;127128/**129* Decodes the specified bytes and initializes this message.130* For internal use only.131*132* @param inputBytes The bytes to be decoded.133*134* @exception SnmpStatusException If the specified bytes are not a valid encoding.135*/136public abstract void decodeMessage(byte[] inputBytes, int byteCount)137throws SnmpStatusException;138139/**140* Initializes this message with the specified <CODE>pdu</CODE>.141* <P>142* This method initializes the data field with an array of143* <CODE>maxDataLength</CODE> bytes. It encodes the <CODE>pdu</CODE>.144* The resulting encoding is stored in the data field145* and the length of the encoding is stored in <CODE>dataLength</CODE>.146* <p>147* If the encoding length exceeds <CODE>maxDataLength</CODE>,148* the method throws an exception.149*150* @param pdu The PDU to be encoded.151* @param maxDataLength The maximum length permitted for the data field.152*153* @exception SnmpStatusException If the specified <CODE>pdu</CODE> is not valid.154* @exception SnmpTooBigException If the resulting encoding does not fit155* into <CODE>maxDataLength</CODE> bytes.156* @exception ArrayIndexOutOfBoundsException If the encoding exceeds <CODE>maxDataLength</CODE>.157*/158public abstract void encodeSnmpPdu(SnmpPdu pdu, int maxDataLength)159throws SnmpStatusException, SnmpTooBigException;160161162/**163* Gets the PDU encoded in this message.164* <P>165* This method decodes the data field and returns the resulting PDU.166*167* @return The resulting PDU.168* @exception SnmpStatusException If the encoding is not valid.169*/170public abstract SnmpPdu decodeSnmpPdu()171throws SnmpStatusException;172173/**174* Dumps the content of a byte buffer using hexadecimal form.175*176* @param b The buffer to dump.177* @param offset The position of the first byte to be dumped.178* @param len The number of bytes to be dumped starting from offset.179*180* @return The string containing the dump.181*/182public static String dumpHexBuffer(byte [] b, int offset, int len) {183StringBuffer buf = new StringBuffer(len << 1) ;184int k = 1 ;185int flen = offset + len ;186187for (int i = offset; i < flen ; i++) {188int j = b[i] & 0xFF ;189buf.append(Character.forDigit((j >>> 4) , 16)) ;190buf.append(Character.forDigit((j & 0x0F), 16)) ;191k++ ;192if (k%16 == 0) {193buf.append('\n') ;194k = 1 ;195} else196buf.append(' ') ;197}198return buf.toString() ;199}200201/**202* Dumps this message in a string.203*204* @return The string containing the dump.205*/206public String printMessage() {207StringBuffer sb = new StringBuffer() ;208sb.append("Version: ") ;209sb.append(version) ;210sb.append("\n") ;211if (data == null) {212sb.append("Data: null") ;213}214else {215sb.append("Data: {\n") ;216sb.append(dumpHexBuffer(data, 0, dataLength)) ;217sb.append("\n}\n") ;218}219220return sb.toString() ;221}222223/**224* For SNMP Runtime private use only.225*/226public void encodeVarBindList(BerEncoder benc,227SnmpVarBind[] varBindList)228throws SnmpStatusException, SnmpTooBigException {229//230// Remember: the encoder does backward encoding231//232int encodedVarBindCount = 0 ;233try {234benc.openSequence() ;235if (varBindList != null) {236for (int i = varBindList.length - 1 ; i >= 0 ; i--) {237SnmpVarBind bind = varBindList[i] ;238if (bind != null) {239benc.openSequence() ;240encodeVarBindValue(benc, bind.value) ;241benc.putOid(bind.oid.longValue()) ;242benc.closeSequence() ;243encodedVarBindCount++ ;244}245}246}247benc.closeSequence() ;248}249catch(ArrayIndexOutOfBoundsException x) {250throw new SnmpTooBigException(encodedVarBindCount) ;251}252}253254/**255* For SNMP Runtime private use only.256*/257void encodeVarBindValue(BerEncoder benc,258SnmpValue v)throws SnmpStatusException {259if (v == null) {260benc.putNull() ;261}262else if (v instanceof SnmpIpAddress) {263benc.putOctetString(((SnmpIpAddress)v).byteValue(), SnmpValue.IpAddressTag) ;264}265else if (v instanceof SnmpCounter) {266benc.putInteger(((SnmpCounter)v).longValue(), SnmpValue.CounterTag) ;267}268else if (v instanceof SnmpGauge) {269benc.putInteger(((SnmpGauge)v).longValue(), SnmpValue.GaugeTag) ;270}271else if (v instanceof SnmpTimeticks) {272benc.putInteger(((SnmpTimeticks)v).longValue(), SnmpValue.TimeticksTag) ;273}274else if (v instanceof SnmpOpaque) {275benc.putOctetString(((SnmpOpaque)v).byteValue(), SnmpValue.OpaqueTag) ;276}277else if (v instanceof SnmpInt) {278benc.putInteger(((SnmpInt)v).intValue()) ;279}280else if (v instanceof SnmpString) {281benc.putOctetString(((SnmpString)v).byteValue()) ;282}283else if (v instanceof SnmpOid) {284benc.putOid(((SnmpOid)v).longValue()) ;285}286else if (v instanceof SnmpCounter64) {287if (version == snmpVersionOne) {288throw new SnmpStatusException("Invalid value for SNMP v1 : " + v) ;289}290benc.putInteger(((SnmpCounter64)v).longValue(), SnmpValue.Counter64Tag) ;291}292else if (v instanceof SnmpNull) {293int tag = ((SnmpNull)v).getTag() ;294if ((version == snmpVersionOne) && (tag != SnmpValue.NullTag)) {295throw new SnmpStatusException("Invalid value for SNMP v1 : " + v) ;296}297if ((version == snmpVersionTwo) &&298(tag != SnmpValue.NullTag) &&299(tag != SnmpVarBind.errNoSuchObjectTag) &&300(tag != SnmpVarBind.errNoSuchInstanceTag) &&301(tag != SnmpVarBind.errEndOfMibViewTag)) {302throw new SnmpStatusException("Invalid value " + v) ;303}304benc.putNull(tag) ;305}306else {307throw new SnmpStatusException("Invalid value " + v) ;308}309310}311312313/**314* For SNMP Runtime private use only.315*/316public SnmpVarBind[] decodeVarBindList(BerDecoder bdec)317throws BerException {318bdec.openSequence() ;319Vector<SnmpVarBind> tmp = new Vector<SnmpVarBind>() ;320while (bdec.cannotCloseSequence()) {321SnmpVarBind bind = new SnmpVarBind() ;322bdec.openSequence() ;323bind.oid = new SnmpOid(bdec.fetchOid()) ;324bind.setSnmpValue(decodeVarBindValue(bdec)) ;325bdec.closeSequence() ;326tmp.addElement(bind) ;327}328bdec.closeSequence() ;329SnmpVarBind[] varBindList= new SnmpVarBind[tmp.size()] ;330tmp.copyInto(varBindList);331return varBindList ;332}333334335/**336* For SNMP Runtime private use only.337*/338SnmpValue decodeVarBindValue(BerDecoder bdec)339throws BerException {340SnmpValue result = null ;341int tag = bdec.getTag() ;342343// bugId 4641696 : RuntimeExceptions must be transformed in344// BerException.345switch(tag) {346347//348// Simple syntax349//350case BerDecoder.IntegerTag :351try {352result = new SnmpInt(bdec.fetchInteger()) ;353} catch(RuntimeException r) {354throw new BerException();355// BerException("Can't build SnmpInt from decoded value.");356}357break ;358case BerDecoder.OctetStringTag :359try {360result = new SnmpString(bdec.fetchOctetString()) ;361} catch(RuntimeException r) {362throw new BerException();363// BerException("Can't build SnmpString from decoded value.");364}365break ;366case BerDecoder.OidTag :367try {368result = new SnmpOid(bdec.fetchOid()) ;369} catch(RuntimeException r) {370throw new BerException();371// BerException("Can't build SnmpOid from decoded value.");372}373break ;374case BerDecoder.NullTag :375bdec.fetchNull() ;376try {377result = new SnmpNull() ;378} catch(RuntimeException r) {379throw new BerException();380// BerException("Can't build SnmpNull from decoded value.");381}382break ;383384//385// Application syntax386//387case SnmpValue.IpAddressTag :388try {389result = new SnmpIpAddress(bdec.fetchOctetString(tag)) ;390} catch (RuntimeException r) {391throw new BerException();392// BerException("Can't build SnmpIpAddress from decoded value.");393}394break ;395case SnmpValue.CounterTag :396try {397result = new SnmpCounter(bdec.fetchIntegerAsLong(tag)) ;398} catch(RuntimeException r) {399throw new BerException();400// BerException("Can't build SnmpCounter from decoded value.");401}402break ;403case SnmpValue.GaugeTag :404try {405result = new SnmpGauge(bdec.fetchIntegerAsLong(tag)) ;406} catch(RuntimeException r) {407throw new BerException();408// BerException("Can't build SnmpGauge from decoded value.");409}410break ;411case SnmpValue.TimeticksTag :412try {413result = new SnmpTimeticks(bdec.fetchIntegerAsLong(tag)) ;414} catch(RuntimeException r) {415throw new BerException();416// BerException("Can't build SnmpTimeticks from decoded value.");417}418break ;419case SnmpValue.OpaqueTag :420try {421result = new SnmpOpaque(bdec.fetchOctetString(tag)) ;422} catch(RuntimeException r) {423throw new BerException();424// BerException("Can't build SnmpOpaque from decoded value.");425}426break ;427428//429// V2 syntaxes430//431case SnmpValue.Counter64Tag :432if (version == snmpVersionOne) {433throw new BerException(BerException.BAD_VERSION) ;434}435try {436result = new SnmpCounter64(bdec.fetchIntegerAsLong(tag)) ;437} catch(RuntimeException r) {438throw new BerException();439// BerException("Can't build SnmpCounter64 from decoded value.");440}441break ;442443case SnmpVarBind.errNoSuchObjectTag :444if (version == snmpVersionOne) {445throw new BerException(BerException.BAD_VERSION) ;446}447bdec.fetchNull(tag) ;448result = SnmpVarBind.noSuchObject ;449break ;450451case SnmpVarBind.errNoSuchInstanceTag :452if (version == snmpVersionOne) {453throw new BerException(BerException.BAD_VERSION) ;454}455bdec.fetchNull(tag) ;456result = SnmpVarBind.noSuchInstance ;457break ;458459case SnmpVarBind.errEndOfMibViewTag :460if (version == snmpVersionOne) {461throw new BerException(BerException.BAD_VERSION) ;462}463bdec.fetchNull(tag) ;464result = SnmpVarBind.endOfMibView ;465break ;466467default:468throw new BerException() ;469470}471472return result ;473}474475}476477478