
如上圖所示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)
