热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

简单的发包工具——网络协议编辑器(python+scapy+pycharm)

简单的发包工具——网络协议编辑器(python+scapy+pycharm),Go语言社区,Golang程序员人脉社

一、实现的功能

    基于python+scapy设计协议编辑器,基于Tkinter的Python  GUI界面设计。实现了MAC、ARP、IP 、TCP、UDP协议的编辑与发送,并且支持生成协议字段的默认值,支持用户输入协议字段值,发包前对协议字段的合理性进行检查,发包前自动计算并显示校验和,支持单次发包、多次发包,支持连续发包,连续发包时可随时停止和计算并显示数据包发送速度的功能。

注:

程序源代码:https://download.csdn.net/download/wmrem/10439779

运行前需要先安装第三方库scapy,安装方法:https://blog.csdn.net/wmrem/article/details/80004819

二、主要函数说明——IP包的编辑与发送为例

1.创建IP包编辑器界面,为每个按钮绑定单击响应时间。
def create_ip_sender():
   1.设置协议编辑器的界面
    ip_fields = 'IP协议的版本:',…… , '目的IP地址:'
    entries = create_protocol_editor(protocol_editor_panedwindow, ip_fields)
    2.创建发送,默认值,清空按钮,并绑定功能
    send_packet_button, reset_button, default_packet_button = create_bottom_buttons(protocol_editor_panedwindow)
    3.为"回车键"的Press事件编写事件响应代码,发送IP包
    tk.bind('', (lambda event: send_ip_packet(entries, send_packet_button)))  # 代表回车键
    4.为"发送"、默认值、按钮的单击事件编写事件响应代码,发送IP包
    send_packet_button.bind('', (
        lambda event: send_ip_packet(entries, send_packet_button)))

2. 在协议字段编辑框中填入默认IP包的字段值,为IP数据包的发送做好准备
def create_default_ip_packet(entries):
    1.清空各字段的值
    clear_protocol_editor(entries)
    2.创建默认的IP数据包,并将其各字段的值填入协议编辑器的对应的文本框中
    default_ip_packet = IP()
    entries[0].insert(0, int(default_ip_packet.version))

    …

3.获取协议编辑器文本框的值,创建对应的数据包并开启一个线程用于连续发送数据包。
def send_ip_packet(entries, send_packet_button):
    if 按钮为发送时:
1. 从协议编辑框中获取要发送的数据包的各个字段的值
        ip_version = int(entries[0].get())

        2.用获取的数据包的各字段的值创建相应的数据包
        packet_to_send = IP(version=ip_version,……,src=ip_src, dst=ip_dst)
        3.开一个线程用于连续发送数据包,并启动
        t = threading.Thread(target=send_packet, args=(packet_to_send,))
        t.start()
        4.使协议导航树不可用
        toggle_protocols_tree_state()
        send_packet_button['text'] = '停止'
    else 按钮为停止时:
        5.按钮为停止时可以终止数据包发送线程
        stop_sending.set()
        6.恢复协议导航树可用
        toggle_protocols_tree_state()

        send_packet_button['text'] = '发送'

4.发送数据包的线程函数,并计算数据包发送速度
def send_packet(packet_to_send):
    stop_sending.clear()
    1.计算待发送数据包的长度(用于计算发送速度)
    packet_size = len(packet_to_send)
    2.推导数据包的协议类型
    3.计算发包开始发送时间点
    begin_time = datetime.now()
    4.连续发送数据包直到进程关闭
    while 进程没有关闭:
        if 发送Ether:
            sendp(packet_to_send, verbose=0)  # verbose=0,不在控制回显'Sent 1 packets'.
        else:
            send(packet_to_send, verbose=0)
        5.计算发送的总字节数
        total_bytes = packet_size * n
        6.计算发包用的总时间 
        total_time = (end_time - begin_time).total_seconds()
7.计算发包的速度
        bytes_per_secOnd= total_bytes / total_time / 1024

三、基础知识准备

