Python编写网络嗅探器程序捕获和显示IP数据包的头部信息

Python编写网络嗅探器程序捕获和显示IP数据包的头部信息

抓取网络数据包并解析其中的IP首部信息,并通过GUI界面显示解析结果。程序展示了如何使用Python的socket和ctypes库来捕获和解析网络数据包,并使用Tkinter创建一个简单的GUI界面来显示捕获到的IP头部信息。这可以作为网络分析和监控工具的基础。

代码的主要部分包括以下几个类:

  1. IP类:使用ctypes库定义的数据结构,表示IP首部的各个字段。它包含了首部的各个字段,如版本、首部长度、区分服务、总长度、标识、片偏移、生存时间、协议、校验和等。它还具有解析IP地址的功能。
  2. Sniffer类:用于创建网络套接字,并通过原始套接字接收网络数据包。设置套接字的参数,以便在抓包时使用混杂模式。它还包含一个captureAPacket方法,用于抓取一个数据包并返回解析后的IP首部。
  3. SnifferWindow类:网络嗅探器类。使用tkinter库创建了一个窗口,并在窗口中添加了一个按钮和一些文本框。当点击按钮时,它会调用Sniffer类的方法抓取一个数据包,并将解析结果显示在文本框中。
    最后,代码通过创建一个SnifferWindow对象启动网络嗅探器的GUI界面。
    在这里插入图片描述

使用流程

1.敲代码,实现界面与网络嗅探功能

目标ip
192.168.1.112
2.在cmd命令行ping 192.168.1.112
在这里插入图片描述

3.运行程序获取信息

在这里插入图片描述

4.运行wireshark获取信息进行检验

在这里插入图片描述

5.对比信息可正常使用

在这里插入图片描述

详情

必要的库

  • socket: 用于创建原始套接字,捕获网络数据包
  • struct: 用于将原始数据转换为可读的格式
  • ctypes: 用于定义IP头部结构体
  • tkinter: 用于创建GUI界面
import socket
import struct
from ctypes import *
from tkinter import *

IP类:

继承自ctypes.Structure的结构体,用于表示IP数据包的头部信息。
定义了11个字段,分别对应IP头部的各个部分,如版本号、长度、协议、源IP地址和目标IP地址等。
在构造函数中,将IP地址从数字形式转换为点分十进制形式,并将协议号转换为对应的协议名称。

class IP(Structure):
    _fields_ = [
        ("ihl", c_ubyte, 4),         # 头部长度(4位)
        ("version", c_ubyte, 4),     # IP版本(4位)
        ("tos", c_ubyte),            # 服务类型
        ("len", c_ushort),           # 总长度
        ("id", c_ushort),            # 标识
        ("offset", c_ushort),        # 分片偏移
        ("ttl", c_ubyte),            # 存活时间
        ("protocol_num", c_ubyte),   # 协议号
        ("sum", c_ushort),           # 校验和
        ("src", c_uint32),           # 源IP地址
        ("dst", c_uint32)            # 目标IP地址
    ]
    def __new__(self, socket_buffer=None):
        return self.from_buffer_copy(socket_buffer)
    def __init__(self, socket_buffer=None):
        self.protocol_map = {1: "ICMP", 6: "TCP", 17: "UDP"}
        self.src_address = socket.inet_ntoa(struct.pack("@I", self.src))
        self.dst_address = socket.inet_ntoa(struct.pack("@I", self.dst))
        try:
            self.protocol= self.protocol_map[self.protocol_num]
        except :
            self.protocol = str(self.protocol_num)

Sniffer类

捕获网络数据包。
在构造函数中,创建一个原始套接字,并将其绑定到本地主机的所有网络接口上。
captureAPacket()方法用于捕获一个数据包,并返回一个IP对象,其中包含了IP头部的信息。

class Sniffer:
    def __init__(self):
        HOST = socket.gethostbyname(socket.gethostname())
        self.s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
        self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.s.bind((HOST, 0))
        self.s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
    def captureAPacket(self):
        self.s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
        bufferSize = 65565
        package = self.s.recvfrom(bufferSize)
        raw_buffer = package[0]
        ipHeader = IP(raw_buffer[0:20])
        self.s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
        return ipHeader

SnifferWindow类

