Package com.caucho.server.snmp

Source Code of com.caucho.server.snmp.SnmpRequest

/*
* Copyright (c) 1998-2011 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.OutputStream;
import java.util.HashMap;
import java.util.logging.Logger;

import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;

import com.caucho.jmx.Jmx;
import com.caucho.network.listen.AbstractProtocolConnection;
import com.caucho.network.listen.SocketLink;
import com.caucho.server.snmp.types.GetResponsePduValue;
import com.caucho.server.snmp.types.IntegerValue;
import com.caucho.server.snmp.types.NullValue;
import com.caucho.server.snmp.types.ObjectIdentifierValue;
import com.caucho.server.snmp.types.OctetStringValue;
import com.caucho.server.snmp.types.SnmpMessageValue;
import com.caucho.server.snmp.types.SnmpValue;
import com.caucho.server.snmp.types.VarBindListValue;
import com.caucho.server.snmp.types.VarBindValue;
import com.caucho.util.L10N;
import com.caucho.vfs.ReadStream;

/*
* Responds to SNMP requests.
*/
public class SnmpRequest extends AbstractProtocolConnection
{
  private static final Logger log
    = Logger.getLogger(SnmpRequest.class.getName());
 
  private static final L10N L = new L10N(SnmpRequest.class);
 
  public static final int NO_ERROR = 0;
  public static final int TOO_BIG = 1;
  public static final int NO_SUCH_NAME = 2;
  public static final int BAD_VALUE = 3;
  public static final int READ_ONLY = 4;
  public static final int GENERAL_ERROR = 5;
 
  private final SocketLink _connection;

  private IntegerValue _version = IntegerValue.ZERO;
  private final OctetStringValue _communityString;
 
  private HashMap<String, Oid> _mibMap;
 
  public SnmpRequest(SocketLink connection,
                     HashMap<String, Oid> mibMap,
                     OctetStringValue community)
  {
    _connection = connection;
    _mibMap = mibMap;
   
    _communityString = community;
  }

  /**
   * Initialize the connection.  At this point, the current thread is the
   * connection thread.
   */
  public void init()
  {
  }

  /**
   * Return true if the connection should wait for a read before
   * handling the request.
   */
  public boolean isWaitForRead()
  {
    return true;
  }

  public void startConnection()
  {
  }
 
  /**
   * Handles a new connection.  The controlling TcpServer may call
   * handleConnection again after the connection completes, so
   * the implementation must initialize any variables for each connection.
   */
  public boolean handleRequest()
    throws IOException
  {
    ReadStream in = _connection.getReadStream();
   
    SnmpParser parser = new SnmpParser(in);
    SnmpMessageValue req = parser.readMessage();
   
    checkVersion(req);
    authenticate(req);
   
    SnmpMessageValue response = composeResponse(req);

    sendResponse(response);
   
    return true;
  }
 
  final protected void checkVersion(SnmpMessageValue req)
  {
    if (! _version.equals(req.getVersion())) {
      log.fine(L.l("expected version {0} != {1}",
                   _version,
                   req.getVersion()));
     
      throw new SnmpRuntimeException(L.l("expected version {0} != {1}",
                                         _version,
                                         req.getVersion()));
    }
  }
 
  final protected void authenticate(SnmpMessageValue req)
  {
    if (! _communityString.equals(req.getCommunityString())) {
      log.fine(L.l("non-matching community string"));
     
      throw new SnmpRuntimeException(L.l("non-matching community string"));
    }
  }
 
  final protected void sendResponse(SnmpValue response)
    throws IOException
  {
    OutputStream out = _connection.getWriteStream();
   
    StringBuilder sb = new StringBuilder();
    response.toAsn1(sb);

    for (int i = 0; i < sb.length(); i++) {
      out.write((byte) sb.charAt(i));
    }
    out.flush();
  }
 
