wireshark录制 UDP 数据分包分片重组

个人公众号“代码就是生产力”,发布更多有用的工具
对于UDP来说,如果发现数据过大,那么 IP 层会自动对数据进行切割,分片,但是通常应用层我们不会发现有什么影响,因为已经自动合并了分片数据,但是如果是使用 wireshark 录制的数据,就会出现数据分片了,但是没有重组的情况,这个时候,需要我们手动对数据进行一个重组,类似如下的情况:

可以看到,一个数据被分成了8个数据分片,但是他们的ID是一样的,然后有不同的offset,那么我们就可以根据这两个特性,把每组的分片重组起来。

仅仅使用 dpkt 工具即可,代码如下。

#coding:utf-8

import dpkt

def main(file_path):

# f = open(file_path)          # 此写法为python2之下,
f = open(file_path, mode='rb') #python3
try:
    pcap = dpkt.pcap.Reader(f)  # 先按.pcap格式解析,若解析不了,则按pcapng格式解析
except:
    print("it is not pcap ... format, pcapng format...")
    pcap = dpkt.pcapng.Reader(f)
    # 接下来就可以对pcap做进一步解析了,记住在使用结束后最好使用f.close()关掉打开的文件,虽然程序运行结束后,
    # 系统会自己关掉,但是养成好习惯是必不可少的。当前变量pcap中是按照“间戳:单包”的格式存储着各个单包

first_flag = 1
raw_data = []
# 将时间戳和包数据分开,一层一层解析,其中ts是时间戳,buf存放对应的包
for (ts, buf) in pcap:
    try:
        eth = dpkt.ethernet.Ethernet(buf)  # 解包,物理层
        if not isinstance(eth.data, dpkt.ip.IP):  # 解包,网络层,判断网络层是否存在,
            continue
        ip = eth.data
        print(ip.id, ip.offset)

        # if not isinstance(ip.data, dpkt.tcp.TCP):  # 解包,判断传输层协议是否是TCP,即当你只需要TCP时,可用来过滤
        #     continue
        # if not isinstance(ip.data, dpkt.udp.UDP):#解包,判断传输层协议是否是UDP ; 分片的节点是ip.data.data 不然是 ip.data
        #     continue

        if first_flag:
            raw_data.append(ip.data.data)
        else:
            # if (id_flag != ip.id and ip.offset == 0):
            if (ip.offset == 0):
                # 可以在这里对每次UDP分片的数量做更严格的限制,因为基本上同一个数据来源的分片数量是固定的,比如每次发送3000byte,那么每次都是分成2个片段
                # 比如我这里每个数据被分成了9个片段,那么我就只要9个片段的数据,不是9个片段的数据就丢弃
                # if len(raw_data) != 9:
                #     raw_data.clear()
                #     raw_data.append(ip.data.data)
                #     continue
                result = b""
                for i in raw_data:
                    result += i
                tempeth.data.data = result
                writer.writepkt(tempeth, ts=ts)  # 如果不加ts参数的话,这个数据包的时间戳默认是当前时间!
                newpacpfile.flush()
                raw_data.clear()
                if not isinstance(ip.data.data, bytes):  # 可能存在其他类型数据
                    continue
                raw_data.append(ip.data.data)
            else:
                # print(len(raw_data), "len(raw_data)", type(ip.data))
                if not isinstance(ip.data, bytes):  # 可能存在其他类型数据
                    continue
                raw_data.append(ip.data)
                tempeth = eth

        first_flag = 0

    except Exception as err:
        print( "[error] %s" % err)
f.close()

if name == ‘main’:
path = “0325_1024.pcap”
newpacpfile = open(“new.pcap”, “wb”)
writer = dpkt.pcap.Writer(newpacpfile)
main(path)
newpacpfile.close()

最后效果如下:

从数据的容量可以看到,多个分片的数据已经被组合在一起了,但是其实还有缺点,每个分片的tag还是分片的标签。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点云-激光雷达-Slam-三维牙齿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值