创建一个GUI界面,显示捕获到的IP数据包的头部信息。
在构造函数中,创建了一个Tkinter窗口,并添加了一个"抓包"按钮。
还创建了多个标签和文本框显示IP头部的各个字段,如版本号、首部长度、服务类型、总长度、标识、片偏移、生存时间、协议、校验和,以及源IP地址和目标IP地址。
show()方法被"抓包"按钮的command属性调用,它创建一个Sniffer对象,并调用其captureAPacket()方法来捕获一个数据包。然后,它将捕获到的IP头部信息显示在GUI窗口中。

class SnifferWindow:
    def __init__(self):
        window = Tk()
        window.title("网络嗅探器")
        button1 = Button(window, text="抓包", command=self.show)
        button1.pack()
        frame1 = Frame(window)
        frame1.pack(pady=15)
        labelVersion = Label(frame1, text="版本: ")
        labelVersion.grid(row=1, column=1, sticky="E")
        self.version = StringVar()
        entryVersion = Entry(frame1, textvariable=self.version, width=50)
        entryVersion.grid(row=1, column=2, padx=15, sticky="WE")
        labelHeadlen = Label(frame1, text="首部长度: ")
        labelHeadlen.grid(row=2, column=1, sticky="E")
        self.headlen = StringVar()
        entryHeadlen = Entry(frame1, textvariable=self.headlen)
        entryHeadlen.grid(row=2, column=2, padx=15, sticky="WE")
        labelTypeOfService = Label(frame1, text="区分服务: ")
        labelTypeOfService.grid(row=3, column=1, sticky="E")
        self.typeOfService = StringVar()
        entryTypeOfService = Entry(frame1, textvariable=self.typeOfService)
        entryTypeOfService.grid(row=3, column=2, padx=15, sticky="WE")
        labelLength = Label(frame1, text="总长度: ")
        labelLength.grid(row=4, column=1, sticky="E")
        self.length = StringVar()
        entryLength = Entry(frame1, textvariable=self.length)
        entryLength.grid(row=4, column=2, padx=15, sticky="WE")
        labelId = Label(frame1, text="标识: ")
        labelId.grid(row=5, column=1, sticky="E")
        self.id = StringVar()
        entryId = Entry(frame1, textvariable=self.id)
        entryId.grid(row=5, column=2, padx=15, sticky="WE")
        labelOffSet = Label(frame1, text="片偏移: ")
        labelOffSet.grid(row=6, column=1, sticky="E")
        self.offSet = StringVar()
        entryOffSet = Entry(frame1, textvariable=self.offSet)
        entryOffSet.grid(row=6, column=2, padx=15, sticky="WE")
        labelTtl = Label(frame1, text="生存时间: ")
        labelTtl.grid(row=7, column=1, sticky="E")
        self.ttl = StringVar()
        entryTtl = Entry(frame1, textvariable=self.ttl)
        entryTtl.grid(row=7, column=2, padx=15, sticky="WE")
        labelProtocol = Label(frame1, text="协议: ")
        labelProtocol.grid(row=8, column=1, sticky="E")
        self.protocol = StringVar()
        entryProtocol = Entry(frame1, textvariable=self.protocol)
        entryProtocol.grid(row=8, column=2, padx=15, sticky="WE")
        labelSum = Label(frame1, text="校验和: ")
        labelSum.grid(row=9, column=1, sticky="E")
        self.sum = StringVar()
        entrySum = Entry(frame1, textvariable=self.sum)
        entrySum.grid(row=9, column=2, padx=15, sticky="WE")
        labelSrcAddress = Label(frame1, text="源IP地址: ")
        labelSrcAddress.grid(row=10, column=1, sticky="E")
        self.srcAddress = StringVar()
        entrySrcAddress = Entry(frame1, textvariable=self.srcAddress)
        entrySrcAddress.grid(row=10, column=2, padx=15, sticky="WE")
        labelDstAddress = Label(frame1, text="目的IP地址: ")
        labelDstAddress.grid(row=11, column=1, sticky="E")
        self.dstAddress = StringVar()
        entryDstAddress = Entry(frame1, textvariable=self.dstAddress)
        entryDstAddress.grid(row=11, column=2, padx=15, sticky="WE")
        window.mainloop()
    def show(self):
        sniffer = Sniffer()
        ipHeader = sniffer.captureAPacket()
        self.version.set(str(ipHeader.version))
        self.headlen.set(str(ipHeader.ihl))
        self.typeOfService.set(str(ipHeader.tos))
        self.length.set(str(ipHeader.len))
        self.id.set(str(ipHeader.id))
        self.offSet.set(str(ipHeader.offset))
        self.ttl.set(str(ipHeader.ttl))
        self.protocol.set(str(ipHeader.protocol_num) + "(" + ipHeader.protocol + ")")
        self.sum.set(str(ipHeader.sum))
        self.srcAddress.set(str(ipHeader.src) + "(" + ipHeader.src_address + ")")
        self.dstAddress.set(str(ipHeader.dst) + "(" + ipHeader.dst_address + ")")