1.构造数据包,发送数据包——“/"运算符数据包的拼装,send()用于3层发包,可直接发送IP数据包,自动加以太帧;只发送以太帧使用sendp()。

2.计算校验和——IP包的校验和默认值为None,在IP包被发送时,其校验和被被自动计算并填充在IP包中
以下方式可以在发包前计算IP包的校验和,直接用packet.show2()命令也可以显示校验和。raw(packet)将数据包的内容转换为字节。

 

3.查看数据包的字段值(使用ls()),查看某层协议数据包对象支持的函数(使用help())

4.ls()列出scapy支持的所有数据包,协议;lsc()列出scapy支持的全部命令;conf列出scapy的当前配置。

四、主要功能实现代码——以IP包为例

1.创建IP包编辑器的界面

# 创建协议字段编辑区 def create_protocol_editor(root, field_names): """ 创建协议字段编辑区 :param root: 协议编辑区 :param field_names: 协议字段名列表 :return: 协议字段编辑框列表 """ entries = [] for field in field_names: row = Frame(root) label = Label(row, e') entry = Entry(row, fOnt=('Courier', '12', 'bold'), state='normal') # 设置编辑框为等宽字体 row.pack(side=TOP, fill=X, padx=5, pady=5) label.pack(side=LEFT) entry.pack(side=RIGHT, expand=YES, fill=X) entries.append(entry) return entries

def create_ip_sender(): """ 创建IP包编辑器 :return: None """ # IP帧编辑区 ip_fields = 'IP协议的版本:', '首部长度(5-15):', '区分服务:', '总长度:', '标识:', '标志(0-2)DF,MF:', '片偏移:', '生存时间:', '协议(数据部分):', '首部校验和:', '源IP地址:', '目的IP地址:' entries = create_protocol_editor(protocol_editor_panedwindow, ip_fields) send_packet_button, reset_button, default_packet_button = create_bottom_buttons(protocol_editor_panedwindow) # 为"回车键"的Press事件编写事件响应代码,发送ARP包 tk.bind('', (lambda event: send_ip_packet(entries, send_packet_button))) # 代表回车键 # 为"发送"按钮的单击事件编写事件响应代码,发送ARP包 send_packet_button.bind('', ( lambda event: send_ip_packet(entries, send_packet_button))) # 代表鼠标左键单击 # 为"清空"按钮的单击事件编写事件响应代码,清空协议字段编辑框 reset_button.bind('', (lambda event: clear_protocol_editor(entries))) # 为"默认值"按钮的单击事件编写事件响应代码,在协议字段编辑框填入ARP包字段的默认值 default_packet_button.bind('', (lambda event: create_default_ip_packet(entries)))

2.在协议字段编辑框中填入默认IP包的字段值,填入前需要先清空当前值。

def clear_protocol_editor(entries): """ 清空协议编辑器的当前值 :param entries: 协议字段编辑框列表 :return: None """ for entry in entries: # 如果有只读Entry,也要清空它的当前值 state = entry['state'] entry['state'] = 'normal' entry.delete(0, END) entry['state'] = state

# 当前网卡的默认网关 default_gateway = [a for a in os.popen('route print').readlines() if ' 0.0.0.0 ' in a][0].split()[-3]

def create_default_ip_packet(entries): """ 在协议字段编辑框中填入默认IP包的字段值 :param entries: 协议字段编辑框列表 :return: None """ clear_protocol_editor(entries) default_ip_packet = IP() entries[0].insert(0, int(default_ip_packet.version)) entries[1].insert(0, 5) entries[3].insert(0, 20) entries[2].insert(0, hex(default_ip_packet.tos)) entries[4].insert(0, int(default_ip_packet.id)) entries[5].insert(0, int(default_ip_packet.flags)) entries[6].insert(0, int(default_ip_packet.frag)) entries[7].insert(0, int(default_ip_packet.ttl)) entries[8].insert(0, int(default_ip_packet.proto)) entries[9]['state'] = NORMAL # 可操作 entries[9].insert(0, "单机发送时自动计算") entries[9]['state'] = DISABLED # 不可操作 # 目标IP地址设成本地默认网关 entries[11].insert(0, default_gateway) default_ip_packet = IP(dst=entries[11].get())#可以省略 entries[10].insert(0, default_ip_packet.src)

