卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章1829本站已运行4109

Python 网络ARP抓包工具

用来抓取未知对端设备的IP地址(仅适用于会发送免费ARP包的设备)
import threading
import tkinter as tk
from tkinter.ttk import Treeview, Combobox, Button, Entry, Scale, Style
from scapy.all import sniff
from scapy.layers.l2 import Ether
from scapy.layers.l2 import ARP
import psutil
class PacketSnifferController:
    def __init__(self):
        self.win = None
        self.packet_count = 10  # 默认捕获数据包数量

    def init(self, win):
        self.win = win

    def start_sniffing(self):
        # 获取用户设置的数据包数量
        self.packet_count = self.win.tk_input_lrg2klel.get()

        # 启动数据包嗅探线程
        sniff_thread = threading.Thread(target=self.sniff_packets)
        sniff_thread.start()

    def sniff_packets(self):
        selected_interface = self.win.tk_select_box_lrg2i35c.get()
        print(self.packet_count,selected_interface)
        # 设置捕获条件,可以根据需要进行修改
        # 在这个例子中,只捕获前 self.packet_count 个 ARP 数据包
        packets = sniff(iface=selected_interface, count=int(self.packet_count), filter="arp", stop_filter=None)

        # 处理捕获到的数据包
        for packet in packets:
            self.packet_callback(packet)

    def packet_callback(self, packet):
        # 获取捕获的数据包信息
        captured_info = (
            packet[Ether].dst,
            packet[Ether].src,
            packet[Ether].type,
            packet[ARP].hwtype,
            packet[ARP].ptype,
            packet[ARP].hwlen,
            packet[ARP].plen,
            packet[ARP].op,
            packet[ARP].hwsrc,
            packet[ARP].psrc,
            packet[ARP].hwdst,
            packet[ARP].pdst
        )

        print("Captured info before insertion:", captured_info)  # 调试输出

        # 插入新行数据,从第一列开始
        self.win.tk_table_lrg2fz4k.insert("", tk.END, values=captured_info)

