snmpparser.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 562 行

JAVA
562
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source 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 2 of the License, or * (at your option) any later version. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Nam Nguyen */package com.caucho.server.snmp;import java.io.IOException;import java.io.InputStream;import com.caucho.server.snmp.types.*;import com.caucho.util.L10N;public class SnmpParser{  private static final L10N L = new L10N(SnmpParser.class);  private InputStream _is;  private int _bytesRead = 0;    private boolean _isCheckIdentifier = true;    public SnmpParser(InputStream is)   {    _is = is;  }    public SnmpParser(String s)  {    _is = new StringInputStream(s);  }    public SnmpMessageValue readMessage()    throws IOException  {    checkIdentifier(SnmpValue.SEQUENCE);    int expectedLen = readLength();    int bytesRead = getBytesRead();        IntegerValue version = readInteger();    OctetStringValue communityString = readOctetString();    int id = readByte();    _isCheckIdentifier = false;        PduValue pdu;    switch(id) {      case SnmpValue.GET_REQUEST_PDU:        pdu = readGetRequestPdu();        break;      case SnmpValue.GET_NEXT_REQUEST_PDU:        pdu = readGetNextRequestPdu();        break;      case SnmpValue.SET_REQUEST_PDU:        pdu = readSetRequestPdu();        break;      case SnmpValue.GET_RESPONSE_PDU:        pdu = readGetResponsePdu();        break;      //case SnmpValue.TRAP_PDU:        //break;      default:        throw new SnmpParsingException(L.l("unknown PDU type '{0}'", id));    }        checkLength(expectedLen, getBytesRead() - bytesRead);        return new SnmpMessageValue(version, communityString, pdu);  }  public PduValue readGetRequestPdu()    throws IOException  {    return readPdu(SnmpValue.GET_REQUEST_PDU);  }    public PduValue readGetNextRequestPdu()    throws IOException  {    return readPdu(SnmpValue.GET_NEXT_REQUEST_PDU);  }    public PduValue readSetRequestPdu()    throws IOException  {    return readPdu(SnmpValue.SET_REQUEST_PDU);  }    public PduValue readGetResponsePdu()    throws IOException  {    return readPdu(SnmpValue.GET_RESPONSE_PDU);  }    private PduValue readPdu(int type)    throws IOException  {    checkIdentifier(type);        int expectedLen = readLength();    int bytesRead = getBytesRead();        IntegerValue requestId = readInteger();        // errors are ignored for requests    IntegerValue error = readInteger();    IntegerValue errorIndex = readInteger();        VarBindListValue varBindList = readVarBindList();        checkLength(expectedLen, getBytesRead() - bytesRead);        return PduValue.create(type,                           requestId,                           error,                           errorIndex,                           varBindList);  }  public VarBindListValue readVarBindList()     throws IOException  {    checkIdentifier(SnmpValue.SEQUENCE);        int expectedLen = readLength();    int bytesRead = 0;        VarBindListValue varBindList = new VarBindListValue();        while (bytesRead < expectedLen) {      bytesRead -= getBytesRead();            varBindList.addVarBind(readVarBind());            bytesRead += getBytesRead();    }        checkLength(expectedLen, bytesRead);        return varBindList;  }    public VarBindValue readVarBind()    throws IOException  {    checkIdentifier(SnmpValue.SEQUENCE);        int expectedLen = readLength();    int bytesRead = getBytesRead();        VarBindValue varBind = new VarBindValue(readObjectIdentifier(),                                            read());    checkLength(expectedLen, getBytesRead() - bytesRead);        return varBind;  }    public void skipObject()    throws IOException  {    readByte();        int len = readLength();        for (int i = 0; i < len; i++) {      readByte();    }  }    public SnmpValue read()    throws IOException  {    int identifier = readByte();        _isCheckIdentifier = false;    switch (identifier) {      case SnmpValue.NULL:        return readNull();      case SnmpValue.INTEGER:        return readInteger();      case SnmpValue.OCTET_STRING:        return readOctetString();      case SnmpValue.OBJECT_IDENTIFIER:        return readObjectIdentifier();      case SnmpValue.SEQUENCE:        return readSequence();      case SnmpValue.IP_ADDRESS:        return readIpAddress();      case SnmpValue.COUNTER:        return readCounter();      case SnmpValue.GAUGE:        return readGauge();      case SnmpValue.TIME_TICKS:        return readTimeTicks();      case SnmpValue.OPAQUE:        return readOpaque();      case SnmpValue.GET_REQUEST_PDU:        return readGetRequestPdu();      case SnmpValue.GET_NEXT_REQUEST_PDU:        return readGetNextRequestPdu();      case SnmpValue.GET_RESPONSE_PDU:        return readGetResponsePdu();      case SnmpValue.SET_REQUEST_PDU:        return readSetRequestPdu();      //case SnmpValue.TRAP_PDU:      //  break;      default:        throw new SnmpParsingException(L.l("unknown identifier {0}", identifier));    }  }      public NullValue readNull()    throws IOException  {    checkIdentifier(SnmpValue.NULL);    int len = readLength();    if (len != 0)      throw new SnmpParsingException("length must be zero for NULL");        return NullValue.NULL;  }    public IntegerValue readInteger()    throws IOException  {    checkIdentifier(SnmpValue.INTEGER);    int len = readLength();    if (len < 1 || len > 4)      throw new SnmpParsingException(L.l("integer length {0} must be 1-4"));    int value =  readByte();    boolean isNeg = (value & 0x80) > 0;    for (int i = 1; i < len; i++) {      value <<= 8;      value |= readByte();    }        if (isNeg) {      while (len != 4) {        value |= 0xFF << (8 * len++);      }    }        return new IntegerValue(value);  }  public OctetStringValue readOctetString()    throws IOException  {    checkIdentifier(SnmpValue.OCTET_STRING);    int expectedLen = readLength();        StringBuilder sb = new StringBuilder();        for (int i = 0; i < expectedLen; i++) {      sb.append((char) readByte());    }    return new OctetStringValue(sb.toString());  }    public ObjectIdentifierValue readObjectIdentifier()    throws IOException  {    checkIdentifier(SnmpValue.OBJECT_IDENTIFIER);    int len = readLength();        StringBuilder sb = new StringBuilder();    int total = 0;    while (len-- > 0) {      int b = readByte();            total <<= 7;      total += (b & 0x7F);            if ((b & 0x80) == 0) {        break;      }    }        // total is (40x + y)    // x can only be 0,1,2    // y can not be more than 39 for x = 0,1        int x;    int y;        if (total < 40) {      x = 0;      y = total;    }    else if (total < 80) {      x = 1;      y = total - 40;    }    else {      x = 2;      y = total - 80;    }        sb.append(x);    sb.append('.');    sb.append(y);        while (len > 0) {      int val = 0;            while (len-- > 0) {        int b = readByte();                val <<= 7;        val += (b & 0x7F);                if ((b & 0x80) == 0) {          break;        }      }            sb.append('.');      sb.append(val);    }    return new ObjectIdentifierValue(sb.toString());  }    public IpAddressValue readIpAddress()    throws IOException  {    checkIdentifier(SnmpValue.IP_ADDRESS);    int expectedLen = readLength();        StringBuilder sb = new StringBuilder();        for (int i = 0; i < expectedLen; i++) {      int b = readByte();            if (b < 0x00 || b > 0xFF) {        throw new SnmpParsingException(L.l("IP address digit {0} out of range", b));      }            if (i != 0)        sb.append('.');      sb.append(b);    }    return new IpAddressValue(sb.toString());  }    public CounterValue readCounter()    throws IOException  {    checkIdentifier(SnmpValue.COUNTER);    int expectedLen = readLength();        long value = 0;        for (int i = 0; i < expectedLen; i++) {      value <<= 8;      value |= readByte();    }    return new CounterValue(value);  }    public GaugeValue readGauge()    throws IOException  {    checkIdentifier(SnmpValue.GAUGE);    int expectedLen = readLength();        long value = 0;        for (int i = 0; i < expectedLen; i++) {      value <<= 8;      value |= readByte();    }    return new GaugeValue(value);  }    public TimeTicksValue readTimeTicks()    throws IOException  {    checkIdentifier(SnmpValue.TIME_TICKS);    int expectedLen = readLength();        long value = 0;        for (int i = 0; i < expectedLen; i++) {      value <<= 8;      value |= readByte();    }    return new TimeTicksValue(value);  }    public OpaqueValue readOpaque()    throws IOException  {    checkIdentifier(SnmpValue.OPAQUE);    int expectedLen = readLength();        StringBuilder sb = new StringBuilder();        for (int i = 0; i < expectedLen; i++) {      sb.append((char) readByte());    }    return new OpaqueValue(sb.toString());  }  public SequenceValue<SnmpValue> readSequence()    throws IOException  {    checkIdentifier(SnmpValue.SEQUENCE);    int expectedLen = readLength();        SequenceValue<SnmpValue> sequence = new SequenceValue<SnmpValue>();        int bytesRead = 0;    while (bytesRead < expectedLen) {      bytesRead -= getBytesRead();            SnmpValue item = read();      sequence.add(item);      bytesRead += getBytesRead();    }    if (bytesRead != expectedLen) {      throw new SnmpParsingException(L.l("expected sequence length {0} != {1}",                                          expectedLen, bytesRead));    }    return sequence;  }  public int readLength()    throws IOException  {    int octlet = readByte();    if ((octlet & 0x80) == 0)      return octlet & 0x7F;        int numOfOctlets = octlet & 0x7F;    int len = 0;    for (int i = 0; i < numOfOctlets; i++) {      octlet = readByte();            len <<= 8;      len |= octlet;    }    return len;  }    private int readByte()    throws IOException  {    _bytesRead++;        int ch = _is.read();        if (ch < 0)      throw new SnmpParsingException("unexpected EOF");        return ch;  }  private int getBytesRead()  {    return _bytesRead;  }    private void checkLength(int expected, int bytesRead)    throws SnmpParsingException  {    if (expected != bytesRead) {      throw new SnmpParsingException(L.l("expected length {0} != {1}", expected, bytesRead));    }  }    private void checkIdentifier(int expected)    throws IOException  {    if (_isCheckIdentifier)      checkIdentifier(expected, readByte());        _isCheckIdentifier = true;  }    private void checkIdentifier(int expected, int identifier)    throws SnmpParsingException  {    if ( expected != identifier) {      throw new SnmpParsingException(L.l("saw '{0}' but expected type '{1}'", type(identifier), type(expected)));    }  }    private static String type(int identifier)  {    return SnmpValue.typeName(identifier);  }    static class StringInputStream extends InputStream  {    private String _s;    private int _len;    private int _index;        public StringInputStream(String s)    {      _s = s;      _len = s.length();    }        public int read()      throws IOException    {      if (_index < _len)        return _s.charAt(_index++);      else        return -1;    }  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?