Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/jmx/snmp/SnmpMessage.java
38924 views
/*1* Copyright (c) 1998, 2007, 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*/242526package com.sun.jmx.snmp;27282930// java imports31//32import java.util.logging.Level;33import java.util.Vector;34import java.net.InetAddress;3536import static com.sun.jmx.defaults.JmxProperties.SNMP_LOGGER;3738/**39* Is a partially decoded representation of an SNMP packet.40* <P>41* You will not normally need to use this class unless you decide to42* implement your own {@link com.sun.jmx.snmp.SnmpPduFactory SnmpPduFactory} object.43* <P>44* The <CODE>SnmpMessage</CODE> class is directly mapped onto the45* <CODE>Message</CODE> syntax defined in RFC1157 and RFC1902.46* <BLOCKQUOTE>47* <PRE>48* Message ::= SEQUENCE {49* version INTEGER { version(1) }, -- for SNMPv250* community OCTET STRING, -- community name51* data ANY -- an SNMPv2 PDU52* }53* </PRE>54* </BLOCKQUOTE>55*56* <p><b>This API is a Sun Microsystems internal API and is subject57* to change without notice.</b></p>58* @see SnmpPduFactory59* @see SnmpPduPacket60*61*/6263public class SnmpMessage extends SnmpMsg implements SnmpDefinitions {64/**65* Community name.66*/67public byte[] community ;6869/**70* Encodes this message and puts the result in the specified byte array.71* For internal use only.72*73* @param outputBytes An array to receive the resulting encoding.74*75* @exception ArrayIndexOutOfBoundsException If the result does not fit76* into the specified array.77*/78public int encodeMessage(byte[] outputBytes) throws SnmpTooBigException {79int encodingLength = 0 ;80if (data == null)81throw new IllegalArgumentException("Data field is null") ;8283//84// Reminder: BerEncoder does backward encoding !85//86try {87BerEncoder benc = new BerEncoder(outputBytes) ;88benc.openSequence() ;89benc.putAny(data, dataLength) ;90benc.putOctetString((community != null) ? community : new byte[0]) ;91benc.putInteger(version) ;92benc.closeSequence() ;93encodingLength = benc.trim() ;94}95catch(ArrayIndexOutOfBoundsException x) {96throw new SnmpTooBigException() ;97}9899return encodingLength ;100}101/**102* Returns the associated request ID.103* @param inputBytes The flat message.104* @return The request ID.105*106* @since 1.5107*/108public int getRequestId(byte[] inputBytes) throws SnmpStatusException {109int requestId = 0;110BerDecoder bdec = null;111BerDecoder bdec2 = null;112byte[] any = null;113try {114bdec = new BerDecoder(inputBytes);115bdec.openSequence();116bdec.fetchInteger();117bdec.fetchOctetString();118any = bdec.fetchAny();119bdec2 = new BerDecoder(any);120int type = bdec2.getTag();121bdec2.openSequence(type);122requestId = bdec2.fetchInteger();123}124catch(BerException x) {125throw new SnmpStatusException("Invalid encoding") ;126}127try {128bdec.closeSequence();129}130catch(BerException x) {131}132try {133bdec2.closeSequence();134}135catch(BerException x) {136}137return requestId;138}139/**140* Decodes the specified bytes and initializes this message.141* For internal use only.142*143* @param inputBytes The bytes to be decoded.144*145* @exception SnmpStatusException If the specified bytes are not a valid encoding.146*/147public void decodeMessage(byte[] inputBytes, int byteCount)148throws SnmpStatusException {149try {150BerDecoder bdec = new BerDecoder(inputBytes/*, byteCount */) ; // FIXME151bdec.openSequence() ;152version = bdec.fetchInteger() ;153community = bdec.fetchOctetString() ;154data = bdec.fetchAny() ;155dataLength = data.length ;156bdec.closeSequence() ;157}158catch(BerException x) {159throw new SnmpStatusException("Invalid encoding") ;160}161}162163/**164* Initializes this message with the specified <CODE>pdu</CODE>.165* <P>166* This method initializes the data field with an array of167* <CODE>maxDataLength</CODE> bytes. It encodes the <CODE>pdu</CODE>.168* The resulting encoding is stored in the data field169* and the length of the encoding is stored in <CODE>dataLength</CODE>.170* <p>171* If the encoding length exceeds <CODE>maxDataLength</CODE>,172* the method throws an exception.173*174* @param pdu The PDU to be encoded.175* @param maxDataLength The maximum length permitted for the data field.176*177* @exception SnmpStatusException If the specified <CODE>pdu</CODE> is not valid.178* @exception SnmpTooBigException If the resulting encoding does not fit179* into <CODE>maxDataLength</CODE> bytes.180* @exception ArrayIndexOutOfBoundsException If the encoding exceeds <CODE>maxDataLength</CODE>.181*182* @since 1.5183*/184public void encodeSnmpPdu(SnmpPdu pdu, int maxDataLength)185throws SnmpStatusException, SnmpTooBigException {186//187// The easy work188//189SnmpPduPacket pdupacket = (SnmpPduPacket) pdu;190version = pdupacket.version ;191community = pdupacket.community ;192address = pdupacket.address ;193port = pdupacket.port ;194195//196// Allocate the array to receive the encoding.197//198data = new byte[maxDataLength] ;199200//201// Encode the pdupacket202// Reminder: BerEncoder does backward encoding !203//204205try {206BerEncoder benc = new BerEncoder(data) ;207benc.openSequence() ;208encodeVarBindList(benc, pdupacket.varBindList) ;209210switch(pdupacket.type) {211212case pduGetRequestPdu :213case pduGetNextRequestPdu :214case pduInformRequestPdu :215case pduGetResponsePdu :216case pduSetRequestPdu :217case pduV2TrapPdu :218case pduReportPdu :219SnmpPduRequest reqPdu = (SnmpPduRequest)pdupacket ;220benc.putInteger(reqPdu.errorIndex) ;221benc.putInteger(reqPdu.errorStatus) ;222benc.putInteger(reqPdu.requestId) ;223break ;224225case pduGetBulkRequestPdu :226SnmpPduBulk bulkPdu = (SnmpPduBulk)pdupacket ;227benc.putInteger(bulkPdu.maxRepetitions) ;228benc.putInteger(bulkPdu.nonRepeaters) ;229benc.putInteger(bulkPdu.requestId) ;230break ;231232case pduV1TrapPdu :233SnmpPduTrap trapPdu = (SnmpPduTrap)pdupacket ;234benc.putInteger(trapPdu.timeStamp, SnmpValue.TimeticksTag) ;235benc.putInteger(trapPdu.specificTrap) ;236benc.putInteger(trapPdu.genericTrap) ;237if(trapPdu.agentAddr != null)238benc.putOctetString(trapPdu.agentAddr.byteValue(), SnmpValue.IpAddressTag) ;239else240benc.putOctetString(new byte[0], SnmpValue.IpAddressTag);241benc.putOid(trapPdu.enterprise.longValue()) ;242break ;243244default:245throw new SnmpStatusException("Invalid pdu type " + String.valueOf(pdupacket.type)) ;246}247benc.closeSequence(pdupacket.type) ;248dataLength = benc.trim() ;249}250catch(ArrayIndexOutOfBoundsException x) {251throw new SnmpTooBigException() ;252}253}254/**255* Gets the PDU encoded in this message.256* <P>257* This method decodes the data field and returns the resulting PDU.258*259* @return The resulting PDU.260* @exception SnmpStatusException If the encoding is not valid.261*262* @since 1.5263*/264public SnmpPdu decodeSnmpPdu()265throws SnmpStatusException {266//267// Decode the pdu268//269SnmpPduPacket pdu = null ;270BerDecoder bdec = new BerDecoder(data) ;271try {272int type = bdec.getTag() ;273bdec.openSequence(type) ;274switch(type) {275276case pduGetRequestPdu :277case pduGetNextRequestPdu :278case pduInformRequestPdu :279case pduGetResponsePdu :280case pduSetRequestPdu :281case pduV2TrapPdu :282case pduReportPdu :283SnmpPduRequest reqPdu = new SnmpPduRequest() ;284reqPdu.requestId = bdec.fetchInteger() ;285reqPdu.errorStatus = bdec.fetchInteger() ;286reqPdu.errorIndex = bdec.fetchInteger() ;287pdu = reqPdu ;288break ;289290case pduGetBulkRequestPdu :291SnmpPduBulk bulkPdu = new SnmpPduBulk() ;292bulkPdu.requestId = bdec.fetchInteger() ;293bulkPdu.nonRepeaters = bdec.fetchInteger() ;294bulkPdu.maxRepetitions = bdec.fetchInteger() ;295pdu = bulkPdu ;296break ;297298case pduV1TrapPdu :299SnmpPduTrap trapPdu = new SnmpPduTrap() ;300trapPdu.enterprise = new SnmpOid(bdec.fetchOid()) ;301byte []b = bdec.fetchOctetString(SnmpValue.IpAddressTag);302if(b.length != 0)303trapPdu.agentAddr = new SnmpIpAddress(b) ;304else305trapPdu.agentAddr = null;306trapPdu.genericTrap = bdec.fetchInteger() ;307trapPdu.specificTrap = bdec.fetchInteger() ;308trapPdu.timeStamp = bdec.fetchInteger(SnmpValue.TimeticksTag) ;309pdu = trapPdu ;310break ;311312default:313throw new SnmpStatusException(snmpRspWrongEncoding) ;314}315pdu.type = type ;316pdu.varBindList = decodeVarBindList(bdec) ;317bdec.closeSequence() ;318} catch(BerException e) {319if (SNMP_LOGGER.isLoggable(Level.FINEST)) {320SNMP_LOGGER.logp(Level.FINEST, SnmpMessage.class.getName(),321"decodeSnmpPdu", "BerException", e);322}323throw new SnmpStatusException(snmpRspWrongEncoding);324} catch(IllegalArgumentException e) {325// bug id 4654066326if (SNMP_LOGGER.isLoggable(Level.FINEST)) {327SNMP_LOGGER.logp(Level.FINEST, SnmpMessage.class.getName(),328"decodeSnmpPdu", "IllegalArgumentException", e);329}330throw new SnmpStatusException(snmpRspWrongEncoding);331}332333//334// The easy work335//336pdu.version = version ;337pdu.community = community ;338pdu.address = address ;339pdu.port = port ;340341return pdu;342}343/**344* Dumps this message in a string.345*346* @return The string containing the dump.347*/348public String printMessage() {349StringBuffer sb = new StringBuffer();350if (community == null) {351sb.append("Community: null") ;352}353else {354sb.append("Community: {\n") ;355sb.append(dumpHexBuffer(community, 0, community.length)) ;356sb.append("\n}\n") ;357}358return sb.append(super.printMessage()).toString();359}360361}362363364