使用libpcap捕获任何接口时无法获取协议

问题描述

我使用 <div> <i class="fa fa-caret-left" style="font-size:35px"></i> NOVEMBER 2020 <i class="fa fa-caret-Right" style="font-size:35px"></i> </div> 代码通过以下代码捕获Ubuntu中的网络流量,但在解析数据包协议时遇到问题:

libpcap

问题是,当我选择在#include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <stdio.h> #include <time.h> #include <pcap.h> #include <netinet/in.h> #include <netinet/if_ether.h> #include <netinet/ip.h> int main(int argc,char *argv[]) { char *device = "any"; char error_buffer[PCAP_ERRBUF_SIZE]; pcap_t *handle; const u_char *packet; struct pcap_pkthdr packet_header; int packet_count_limit = 1; int timeout_limit = 20000; /* In milliseconds */ bpf_u_int32 net; bpf_u_int32 mask; if ( -1 == pcap_lookupnet(device,&net,&mask,error_buffer)) printf("error netmask\n"); /* Open device for live capture */ handle = pcap_open_live( device,BUFSIZ,packet_count_limit,timeout_limit,error_buffer ); if(NULL == handle) printf("error! %s\n",error_buffer); struct pcap_pkthdr* header; u_char *buffer; while(1) { int ret = pcap_next_ex(handle,&header,&buffer); if(header->len ==0) { printf("cont\n"); continue; } struct iphdr *iph = (struct iphdr*) (buffer + sizeof(struct ethhdr)); printf("protocol = %d \n",iph->protocol); } return 0; } 接口any中捕获时,我总是得到 protocol = 0

但是当我选择char *device = "any";时,我得到了正确的协议(例如TCP使用6)

那是为什么?

解决方法

libpcap有时会根据所选择的接口,将第2层标头(在这种情况下为以太网)替换为Linux cooked header,该长度与以太网标头的长度不同。您可以使用pcap_t函数检查pcap_datalink的数据链路类型。

unsigned int layer_2_header_length;

switch ( pcap_datalink(handle) ) {
case DLT_EN10MB: // Ethernet header
    layer_2_header_length = 14;
    break;

case DLT_LINUX_SLL: // Linux cooked header
    layer_2_header_length = 16;
    break;

// other options
}