3

我正在使用 libpcap 来嗅探流量。我想在当前活动的网络设备上执行此操作(例如,具有分配 IP 地址的设备等)。最好的方法是什么?我假设我必须执行以下操作:

pcap_findalldevs(&alldevs, errbuf)

获取所有网络设备,然后循环并检查当前处于活动状态的设备。


编辑:以下功能

(pcap_lookupnet(dev, &net, &mask, errbuf) 

返回网络设备的网络地址和子网掩码。我在计算机上使用不同的以太网适配器进行了一些测试,当我在未连接到网络的适配器上调用它时,它返回 -1。这会是获得活动界面的防弹方法吗?它会错过任何边缘情况吗?

4

4 回答 4

2

pcap 用于查找符合某些用户定义规则的接口的 API 是微不足道的。您确实可以使用 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,但复杂性是高的。

总之,接口查找逻辑可以很容易地编写到任何系统上的一些包装程序中,并将结果作为参数传递给您的嗅探器。

于 2010-12-05T12:31:20.980 回答
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;
}
于 2010-12-05T12:53:31.883 回答
0

我以前曾多次走这条路,通常发现自己回退到添加一个-i开关以允许用户精确识别界面。

它使您的工作更简单,并避免任何边缘条件。

于 2010-12-05T16:11:59.787 回答
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)

于 2010-12-08T10:28:32.827 回答