qw_dmz 发表于 2024-1-16 22:31

网络ARP抓包工具

**无聊写的,用来抓取未知对端设备的IP地址(仅适用于会发送免费ARP包的设备)
**
全部代码。
```python
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.dst,
            packet.src,
            packet.type,
            packet.hwtype,
            packet.ptype,
            packet.hwlen,
            packet.plen,
            packet.op,
            packet.hwsrc,
            packet.psrc,
            packet.hwdst,
            packet.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()

```

文件太大上传不上来
有能力的自己还是编译吧

qw_dmz 发表于 2024-9-11 10:45

残夕若此 发表于 2024-9-10 17:45
有没有编译好的,完全不会py...

链接: https://pan.baidu.com/s/1M3ac_RAQGQQpToNmVLH2Ag?pwd=8t8s 提取码: 8t8s
拿去

lzy541541 发表于 2024-1-17 11:02

看起来不错先收藏一下

laustar 发表于 2024-1-17 11:06

不错。学习一下。

stwpw 发表于 2024-1-17 11:16

不明觉厉{:1_908:}

111wdw 发表于 2024-1-17 11:45

感觉很强大的样子

piaoyanggege 发表于 2024-1-17 15:14

很强大的样子

longboy1517 发表于 2024-1-26 21:38

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

zmy328 发表于 2024-1-30 13:09

挺好,代码学习了

优品食代 发表于 2024-2-6 13:21

大佬,测试下这个,能抓到什么
http://122.51.203.47:81/

减肥的蚊子 发表于 2024-2-26 18:16

谢谢大佬
页: [1] 2
查看完整版本: 网络ARP抓包工具