Snmp Package API 常被人忽视的Agent开发

来源:互联网 发布:嘉兴菜鸟网络食堂 编辑:程序博客网 时间:2024/05/16 05:55
 
  • Agent功能
Agent功能,可以使当前主机成为一台可以接收和处理从客户端发来的GET,GETNEXT,SET,GETBULK等SNMP REQUEST请求的网络设备.
多数入门级SNMP开发框架不支持Agent,Snmp Package API Agent开发,也是其新版本增加的功能.

  • Agent开发的意义
可以使你的软件产品的硬件平台具有被SNMP管理的功能,而又不需要设置安装一些专业的SNMP软件包比如net-snmpd.这些软件包经常很大型,支持很多平台和环境(因为是通用型软件),提供丰富但很多我们用不上的功能,相应的开销也很大. 而且这些专业级软件包很难进行二次开发上,不仅有开源的问题,还牵扯到GPL,LGPL等法律问题(比如允许开源但不允许加入商业行为).


  • snmp agent 开发例子

public class AgentTest implements SNMPRequestListener,Runnable
{
    private static Logger log = Logger.getLogger(AgentTest.class);
   
    private SNMPv1AgentInterface agentInterface;
    private String communityName = "public";
   
    private Thread readerThread;         
   
    private SortedMap mibMap = new TreeMap();
   
    public AgentTest()
    
        mibInitial();
       