  final protected SnmpMessageValue composeResponse(SnmpMessageValue req)
  {
    IntegerValue error = IntegerValue.ZERO;
    IntegerValue errorIndex = IntegerValue.ZERO;
    VarBindListValue varBindList = new VarBindListValue();
   
    int i = -1;
    try {
      switch (req.getPdu().getType()) {
        case SnmpValue.GET_REQUEST_PDU:
        {
          ObjectIdentifierValue []oids = req.getVarBindList().getNames();
         
          for (i = 0; i < oids.length; i++) {
            SnmpValue attr = getMBean(oids[i]);

            VarBindValue varBind;
           
            if (attr != null)
              varBind = new VarBindValue(oids[i], attr);
            else {
              varBind = new VarBindValue(oids[i], NullValue.NULL);
             
              if (error.getLong() == 0) {
                error = new IntegerValue(NO_SUCH_NAME);
                errorIndex = new IntegerValue(i + 1);
              }
            }
           
            varBindList.add(varBind);
          }

          break;
        }
        case SnmpValue.GET_NEXT_REQUEST_PDU:
        {
          break;
        }
        case SnmpValue.SET_REQUEST_PDU:
        {
          break;
        }
        default:
          log.fine(L.l("invalid pdu type {0}", req.getType()));
         
          throw new SnmpRuntimeException(L.l("invalid pdu type {0}",
                                             req.getType()));
      }
    }
    catch (Exception e) {
      if (error.getLong() == 0) {
        error = new IntegerValue(GENERAL_ERROR);
        errorIndex = new IntegerValue(i + 1);
      }
     
      if (req.getVarBindList().size() > i) {
        VarBindValue varBind
          = new VarBindValue(req.getVarBindList().get(i).getName(),
                             new OctetStringValue(e.getMessage()));
       
        varBindList.add(varBind);
      }
    }

    GetResponsePduValue pdu = new GetResponsePduValue(req.getRequestId(),
                                                      error,
                                                      errorIndex,
                                                      varBindList);

    return new SnmpMessageValue(req.getVersion(),
                                req.getCommunityString(),
                                pdu);
   
  }
 
  //@In MBeanServer _jmx;
  protected SnmpValue getMBean(ObjectIdentifierValue objectIdentifier)
  {
    MBeanServer mbeanServer = getMBeanServer();

    Oid oid = _mibMap.get(objectIdentifier.getString());

    if (oid == null)
      return null;

    try {
      ObjectName mbean = new ObjectName(oid.getMbean());

      Object attr = mbeanServer.getAttribute(mbean, oid.getAttribute());
     
      //XXX: complex attributes that are not either Integer or String
      //     i.e. from java.lang:type=Memory mbean
     
      return SnmpValue.create(attr, oid.getType());
    }
    catch (MalformedObjectNameException e) {
      log.fine(e.getMessage());
     
      throw new SnmpRuntimeException(e);
    }
    catch (AttributeNotFoundException e) {
      log.fine(e.getMessage());
     
      return null;
    }
    catch (InstanceNotFoundException e) {
      log.fine(e.getMessage());
     
      return null;
    }
    catch (MBeanException e) {
      log.fine(e.getMessage());
     
      throw new SnmpRuntimeException(e);
    }
    catch (ReflectionException e) {
      log.fine(e.getMessage());
     
      throw new SnmpRuntimeException(e);
    }
    catch (Exception e) {
      log.fine(e.getMessage());
     
      return null;
    }
  }
 
  //@In MBeanServer _jmx;
  protected MBeanServer getMBeanServer()
  {
    return Jmx.getMBeanServer();
  }

  /**
   * Resumes processing after a wait.
   */
  public boolean handleResume()
    throws IOException
  {
    return false;
  }

  /**
   * Handles a close event when the connection is closed.
   */
  public void onCloseConnection()
  {
  }

  /*
   * Sets the SNMP version.
   */
  public void setVersion(int version)
  {
    _version = new IntegerValue(version);
  }
 
  public HashMap<String, Oid> getMib()
  {
    return _mibMap;
  }
}
TOP

Related Classes of com.caucho.server.snmp.SnmpRequest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.