关于用Perl的File::PCAP::Reader解析pcap文件提取地址的问题
使用Perl的File::PCAP::Reader解析PCAP提取地址
核心解决思路
File::PCAP::Reader的next_packet()返回的数据包结构里,data字段是原始二进制帧数据,你需要手动解析以太网链路层和IP网络层的头部,才能提取出MAC地址和IP地址。
完整代码示例
use strict; use warnings; use File::PCAP::Reader; use Socket qw(inet_ntoa); # 初始化PCAP文件读取器 my $fpr = File::PCAP::Reader->new('my.pcap') or die "无法打开PCAP文件: $!"; # 读取全局头部(可选,new方法已完成读取) $fpr->global_header(); while (my $packet = $fpr->next_packet()) { # 跳过长度不足的无效以太网帧 next unless length($packet->{data}) >= 14; # 解析以太网头部:目的MAC、源MAC、以太网类型 my ($dst_mac_raw, $src_mac_raw, $ethertype) = unpack('H12 H12 n', substr($packet->{data}, 0, 14)); # 格式化MAC地址为xx:xx:xx:xx:xx:xx格式 my $dst_mac = join(':', $dst_mac_raw =~ /(..)/g); my $src_mac = join(':', $src_mac_raw =~ /(..)/g); # 仅处理IPv4数据包(以太网类型0x0800对应IPv4) if ($ethertype == 0x0800) { # 提取IP头部(跳过14字节以太网头部,取前20字节基本IP头部) my $ip_header = substr($packet->{data}, 14, 20); next unless length($ip_header) == 20; # 解析IP头部中的源IP和目的IP my ($src_ip_packed, $dst_ip_packed) = unpack('x12 a4 a4', $ip_header); my $src_ip = inet_ntoa($src_ip_packed); my $dst_ip = inet_ntoa($dst_ip_packed); # 打印提取到的地址信息 print "源MAC: $src_mac | 目的MAC: $dst_mac | 源IP: $src_ip | 目的IP: $dst_ip\n"; } }
关键代码说明
- 以太网头部解析:通过
unpack从二进制数据中提取原始MAC字符串和以太网类型,再用正则将连续十六进制字符串分割为带冒号的标准MAC格式。 - IPv4头部解析:以太网类型
0x0800标识IPv4数据包,跳过以太网头部后,从IP头部的固定偏移位置提取二进制IP,用inet_ntoa转换为可读的字符串IP。 - 边界校验:加入长度检查,避免解析不完整的无效数据包导致报错。
注意事项
- 如果你的PCAP文件不是以太网类型(比如PPP、802.11无线帧等),需要对应调整链路层头部的解析逻辑。
- 若要处理IPv6或其他协议,需修改
ethertype判断值和对应的头部解析代码。
内容的提问来源于stack exchange,提问作者dave
相关产品推荐
相关产品推荐

