使用PCAP++的PfRingDevice捕获lo回环接口流量的相关问题
解决方案
1 选择lo回环接口的方法
PCAP的PfRingDeviceList枚举接口逻辑默认会过滤掉非物理网卡(包含回环lo、虚拟网卡等),所以你用列表查询方式找不到lo接口。
不需要通过PfRingDeviceList获取设备,直接手动构造PfRingDevice实例即可,原生PF_RING本身支持lo接口,PCAP只是枚举逻辑做了限制,没有限制底层使用。
2 配置PF_RING自定义参数的方法
PCAP++的PfRingDevice类已经封装了对应原生PF_RING的参数配置接口:
- 打开标识:调用
open()方法时,第三个参数直接传入自定义的PF_RING标识组合即可,默认标识仅为PF_RING_PROMISC - 数据方向:调用
setDirection()方法,入参与原生PF_RING的方向枚举完全一致,比如rx_only_direction - 套接字模式:调用
setSocketMode()方法,入参与原生PF_RING的模式枚举完全一致,比如recv_only_mode
可运行的完整测试代码
#include <iostream> #include <string> #include <arpa/inet.h> #include <unistd.h> #include <pcapplusplus/PfRingDevice.h> #include <pcapplusplus/Packet.h> #include <pcapplusplus/IPv4Layer.h> // 抓包回调函数 static bool onPacketArrives(pcpp::RawPacket* packet, pcpp::PfRingDevice* dev, void* cookie) { pcpp::Packet parsedPacket(packet); pcpp::IPv4Layer* ipLayer = parsedPacket.getLayerOfType<pcpp::IPv4Layer>(); if (ipLayer == nullptr) { return true; } char srcIp[INET_ADDRSTRLEN], dstIp[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &ipLayer->getSrcIpAddress().toInt(), srcIp, INET_ADDRSTRLEN); inet_ntop(AF_INET, &ipLayer->getDstIpAddress().toInt(), dstIp, INET_ADDRSTRLEN); std::cout << srcIp << " --> " << dstIp << std::endl; // 抓到10个包就停止 static int cnt = 0; if (++cnt >= 10) { return false; } return true; } int main(int argc, char** argv) { std::string ifaceName = "lo"; if (argc > 1) { ifaceName = argv[1]; } // 手动构造PfRingDevice实例,不需要走PfRingDeviceList枚举 pcpp::PfRingDevice* dev = new pcpp::PfRingDevice(ifaceName); if (!dev) { std::cout << "创建设备实例失败" << std::endl; return 1; } // 配置自定义PF_RING打开标识 uint32_t customFlags = PF_RING_PROMISC | PF_RING_DO_NOT_PARSE | PF_RING_DO_NOT_TIMESTAMP; // 打开设备:阻塞模式、最大捕获长度、自定义标识 if (!dev->open(true, 0xffff, customFlags)) { std::cout << "打开设备失败,请确认已加载PF_RING内核模块且有root权限" << std::endl; delete dev; return 1; } // 配置数据方向为仅收 dev->setDirection(rx_only_direction); // 配置套接字模式为仅接收 dev->setSocketMode(recv_only_mode); // 设置应用名称 pfring_set_application_name(dev->getPfRingHandler(), "traffic_capture"); std::cout << "开始捕获流量,执行 ping -I lo 127.0.0.3 触发回环流量..." << std::endl; // 启动捕获,抓到10个包后自动停止 dev->startCapture(onPacketArrives, nullptr); // 等待捕获结束 while (dev->isCapturing()) { sleep(1); } dev->stopCapture(); std::cout << "DONE: 处理完成10个数据包" << std::endl; dev->close(); delete dev; return 0; }
验证说明
执行程序需root权限,启动后另开终端执行ping -I lo 127.0.0.3即可看到捕获到的回环流量。
内容的提问来源于stack exchange,提问作者AlekseyLeb
相关产品推荐
相关产品推荐

