package org.infosec.ismp.trapd; import java.io.IOException; import java.net.UnknownHostException; import java.util.List; import java.util.Vector; import org.infosec.ismp.manager.rmi.event.modle.TrapEvent; import org.infosec.ismp.manager.rmi.event.modle.TrapEventWrapper; import org.infosec.ismp.util.ThreadCategory; import org.snmp4j.CommandResponder; import org.snmp4j.CommandResponderEvent; import org.snmp4j.MessageDispatcherImpl; import org.snmp4j.Snmp; import org.snmp4j.TransportMapping; import org.snmp4j.mp.MPv1; import org.snmp4j.mp.MPv2c; import org.snmp4j.mp.MPv3; import org.snmp4j.security.SecurityModels; import org.snmp4j.security.SecurityProtocols; import org.snmp4j.security.USM; import org.snmp4j.smi.Address; import org.snmp4j.smi.GenericAddress; import org.snmp4j.smi.OctetString; import org.snmp4j.smi.TcpAddress; import org.snmp4j.smi.UdpAddress; import org.snmp4j.smi.VariableBinding; import org.snmp4j.transport.DefaultTcpTransportMapping; import org.snmp4j.transport.DefaultUdpTransportMapping; import org.snmp4j.util.MultiThreadedMessageDispatcher; import org.snmp4j.util.ThreadPool; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; /** * 负责接收snmpTrap的类 * @author lianglin * */ @Component public class SnmpTrapHandler implements CommandResponder { private MultiThreadedMessageDispatcher dispatcher; private Snmp snmp = null; private Address listenAddress; private ThreadPool threadPool; private TrapNodeMessageSend messageSend; @Autowired(required=true) @Qualifier(value="snmpTrapSend") public void setMessageSend(TrapNodeMessageSend messageSend) { this.messageSend = messageSend; } private TrapNodeManager trapNodeManager; public SnmpTrapHandler() { } public void setTrapNodeManager(TrapNodeManager trapNodeManager) { this.trapNodeManager = trapNodeManager; } private void init() throws UnknownHostException, IOException { // Assert.state(trapNodeManager!=null,"trapNodeManager必须设置,请检查"); threadPool = ThreadPool.create("Trap", 2); dispatcher = new MultiThreadedMessageDispatcher(threadPool, new MessageDispatcherImpl()); listenAddress = GenericAddress.parse(System.getProperty( "snmp4j.listenAddress", "udp:0.0.0.0/162")); // 本地IP与监听端口 TransportMapping transport; // 对TCP与UDP协议进行处理 if (listenAddress instanceof UdpAddress) { transport = new DefaultUdpTransportMapping( (UdpAddress) listenAddress); } else { transport = new DefaultTcpTransportMapping( (TcpAddress) listenAddress); } snmp = new Snmp(dispatcher, transport); snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1()); snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c()); snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3()); USM usm = new USM(SecurityProtocols.getInstance(), new OctetString( MPv3.createLocalEngineID()), 0); SecurityModels.getInstance().addSecurityModel(usm); snmp.listen(); } public void run() { try { init(); snmp.addCommandResponder(this); System.out.println("开始监听Trap信息!"); } catch (Exception ex) { ex.printStackTrace(); } } /** * 实现CommandResponder的processPdu方法, 用于处理传入的请求、PDU等信息 当接收到trap时,会自动进入这个方法 * * @param respEvnt */ public void processPdu(CommandResponderEvent respEvnt) { // 解析Response // System.out.println("地址是: "+respEvnt.getPeerAddress()); Address address = respEvnt.getPeerAddress(); String addressStr = address.toString(); int index = addressStr.indexOf('/'); String fromIp = addressStr.substring(0, index); List<TrapNode> nodes = trapNodeManager.getAllTrapNodes(); boolean matchFlag = false; for (TrapNode node : nodes) { String ip = node.getIpAddr(); if (fromIp.equals(ip)) { TrapEvent event = new TrapEvent(); event.setMaxSizeResponsePDU(respEvnt.getMaxSizeResponsePDU()); event.setMessageProcessingModel(respEvnt .getMessageProcessingModel()); event.setPdu(respEvnt.getPDU()); event.setPeerAddress(respEvnt.getPeerAddress()); event.setSecurityLevel(respEvnt.getSecurityLevel()); event.setSecurityModel(respEvnt.getSecurityModel()); event.setSecurityName(respEvnt.getSecurityName()); event.setTransportMapping(respEvnt.getTransportMapping()); event.setProcessed(respEvnt.isProcessed()); matchFlag = true; TrapEventWrapper wrapper = new TrapEventWrapper(event); wrapper.setIp(fromIp); wrapper.setNodeId(node.getNodeid()); messageSend.springsend(wrapper); break; } } if (!matchFlag) { log().info("收到的Trap event 被抛弃"); } // Constants.addTrap(event); } /** * 显示解析好的事件的信息 display */ public void display(TrapEvent trap) { if (trap != null && trap.getPdu() != null) { Vector<VariableBinding> recVBs = trap.getPdu() .getVariableBindings(); for (int i = 0; i < recVBs.size(); i++) { VariableBinding recVB = recVBs.elementAt(i); System.out .println(recVB.getOid() + " : " + recVB.getVariable()); } } else { System.out.println("trap is null!"); } } /** * @param s把16进制转换成字符串 * @return */ public static String toStringHex(String s) { byte[] baKeyword = new byte[s.length() / 2]; for (int i = 0; i < baKeyword.length; i++) { try { baKeyword[i] = (byte) (0xff & Integer.parseInt( s.substring(i * 2, i * 2 + 2), 16)); } catch (Exception e) { e.printStackTrace(); } } try { s = new String(baKeyword, "gb2312");// UTF-16le:Not } catch (Exception e1) { e1.printStackTrace(); } return s; } public static String toStringHexUtf8(String s) { byte[] baKeyword = new byte[s.length() / 2]; for (int i = 0; i < baKeyword.length; i++) { try { baKeyword[i] = (byte) (0xff & Integer.parseInt( s.substring(i * 2, i * 2 + 2), 16)); } catch (Exception e) { e.printStackTrace(); } } try { s = new String(baKeyword, "utf8");// UTF-16le:Not } catch (Exception e1) { e1.printStackTrace(); } return s; } public static void main(String[] args) { SnmpTrapHandler handler = new SnmpTrapHandler(); handler.setTrapNodeManager(new TrapNodeManager()); handler.run(); while (true) { System.out.println("test"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } protected ThreadCategory log() { return ThreadCategory.getInstance(getClass()); } }