PLC场景下Linux管道TCPDump转存pcap文件失败问题求助
问题分析与解决方案
原脚本的核心问题
cat mypipe阻塞无法退出:cat会一直等待管道写端关闭才会终止,但tcpdump持续向管道写入数据,导致第一个文件无限增大,永远无法进入sleep环节;强制停止时文件没有完整的pcap结尾,Wireshark无法识别。- 未处理数据包截断与流量过滤:既没过滤OPC UA流量,也没实现丢弃前54字节的需求。
无依赖解决方案脚本
以下脚本仅使用Linux基础命令(tcpdump/dd/xxd/od/timeout),适配无包管理器的PLC环境:
#!/bin/bash output_dir="/opt/plcnext/" output_base_name="capture" interval=300 pipe_name="mypipe" opcua_port="4840" # OPC UA默认端口,若使用其他端口请修改 # 确保输出目录存在 mkdir -p "$output_dir" # 清理旧管道并创建新管道 rm -f "$pipe_name" mkfifo "$pipe_name" # 处理pcap数据包:丢弃前54字节并修正pcap记录头 process_pcap() { # 读取并输出pcap文件头(固定24字节) dd bs=24 count=1 2>/dev/null # 循环处理每个数据包记录 while true; do # 读取16字节的数据包记录头 read -r -n 16 rec_header || break # 解析记录头中的捕获长度与原始长度(小端序) cap_len=$(echo "$rec_header" | dd bs=1 skip=8 count=4 2>/dev/null | xxd -p -r | od -t u4 -An | tr -d ' ') orig_len=$(echo "$rec_header" | dd bs=1 skip=12 count=4 2>/dev/null | xxd -p -r | od -t u4 -An | tr -d ' ') # 仅处理长度≥54字节的数据包 if [ "$cap_len" -ge 54 ] && [ "$orig_len" -ge 54 ]; then new_cap_len=$((cap_len - 54)) new_orig_len=$((orig_len - 54)) # 生成修改后的记录头(替换长度字段为截断后的值) new_rec_header=$(echo -n "${rec_header:0:8}" \ && echo -n "$new_cap_len" | od -t u4 -An -w4 --endian=little | xxd -r -p \ && echo -n "$new_orig_len" | od -t u4 -An -w4 --endian=little | xxd -r -p) # 输出修改后的记录头 echo -n "$new_rec_header" # 读取数据包内容,跳过前54字节并输出剩余部分 dd bs=1 skip=54 count="$new_cap_len" 2>/dev/null else # 长度不足的数据包直接丢弃 dd bs=1 count="$cap_len" 2>/dev/null >/dev/null fi done } # 后台启动tcpdump:过滤OPC UA流量,处理后写入命名管道 tcpdump -i any -w - port "$opcua_port" 2>/dev/null | process_pcap > "$pipe_name" & tcpdump_pid=$! # 捕获中断信号,清理进程与管道 trap "kill $tcpdump_pid; rm -f $pipe_name; exit" INT TERM # 循环每5分钟保存一次管道内容 while true; do current_time=$(date +"%Y%m%d%H%M%S") output_file="${output_dir}/${output_base_name}_${current_time}.pcap" # 读取管道内容300秒后自动终止,写入目标文件 timeout "$interval" cat "$pipe_name" > "$output_file" # 清理空文件 if [ -s "$output_file" ]; then echo "Saved capture to $output_file" else rm -f "$output_file" echo "No data captured in this interval, skipped file creation" fi done
关键逻辑说明
- 流量过滤:通过
tcpdump port 4840仅捕获OPC UA默认端口的流量。 - 数据包截断:解析pcap记录头,修改数据包长度字段后,丢弃每个以太网帧的前54字节(以太网头14+IP头20+TCP头20),保留IP地址与OPC UA消息内容。
- 定时转存:用
timeout 300 cat mypipe实现每5分钟读取一次管道内容,避免阻塞;生成的文件是完整的pcap格式,可直接在Wireshark中打开。 - 资源清理:通过
trap捕获中断信号,自动停止tcpdump并删除管道,避免残留进程。
内容的提问来源于stack exchange,提问作者BrenDs
相关产品推荐
相关产品推荐