class WinGUI(tk.Tk):
    def __init__(self):
        super().__init__()
        self.__win()
        self.tk_button_lrg2fjic = self.__tk_button_lrg2fjic(self)
        self.tk_table_lrg2fz4k = self.__tk_table_lrg2fz4k(self)
        self.tk_label_lrg2h7am = self.__tk_label_lrg2h7am(self)
        self.tk_select_box_lrg2i35c = self.__tk_select_box_lrg2i35c(self)
        self.tk_frame_lrg2jofg = self.__tk_frame_lrg2jofg(self)
        self.tk_input_lrg2klel = self.__tk_input_lrg2klel(self.tk_frame_lrg2jofg)
        self.tk_scale_lrg2krvw = self.__tk_scale_lrg2krvw(self.tk_frame_lrg2jofg)
        self.tk_label_lrg2l0vn = self.__tk_label_lrg2l0vn(self.tk_frame_lrg2jofg)

    def __win(self):
        self.title("数据包嗅探器")
        # 设置窗口大小、居中
        width = 1600
        height = 500
        screenwidth = self.winfo_screenwidth()
        screenheight = self.winfo_screenheight()
        geometry = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
        self.geometry(geometry)

        self.resizable(width=False, height=False)

    def scrollbar_autohide(self, vbar, hbar, widget):
        """自动隐藏滚动条"""
        def show():
            if vbar: vbar.lift(widget)
            if hbar: hbar.lift(widget)
        def hide():
            if vbar: vbar.lower(widget)
            if hbar: hbar.lower(widget)
        hide()
        widget.bind("<Enter>", lambda e: show())
        if vbar: vbar.bind("<Enter>", lambda e: show())
        if vbar: vbar.bind("<Leave>", lambda e: hide())
        if hbar: hbar.bind("<Enter>", lambda e: show())
        if hbar: hbar.bind("<Leave>", lambda e: hide())
        widget.bind("<Leave>", lambda e: hide())

    def v_scrollbar(self, vbar, widget, x, y, w, h, pw, ph):
        widget.configure(yscrollcommand=vbar.set)
        vbar.config(command=widget.yview)
        vbar.place(relx=(w + x) / pw, rely=y / ph, relheight=h / ph, anchor='ne')

    def h_scrollbar(self, hbar, widget, x, y, w, h, pw, ph):
        widget.configure(xscrollcommand=hbar.set)
        hbar.config(command=widget.xview)
        hbar.place(relx=x / pw, rely=(y + h) / ph, relwidth=w / pw, anchor='sw')

    def create_bar(self, master, widget, is_vbar, is_hbar, x, y, w, h, pw, ph):
        vbar, hbar = None, None
        if is_vbar:
            vbar = tk.Scrollbar(master)
            self.v_scrollbar(vbar, widget, x, y, w, h, pw, ph)
        if is_hbar:
            hbar = tk.Scrollbar(master, orient="horizontal")
            self.h_scrollbar(hbar, widget, x, y, w, h, pw, ph)
        self.scrollbar_autohide(vbar, hbar, widget)

    def __tk_button_lrg2fjic(self, parent):
        btn = Button(parent, text="开始嗅探", takefocus=False)
        btn.place(x=520, y=71, width=67, height=30)
        return btn

    def __tk_table_lrg2fz4k(self, parent):
        # 表头字段 表头宽度
        columns = {"目的地址": 119, "源地址": 179, "类型": 100, "硬件类型": 100, "协议类型": 100, "硬件地址长度": 130,
                   "协议地址长度": 130, "操作码": 100, "源硬件地址": 150, "源协议地址": 150, "目的硬件地址": 150,
                   "目的协议地址": 150}
        tk_table = Treeview(parent, show="headings", columns=list(columns))
        for text, width in columns.items():  # 批量设置列属性
            tk_table.heading(text, text=text, anchor='center')
            tk_table.column(text, anchor='center', width=width, stretch=False)  # stretch 不自动拉伸

        tk_table.place(x=0, y=166, width=1600, height=334)
        return tk_table

    def __tk_label_lrg2h7am(self, parent):
        label = tk.Label(parent, text="选择网络接口:", anchor="center")
        label.place(x=11, y=14, width=112, height=30)
        return label

    def __tk_select_box_lrg2i35c(self, parent):
        cb = Combobox(parent, state="readonly", values=list(psutil.net_if_stats().keys()))
        cb.place(x=138, y=16, width=150, height=30)
        return cb

    def __tk_frame_lrg2jofg(self, parent):
        frame = tk.Frame(parent)
        frame.place(x=312, y=2, width=200, height=150)
        return frame

    def __tk_input_lrg2klel(self, parent):
        ipt = Entry(parent)
        ipt.insert(0, "10")  # 设置默认值为 "10"
        ipt.place(x=153, y=100, width=41, height=30)
        return ipt

    def __tk_scale_lrg2krvw(self, parent):
        scale = Scale(parent, orient=tk.HORIZONTAL, from_=1, to=100, command=self.update_entry_value)
        scale.place(x=11, y=98, width=130, height=30)
        return scale

    def update_entry_value(self, value):
        try:
            int_value = int(float(value))
            self.tk_input_lrg2klel.delete(0, tk.END)
            self.tk_input_lrg2klel.insert(0, str(int_value))
        except ValueError:
            # 处理无效值的情况,可以在这里添加适当的错误处理或默认值
            pass

    def __tk_label_lrg2l0vn(self, parent):
        label = tk.Label(parent, text="捕获数据包数量", anchor="center")
        label.place(x=10, y=28, width=180, height=30)
        return label

class Win(WinGUI):
    def __init__(self, controller):
        self.ctl = controller
        super().__init__()
        self.__event_bind()
        self.__style_config()
        self.ctl.init(self)

    def __event_bind(self):
        self.tk_button_lrg2fjic.config(command=self.ctl.start_sniffing)

    def __style_config(self):
        # 设置 Treeview 样式
        style = Style()
        style.configure("Treeview", rowheight=30)
        style.configure("Treeview.Heading", font=("Arial", 10, "bold"))

if __name__ == "__main__":
    controller = PacketSnifferController()
    win = Win(controller)
    win.mainloop()
有能力的自己还是编译吧
卓越飞翔博客
上一篇: python脚本,有道翻译,一丢丢js逆向加解密
下一篇: 谷歌翻译接口API,中英互翻,自动识别多国语言,无请求限制
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