gpt4 book ai didi

c++ - 查询接口(interface)以使用 libpcap 查找设备

转载 作者:行者123 更新时间:2023-11-28 06:12:23 28 4
gpt4 key购买 nike

好的,我的系统可以插入目标计算机上任意数量的以太网端口。我的目标是遍历每个设备,收集大约 20 个数据包,或者如果没有数据则跳过它,直到找到我要查找的数据,然后选择该设备作为我的“捕获设备”。看起来很简单。然而,我很快了解到,如果没有数据进入,libpcap 不会简单地超时。因此,我尝试使用 pcap_setnonblock 将我的捕获设备设置为非阻塞模式。但是,这会导致我阅读的目标端口完全崩溃。这是我的代码。愿意接受有关可能发生的事情的建议,或者甚至是更好的方法。谢谢

附言。 Type1 Type2 变量名不要敲,是用来混淆的。

pcap_if_t *alldevs;
pcap_if_t *d;
pcap_t *fp;
struct pcap_pkthdr *header;
const u_char *pkt_data;
char errbuf[PCAP_ERRBUF_SIZE];
const int FIND_DEVICE_PACKET_LIMIT = 20;

#ifdef WIN32
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
#else
if (pcap_findalldevs(&alldevs, errbuf) == -1)
#endif
{
cerr << "Error in pcap_findalldevs_ex: " << errbuf << endl;
return;
}

// For each device, capture until timeout
// or until a matching packet is found.
for(d=alldevs; d; d=d->next)
{
if ((fp = pcap_open_live(d->name,
1514 /*snaplen*/,
1 /*flags, 1=promiscuous, 0=not promiscuous*/,
20 /*read timeout*/,
errbuf)
) == NULL)
{
cerr << endl << "Unable to open the adapter." << endl;
continue;
}

int res = 0;
int packetCounter = 0;


pcap_setnonblock(fp, true, errbuf);

// Capture at most FIND_DEVICE_PACKET_LIMIT packets
// to determine whether scanner is sending packets
// or no scanner found.
while ((res = pcap_next_ex(fp, &header, &pkt_data)) >=0) {
struct iphdr *iph = (struct iphdr *)(pkt_data + sizeof(struct ethhdr));
struct udphdr *udph = (struct udphdr*)(pkt_data + (iph->ihl*4) + sizeof(struct ethhdr));
u_int destPort = ntohs(udph->dest);

if (destPort==TYPE1_DATA_PORT || destPort==TYPE1_GPS_PORT) {
detectedScanners->type1 = true;
} else if (destPort==TYPE2_DATA_PORT || destPort==TYPE2_STATUS_PORT || destPort==TYPE2_NMEA_PORT) {
detectedScanners->type2 = true;
}

if (++packetCounter > FIND_DEVICE_PACKET_LIMIT) {
break;
}
}

if (detectedScanners->type1==true || detectedScanners->type2==true) {
*interface = d->name;
break;
}
}

最佳答案

在非阻塞模式下,如果没有数据包可读取,pcap_next_ex()将返回 0,并且 NOT 不会返回任何数据包信息,因此,如果它返回 0,你应该 不要查看headerpacket_data指向的任何内容。

即,做

while ((res = pcap_next_ex(fp, &header, &pkt_data)) >=0) {
if (res != 0) {
struct iphdr *iph = (struct iphdr *)(pkt_data + sizeof(struct ethhdr));
struct udphdr *udph = (struct udphdr*)(pkt_data + (iph->ihl*4) + sizeof(struct ethhdr));
u_int destPort = ntohs(udph->dest);

if (destPort==TYPE1_DATA_PORT || destPort==TYPE1_GPS_PORT) {
detectedScanners->type1 = true;
} else if (destPort==TYPE2_DATA_PORT || destPort==TYPE2_STATUS_PORT || destPort==TYPE2_NMEA_PORT) {
detectedScanners->type2 = true;
}

if (++packetCounter > FIND_DEVICE_PACKET_LIMIT) {
break;
}
}
}

但是请注意,您的程序将在该循环中不断旋转,消耗 CPU,永远。这意味着您永远不会错过第一台设备。

您可能真正想做的是:

  • 打开所有设备,将它们的pcap_t *放入一个数组中,并使它们进入非阻塞模式;
  • 对于每个设备,在 UN*X 上调用pcap_get_selectable_fd(),在 Windows 上调用pcap_getevent(),并将该调用的结果保存到一个数组中(你可以有并行数组,或者一个结构数组,其中包含pcap_t * ”和intHANDLE作为成员);
  • 在循环中,在 UN*X 上的select()中的所有poll()上使用intpcap_get_selectable_fd(),在 Windows 上的WaitForMultipleObjects()中的所有HANDLE上使用pcap_getevent()和,当select()/poll()/WaitForMultipleObjects()返回时,尝试使用pcap_t *每个pcap_next_ex()读取一个数据包,如果你得到一个数据包就处理它。<

这样,您就可以并行扫描所有设备,而不会占用 CPU。

关于c++ - 查询接口(interface)以使用 libpcap 查找设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30990299/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com