
如上图所示dpkt所有的协议:
现在仅其中的arp, dpkt, ethernet, icmp, ip, tcp, udp等常用的网络协议解析和简单使用
1.arp的文档及使用
文档源码:
# $Id: arp.py 23 2006-11-08 15:45:33Z dugsong $
# -*- coding: utf-8 -*-
"""Address Resolution Protocol."""
from __future__ import absolute_import
from . import dpkt
# Hardware address format
ARP_HRD_ETH = 0x0001 # ethernet hardware
ARP_HRD_IEEE802 = 0x0006 # IEEE 802 hardware
# Protocol address format
ARP_PRO_IP = 0x0800 # IP protocol
# ARP operation
ARP_OP_REQUEST = 1 # request to resolve ha given pa
ARP_OP_REPLY = 2 # response giving hardware address
ARP_OP_REVREQUEST = 3 # request to resolve pa given ha
ARP_OP_REVREPLY = 4 # response giving protocol address
class ARP(dpkt.Packet):
"""Address Resolution Protocol.
See more about the ARP on \
https://en.wikipedia.org/wiki/Address_Resolution_Protocol
Attributes:
__hdr__: Header fields of ARP.
"""
__hdr__ = (
('hrd', 'H', ARP_HRD_ETH),
('pro', 'H', ARP_PRO_IP),
('hln', 'B', 6), # hardware address length
('pln', 'B', 4), # protocol address length
('op', 'H', ARP_OP_REQUEST),
('sha', '6s', b''),
('spa', '4s', b''),
('tha', '6s', b''),
('tpa', '4s', b'')
)
通过调用arp的属性来使用arp,接下来我们测试一下:
需要用到以太网的类型属性用来判定

定义中 ETH_TYPE_ARP = 0x0806 #属于arp的定义
import dpkt
import collections #有序字典需要的模块
import time
file_path = 'rec_6377505_eth1_2021-11-25-11-14-14.pcap'
def main_read(file_path):
#f = open(file_path) #此写法为python2之下,
# f = open(file_path,mode='rb') #python3
fr = open(file_path, 'rb')
pcap = dpkt.pcap.Reader(fr)
number = 0
p1 = open('data.csv', 'w')
for (ts,buf) in pcap:
try:
eth = dpkt.ethernet.Ethernet(buf) #解包,物理层
if hex(eth.type) == '0x806':
print("arp")
arp = eth.data
print(type(arp.data))
p1.write(str(arp.data.hex()) + '\n')
number += 1
except Exception as err:
print("[error] %s" % err)
fr.close()
p1.close()
print("总UDP数量 %s" % number)
if __name__ == '__main__':
main_read(file_path)
2,ethernet
属性
__hdr__ = (
('dst', '6s', b''),
('src', '6s', b''),
('type', 'H', ETH_TYPE_IP)
)
方法
def __bytes__(self)
def __len__(self)
def set_type(cls, t, pktclass)
def get_type(cls, t)
def get_type_rev(cls, k)
使用
import dpkt
import collections #有序字典需要的模块
import time
file_path = 'rec_6377505_eth1_2021-11-22-11-09-47.pcap'
def main_read(file_path):
#f = open(file_path) #此写法为python2之下,
# f = open(file_path,mode='rb') #python3
fr = open(file_path, 'rb')
pcap = dpkt.pcap.Reader(fr)
print(type(pcap))
#print(type(pcap.readpkts()))
#print(pcap.readpkts()[0][1].hex())
all_pcap_data=collections.OrderedDict()
all_pcap_data_hex=collections.OrderedDict()
number = 0
for (ts,buf) in pcap:
try:
eth = dpkt.ethernet.Ethernet(buf) #解包,物理层
print(type(eth))
print(type(eth.data))
print(type(eth.data.data))
print(type(eth.data.data.data))
print(eth)
print(eth.data.__bytes__())
print(eth.data.__len__())
print(eth.data.src.hex())
print(eth.data.data.ulen)
if not isinstance(eth.data, dpkt.ip.IP): #解包,网络层,判断网络层是否存在,
continue
ip = eth.data
if not isinstance(ip.data, dpkt.udp.UDP): #解包,判断传输层协议是否是TCP,即当你只需要TCP时,可用来过滤
continue
# if not isinstance(ip.data, dpkt.udp.UDP):#解包,判断传输层协议是否是UDP
# continue
udp_data = eth.data.data #传输层负载数据,基本上分析流量的人都是分析这部分数据,即应用层负载流量
if not len(udp_data.data): #如果应用层负载长度为0,即该包为单纯的tcp包,没有负载,则丢弃
continue
all_pcap_data[ts]= eth.data.data.data #将时间戳与应用层负载按字典形式有序放入字典中,方便后续分析.
all_pcap_data_hex[ts]=udp_data.data.hex()
number += 1
except Exception as err:
print("[error] %s" % err)
fr.close()
print("总UDP数量 %s" % number)
if __name__ == '__main__':
main_read(file_path)
