为什么pcap_datalink()总是返回1(以太网),即使在无线设备上也是如此?

我遇到的问题是pcap_datalink()总是返回1 。 根据我的理解,这是LINKTYPE_ETHERNET 。 但是,我使用的设备是无线网卡,在我的情况下是en0

这使我无法将卡置于监控模式,并阻止我的WLANfilter工作。 我试图在OSX和Linux上运行它,结果相同。 我也是以root身份运行的。

这是我的代码中导致问题的部分。 例如,假设dev设置为en0 (Mac上的无线设备)。

 #include  #include  #include  int main(int argc, char *argv[]) { pcap_t *pcap_h; char *dev, errbuf[PCAP_ERRBUF_SIZE]; struct bpf_program fp; struct pcap_pkthdr header; const u_char *packet; if(argc < 2) { printf("Usage: %s device\n", argv[0]); exit(EXIT_FAILURE); } dev = argv[1]; if((pcap_h = pcap_create(dev, errbuf)) == NULL) { printf("pcap_create() failed: %s\n", errbuf); exit(EXIT_FAILURE); } if(pcap_can_set_rfmon(pcap_h) == 0) { printf("Monitor mode can not be set.\n"); } if(pcap_set_rfmon(pcap_h, 1) != 0) { printf("Failed to set monitor mode.\n"); exit(EXIT_FAILURE); } if(pcap_activate(pcap_h) != 0) { printf("pcap_activate() failed\n"); exit(EXIT_FAILURE); } /* * Compile a filter to sniff 802.11 probe requests * Filter: type mgt subtype probe-req */ if(pcap_compile(pcap_h, &fp, "type mgt subtype probe-req", 0, PCAP_NETMASK_UNKNOWN) == -1) { printf("pcap_compile() failed: %s\n", pcap_geterr(pcap_h)); exit(EXIT_FAILURE); } /* * Set the compiled filter */ if(pcap_setfilter(pcap_h, &fp) == -1) { printf("pcap_setfilter() failed: %s\n", pcap_geterr(pcap_h)); exit(EXIT_FAILURE); } pcap_freecode(&fp); packet = pcap_next(pcap_h, &header); printf("Header: %d\n", header.len); pcap_close(pcap_h); return 0; } 

任何想法为什么pcap_datalink()总是返回1

编辑

更新了代码,并在调用pcap_set_rfmon()之前添加了pcap_activate() 。 我收到一个错误:

 pcap_compile() failed: 802.11 link-layer types supported only on 802.11 

您是否真的阻止您将卡置于监控模式,停止WLANfilter工作,或者您是否打算将pcap_datalink()作为检查来查明问题?

请注意,来自PCAP-LINKTYPE(7):

对于实时捕获或“savefile”,libpcap提供一个值,作为pcap_datalink(3PCAP)例程的返回值,指示它提供的数据包开头的链路层头的类型。 这不一定是被捕获的数据包在它们被捕获的网络上具有的链路层报头的类型; 例如,来自IEEE 802.11网络的数据包可能由libpcap提供,网络适配器或网络适配器驱动程序从802.11标头生成以太网标头。

因此,我不会将此LINKTYPE_ETHERNET / DLT_EN10MB返回值作为此处问题的确切指示。

编辑:此外,pcap_set_rfmon()应该激活句柄之前调用,这在您的代码中是不可见的。

pcap对于应该完成的顺序非常敏感。 查看pcap_can_set_rfmonpcap_set_rfmon的手册页。

订单应该是:

  • pcap_create
  • pcap_can_set_rfmon
  • pcap_set_rfmon(如果到目前为止那么好)
  • 然后,只有这样,pcap_activate