python使用dpkt分析wireshak报文(Modbus规约)

运行环境python2.7

需要安装dpkt-1.8.6.2和win_inet_pton-1.0.1两个库

#!/usr/bin/env python

import dpkt
import datetime
import socket
import binascii
import win_inet_pton
from ctypes import *

def inet_to_str(inet):
    try:
        return socket.inet_ntop(socket.AF_INET, inet)
    except ValueError:
        return socket.inet_ntop(socket.AF_INET6, inet)

def process_modbus_ctrl(data):
    byte = ''
    byte_list = []
    for i in range(0,len(data)):
        if i % 2  == 0 and i != len(data) -1:
            byte = byte + '0x'
        byte = byte +data[i]
        if i % 2 == 1:
            byte_list.append(byte)
            byte = ''
    if byte_list[7] == '0x06':
        addr = byte_list[8] + ' ' + byte_list[9]
        value = int(byte_list[10],16) * 256 + int(byte_list[11],16)
        print('Addr:%s Set value:%d' % (addr,value))

def process_short_value(byte_list):
    index_list = [4,14,16,18,20,22,24,26]
    print_buf = ''
    for index in index_list:
        real_index = index + 9
        value = int(byte_list[real_index],16) * 256 + int(byte_list[real_index + 1],16)
        if value > 32767:
            value = value - 65536
        print_buf = print_buf + 'Addr Index:' + str(index/2) + ' Value:' + str(value) + ',' 
    print(print_buf[:-1])

def convert(s):
    i = int(s, 16)                  
    cp = pointer(c_int(i))           
    fp = cast(cp, POINTER(c_float))  
    return fp.contents.value

def process_float_value(byte_list):
    index_list = [0,76,108,220,224,228]
    print_buf = ''
    value_buf = ''
    for index in index_list:
        real_index = index + 9
        value_buf = byte_list[real_index][2:]+byte_list[real_index+1][2:]+byte_list[real_index+2][2:]+byte_list[real_index+3][2:]
        value = convert(value_buf)
        print_buf = print_buf + 'Addr Index:' + str(index/2) + ' Value:' + str(value) + ',' 
    print(print_buf[:-1])

def process_modbus_data(data,data_type):
    byte = ''
    byte_list = []
    for i in range(0,len(data)):
        if i % 2  == 0 and i != len(data) -1:
            byte = byte + '0x'
        byte = byte +data[i]
        if i % 2 == 1:
            byte_list.append(byte)
            byte = ''
    if byte_list[7] == '0x06':
        pass
    else:
        if data_type == 0:
            process_short_value(byte_list)
        else:
             process_float_value(byte_list)
    
def analyze_packet(pcap,hostIp,port,flag,data_type):
    for timestamp, buf in pcap:
        eth = dpkt.ethernet.Ethernet(buf)
        if not isinstance(eth.data, dpkt.ip.IP):
            print('Non IP Packet type not supported %s\n' % eth.data.__class__.__name__)
            continue
        ip = eth.data
        tcp = ip.data

        srcIp = inet_to_str(ip.src)
        dstIp = inet_to_str(ip.dst)
        
        if (tcp.dport != port and tcp.sport != port) or len(tcp.data) <= 0:
            continue
        
        if flag == 0:
            if srcIp == hostIp:
                hex_data = binascii.hexlify(tcp.data)
                process_modbus_ctrl(hex_data)
        elif flag == 1:
            if dstIp == hostIp:
                hex_data = binascii.hexlify(tcp.data)
                process_modbus_data(hex_data,data_type)
        else:
            pass            

if __name__ == '__main__':
    with open('device_tcpdump.cap', 'rb') as f:
        hostIp = '192.168.201.23'
        port = 502
        flag = 1    #flag=0:ctrl,flag=1:data
        data_type = 1   #data_type=0:short,data_type=1:sw_float
        pcap = dpkt.pcap.Reader(f)
        analyze_packet(pcap,hostIp,port,flag,data_type)
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值