解析数据包

Posted by FanHao on 2018-12-12

解析数据包

通过使用tshark命令将pcap文件转换为xml文件,此时xml文件的报文都变成单个tree结构。然后通过ElementTree类对xml文件进行解析查找。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/usr/local/bin/python
#coding=utf-8
# --------------------------------------------------------------------#
# FileName: parserPkt.py
# Version: V1.0
# Date: 2018-11-25
# Description: parserPacket
#
# History:
# <author> <time> <version > <desc>
# --------------------------------------------------------------------#
from scapy.all import *
import sys,getopt,os,datetime,hashlib,time
try:
import xml.etree.cElementTree as ET
except ImportError:
import xml.etree.ElementTree as ET
#调用python文件的帮助信息
def usage():
Usage = """
Usage:
Options:
[--args args] \t\t-- 需要查询或者获取的参数\n \
[-f filename.cap] \t\t-- 获取数据包的目录,默认/tmp/packet.cap\n \
[-o parser_filename] \t-- 生成需要数据的文件 默认/tmp/packet_result.txt\n \
[-h | --help] \t\t-- 显示此帮助信息\n \
eg:
--args ip.src=192.168.0.1,ip.dst=224.0.0.22,igmp.type
表示查询源地址为0.1、目的IP为0.22的组播type值
"""
print(Usage)

#处理外部传入的参数
opts,args=getopt.getopt(sys.argv[1:],"vf:h",["help","args="])
print('opts:',opts)
print('args:',args)
for op,value in opts:
if op == "-f":
print("fff")
elif op == "-v":
print('version 1.0')
elif op == "--args":
allargs=value
kargs={}
largs=[]
for subargs in allargs.split(','):
if "=" in subargs:
kargs[subargs.split('=')[0]]=subargs.split('=')[1]
else:
largs.append(subargs)
print("kargs",kargs)
print("largs",largs)
elif op in ('-h','--help'):
usage()
sys.exit()

#获取文件工作路径
def current_path():
path=sys.path[0]
if os.path.isdir(path):
return path
elif os.path.isfile(path):
return os.path.dirname(path)

path=current_path()
XmlFile=(path+"/igmp.xml").replace('\\','/')
ParserFile=(path+"/result.txt").replace('\\','/')
PacketFile='D:\\2019H1work\\自动化平台发包函数\\igmp.pcap'
# print(XmlFile)
# print(ParserFile)

#利用tshark将报文解析成xml文档
cmd="tshark -r %s -V -T pdml > %s" %(PacketFile,XmlFile)
if not os.system(cmd):
print("format done")
# if not os.system("rm -rf %s" %(ParserFile)):
# print("rm -rf failed")
#报文处理主函数
def checkopt(*args,**kargs):
try:
tree=ET.parse(XmlFile)
root=tree.getroot()
except Exception as e:
print('Error:cannot parser %s',XmlFile)
sys.exit(1)
for packet in root:
# print(packet)
getdict={}
BeFind=True
for key,value in kargs.items():
result=findstr(key,value,packet)
if not result:
BeFind=False
break
getdict[key]=value
print(getdict[key])
print(BeFind)
if BeFind:
for listkey in args:
ret,value=getstr(listkey,packet)
if not ret:
BeFind=False
break
else:
getdict[listkey]=value
#将结果写到文件中
# print(BeFind)
if BeFind:
fd=open(ParserFile,"a+")
for key,value in getdict.items():
fd.write("%s={%s} " %(key,value))
fd.write("\n")
fd.close()
#查找报文是否满足条件
def findstr(key,value,packet,level=1):
parent_key='.'.join(key.split('.')[:level])
ktype=key.split('.')[:-1]
for sub in packet:
# print("sub.attrib['name']=",sub.attrib['name'])
if sub.attrib['name']==parent_key:
child=sub.getchildren()
if len(child) == 0 or sub.get('show') == value:
ret = sub.get('show') == value
# print(ret)
if ret:
return True
else:
return False
else:
return findstr(key,value,sub,level=level+1)
#满足findstr()获取报文字段值
def getstr(key,packet,level=1):
parent_key=".".join(key.split('.')[:level])
# print('parent_key:',parent_key)
ktype=key.split('.')[:-1]
for sub in packet:
# print("sub.attrib['name']=%s",sub.attrib['name'])
if sub.attrib['name'] == parent_key:
print(sub.attrib['name'])
child=sub.getchildren()
if len(child) == 0 or parent_key==key:
print(parent_key,sub.get("show"),type(sub.get("show")))
return (True,sub.get('show'))
else:
return getstr(key,sub,level+1)
return (False,None)
if __name__ == '__main__':
checkopt(*largs,**kargs)