Python 解析数据包

发布于 2024-06-14 03:14:50 字数 5338 浏览 15 评论 0

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

#!/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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

笑梦风尘

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

我们的影子

文章 0 评论 0

素年丶

文章 0 评论 0

南笙

文章 0 评论 0

18215568913

文章 0 评论 0

qq_xk7Ean

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文