| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
package com.sun.jmx.snmp;  | 
 | 
 | 
 | 
import com.sun.jmx.snmp.SnmpSecurityParameters;  | 
 | 
// java imports  | 
 | 
 | 
 | 
import java.util.Vector;  | 
 | 
import java.net.InetAddress;  | 
 | 
 | 
 | 
 | 
 | 
import com.sun.jmx.snmp.SnmpStatusException;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
public abstract class SnmpMsg implements SnmpDefinitions { | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public int version = 0;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public byte[] data = null;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public int dataLength = 0;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public InetAddress address = null;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public int port = 0;  | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public SnmpSecurityParameters securityParameters = null;  | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public static int getProtocolVersion(byte[] data)  | 
 | 
        throws SnmpStatusException { | 
 | 
        int version = 0;  | 
 | 
        BerDecoder bdec = null;  | 
 | 
        try { | 
 | 
            bdec = new BerDecoder(data);  | 
 | 
            bdec.openSequence();  | 
 | 
            version = bdec.fetchInteger();  | 
 | 
        }  | 
 | 
        catch(BerException x) { | 
 | 
            throw new SnmpStatusException("Invalid encoding") ; | 
 | 
        }  | 
 | 
        try { | 
 | 
            bdec.closeSequence();  | 
 | 
        }  | 
 | 
        catch(BerException x) { | 
 | 
        }  | 
 | 
        return version;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public abstract int getRequestId(byte[] data) throws SnmpStatusException;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public abstract int encodeMessage(byte[] outputBytes)  | 
 | 
        throws SnmpTooBigException;  | 
 | 
 | 
 | 
       | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public abstract void decodeMessage(byte[] inputBytes, int byteCount)  | 
 | 
        throws SnmpStatusException;  | 
 | 
 | 
 | 
       | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public abstract void encodeSnmpPdu(SnmpPdu pdu, int maxDataLength)  | 
 | 
        throws SnmpStatusException, SnmpTooBigException;  | 
 | 
 | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public abstract SnmpPdu decodeSnmpPdu()  | 
 | 
        throws SnmpStatusException;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public static String dumpHexBuffer(byte [] b, int offset, int len) { | 
 | 
        StringBuffer buf = new StringBuffer(len << 1) ;  | 
 | 
        int k = 1 ;  | 
 | 
        int flen = offset + len ;  | 
 | 
 | 
 | 
        for (int i = offset; i < flen ; i++) { | 
 | 
            int j = b[i] & 0xFF ;  | 
 | 
            buf.append(Character.forDigit((j >>> 4) , 16)) ;  | 
 | 
            buf.append(Character.forDigit((j & 0x0F), 16)) ;  | 
 | 
            k++ ;  | 
 | 
            if (k%16 == 0) { | 
 | 
                buf.append('\n') ; | 
 | 
                k = 1 ;  | 
 | 
            } else  | 
 | 
                buf.append(' ') ; | 
 | 
        }  | 
 | 
        return buf.toString() ;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public String printMessage() { | 
 | 
        StringBuffer sb = new StringBuffer() ;  | 
 | 
        sb.append("Version: ") ; | 
 | 
        sb.append(version) ;  | 
 | 
        sb.append("\n") ; | 
 | 
        if (data == null) { | 
 | 
            sb.append("Data: null") ; | 
 | 
        }  | 
 | 
        else { | 
 | 
            sb.append("Data: {\n") ; | 
 | 
            sb.append(dumpHexBuffer(data, 0, dataLength)) ;  | 
 | 
            sb.append("\n}\n") ; | 
 | 
        }  | 
 | 
 | 
 | 
        return sb.toString() ;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public void encodeVarBindList(BerEncoder benc,  | 
 | 
                                  SnmpVarBind[] varBindList)  | 
 | 
        throws SnmpStatusException, SnmpTooBigException { | 
 | 
        //  | 
 | 
        // Remember: the encoder does backward encoding  | 
 | 
          | 
 | 
        int encodedVarBindCount = 0 ;  | 
 | 
        try { | 
 | 
            benc.openSequence() ;  | 
 | 
            if (varBindList != null) { | 
 | 
                for (int i = varBindList.length - 1 ; i >= 0 ; i--) { | 
 | 
                    SnmpVarBind bind = varBindList[i] ;  | 
 | 
                    if (bind != null) { | 
 | 
                        benc.openSequence() ;  | 
 | 
                        encodeVarBindValue(benc, bind.value) ;  | 
 | 
                        benc.putOid(bind.oid.longValue()) ;  | 
 | 
                        benc.closeSequence() ;  | 
 | 
                        encodedVarBindCount++ ;  | 
 | 
                    }  | 
 | 
                }  | 
 | 
            }  | 
 | 
            benc.closeSequence() ;  | 
 | 
        }  | 
 | 
        catch(ArrayIndexOutOfBoundsException x) { | 
 | 
            throw new SnmpTooBigException(encodedVarBindCount) ;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    void encodeVarBindValue(BerEncoder benc,  | 
 | 
                            SnmpValue v)throws SnmpStatusException { | 
 | 
        if (v == null) { | 
 | 
            benc.putNull() ;  | 
 | 
        }  | 
 | 
        else if (v instanceof SnmpIpAddress) { | 
 | 
            benc.putOctetString(((SnmpIpAddress)v).byteValue(), SnmpValue.IpAddressTag) ;  | 
 | 
        }  | 
 | 
        else if (v instanceof SnmpCounter) { | 
 | 
            benc.putInteger(((SnmpCounter)v).longValue(), SnmpValue.CounterTag) ;  | 
 | 
        }  | 
 | 
        else if (v instanceof SnmpGauge) { | 
 | 
            benc.putInteger(((SnmpGauge)v).longValue(), SnmpValue.GaugeTag) ;  | 
 | 
        }  | 
 | 
        else if (v instanceof SnmpTimeticks) { | 
 | 
            benc.putInteger(((SnmpTimeticks)v).longValue(), SnmpValue.TimeticksTag) ;  | 
 | 
        }  | 
 | 
        else if (v instanceof SnmpOpaque) { | 
 | 
            benc.putOctetString(((SnmpOpaque)v).byteValue(), SnmpValue.OpaqueTag) ;  | 
 | 
        }  | 
 | 
        else if (v instanceof SnmpInt) { | 
 | 
            benc.putInteger(((SnmpInt)v).intValue()) ;  | 
 | 
        }  | 
 | 
        else if (v instanceof SnmpString) { | 
 | 
            benc.putOctetString(((SnmpString)v).byteValue()) ;  | 
 | 
        }  | 
 | 
        else if (v instanceof SnmpOid) { | 
 | 
            benc.putOid(((SnmpOid)v).longValue()) ;  | 
 | 
        }  | 
 | 
        else if (v instanceof SnmpCounter64) { | 
 | 
            if (version == snmpVersionOne) { | 
 | 
                throw new SnmpStatusException("Invalid value for SNMP v1 : " + v) ; | 
 | 
            }  | 
 | 
            benc.putInteger(((SnmpCounter64)v).longValue(), SnmpValue.Counter64Tag) ;  | 
 | 
        }  | 
 | 
        else if (v instanceof SnmpNull) { | 
 | 
            int tag = ((SnmpNull)v).getTag() ;  | 
 | 
            if ((version == snmpVersionOne) && (tag != SnmpValue.NullTag)) { | 
 | 
                throw new SnmpStatusException("Invalid value for SNMP v1 : " + v) ; | 
 | 
            }  | 
 | 
            if ((version == snmpVersionTwo) &&  | 
 | 
                (tag != SnmpValue.NullTag) &&  | 
 | 
                (tag != SnmpVarBind.errNoSuchObjectTag) &&  | 
 | 
                (tag != SnmpVarBind.errNoSuchInstanceTag) &&  | 
 | 
                (tag != SnmpVarBind.errEndOfMibViewTag)) { | 
 | 
                throw new SnmpStatusException("Invalid value " + v) ; | 
 | 
            }  | 
 | 
            benc.putNull(tag) ;  | 
 | 
        }  | 
 | 
        else { | 
 | 
            throw new SnmpStatusException("Invalid value " + v) ; | 
 | 
        }  | 
 | 
 | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public SnmpVarBind[] decodeVarBindList(BerDecoder bdec)  | 
 | 
        throws BerException { | 
 | 
            bdec.openSequence() ;  | 
 | 
            Vector<SnmpVarBind> tmp = new Vector<SnmpVarBind>() ;  | 
 | 
            while (bdec.cannotCloseSequence()) { | 
 | 
                SnmpVarBind bind = new SnmpVarBind() ;  | 
 | 
                bdec.openSequence() ;  | 
 | 
                bind.oid = new SnmpOid(bdec.fetchOid()) ;  | 
 | 
                bind.setSnmpValue(decodeVarBindValue(bdec)) ;  | 
 | 
                bdec.closeSequence() ;  | 
 | 
                tmp.addElement(bind) ;  | 
 | 
            }  | 
 | 
            bdec.closeSequence() ;  | 
 | 
            SnmpVarBind[] varBindList= new SnmpVarBind[tmp.size()] ;  | 
 | 
            tmp.copyInto(varBindList);  | 
 | 
            return varBindList ;  | 
 | 
        }  | 
 | 
 | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    SnmpValue decodeVarBindValue(BerDecoder bdec)  | 
 | 
        throws BerException { | 
 | 
        SnmpValue result = null ;  | 
 | 
        int tag = bdec.getTag() ;  | 
 | 
 | 
 | 
        // bugId 4641696 : RuntimeExceptions must be transformed in  | 
 | 
          | 
 | 
        switch(tag) { | 
 | 
 | 
 | 
            //  | 
 | 
            // Simple syntax  | 
 | 
              | 
 | 
        case BerDecoder.IntegerTag :  | 
 | 
            try { | 
 | 
                result = new SnmpInt(bdec.fetchInteger()) ;  | 
 | 
            } catch(RuntimeException r) { | 
 | 
                throw new BerException();  | 
 | 
                // BerException("Can't build SnmpInt from decoded value."); | 
 | 
            }  | 
 | 
            break ;  | 
 | 
        case BerDecoder.OctetStringTag :  | 
 | 
            try { | 
 | 
                result = new SnmpString(bdec.fetchOctetString()) ;  | 
 | 
            } catch(RuntimeException r) { | 
 | 
                throw new BerException();  | 
 | 
                // BerException("Can't build SnmpString from decoded value."); | 
 | 
            }  | 
 | 
            break ;  | 
 | 
        case BerDecoder.OidTag :  | 
 | 
            try { | 
 | 
                result = new SnmpOid(bdec.fetchOid()) ;  | 
 | 
            } catch(RuntimeException r) { | 
 | 
                throw new BerException();  | 
 | 
                // BerException("Can't build SnmpOid from decoded value."); | 
 | 
            }  | 
 | 
            break ;  | 
 | 
        case BerDecoder.NullTag :  | 
 | 
            bdec.fetchNull() ;  | 
 | 
            try { | 
 | 
                result = new SnmpNull() ;  | 
 | 
            } catch(RuntimeException r) { | 
 | 
                throw new BerException();  | 
 | 
                // BerException("Can't build SnmpNull from decoded value."); | 
 | 
            }  | 
 | 
            break ;  | 
 | 
 | 
 | 
            //  | 
 | 
            // Application syntax  | 
 | 
              | 
 | 
        case SnmpValue.IpAddressTag :  | 
 | 
            try { | 
 | 
                result = new SnmpIpAddress(bdec.fetchOctetString(tag)) ;  | 
 | 
            } catch (RuntimeException r) { | 
 | 
                throw new  BerException();  | 
 | 
              // BerException("Can't build SnmpIpAddress from decoded value."); | 
 | 
            }  | 
 | 
            break ;  | 
 | 
        case SnmpValue.CounterTag :  | 
 | 
            try { | 
 | 
                result = new SnmpCounter(bdec.fetchIntegerAsLong(tag)) ;  | 
 | 
            } catch(RuntimeException r) { | 
 | 
                throw new BerException();  | 
 | 
                // BerException("Can't build SnmpCounter from decoded value."); | 
 | 
            }  | 
 | 
            break ;  | 
 | 
        case SnmpValue.GaugeTag :  | 
 | 
            try { | 
 | 
                result = new SnmpGauge(bdec.fetchIntegerAsLong(tag)) ;  | 
 | 
            } catch(RuntimeException r) { | 
 | 
                throw new BerException();  | 
 | 
                // BerException("Can't build SnmpGauge from decoded value."); | 
 | 
            }  | 
 | 
            break ;  | 
 | 
        case SnmpValue.TimeticksTag :  | 
 | 
            try { | 
 | 
                result = new SnmpTimeticks(bdec.fetchIntegerAsLong(tag)) ;  | 
 | 
            } catch(RuntimeException r) { | 
 | 
                throw new BerException();  | 
 | 
             // BerException("Can't build SnmpTimeticks from decoded value."); | 
 | 
            }  | 
 | 
            break ;  | 
 | 
        case SnmpValue.OpaqueTag :  | 
 | 
            try { | 
 | 
                result = new SnmpOpaque(bdec.fetchOctetString(tag)) ;  | 
 | 
            } catch(RuntimeException r) { | 
 | 
                throw new BerException();  | 
 | 
                // BerException("Can't build SnmpOpaque from decoded value."); | 
 | 
            }  | 
 | 
            break ;  | 
 | 
 | 
 | 
            //  | 
 | 
            // V2 syntaxes  | 
 | 
              | 
 | 
        case SnmpValue.Counter64Tag :  | 
 | 
            if (version == snmpVersionOne) { | 
 | 
                throw new BerException(BerException.BAD_VERSION) ;  | 
 | 
            }  | 
 | 
            try { | 
 | 
                result = new SnmpCounter64(bdec.fetchIntegerAsLong(tag)) ;  | 
 | 
            } catch(RuntimeException r) { | 
 | 
                throw new BerException();  | 
 | 
             // BerException("Can't build SnmpCounter64 from decoded value."); | 
 | 
            }  | 
 | 
            break ;  | 
 | 
 | 
 | 
        case SnmpVarBind.errNoSuchObjectTag :  | 
 | 
            if (version == snmpVersionOne) { | 
 | 
                throw new BerException(BerException.BAD_VERSION) ;  | 
 | 
            }  | 
 | 
            bdec.fetchNull(tag) ;  | 
 | 
            result = SnmpVarBind.noSuchObject ;  | 
 | 
            break ;  | 
 | 
 | 
 | 
        case SnmpVarBind.errNoSuchInstanceTag :  | 
 | 
            if (version == snmpVersionOne) { | 
 | 
                throw new BerException(BerException.BAD_VERSION) ;  | 
 | 
            }  | 
 | 
            bdec.fetchNull(tag) ;  | 
 | 
            result = SnmpVarBind.noSuchInstance ;  | 
 | 
            break ;  | 
 | 
 | 
 | 
        case SnmpVarBind.errEndOfMibViewTag :  | 
 | 
            if (version == snmpVersionOne) { | 
 | 
                throw new BerException(BerException.BAD_VERSION) ;  | 
 | 
            }  | 
 | 
            bdec.fetchNull(tag) ;  | 
 | 
            result = SnmpVarBind.endOfMibView ;  | 
 | 
            break ;  | 
 | 
 | 
 | 
        default:  | 
 | 
            throw new BerException() ;  | 
 | 
 | 
 | 
        }  | 
 | 
 | 
 | 
        return result ;  | 
 | 
    }  | 
 | 
 | 
 | 
}  |