        try
        {
           readerThread = new Thread(this);
           readerThread.start();
           
            int version = 0;    // SNMPv1
           
            agentInterface = new SNMPv1AgentInterface(version);
            agentInterface.addRequestListener(this);
            agentInterface.setReceiveBufferSize(5120);
            agentInterface.startReceiving();
           
        }
        catch(Exception e)
        {
            log.info("Problem starting Agent Test: " + e.toString());
        }
    }
 
   
    private void mibInitial(){
        mibMap.put("1.3.6.1.2.4.55.0", "hello mac!");
        mibMap.put("1.3.6.1.2.4.66.0", "hello 66!");
        mibMap.put("1.3.6.1.2.1.2.2.1.2", "ifDescr");
        mibMap.put("1.3.6.1.2.1.2.2.1.2.99", "interface FE 1/1");
        mibMap.put("1.3.6.1.2.1.2.2.1.2.100","interface FE 2/0");
        mibMap.put("1.3.6.1.2.1.4.2.0", "sysMem");
    }
           
   
    public void run()
        
        try
        {
            while (true){
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    public SNMPSequence processRequest(SNMPPDU pdu, String communityName)
        throws SNMPGetException, SNMPSetException
    {
        // 先显示收到的request的信息
        log.info("Got pdu:\n");
       
        log.info("  community name:     " + communityName );
        log.info("  request ID:         " + pdu.getRequestID() );
        log.info("  pdu type:           ");
        byte pduType = pdu.getPDUType();
        switch (pduType)
        {
            case SNMPBERCodec.SNMPGETREQUEST:
            {
                log.info("SNMPGETREQUEST\n");
                break;
            }
           
            case SNMPBERCodec.SNMPGETNEXTREQUEST:
            {
                log.info("SNMPGETNEXTREQUEST\n");
                break;
            }
           
            case SNMPBERCodec.SNMPSETREQUEST:
            {
                log.info("SNMPSETREQUEST\n");
                break;
            }
           
            case SNMPBERCodec.SNMPGETRESPONSE:
            {
                log.info("SNMPGETRESPONSE\n");
                break;
            }
           
            case SNMPBERCodec.SNMPTRAP:
            {
                log.info("SNMPTRAP\n");
                break;
            }
           
            default:
            {
                log.info("unknown\n");
                break;
                     
        }
       
        // community  authentication
        if (!communityName.equals(this.communityName))
        {
            return null;
        }
       
        // 针对request里的VarBindList一一处理
        SNMPSequence varBindList = pdu.getVarBindList();
        SNMPSequence responseList = new SNMPSequence();
       
        for (int i = 0; i < varBindList.size(); i++)
        {
            SNMPSequence variablePair = (SNMPSequence)varBindList.getSNMPObjectAt(i);
            SNMPObjectIdentifier snmpOID = (SNMPObjectIdentifier)variablePair.getSNMPObjectAt(0);
            SNMPObject snmpValue = (SNMPObject)variablePair.getSNMPObjectAt(1);
           
            log.info("     REQUEST  OID:           " + snmpOID );
            // 对GET,GETNEXT,此request的value一般都是null,只有对SET操作,才有值
            log.info("     REQUEST OID  value:         " + snmpValue ); 
           
            // 这里我们定义了3个OID("1.3.6.1.2.4.55.0","1.3.6.1.2.4.66.0","1.3.6.1.2.1.4.2.0")
            // 注意测试时只能GET这3个OID的值
            // 第一个OID是只读的,只能GET,第二个OID可以SET,第三个OID我们把系统剩余内存返回给请求方
            if (snmpOID.toString().equals("1.3.6.1.2.4.55.0"))
            {
                if (pduType == SNMPBERCodec.SNMPSETREQUEST)
                {
                    // got a set-request for our variable; throw an exception to indicate the
                    // value is read-only
                    int errorIndex = i+1;
                    int errorStatus = SNMPRequestException.VALUE_READ_ONLY;
                   throw new SNMPSetException("Trying to set a read-only variable!",
                             errorIndex, errorStatus);
                }
                else if (pduType == SNMPBERCodec.SNMPGETREQUEST)
                {
                    // got a get-request for our variable; send back a value - just a string
                    try
                    {
                        SNMPVariablePair newPair = new SNMPVariablePair(snmpOID,
                              new SNMPOctetString((String)mibMap.get("1.3.6.1.2.4.55.0")));
                        responseList.addSNMPObject(newPair);
                    }
                    catch (SNMPBadValueException e)
                    {
                        // won't happen...
                    }
                }
               
            }
           
            if (snmpOID.toString().equals("1.3.6.1.2.4.66.0"))
            {
                if (pduType == SNMPBERCodec.SNMPSETREQUEST)
                {
                    // got a set-request for our variable; supplied value must be a string
                    if (snmpValue instanceof SNMPOctetString)
                    {
                      // set new value
                      mibMap.remove("1.3.6.1.2.4.66.0");
             mibMap.put("1.3.6.1.2.4.66.0",((SNMPOctetString)snmpValue).toString());

                        // return SNMPVariablePair to indicate we've handled this OID
                        try
                        {
                            SNMPVariablePair newPair = new SNMPVariablePair(snmpOID,
                             new SNMPOctetString((String)mibMap.get("1.3.6.1.2.4.66.0")));
                            responseList.addSNMPObject(newPair);
                        }
                        catch (SNMPBadValueException e)
                        {
                            // won't happen...
                        }
                   
                    }
                    else
                    {
                        int errorIndex = i+1;
                        int errorStatus = SNMPRequestException.BAD_VALUE;
                        throw new SNMPSetException("Supplied value must be SNMPOctetString",
                                               errorIndex, errorStatus);
                    }
                   
                }
                else if (pduType == SNMPBERCodec.SNMPGETREQUEST)
                {
                    // got a get-request for our variable; send back a value - just a string
                    try
                    {
                        SNMPVariablePair newPair = new SNMPVariablePair(snmpOID,
                               new SNMPOctetString((String)mibMap.get("1.3.6.1.2.4.66.0")));
                        responseList.addSNMPObject(newPair);
                    }
                    catch (SNMPBadValueException e)
                    {
                        // won't happen...
                    }
                }
               
            }
           
           
            if (snmpOID.toString().equals("1.3.6.1.2.1.4.2.0"))
            {
                if (pduType == SNMPBERCodec.SNMPSETREQUEST)
                {
                    int errorIndex = i+1;
                    int errorStatus = SNMPRequestException.VALUE_READ_ONLY;
                    throw new SNMPSetException("Trying to set a read-only variable!",
                                               errorIndex, errorStatus);
                }
                else if (pduType == SNMPBERCodec.SNMPGETREQUEST)
                {
                    // got a get-request for our variable; send back a value - just a string
                    try
                    {
                        SNMPVariablePair newPair = new SNMPVariablePair(
                                snmpOID, new SNMPOctetString((String)getMemery()));
                        responseList.addSNMPObject(newPair);
                    }
                    catch (SNMPBadValueException e)
                    {
                        // won't happen...
                    }
                }
               
            }
           
        }
       
       
        // return the created list of variable pairs
        return responseList;
       
    }


    
    public static String getMemery(){
      OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
      // 总的物理内存+虚拟内存
      long totalvirtualMemory = osmxb.getTotalSwapSpaceSize();
      // 剩余的物理内存
      long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize();
      Double compare=(Double)(1-freePhysicalMemorySize*1.0/totalvirtualMemory)*100;
      String str="内存已使用:"+compare.intValue()+"%";
      return str;
    }

    public SNMPSequence processGetNextRequest(SNMPPDU pdu, String communityName)
        throws SNMPGetException
    {
        // 先显示收到的request的信息
        log.info("Got pdu:\n");
       
        log.info("  community name:     " + communityName );
        log.info("  request ID:         " + pdu.getRequestID() );
        log.info("  pdu type:           ");
        byte pduType = pdu.getPDUType();
       
        switch (pduType)
        {
            case SNMPBERCodec.SNMPGETREQUEST:
            {
                log.info("SNMPGETREQUEST\n");
                break;
            }
           
            case SNMPBERCodec.SNMPGETNEXTREQUEST:
            {
                log.info("SNMPGETNEXTREQUEST\n");
                break;
            }
           
            case SNMPBERCodec.SNMPSETREQUEST:
            {
                log.info("SNMPSETREQUEST\n");
                break;
            }
           
            case SNMPBERCodec.SNMPGETRESPONSE:
            {
                log.info("SNMPGETRESPONSE\n");
                break;
            }
           
            case SNMPBERCodec.SNMPTRAP:
            {
                log.info("SNMPTRAP\n");
                break;
            }
           
            default:
            {
                log.info("unknown\n");
                break;
            }
           
           
        }
       
        // community  authentication
        if (!communityName.equals(this.communityName))
        {
            return null;
        }
       
        // 针对request里的VarBindList一一处理
       
        SNMPSequence varBindList = pdu.getVarBindList();
        SNMPSequence responseList = new SNMPSequence();
       
        for (int i = 0; i < varBindList.size(); i++)
        {
            SNMPSequence variablePair = (SNMPSequence)varBindList.getSNMPObjectAt(i);
            SNMPObjectIdentifier suppliedOID = 
                                        (SNMPObjectIdentifier)variablePair.getSNMPObjectAt(0);
            SNMPObject suppliedObject = (SNMPObject)variablePair.getSNMPObjectAt(1);
           
            log.info("     REQUEST  OID:           " + suppliedOID  );
            // 对GET,GETNEXT,此request的value一般都是null,只有对SET操作,才有值
            log.info("     REQUEST OID  value:         " + suppliedObject );
           
            if (suppliedOID.toString().equals("1.3.6.1.2.1.2.2.1.2"))
            {
                if (pduType == SNMPBERCodec.SNMPGETNEXTREQUEST)
                {
                    try
                    {
                        // create SNMPVariablePair for the next OID and its value
                        SNMPObjectIdentifier nextOID =
                                     new SNMPObjectIdentifier("1.3.6.1.2.1.2.2.1.2.99");
                        SNMPVariablePair innerPair = new SNMPVariablePair(nextOID,
                      new SNMPOctetString((String)mibMap.get("1.3.6.1.2.1.2.2.1.2.99")));

                        SNMPVariablePair outerPair = new SNMPVariablePair(suppliedOID,
                                                                                innerPair);
                       
                        // add the "compound" SNMPVariablePair to the response list
                        responseList.addSNMPObject(outerPair);
                       
                    }
                    catch (SNMPBadValueException e)
                    {
                        // won't happen...
                    } // end of try
                } // end of if
               
            } // end of if

            if (suppliedOID.toString().equals("1.3.6.1.2.1.2.2.1.2.99"))
            {
                if (pduType == SNMPBERCodec.SNMPGETNEXTREQUEST)
                {
                    try
                                        
                        SNMPObjectIdentifier nextOID = new
                                         SNMPObjectIdentifier("1.3.6.1.2.1.2.2.1.2.100");
                        SNMPVariablePair innerPair = new SNMPVariablePair(nextOID,
                       new SNMPOctetString((String)mibMap.get("1.3.6.1.2.1.2.2.1.2.100")));
                       
                        SNMPVariablePair outerPair = new SNMPVariablePair(suppliedOID,
                                                                                   innerPair);
                        responseList.addSNMPObject(outerPair);
                    }
                    catch (SNMPBadValueException e)
                    {
                        // won't happen...
                    } // end of try
                } // end of if
               
            } // end of if           

            if (suppliedOID.toString().equals("1.3.6.1.2.1.2.2.1.2.100"))
            {
                if (pduType == SNMPBERCodec.SNMPGETNEXTREQUEST)
                {
                    try
                                        
                        // create SNMPVariablePair for the next OID and its value
                        SNMPObjectIdentifier nextOID = new SNMPObjectIdentifier(
                                                                       "1.3.6.1.2.999");
                        SNMPVariablePair innerPair = new SNMPVariablePair(nextOID,
                                                        new SNMPOctetString("end of int"));
                       
                        SNMPVariablePair outerPair = new SNMPVariablePair(suppliedOID,
                                                                             innerPair);
                        responseList.addSNMPObject(outerPair);
                    }
                    catch (SNMPBadValueException e)
                    {
                        // won't happen...
                    } // end of try
                } // end of if
               
            } // end of if  
           
            
       
        // return the created list of variable pairs
        return responseList;
       
    }
    public static void main(String args[])
    {
        try
        {
            AgentTest theApp = new AgentTest();
        }
        catch (Exception e){}
      

测试
1. 启动上面的AgentTest.Java2. 用前面文章里的SNMPget类的get()和getNext()方法向AgentTest.Java启动的Agent服务发snmp GET request和snmp GETNEXT request

    public static void main(String[] args) throws IOException {
        Map<String,String> oidMap = new HashMap<String,String>();
        oidMap.put("sysDescr","1.3.6.1.2.1.1.1.0");
        oidMap.put("ifDescr","1.3.6.1.2.1.2.2.1.2");
       
        oidMap.put("agentTest1","1.3.6.1.2.4.55.0");
        oidMap.put("agentTest2","1.3.6.1.2.4.66.0");
        oidMap.put("agentTest3","1.3.6.1.2.1");
        oidMap.put("sysMem","1.3.6.1.2.1.4.2.0");
       
        String host = "192.168.0.100";
        String community = "public";
       
       
        System.out.println("==================get测试=====================");
        String resp = SNMPget.get(host,community,oidMap.get("agentTest1"));
        System.out.println(resp);
        resp = SNMPget.get(host,community,oidMap.get("sysMem"));
        System.out.println(resp);
       
        System.out.println("==================getNext测试=================");
        SortedMap map = SNMPget.getNext(host,community,oidMap.get("ifDescr"));
        System.out.println("共"+map.size()+"个接口");
        Iterator iter = map.keySet().iterator();
        while(iter.hasNext()){
            System.out.println(map.get(iter.next()));
        }
       
    }
看结果:
==================get测试=====================
hello mac!
内存已使用:92%
==================getNext测试=================
共2个接口
interface FE 1/1
interface FE 2/0