使用PcapPlusPlus 23.09解析含多层以太网帧的pcap文件时无法识别IP层
多层以太网封装下的IP包识别问题(PcapPlusPlus 23.09)
问题描述
- 使用PcapPlusPlus 23.09版本解析pcap文件,该文件内每个帧包含多层以太网封装
- 尝试通过以下代码识别IP数据包,但无法匹配到IPv4/IPv6报文:
if (parsedPacket.isPacketOfType(pcpp::IPv4) || parsedPacket.isPacketOfType(pcpp::IPv6)) {....}
- 实际测试确认,PcapPlusPlus默认无法自动识别第二层及后续的以太网封装
解决方案
PcapPlusPlus默认仅解析最外层的以太网协议,对于嵌套的多层以太网帧,需要手动逐层剥离外层封装后再解析内层协议:
1. 单次剥离外层以太网帧
适用于仅存在两层以太网封装的场景:
// 假设parsedPacket为已解析的外层帧对象 pcpp::EthernetLayer* outerEthLayer = parsedPacket.getLayerOfType<pcpp::EthernetLayer>(); if (outerEthLayer != nullptr) { // 获取内层数据的指针与长度 uint8_t* innerPayload = outerEthLayer->getLayerPayload(); size_t payloadLen = outerEthLayer->getLayerPayloadSize(); // 用内层数据构建新的原始包与解析包 pcpp::RawPacket innerRawPacket(innerPayload, payloadLen, parsedPacket.getRawPacket()->getPacketTime(), false); pcpp::ParsedPacket innerParsedPacket; if (innerParsedPacket.parse(innerRawPacket)) { // 在内层包中检测IP协议 if (innerParsedPacket.isPacketOfType(pcpp::IPv4) || innerParsedPacket.isPacketOfType(pcpp::IPv6)) { // 此处编写IP报文处理逻辑 } } }
2. 循环处理多层嵌套封装
如果存在三层及以上以太网嵌套,可通过循环逐层剥离,直到找到IP层或无内层数据:
pcpp::ParsedPacket currentParsedPacket = parsedPacket; while (true) { pcpp::EthernetLayer* ethLayer = currentParsedPacket.getLayerOfType<pcpp::EthernetLayer>(); // 无以太网层或内层无数据时终止循环 if (ethLayer == nullptr || ethLayer->getLayerPayloadSize() == 0) { break; } // 提取内层数据并构建新的解析包 uint8_t* innerPayload = ethLayer->getLayerPayload(); size_t payloadLen = ethLayer->getLayerPayloadSize(); pcpp::RawPacket innerRawPacket(innerPayload, payloadLen, currentParsedPacket.getRawPacket()->getPacketTime(), false); pcpp::ParsedPacket innerParsedPacket; if (!innerParsedPacket.parse(innerRawPacket)) { break; } // 检查是否为IP包,是则处理并终止循环 if (innerParsedPacket.isPacketOfType(pcpp::IPv4) || innerParsedPacket.isPacketOfType(pcpp::IPv6)) { // 编写IP报文处理逻辑 break; } // 否则继续处理下一层封装 currentParsedPacket = innerParsedPacket; }
3. 自定义协议解析器(进阶)
若需长期复用多层以太网解析逻辑,可注册自定义协议解析器让PcapPlusPlus自动识别嵌套封装,但实现复杂度较高,适合有定制化需求的场景。
内容的提问来源于stack exchange,提问作者Abolfazl Diyanat
相关产品推荐
相关产品推荐