程序展示了如何使用Python的socket和ctypes库来捕获和解析网络数据包,并使用Tkinter创建一个简单的GUI界面来显示捕获到的IP头部信息。这可以作为网络分析和监控工具的基础。

总代码

import socket
import struct
from ctypes import *
from tkinter import *

# IP头部结构
class IP(Structure):
    _fields_ = [
        ("ihl", c_ubyte, 4),         # 头部长度(4位)
        ("version", c_ubyte, 4),     # IP版本(4位)
        ("tos", c_ubyte),            # 服务类型
        ("len", c_ushort),           # 总长度
        ("id", c_ushort),            # 标识
        ("offset", c_ushort),        # 分片偏移
        ("ttl", c_ubyte),            # 存活时间
        ("protocol_num", c_ubyte),   # 协议号
        ("sum", c_ushort),           # 校验和
        ("src", c_uint32),           # 源IP地址
        ("dst", c_uint32)            # 目标IP地址
    ]
    def __new__(self, socket_buffer=None):
        return self.from_buffer_copy(socket_buffer)
    def __init__(self, socket_buffer=None):
        self.protocol_map = {1: "ICMP", 6: "TCP", 17: "UDP"}
        self.src_address = socket.inet_ntoa(struct.pack("@I", self.src))
        self.dst_address = socket.inet_ntoa(struct.pack("@I", self.dst))
        try:
            self.protocol= self.protocol_map[self.protocol_num]
        except :
            self.protocol = str(self.protocol_num)
class Sniffer:
    def __init__(self):
        HOST = socket.gethostbyname(socket.gethostname())
        self.s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
        self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.s.bind((HOST, 0))
        self.s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
    def captureAPacket(self):
        self.s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
        bufferSize = 65565
        package = self.s.recvfrom(bufferSize)
        raw_buffer = package[0]
        ipHeader = IP(raw_buffer[0:20])
        self.s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
        return ipHeader

