介绍:
在网络测试和安全分析中,PCAP文件是记录网络流量的重要工具。本文介绍如何使用Python编写一个自动化工具,实现PCAP文件的批量回放、流量分析以及结果记录。通过该工具,您可以轻松地对多个PCAP文件进行回放,并生成详细的测试报告。
主要内容:
-
PCAP文件获取:递归遍历文件夹,自动识别并加载所有PCAP文件。
-
流量回放:使用
tcpreplay
工具对PCAP文件进行多次回放,支持自定义回放速度和次数。 -
流量分析:提取PCAP文件中的源IP和目的IP,记录每次回放的详细信息。
-
结果记录:将回放结果保存到Excel文件中,便于后续分析和报告生成。
适用人群:
-
网络工程师
-
安全研究员
-
网络测试人员
-
对网络流量分析感兴趣的开发者
代码亮点:
-
自动化批量处理PCAP文件,支持递归遍历文件夹。
-
集成
tcpreplay
工具,实现高效的流量回放。 -
详细的日志记录和错误处理,确保工具稳定运行。
-
结果自动保存为Excel文件,便于后续分析。
import os import datetime import logging import signal import subprocess from openpyxl import Workbook from scapy.all import PcapReader, Scapy_Exception, IP def get_pcap_files(folder_path): """递归获取文件夹下所有的Pcap包文件""" pcap_files = [] for root, dirs, files in os.walk(folder_path): for file in files: if file.endswith('.pcap'): pcap_files.append(os.path.join(root, file)) else: logging.warning(f"Skipping non-PCAP file: {file}") return pcap_files def replay_pcap_files(pcap_files, interface, replay_times=5, speed_multiplier=100): """回放所有的Pcap包文件""" wb = Workbook() ws = wb.active ws.append(["时间", "PCAP包名称", "PCAP包所在目录", "源IP", "目的IP"]) for pcap_index, pcap_file in enumerate(pcap_files): logging.info(f"Replaying {pcap_file} - Packet {pcap_index + 1}") play_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") # 修正为 datetime.now() logging.info("Play time: " + play_time) if not os.path.isfile(pcap_file): logging.warning(f"File does not exist: {pcap_file}") continue # 读取文件 try: with PcapReader(pcap_file) as pcap_reader: pkts = [pkt for _, pkt in zip(range(1000), pcap_reader)] # 限制加载包数 except Scapy_Exception as e: logging.error(f"Failed to read PCAP file {pcap_file}: {e}") continue src_ips, dst_ips = set(), set() for pkt in pkts: if IP in pkt: src_ips.add(pkt[IP].src) dst_ips.add(pkt[IP].dst) if not src_ips or not dst_ips: logging.warning(f"No IP packets found in {pcap_file}") continue src_ip = ", ".join(src_ips) dst_ip = ", ".join(dst_ips) for _ in range(replay_times): packet_count = len(pkts) timeout = max(5, packet_count / 100 * 2) command = ["sudo", "tcpreplay", "-i", interface, "-M", str(speed_multiplier), pcap_file] process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) try: stdout, stderr = process.communicate(timeout=timeout) if process.returncode != 0: logging.error(f"tcpreplay failed for {pcap_file} with error: {stderr.decode().strip()}") else: logging.info(f"tcpreplay succeeded for {pcap_file}") except subprocess.TimeoutExpired: logging.warning(f"Replay timed out for {pcap_file}, terminating process") process.terminate() process.wait() ws.append([play_time, os.path.basename(pcap_file), os.path.dirname(pcap_file), src_ip, dst_ip]) return wb def signal_handler(signum, frame): """捕获Ctrl+C信号""" logging.warning("Caught Ctrl+C signal") raise KeyboardInterrupt if __name__ == "__main__": logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") folder_path = "/home/wangbin/wangbin3/pcap_output" interface = "em2" pcap_files = get_pcap_files(folder_path) if pcap_files: wb = None try: signal.signal(signal.SIGINT, signal_handler) wb = replay_pcap_files(pcap_files, interface) except KeyboardInterrupt: logging.warning("Execution interrupted by user") except Exception as e: logging.error(f"Unexpected error occurred: {e}") finally: if wb: result_file_path = os.path.join("/home/wangbin/wangbin3/results", "replay_results_1.xlsx") try: wb.save(result_file_path) logging.info(f"Results saved to {result_file_path}") except Exception as e: logging.error(f"Failed to save Excel file: {e}") else: logging.error("未找到任何Pcap包文件")