网络ARP抓包工具

查看 126|回复 9
作者:qw_dmz   
无聊写的,用来抓取未知对端设备的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("", lambda e: show())
        if vbar: vbar.bind("", lambda e: show())
        if vbar: vbar.bind("", lambda e: hide())
        if hbar: hbar.bind("", lambda e: show())
        if hbar: hbar.bind("", lambda e: hide())
        widget.bind("", 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()
文件太大上传不上来
有能力的自己还是编译吧

数据包, 地址

lzy541541   

看起来不错先收藏一下
laustar   

不错。学习一下。
stwpw   

不明觉厉
111wdw   

感觉很强大的样子
piaoyanggege   

很强大的样子
wangshaobo930   

收藏  学习一下
longboy1517   

虽然看不懂,但不影响它的神奇
zmy328   

挺好,代码学习了
优品食代   

大佬,测试下这个,能抓到什么
http://122.51.203.47:81/
您需要登录后才可以回帖 登录 | 立即注册

返回顶部