Python编写网络嗅探器程序捕获和显示IP数据包的头部信息
抓取网络数据包并解析其中的IP首部信息,并通过GUI界面显示解析结果。程序展示了如何使用Python的socket和ctypes库来捕获和解析网络数据包,并使用Tkinter创建一个简单的GUI界面来显示捕获到的IP头部信息。这可以作为网络分析和监控工具的基础。
代码的主要部分包括以下几个类:
- IP类:使用ctypes库定义的数据结构,表示IP首部的各个字段。它包含了首部的各个字段,如版本、首部长度、区分服务、总长度、标识、片偏移、生存时间、协议、校验和等。它还具有解析IP地址的功能。
- Sniffer类:用于创建网络套接字,并通过原始套接字接收网络数据包。设置套接字的参数,以便在抓包时使用混杂模式。它还包含一个captureAPacket方法,用于抓取一个数据包并返回解析后的IP首部。
- 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