3.发送IP包

def send_ip_packet(entries, send_packet_button): """ 发IP包 :param entries: :param send_packet_button: :return: """ if send_packet_button['text'] == '发送': ip_version = int(entries[0].get()) ip_ihl = int(entries[1].get()) ip_tos = int(entries[2].get(), 16) ip_len = int(entries[3].get()) ip_id = int(entries[4].get()) ip_flags = int(entries[5].get()) ip_frag = int(entries[6].get()) ip_ttl = int(entries[7].get()) ip_proto = int(entries[8].get()) ip_src = entries[10].get() ip_dst = entries[11].get() # ip_optiOns= entries[12].get() packet_to_send = IP(version=ip_version, ihl=ip_ihl, tos=ip_tos, len=ip_len, id=ip_id, frag=ip_frag, flags=ip_flags, ttl=ip_ttl, proto=ip_proto, src=ip_src, dst=ip_dst) packet_to_send = IP(raw(packet_to_send)) entries[9]['state'] = NORMAL # 重新激活 entries[9].delete(0, END) entries[9].insert(0, hex(packet_to_send.chksum)) entries[9]['state'] = DISABLED # 不可操作 # 开一个线程用于连续发送数据包 t = threading.Thread(target=send_packet, args=(packet_to_send,)) t.setDaemon(True) t.start() # 使协议导航树不可用 toggle_protocols_tree_state() send_packet_button['text'] = '停止' else: # 终止数据包发送线程 stop_sending.set() # 恢复协议导航树可用 toggle_protocols_tree_state() send_packet_button['text'] = '发送'

4.线程中运行的用于发送数据包的函数,可以计算发包速度

def send_packet(packet_to_send): """ 在我们给出的发包程序中,如果电脑速度太快,send_packet函数中的send(...)函数执行前后, datetetime返回的begin_time和end_time可能是相同的,结果会报除零错误,所以,send_packet函数应该做修改 用于发送数据包的线程函数,持续发送数据包 :type packet_to_send: 待发送的数据包 """ # print(packet.show(dump=True)) # 对发送的数据包次数进行计数,用于计算发送速度 n = 0 stop_sending.clear() # 待发送数据包的长度(用于计算发送速度) packet_size = len(packet_to_send) # 推导数据包的协议类型 proto_names = ['TCP', 'UDP', 'ICMP', 'IP', 'ARP', 'Ether', 'Unknown'] packet_proto = '' for pn in proto_names: if pn in packet_to_send: packet_proto = pn break # 开始发送时间点 begin_time = datetime.now() while not stop_sending.is_set(): if isinstance(packet_to_send, Ether): sendp(packet_to_send, verbose=0) # verbose=0,不在控制回显'Sent 1 packets'. else: send(packet_to_send, verbose=0) n += 1 end_time = datetime.now() total_bytes = packet_size * n #修改 total_time = (end_time - begin_time).total_seconds() if total_time == 0: total_time = 2.23E-308 # 当begin_time和end_time相等时,将total_time设为IEEE 745标准中规定的最小浮点数 bytes_per_secOnd= total_bytes / total_time / 1024 # bytes_per_secOnd= total_bytes / ((end_time - begin_time).total_seconds()) / 1024 status_bar.set('已经发送了%d个%s数据包, 已经发送了%d个字节,发送速率: %0.2fK字节/秒', n, packet_proto, total_bytes, bytes_per_second)

五、运行结果


推荐阅读
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Python字典推导式及循环列表生成字典方法
    本文介绍了Python中使用字典推导式和循环列表生成字典的方法,包括通过循环列表生成相应的字典,并给出了执行结果。详细讲解了代码实现过程。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文介绍了如何使用python从列表中删除所有的零,并将结果以列表形式输出,同时提供了示例格式。 ... [详细]
author-avatar
祗想抱著伱
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有