wireshark抓包对应xml文件解析

最近在搭建内部平台的时候,需设计一个脚本,将pcap/pcapng文件转化成xml文件,并且需要从xml提取有效数据,将其插入Mongo数据库,实现语言为java,具体实现时引入了一些第三方库,最后生成一个auto.jar文件,因为jar文件可以很方便的被其他脚本直接调用,方便做一些自动化管理。

整个auto.jar的实现分为以下三部分:

1、 通过Process调用tshark命令,将pcap/pcapng文件转化成xml文件

2、 根据提取数据内容的BSON格式设计文档,从xml文件提取有效信息,并调用阿里的fastjson库(Java语言编写的JSON处理器)生成BSON格式信息

3、 通过Mongo3.1.jar库,将BSON信息插入数据库

下面对上述三个部分做一个简单的说明。

一、xml文件生成

示例程序如Example.java文件所示,通过Runtime.getRuntime()执行命令即可。该过程相对较简单,需要注意的是,在Windows和linux平台下,具体命令的表现形式会有所不同,如Window需要加上”cmd.exe /C”,linux需要加上”/bin/sh -c”。

生成xml文件通过tshark命令实现,tshark命令需注意版本,不同版本生成xml标签字段会有一些差别,比如版本1.6.*中UDP包可能就没有Stream index字段,而2.2.6版本则有上述字段。

public class Example {  
    public static void main(String args[]) {  
        try {  
            Runtime runtime = Runtime.getRuntime();  
            Process proc = runtime.exec("tshark -r xxx.pcap -T pdml > yyy.xml");  
            int exitVal = proc.exitValue();  
            System.out.println("Process exitValue: " + exitVal);  
        } catch (Throwable t) {  
            t.printStackTrace();  
        }  
    }  
} 
tshark命令详细信息链接 tshark命令详细说明

二、xml解析

xml解析需选择适当的xml解析库,xml解析库有很多,如SAXParser、dom4j等,思路通常分为两种,一种是首先读取所有的xml文件,然后通过标签节点提取信息,另一种是按一行标签一行标签读取,通过一些特定的接口逻辑,如public void startElement(...), public void endElement(...),实现上下文关联,因为解析xml的时候,有时需要解析完一个顶层标签才能获得想要的信息,而顶层标签可能又包含多行标签,所以需要做一些上下文关联管理。

前者适用于文件较小的xml文件,一般不要超过100M(与电脑硬件配置有关),这种方式可以从xml文件的全局出发去解析xml文件,相对比较直观;后者适用于文件较大的xml文件,如几GB~几十GB,甚至更大。

Demo0是使用dom4j的一个例子。

public class Demo0 {
	
	public static void main(String[] args){
		File xmlFile = new File("D:/s.xml");
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(xmlFile);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.err.println("File is not exsit!");
		}
		
		SAXReader saxReader = new SAXReader();
		List rowList = null;
		try {
			//生成文档对应实体
			Document doc = saxReader.read(fis);
			//获取指定路径下的元素列表,这里指获取所有的data下的row元素
			rowList = doc.selectNodes("//data/row");
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		for(Iterator iter = rowList.iterator();iter.hasNext();){
			//获得具体的row元素 
			Element element = (Element)iter.next();
			//获得row元素的所有属性列表
			List elementList = element.attributes();
			for(Iterator iter1 = elementList.iterator();iter1.hasNext();){
				//将每个属性转化为一个抽象属性,然后获取其名字和值
				AbstractAttribute aa = (AbstractAttribute)iter1.next();
				System.out.println("Name:"+aa.getName()+";Value:"+aa.getValue());
			}
		}
	}
}
这种方式不适合处理大文件,我的电脑上跑大于等于800MB的xml文件就跑不动了(我的电脑内存为16GB)。

Demo1是SAXParser的一个例子。

public class Demo1 extends DefaultHandler {  
	// 执行到起始标签触发
	@Override  
	public void startElement(String uri, String localName, String qName,  
			Attributes attributes) throws SAXException {  
		super.startElement(uri, localName, qName, attributes);  
		for (int i = 0; i < attributes.getLength(); i++) {  
			String value = attributes.getValue(i);// 获取属性的value值  
			System.out.println(attributes.getQName(i) + "-----" + value);  
		}  
	}  
	
	// 执行到标签尾触发
	@Override  
	public void endElement(String uri, String localName, String qName)  
			throws SAXException {  
		super.endElement(uri, localName, qName);   
	}  
	
	// 读完xml文件触发
	@Override  
	public void endDocument() throws SAXException {  
		super.endDocument();  
	}  
} 
Demo1是一行一行标签读取,所有如果需要处理顶层标签,需要结合startElement(...)和endElement(..)接口,做一些应用管理。

由于xml提取出的信息大部分是文本信息,所以要提取具体内容的时候,会使用大量的正则匹配,如提取某个括号内的信息等,会用到一些高级的正则表达式,如前、后向索引等,正则相关内容就不详细讲了。

Xml文件提取后,通过对象进行管理,这里的对象比较广泛,比如TCP流管理对象、packet包管理对象、应用层协议(如http等)管理对象、BSON格式管理对象等,提取的信息最终都是为了满足BSON格式内容要求,因此对象需要做一些特殊的设计,比如对象可能会包含多层结构等。

提取的内容保存在某些对象里面,然后再调用阿里的fastjson jar(github链接)库,可以很方便的将对象转换成BSON格式。BSON格式对大小有要求,不能超过16MByte,否则数据库会返回异常。

三、BSON内容插入数据库

该过程简单,调用Mongo3.1.jar库里面的insert接口即可。

四、总结

整个开发过程是在eclipse上开发的,代码总的来说还是比较简单,代码测试完成后,export生成jar文件,jar文件根据输入的命令行参数做一些输入控制,如-r xxx.pcap,表示读取xxx.pcap文件,auto.jar文件会解析对应的xxx.pcap文件;之所以做一些命令行的处理,是后面需要将auto.jar作为一个命令脚本,供其他脚本调用,这样就可以方便的实现自动化处理流程。

你可能感兴趣的:(xml解析)