import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QComboBox, QTableWidget, QTableWidgetItem, QVBoxLayout, QHBoxLayout, QWidget, QTextEdit, QHeaderView from scapy.all import sniff import threading

class Sniffer(QMainWindow): def init(self): super().init() self.initUI()

def initUI(self):
    self.setWindowTitle('PyQt5 Network Sniffer')
    self.setGeometry(100, 100, 1200, 800)

    mainLayout = QVBoxLayout()

    controlLayout = QHBoxLayout()

    self.comboBox = QComboBox(self)
    self.comboBox.addItems(['All', 'HTTP', 'HTTPS', 'FTP', 'SMTP', 'IMAP', 'POP3', 'DNS'])
    controlLayout.addWidget(self.comboBox)

    self.startButton = QPushButton('Start Sniffing', self)
    self.startButton.clicked.connect(self.start_sniffing)
    controlLayout.addWidget(self.startButton)

    self.stopButton = QPushButton('Stop Sniffing', self)
    self.stopButton.clicked.connect(self.stop_sniffing)
    controlLayout.addWidget(self.stopButton)

    self.resetButton = QPushButton('Reset', self)
    self.resetButton.clicked.connect(self.reset_table)
    controlLayout.addWidget(self.resetButton)

    mainLayout.addLayout(controlLayout)

    self.tableWidget = QTableWidget(self)
    self.tableWidget.setColumnCount(5)
    self.tableWidget.setHorizontalHeaderLabels(['源IP', '源端口', '目标IP', '目标端口', '长度'])
    self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
    self.tableWidget.clicked.connect(self.show_packet_detail)
    mainLayout.addWidget(self.tableWidget)

    self.textEdit = QTextEdit(self)
    mainLayout.addWidget(self.textEdit)

    container = QWidget()
    container.setLayout(mainLayout)
    self.setCentralWidget(container)

    self.stop_sniffing_flag = False
    self.packets = []

def packet_callback(self, packet):
    self.packets.append(packet)
    src_ip = packet['IP'].src if packet.haslayer('IP') else '-'
    dst_ip = packet['IP'].dst if packet.haslayer('IP') else '-'
    src_port = packet[1].sport if hasattr(packet[1], 'sport') else '-'
    dst_port = packet[1].dport if hasattr(packet[1], 'dport') else '-'
    length = len(packet)

    rowPosition = self.tableWidget.rowCount()
    self.tableWidget.insertRow(rowPosition)
    self.tableWidget.setItem(rowPosition, 0, QTableWidgetItem(src_ip))
    self.tableWidget.setItem(rowPosition, 1, QTableWidgetItem(str(src_port)))
    self.tableWidget.setItem(rowPosition, 2, QTableWidgetItem(dst_ip))
    self.tableWidget.setItem(rowPosition, 3, QTableWidgetItem(str(dst_port)))
    self.tableWidget.setItem(rowPosition, 4, QTableWidgetItem(str(length)))

def start_sniffing(self):
    self.startButton.setEnabled(False)  # Disable the startButton
    protocol = self.comboBox.currentText().lower()
    if protocol == 'all':
        filter_str = 'ip'
    else:
        filter_str = {
            'http': 'tcp port 80',
            'https': 'tcp port 443',
            'ftp': 'tcp port 21',
            'smtp': 'tcp port 25',
            'imap': 'tcp port 143',
            'pop3': 'tcp port 110',
            'dns': 'udp port 53'
        }.get(protocol, 'ip')

    self.stop_sniffing_flag = False
    t = threading.Thread(target=self.sniff_thread, args=(filter_str,))
    t.start()

def sniff_thread(self, filter_str):
    sniff(prn=self.packet_callback, filter=filter_str, stop_filter=lambda x: self.stop_sniffing_flag)

def stop_sniffing(self):
    self.stop_sniffing_flag = True
    self.startButton.setEnabled(True)  # Enable the startButton after stopping sniffing

def reset_table(self):
    self.tableWidget.setRowCount(0)
    self.textEdit.clear()
    self.packets = []

def show_packet_detail(self):
    row = self.tableWidget.currentRow()
    packet = self.packets[row]
    self.textEdit.clear()
    self.textEdit.append(packet.show(dump=True))

if name == 'main': app = QApplication(sys.argv) mainWin = Sniffer() mainWin.show() sys.exit(app.exec_())

PyQt5 网络嗅探器 - 实时捕获和分析网络数据包

原文地址: https://www.cveoy.top/t/topic/bpyC 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录