我正在使用libpcap来嗅探流量。我想在当前活动的网络设备上进行此操作(例如,具有分配的IP地址的设备等)。最好的方法是什么?我假设我必须做以下事情:
pcap_findalldevs(&alldevs, errbuf)
获取所有网络设备,然后循环并检查哪一个当前处于活动状态。
编辑:以下功能
(pcap_lookupnet(dev, &net, &mask, errbuf)
返回网络设备的网络地址和子网掩码。我在计算机上使用不同的以太网适配器运行了一些测试,当我在未连接到网络的适配器上调用它时,它返回-1。这是获得活动界面的防弹方式吗?是否会遗漏任何边缘情况?
答案 0 :(得分:2)
API pcap用于查找符合某些用户定义规则的接口是微不足道的。您确实可以使用pcap_findalldevs()来交互所有适合使用的网络设备,或者使用pcap_lookupdev()来获取可以与pcap一起使用的下一个网络设备。在具有多个网络设备的系统上定义要与嗅探器一起使用的接口可能存在问题(代码明智),并且您希望为选择此类接口定义更明确的规则。这些规则通常是静态定义的(例如“安装了默认路由的活动接口”)。但是,您可能有多个默认路由(想想负载平衡),在这里您可能想要嗅探所有这些路由或(例如)仅在ppp接口上。因此,选择目标接口,我会说是在嗅探器之外解决的任务,而不是在嗅探器代码中的运行时。
例如:
如果通过“活动接口”我们了解安装默认路由的接口(我假设这是一个linux系统):
ip route show 0.0.0.0/0 | awk ' { print $5 ; } ' | xargs ./sniffer
如果你想从你的嗅探器代码获得安装了默认路由的活动接口,你宁可使用netlink(7)或proc(5)(/ proc / net / route)而不是pcap的设备查找api但是复杂性很高。
总之,接口查找逻辑可以很容易地编写到任何系统上的某个包装器程序中,并将结果作为参数传递给您的嗅探器。
答案 1 :(得分:0)
为什么不在“任何”设备上捕获(在所有接口上捕获的伪设备)?
无论如何,这里有一个小片段,可以帮助您找到“活动”界面
#include <stdio.h>
#include <pcap.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
static void
dump_addresses (pcap_addr_t *addresses)
{
pcap_addr_t *addr = addresses;
printf("(");
while (addr) {
struct sockaddr_in *ip = (struct sockaddr_in *)addr->addr;
struct sockaddr_in *nm = (struct sockaddr_in *)addr->netmask;
if (ip && nm)
printf("%s/%s ",
inet_ntoa(ip->sin_addr), inet_ntoa(nm->sin_addr));
addr = addr->next;
}
printf(")");
}
static void
devs_dump (pcap_if_t *devs)
{
pcap_if_t *dev = devs;
while (dev) {
printf("dev: %s - %s - ",
dev->name, dev->description);
dump_addresses(dev->addresses);
printf("\n");
dev = dev->next;
}
}
int
main(int argc, char *argv[])
{
int r;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t *devs;
r = pcap_findalldevs (&devs, errbuf);
if (r) {
printf("Findalldevs: %d (%s)\n", r, errbuf);
return -1;
}
devs_dump(devs);
pcap_freealldevs (devs);
return 0;
}
答案 2 :(得分:0)
我以前曾经多次走过这条路,并且经常发现自己回到添加-i
开关以允许用户精确识别界面。
它使您的工作更简单,并避免任何边缘条件。
答案 3 :(得分:0)
根据pcap_open_live(3):
DESCRIPTION
pcap_open_live() is used to obtain a packet capture handle to
look at packets on the network. device is a string that
specifies the network device to open; on Linux systems with
2.2 or later kernels, a device argument of "any" or NULL can
be used to capture packets from all interfaces.
但它现在似乎已被弃用,你应该使用pcap_create(3)