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