/** * */ package org.infosec.ismp.manager.server.event.analytic.trap; import java.lang.reflect.Method; import java.net.URL; import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.Map; import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.digester.Digester; import org.apache.commons.digester.xmlrules.DigesterLoader; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.infosec.ismp.manager.rmi.event.modle.NormalizedEvent; import org.infosec.ismp.manager.rmi.event.modle.TrapEvent; import org.infosec.ismp.manager.server.event.EventTrapReceive; import org.infosec.ismp.manager.server.event.analytic.trap.digester.TrapBinding; import org.infosec.ismp.manager.server.event.analytic.trap.digester.TrapMatcher; import org.infosec.ismp.manager.server.event.analytic.trap.digester.TrapParser; import org.infosec.ismp.manager.server.event.analytic.trap.digester.TrapParsers; import org.infosec.ismp.manager.server.event.analytic.trap.digester.TrapTransform; import org.infosec.ismp.manager.server.event.util.Constants; import org.snmp4j.smi.VariableBinding; import org.springframework.stereotype.Component; /** * @author 林超 * * @date {@link MultiThreadedTrapReceiver} * */ @Component public class MultiThreadedTrapReceiver implements EventTrapReceive { protected final Log log = LogFactory.getLog(getClass()); private IDSTrapAssemble idsTrapAssemble;// 用于处理IDS数据 public void setIdsTrapAssemble(IDSTrapAssemble idsTrapAssemble) { this.idsTrapAssemble = idsTrapAssemble; } int firewallCount = 0; SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 标准化事件格式 Vector<NormalizedEvent> batch = new Vector<NormalizedEvent>(); // 实例化一个存放解析并进行归一化后的事件向量 // List<NormalizedEvent> eventBatch = new ArrayList<NormalizedEvent>(); // // private EventSender sendEvent = new EventSenderImpl(); // // public static final int MANAGER_EVENT_FLAG = 21; URL input; URL rules; /** * */ public MultiThreadedTrapReceiver() { ClassLoader c = MultiThreadedTrapReceiver.class.getClassLoader(); input = c.getResource("trap.xml"); rules = c.getResource("trap_rule.xml"); } private int sumEvent = 0; private long sumStartTime = 0; /** * 运行监听接收trap程序,同时进行对trap的解析,采用digester方式 run */ public synchronized void trapAnalytic(TrapEvent trap, String domainId, String nodeId, String ip) { if (sumStartTime == 0) { sumStartTime = System.currentTimeMillis(); } // System.out // .println("----MultiThreadedTrapReceiver.trapAnalytic(Integer agentId,Vector<TrapEvent> traps)------"); /** * 存放要解析的事件 */ Map<String, TrapParser> trapParserMap = new HashMap<String, TrapParser>(); // PrintWriter log; // String logFile = "log/audit_trap_error.log"; // try { // log = new PrintWriter(new FileWriter(logFile, true), true); // } catch (IOException e) { // System.err.println("error exception: " + logFile); // log = new PrintWriter(System.err); // } try { // File input = new File("configs/trap.xml"); // File rules = new File("configs/trap_rule.xml"); // 配置解析规则 Digester digester; digester = DigesterLoader.createDigester(rules); TrapParsers trapParsers = (TrapParsers) digester.parse(input); trapParserMap = trapParsers.getTrapParsers(); // log.println(new java.util.Date() + "\n" + trapParsers // + "\n----------------------------"); } catch (Exception e1) { e1.printStackTrace(); } long startTime = System.currentTimeMillis(); log.debug("开始处理事件时间(毫秒):" + startTime); int num = 0; // 处理事件数据计数用 int errNum = 0; try { // if(trapSize != 0){ // System.out.println("trap is " + traps.get(0)); // } // **************************** num += num; // **************************** TrapParser trapParser = (TrapParser) trapParserMap.get(ip); // 在配置文件已提前定义好的要监听并接收trap的设备IP // ,目前是接收本地发送的trap // System.out.println("-----解析规则对象trapParser------" // + trapParser); if (trapParser != null) { String type = trapParser.getType().trim();// 获取该设备信息型号 // . String deconding = trapParser.getDeconding();// 需转换的字符编码 NormalizedEvent event = new NormalizedEvent(); // 初始化归一化事件 if (trapParser != null) { Vector<TrapMatcher> trapMatchers = trapParser .getTrapMatchers(); // System.out.println("trapmatcher's size is " // + trapMatchers.size()); //FIXME for NPE bug for (TrapMatcher trapMatcher : trapMatchers) { Vector<TrapBinding> trapBindings = trapMatcher .getTrapBindings(); /** * TrapBinding是匹配发送过来的trap信息的第几行是我们想要的内容, 即bindingNumber */ for (TrapBinding trapBinding : trapBindings) { int i = Integer.parseInt(trapBinding .getBindingNumber()); Vector<VariableBinding> recVBs = trap.getPdu() .getVariableBindings(); // 取出PDU中储存的所有trap事件信息 if (recVBs.size() >= i && recVBs.size() > 0) { String message = ""; if (i > 0) { VariableBinding recVB = recVBs.elementAt(i); // 取出配置文件中定义好的某行的trap信息 message = new String((String) recVB .getVariable().toString()); // // System.out // .println("------message---1111111-----" // + message); // 进行16进制转换和编码转换 String mestr = message.replace(":", ""); boolean flag = mestr .matches("[\\da-fA-F]+"); if (flag) { message = toStringHex(mestr); } if (deconding != null && deconding.trim().length() > 0) { byte[] bs = message.getBytes(); String str = new String(bs, deconding); message = str; } // System.out // .println("------message---222222222-----" // + message); } else if (i == 0 && type.equals("3") && recVBs.size() > 10) { for (int j = 2; j < recVBs.size(); j++) { VariableBinding recVB = recVBs .elementAt(j); String mes = new String((String) recVB .getVariable().toString() .trim()); // System.out // .println("------type.equals(3)---------" // + mes); // 进行16进制转换和编码转换 if (j != 8 && j != 9 && j != 12 && j != 14) { String mestr = mes.replace(":", ""); boolean flag = mestr .matches("[\\da-fA-F]{2,}"); if (flag) { if (j == 15) { mes = toStringHexUtf8(mestr); } else { mes = toStringHex(mestr); } } if (deconding != null && deconding.trim() .length() > 0) { byte[] bs = mes.getBytes(); String str = new String(bs, deconding); mes = str; } // System.out // .println("------type.equals(3)-----" // + mes); } message = message + mes + ";"; log.debug(message); // System.out // .println("------message---333333333333----" // + message); } } /** * 用正则表达式匹配获取的事件信息 */ if (message != null && message.length() > 0) { String regex = trapBinding.getRegex(); Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(message); if (matcher.find()) { String[] parsedMessage = new String[matcher .groupCount()]; for (int k = 0; k < parsedMessage.length; k++) { parsedMessage[k] = matcher .group(k + 1); } Vector<TrapTransform> trapTransforms = trapBinding .getTrapTransforms(); if (trapTransforms.size() > 0) { TrapTransformer transformer = new TrapTransformer(); for (TrapTransform trapTransform : trapTransforms) { String sn = trapTransform .getSerialNumber(); String time = parsedMessage[Integer .parseInt(sn)]; if (time != null && time.trim().length() > 0) { String methodName = trapTransform .getMethod(); Method transforming = transformer .getClass() .getMethod( methodName, String.class); parsedMessage[Integer .parseInt(sn)] = (String) transforming .invoke( transformer, parsedMessage[Integer .parseInt(sn)]); } } } /** * 对事件进行归一化处理和存储 */ if (type.equals("1")) { event = idsTrapAssemble .assemble(parsedMessage); } else if (type.equals("2")) { event = idsTrapAssemble .yingYanAssemble(parsedMessage); } else if (type.equals("3")) { event = idsTrapAssemble .iceyeAssemble(parsedMessage); } event.setIpaddr(ip); event.setDomain(domainId); } else { // System.out.println( // "nu match!"); } } } } } /** * 对归一化后的事件进行过滤,剔除掉格式不符合的事件,这里是根据源IP,目的IP, 和事件时间来过滤事件 */ if (event.getDestip().equals("") || event.getSrcip().equals("") || event.getTimestamp() == null) { errNum++; if (errNum % 10 == 0) { log.debug("丢弃事件数量:" + errNum); } // System.out // .println( // "\n the trap formatter is not right!! \n") // ; } else { // System.out.println("threrank XXXxXXXXXXXXXXXXXXX is " // + event.getThrerank()); // System.out.println("event src_ip is " // + event.getSrcip()); // // System.out.println("event faci_ip is " // + event.getIpaddr()); // // System.out.println("---------------------"); // 2010-6-1 lchao //FIXME 发送给态势模块 Constants.addAuditEvent(event); sumEvent++; // System.out.println(System.currentTimeMillis() + "---" // + sumStartTime + "==" // + (System.currentTimeMillis() - sumStartTime)); // System.out.println(sumEvent); if ((System.currentTimeMillis() - sumStartTime) >= 60000) { System.out.println("现在已处理条数:" + sumEvent); System.out .println("耗费时间(毫秒):" + (System.currentTimeMillis() - sumStartTime)); sumEvent = 0; sumStartTime = System.currentTimeMillis(); } } } else { // System.out.println("trap parser is null!"); } } // eventBatch = Constants.getNormalEvents(); // if(eventBatch.size() > 0){ // sendEvent.sendEventsToManager(MANAGER_EVENT_FLAG, // eventBatch); // } log.debug("现在已处理条数:" + num); long endTime = System.currentTimeMillis(); log.debug("耗费时间(毫秒):" + (endTime - startTime)); } catch (Exception e2) { e2.printStackTrace(); // System.out.println("while错误"); } } // public List<BaseEvent> getBatch() { // return batch; // } // // public void setBatch(List<BaseEvent> vBatch) { // batch = vBatch; // } // /** // * 显示解析好的事件的信息 display // */ // public void display() { // Vector<CommandResponderEvent> traps = new // Vector<CommandResponderEvent>(); // traps = Constants.getTraps(traps); // System.out.println("trap NO:" + traps.size()); // int iCount = 0; // if (traps.size() > 0) { // for (CommandResponderEvent trap : traps) { // if (trap != null && trap.getPDU() != null) { // Vector<VariableBinding> recVBs = trap.getPDU() // .getVariableBindings(); // System.out.println("received one trap:" + (++iCount)); // 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!"); // } // } // } // traps.removeAllElements(); // } /** * @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) { // MultiThreadedTrapReceiver multithreadedtrapreceiver = new // MultiThreadedTrapReceiver(); // multithreadedtrapreceiver.start(); } }