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