package com.nms.server.util; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.Vector; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.snmp4j.CommunityTarget; import org.snmp4j.DefaultTimeoutModel; import org.snmp4j.PDU; import org.snmp4j.ScopedPDU; import org.snmp4j.Snmp; import org.snmp4j.Target; import org.snmp4j.TransportMapping; import org.snmp4j.UserTarget; import org.snmp4j.event.ResponseEvent; import org.snmp4j.mp.MPv1; import org.snmp4j.mp.MPv2c; import org.snmp4j.mp.MPv3; import org.snmp4j.mp.SnmpConstants; import org.snmp4j.security.AuthMD5; import org.snmp4j.security.AuthSHA; import org.snmp4j.security.PrivAES128; import org.snmp4j.security.PrivAES192; import org.snmp4j.security.PrivAES256; import org.snmp4j.security.PrivDES; import org.snmp4j.security.SecurityLevel; import org.snmp4j.security.SecurityModels; import org.snmp4j.security.SecurityProtocols; import org.snmp4j.security.USM; import org.snmp4j.security.UsmUser; import org.snmp4j.smi.OID; import org.snmp4j.smi.OctetString; import org.snmp4j.smi.UdpAddress; import org.snmp4j.smi.VariableBinding; import org.snmp4j.transport.DefaultUdpTransportMapping; import org.snmp4j.util.DefaultPDUFactory; import org.snmp4j.util.TreeEvent; import org.snmp4j.util.TreeUtils; import com.nms.server.common.Common; import com.nms.server.common.Constants; /** * 最近项目上用到了SNMP操作,在网上找了找有关java操作SNMP 的例子发现原创的非常少,要么就是不完整。 * 看了一下SNMP4J的文档自己写了一个工具类, * @author Administrator * */ public class SNMP4JUtils { private static Logger logger = Logger.getLogger(SNMP4JUtils.class); public static final String ROOT="WALK"; private static final Integer C_P_RETRIES=0; private static final Integer C_P_TIME_OUT=7000; private static final String C_P_COMMUNITY="public"; private static final int C_P_VERSION = SnmpConstants.version2c; private static final Snmp snmp = createSnmp(); /** * * @param datas * @param oids * @param snmp * @param target * @throws Exception */ public static void snmpGet(Map datas,String[] oids,Target target) throws Exception{ if(target.getVersion() == SnmpConstants.version3){ snmpGetV3(datas,oids,target,Constants.SNMP_V3_SECURITY_NAME); }else{ snmpGetV2(datas,oids,snmp,target); } } /** * * @param datas * @param oids * @param snmp * @param target * @throws Exception */ public static void snmpGetV2(Map datas,String[] oids,Snmp snmp,Target target) throws Exception{ PDU request = createPDU(PDU.GET); for(String oid :oids ){ if((oid.toString()).endsWith(".0")) request.add(new VariableBinding(new OID(oid))); else{ // throw new Exception(oid+" 为非基本节点"); throw new Exception(oid+" is not basic node"); } } ResponseEvent respEvent = snmp.send(request, target); PDU response = respEvent.getResponse(); // if(isNullPDU(response,"SNMP4J 响应结果为空")){ if(isNullPDU(response,"The result of the SNMP4J response is empty")){ return; } if(response.getErrorIndex()==PDU.noError&&response.getErrorStatus()==PDU.noError){ Vector vector = (Vector) response.getVariableBindings(); for(VariableBinding vb : vector){ String key = vb.getOid().toString(); datas.put(key,vb.getVariable().toString()); //pl(key+" 88 "+vb.getVariable().toString()); } }else{ // throw new Exception("错误信息:"+response.getErrorStatusText()); throw new Exception("Error information:"+response.getErrorStatusText()); } } public static void snmpGetV3(Map datas,String[] oids,Target target,String contextName) throws Exception{ ScopedPDU request = new ScopedPDU(); for(String oid :oids){ if((oid.toString()).endsWith(".0")) request.add(new VariableBinding(new OID(oid))); else{ throw new Exception(oid+" is not basic node"); } } // request.setContextName(new OctetString(contextName)); request.setType(PDU.GET); ResponseEvent respEvent = snmp.send(request, target); System.out.println(snmp.getUSM().getUserTable().getUser(new OctetString(contextName))); System.out.println(respEvent.getResponse()); PDU response = respEvent.getResponse(); // if(isNullPDU(response,"SNMP4J 响应结果为空")){ if(isNullPDU(response,"The result of the SNMP4J response is empty")){ return; } if(response.getErrorIndex()==PDU.noError&&response.getErrorStatus()==PDU.noError){ Vector vector = (Vector) response.getVariableBindings(); for(VariableBinding vb : vector){ String key = vb.getOid().toString(); datas.put(key,vb.getVariable().toString()); } }else{ // throw new Exception("错误信息:"+response.getErrorStatusText()); throw new Exception("Error information:"+response.getErrorStatusText()); } } private static Map resoveVersion2c(PDU response) throws Exception{ Map datas = new HashMap(); if (response.getErrorIndex()==PDU.noError&&response.getErrorStatus()==PDU.noError) { Object obj = response.getVariableBindings().firstElement(); VariableBinding variable = (VariableBinding) obj; String key = variable.getOid().toString(); System.out.println("key:"+key+":"+variable.getVariable().toString()); datas.put(key,variable.getVariable().toString()); } else { // throw new Exception("错误信息:"+response.getErrorStatusText()); throw new Exception("Error information:"+response.getErrorStatusText()); } return datas; } /** * 将十进六制转换成为中文 */ private static String hexString = "0123456789ABCDEF"; public static String toStringHex(String bytes) { ByteArrayOutputStream baos = new ByteArrayOutputStream( bytes.length() / 2); //将每2位16进制整数组装成一个字节 for (int i = 0; i < bytes.length(); i += 2) { baos.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString .indexOf(bytes.charAt(i + 1)))); } return new String(baos.toByteArray()); } private static Map resoveVersion3(PDU response) throws Exception{ Map datas = new HashMap(); for (int i = 0; i < response.size(); i++) { VariableBinding vb = response.get(i); String[] str = vb.getVariable().toString().toUpperCase().split(":"); String strOut = ""; int intLength = str.length; logger.debug("长度==> " + intLength); for (int j = 0; j < intLength; j++) { strOut += str[j]; } // System.out.println("snmpWalkKey:"+vb.getOid()+" : "+vb.getVariable().toString()+" --中文: "); datas.put(vb.getOid().toString(), vb.getVariable().toString()); if (str.length != 1) { logger.debug("==第284行=vb.getVariable()=" + toStringHex(strOut));//显示中文 } } return datas; } public static CommunityTarget createCommunityTarget(String host,String port,String community,int retries,int timeout,int version){ CommunityTarget target = new CommunityTarget(); target.setAddress(new UdpAddress(host+"/"+port));//设置Snmp Agent的访问地址和端口 target.setCommunity(new OctetString(StringUtils.isEmpty(community)?C_P_COMMUNITY:community));//设置共同体,默认是"public" target.setRetries(retries==0?C_P_RETRIES:retries);//设置重试次数 target.setTimeout(timeout==0?C_P_TIME_OUT:timeout);//设置超时毫秒数 target.setVersion(version==0?C_P_VERSION : version);//设置snmp的版本号 return target; } public static UserTarget createUserTarget(String host,String port,int retries,int timeout){ UserTarget target = new UserTarget(); target.setAddress(new UdpAddress(host+"/"+port));//设置Snmp Agent的访问地址和端口 target.setRetries(1);//设置重试次数 target.setRetries(retries==0?C_P_RETRIES : retries);//设置重试次数 target.setTimeout(timeout==0?C_P_TIME_OUT : timeout);//设置超时毫秒数 target.setVersion(SnmpConstants.version3);//设置snmp的版本号 switch (Constants.SNMP_V3_SECURITY_LEVEL) { case 0: target.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV); break; case 1: target.setSecurityLevel(SecurityLevel.AUTH_NOPRIV); break; case 2: target.setSecurityLevel(SecurityLevel.AUTH_PRIV); break; default: target.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV); break; } target.setSecurityName(new OctetString(Constants.SNMP_V3_SECURITY_NAME)); return target; } public static Snmp createSnmp() { try { if(snmp == null){ String ip = Common.getLocalIp(); if(StringUtils.isEmpty(ip)){ return null; } TransportMapping transport = new DefaultUdpTransportMapping(); Snmp snmp = new Snmp(transport); snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1()); snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c()); snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3()); snmp.setTimeoutModel(new DefaultTimeoutModel()); USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0); SecurityModels.getInstance().addSecurityModel(usm); snmp.listen(); OID authProtocol = getAuthProtocol(Constants.SNMP_V3_AUTH_PROTOCOL); //认证协议 OID privProtocol = getPrivProtocol(Constants.SNMP_V3_PRIV_PROTOCOL); //加密协议 OctetString securityName = new OctetString(Constants.SNMP_V3_SECURITY_NAME); //认证用户 OctetString authPassphrase = new OctetString(Constants.SNMP_V3_AUTH_PASSPHRASE); //认证密码明文 OctetString privPassphrase = new OctetString(Constants.SNMP_V3_PRIV_PASSPHRASE); //加密密码明文 snmp.getUSM().addUser(securityName, new UsmUser(securityName, authProtocol, authPassphrase, privProtocol, privPassphrase)); logger.info("SNMP 启动成功"); return snmp; }else{ return snmp; } } catch (IOException e) { logger.error("SNMP4J ERROR", e); } catch (Exception e) { logger.error("SNMP4J ERROR", e); } return snmp; } private static OID getAuthProtocol(String auth){ if (auth.equals("MD5")) { return AuthMD5.ID; } else if (auth.equals("SHA")) { return AuthSHA.ID; }else{ return null; } } private static OID getPrivProtocol(String priv){ if (priv.equals("DES")) { return PrivDES.ID; } else if ((priv.equals("AES128")) || (priv.equals("AES"))) { return PrivAES128.ID; } else if (priv.equals("AES192")) { return PrivAES192.ID; } else if (priv.equals("AES256")) { return PrivAES256.ID; }else{ return null; } } private static PDU createPDU(int type){ PDU pdu= new PDU(); pdu.setType(type); return pdu; } /** * PDU为空判断 * @param pdu 需判断的PDU * @param messages PDU为空是输出的提示信息 * @return * @throws Exception */ public static boolean isNullPDU(PDU pdu, String messages) throws Exception{ boolean isNull = true; if(pdu!=null){ isNull = false; }else{ isNull = true; //pdu为空的处理可以添加到这里 // logger.debug(messages); // throw new Exception("错误信息:"+messages); throw new Exception("Error information:"+messages); } return isNull; } public static String checkTypeName = null; public static void snmpTree(List> datasList,List oidModel, String oid,String host,String port,String community,int retries,int timeout,int version,String checktypename) throws Exception{ checkTypeName = checktypename; snmpTree(datasList,oidModel, oid, host, port, community, retries, timeout, version); } public static void snmpTree(List> datasList,List oidModel, String oid,String host,String port,String community,int retries,int timeout,int version) throws Exception{ Target target = null; if (version == SnmpConstants.version3) { target = createUserTarget(host,port,retries,timeout); }else{ target = createCommunityTarget(host,port,community,retries,timeout, version); } treeUtilNew(datasList,oidModel,snmp,target,oid); } /** * * TODO * @author hyx Mar 20, 2013 * @version 1.0 */ public static void snmpIfXTabTree(Map> datasMap,List oidModel, String oid,String host,String port,String community,int retries,int timeout,int version) throws Exception{ Target target = null; if (version == SnmpConstants.version3) { target = createUserTarget(host,port,retries,timeout); }else{ target = createCommunityTarget(host,port,community,retries,timeout, version); } ifXTabTreeUtilNew(datasMap,oidModel,snmp,target,oid); } public static void subTreeUtil( List> datasList,List oidModel,Snmp snmp,Target target,String rootOid)throws Exception{ PDU request = createPDU(PDU.GETBULK); ResponseEvent respEvent = snmp.send(request, target); PDU response = respEvent.getResponse(); // if(isNullPDU(response,"SNMP4J 响应结果为空")){ if(isNullPDU(response,"The result of the SNMP4J response is empty")){ return; } if(response.getErrorIndex()==PDU.noError&&response.getErrorStatus()==PDU.noError){ Vector vector = (Vector) response.getVariableBindings(); for(VariableBinding vb : vector){ String key = vb.getOid().toString(); } }else{ // throw new Exception("错误信息:"+response.getErrorStatusText()); throw new Exception("Error information:"+response.getErrorStatusText()); } } public static void treeUtilNew( List> datasList,List oidModel,Snmp snmp,Target target,String rootOid)throws Exception{ TreeUtils treeUtils = null; List list = null; //如果没有指定oid则取系统基本信息 if(StringUtils.isBlank(rootOid)){ return ;//rootOid = "1.3.6.1.2.1.1"; } treeUtils = new TreeUtils(snmp ,new DefaultPDUFactory()); list = treeUtils.getSubtree(target, new OID(rootOid)); //获取到的所有实例信息,每个keyvalue中包含一个oid的所有实例信息的map Map> mapInstance = new LinkedHashMap>(); for (int j = 0; j < list.size(); j++) { TreeEvent treeEvent = (TreeEvent)list.get(j); if (treeEvent.isError()) throw new Exception((new StringBuilder("Error getting SNMP table:")).append(treeEvent.getErrorMessage()).toString()); if (treeEvent.getException() != null) throw new Exception((new StringBuilder("Get an exception in SNMP table:")).append(treeEvent.getErrorMessage()).append(" ").append(treeEvent.getException().getMessage()).toString()); if (treeEvent.getStatus() != 0) throw new Exception((new StringBuilder("Error getting SNMP table:")).append(treeEvent.getErrorMessage()).toString()); if (treeEvent.getVariableBindings() != null ){ VariableBinding vbArr[] = treeEvent.getVariableBindings(); if(vbArr != null){ for(int i = 0,m= vbArr.length;i map = mapInstance.get(index); if(map == null){ map = new HashMap(); mapInstance.put(index, map); } map.put(oidStr, vb.getVariable().toString()); } } } } } if(mapInstance.size() > 0){ Set>> entrySet = mapInstance.entrySet(); for(Entry> entry : entrySet){ Map value = entry.getValue(); if(value != null && value.size() > 0){ datasList.add(value); } } } logger.debug("datasList -> " + datasList.size()); } /** * * TODO * @author hyx Mar 20, 2013 * @version 1.0 */ public static void ifXTabTreeUtilNew( Map> datasMap,List oidModel,Snmp snmp,Target target,String rootOid)throws Exception{ TreeUtils treeUtils = null; List list = null; //如果没有指定oid则取系统基本信息 if(StringUtils.isBlank(rootOid)){ return ;//rootOid = "1.3.6.1.2.1.1"; } treeUtils = new TreeUtils(snmp ,new DefaultPDUFactory()); list = treeUtils.getSubtree(target, new OID(rootOid)); Vector vector2 = new Vector(); //获取信息过程是否异常 for (int j = 0; j < list.size(); j++) { TreeEvent treeEvent = (TreeEvent)list.get(j); if (treeEvent.isError()) throw new Exception((new StringBuilder("Error getting SNMP table:")).append(treeEvent.getErrorMessage()).toString()); if (treeEvent.getException() != null) throw new Exception((new StringBuilder("Get an exception in SNMP table:")).append(treeEvent.getErrorMessage()).append(" ").append(treeEvent.getException().getMessage()).toString()); if (treeEvent.getStatus() != 0) throw new Exception((new StringBuilder("Error getting SNMP table:")).append(treeEvent.getErrorMessage()).toString()); if (treeEvent.getVariableBindings() != null ){ VariableBinding vbArr[] = treeEvent.getVariableBindings(); if(vbArr != null){ for(int i = 0,m= vbArr.length;i map = datasMap.get(index); if(map == null){ map = new HashMap(); datasMap.put(index, map); } map.put(oidStr, vb.getVariable().toString()); } } } } } //删除空数据 Iterator>> it = datasMap.entrySet().iterator(); while(it.hasNext()){ Entry> next = it.next(); Map value = next.getValue(); if(value == null || value.size() <1){ it.remove(); } } } private static void pl(Object object) { System.out.println(object==null?null:object.toString()); } public static void main(String [] args) throws Exception{ // SNMP4J 》》》》1.3.6.1.2.1.1 10.0.6.230 161 public 3 0 1 //SNMP4J 》》》》 1.3.6.1.4.1.1000.1.2.1 10.0.6.230 161 public 3 0 1> List> datasList = new ArrayList>(); List oidModel = new ArrayList(); // [1.3.6.1.2.1.1.1, 1.3.6.1.2.1.1.2, 1.3.6.1.2.1.1.3, 1.3.6.1.2.1.1.4, 1.3.6.1.2.1.1.5, 1.3.6.1.2.1.1.6, 1.3.6.1.2.1.1.7] /*oidModel.add("1.3.6.1.2.1.1.1"); oidModel.add("1.3.6.1.2.1.1.2"); oidModel.add("1.3.6.1.2.1.1.3"); oidModel.add("1.3.6.1.2.1.1.4"); oidModel.add("1.3.6.1.2.1.1.5"); oidModel.add("1.3.6.1.2.1.1.6"); oidModel.add("1.3.6.1.2.1.1.7");*/ // [1.3.6.1.2.1.31.1.1.1.1, 1.3.6.1.2.1.31.1.1.1.2, 1.3.6.1.2.1.31.1.1.1.3, 1.3.6.1.2.1.31.1.1.1.4, 1.3.6.1.2.1.31.1.1.1.5, 1.3.6.1.2.1.31.1.1.1.6, 1.3.6.1.2.1.31.1.1.1.7, 1.3.6.1.2.1.31.1.1.1.8, 1.3.6.1.2.1.31.1.1.1.9, 1.3.6.1.2.1.31.1.1.1.10, 1.3.6.1.2.1.31.1.1.1.11, 1.3.6.1.2.1.31.1.1.1.12, 1.3.6.1.2.1.31.1.1.1.13, 1.3.6.1.2.1.31.1.1.1.14, 1.3.6.1.2.1.31.1.1.1.15, 1.3.6.1.2.1.31.1.1.1.17, 1.3.6.1.2.1.31.1.1.1.16, 1.3.6.1.2.1.31.1.1.1.19, 1.3.6.1.2.1.31.1.1.1.18] oidModel.add("1.3.6.1.4.1.1000.4.3.1.1"); oidModel.add("1.3.6.1.4.1.1000.4.3.1.2"); oidModel.add("1.3.6.1.4.1.1000.4.3.1.3"); oidModel.add("1.3.6.1.4.1.1000.4.3.1.4"); oidModel.add("1.3.6.1.4.1.1000.4.3.1.5"); oidModel.add("1.3.6.1.4.1.1000.4.3.1.6"); oidModel.add("1.3.6.1.4.1.1000.4.3.1.7"); oidModel.add("1.3.6.1.4.1.1000.4.3.1.8"); oidModel.add("1.3.6.1.4.1.1000.4.3.1.9"); oidModel.add("1.3.6.1.4.1.1000.4.3.1.10"); //String oid = "1.3.6.1.2.1.1"; String oid = "1.3.6.1.4.1.1000.4.3.1"; String host = "10.0.6.230"; String port = "161"; String community = "public"; int retries = 3; int timeout = 0; int version = SnmpConstants.version2c; String checktypename = "checktype100017"; snmpTree(datasList, oidModel, oid, host, port, community, retries, timeout, version, checktypename); System.out.println(datasList.size()); System.out.println(Arrays.toString(datasList.toArray())); } }