class SnifferWindow:
    def __init__(self):
        window = Tk()
        window.title("网络嗅探器")
        button1 = Button(window, text="抓包", command=self.show)
        button1.pack()
        frame1 = Frame(window)
        frame1.pack(pady=15)
        labelVersion = Label(frame1, text="版本: ")
        labelVersion.grid(row=1, column=1, sticky="E")
        self.version = StringVar()
        entryVersion = Entry(frame1, textvariable=self.version, width=50)
        entryVersion.grid(row=1, column=2, padx=15, sticky="WE")
        labelHeadlen = Label(frame1, text="首部长度: ")
        labelHeadlen.grid(row=2, column=1, sticky="E")
        self.headlen = StringVar()
        entryHeadlen = Entry(frame1, textvariable=self.headlen)
        entryHeadlen.grid(row=2, column=2, padx=15, sticky="WE")
        labelTypeOfService = Label(frame1, text="区分服务: ")
        labelTypeOfService.grid(row=3, column=1, sticky="E")
        self.typeOfService = StringVar()
        entryTypeOfService = Entry(frame1, textvariable=self.typeOfService)
        entryTypeOfService.grid(row=3, column=2, padx=15, sticky="WE")
        labelLength = Label(frame1, text="总长度: ")
        labelLength.grid(row=4, column=1, sticky="E")
        self.length = StringVar()
        entryLength = Entry(frame1, textvariable=self.length)
        entryLength.grid(row=4, column=2, padx=15, sticky="WE")
        labelId = Label(frame1, text="标识: ")
        labelId.grid(row=5, column=1, sticky="E")
        self.id = StringVar()
        entryId = Entry(frame1, textvariable=self.id)
        entryId.grid(row=5, column=2, padx=15, sticky="WE")
        labelOffSet = Label(frame1, text="片偏移: ")
        labelOffSet.grid(row=6, column=1, sticky="E")
        self.offSet = StringVar()
        entryOffSet = Entry(frame1, textvariable=self.offSet)
        entryOffSet.grid(row=6, column=2, padx=15, sticky="WE")
        labelTtl = Label(frame1, text="生存时间: ")
        labelTtl.grid(row=7, column=1, sticky="E")
        self.ttl = StringVar()
        entryTtl = Entry(frame1, textvariable=self.ttl)
        entryTtl.grid(row=7, column=2, padx=15, sticky="WE")
        labelProtocol = Label(frame1, text="协议: ")
        labelProtocol.grid(row=8, column=1, sticky="E")
        self.protocol = StringVar()
        entryProtocol = Entry(frame1, textvariable=self.protocol)
        entryProtocol.grid(row=8, column=2, padx=15, sticky="WE")
        labelSum = Label(frame1, text="校验和: ")
        labelSum.grid(row=9, column=1, sticky="E")
        self.sum = StringVar()
        entrySum = Entry(frame1, textvariable=self.sum)
        entrySum.grid(row=9, column=2, padx=15, sticky="WE")
        labelSrcAddress = Label(frame1, text="源IP地址: ")
        labelSrcAddress.grid(row=10, column=1, sticky="E")
        self.srcAddress = StringVar()
        entrySrcAddress = Entry(frame1, textvariable=self.srcAddress)
        entrySrcAddress.grid(row=10, column=2, padx=15, sticky="WE")
        labelDstAddress = Label(frame1, text="目的IP地址: ")
        labelDstAddress.grid(row=11, column=1, sticky="E")
        self.dstAddress = StringVar()
        entryDstAddress = Entry(frame1, textvariable=self.dstAddress)
        entryDstAddress.grid(row=11, column=2, padx=15, sticky="WE")
        window.mainloop()
    def show(self):
        sniffer = Sniffer()
        ipHeader = sniffer.captureAPacket()
        self.version.set(str(ipHeader.version))
        self.headlen.set(str(ipHeader.ihl))
        self.typeOfService.set(str(ipHeader.tos))
        self.length.set(str(ipHeader.len))
        self.id.set(str(ipHeader.id))
        self.offSet.set(str(ipHeader.offset))
        self.ttl.set(str(ipHeader.ttl))
        self.protocol.set(str(ipHeader.protocol_num) + "(" + ipHeader.protocol + ")")
        self.sum.set(str(ipHeader.sum))
        self.srcAddress.set(str(ipHeader.src) + "(" + ipHeader.src_address + ")")
        self.dstAddress.set(str(ipHeader.dst) + "(" + ipHeader.dst_address + ")")
SnifferWindow()

相关推荐

  1. Python解析网络数据包

    2024-07-13 08:40:02       66 阅读
  2. 数据是如何捕捉我们偏好

    2024-07-13 08:40:02       40 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-13 08:40:02       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-13 08:40:02       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-13 08:40:02       57 阅读
  4. Python语言-面向对象

    2024-07-13 08:40:02       68 阅读

热门阅读

  1. py2neo常用语句

    2024-07-13 08:40:02       26 阅读
  2. gitlab 备份和还原

    2024-07-13 08:40:02       29 阅读
  3. 如何实现一个二叉搜索树

    2024-07-13 08:40:02       27 阅读
  4. 小妙招使用sysctl hw.realmem查看实际物理内存@FreeBSD

    2024-07-13 08:40:02       19 阅读
  5. 网络设备安全

    2024-07-13 08:40:02       23 阅读
  6. sqlalchemy.orm中validates对两个字段进行联合校验

    2024-07-13 08:40:02       27 阅读
  7. Grafana

    Grafana

    2024-07-13 08:40:02      24 阅读
  8. VB 实例:掌握 Visual Basic 编程的精髓

    2024-07-13 08:40:02       21 阅读
  9. Spuer().__init__的意义

    2024-07-13 08:40:02       29 阅读
  10. 匿名函数与函数

    2024-07-13 08:40:02       29 阅读
  11. ios CCRuntime.m

    2024-07-13 08:40:02       24 阅读