【问题标题】:Can't get protocol while capture any interfaces with libpcap [duplicate]使用 libpcap 捕获任何接口时无法获取协议 [重复]
【发布时间】:2020-11-01 17:43:56
【问题描述】:

我使用libpcap 代码在我的 Ubuntu 中使用以下代码捕获网络流量我在解析数据包协议时遇到问题:

#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 接口char *device = "any"; 中捕获时,我总是得到protocol = 0

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

这是为什么呢?

【问题讨论】:

标签: c linux ubuntu libpcap packet-sniffers


【解决方案1】:

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

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
}

【讨论】:

  • 这项工作,但我不明白为什么工作,1)我应该计算layer_2_header_length 每个收到的数据包(在一段时间内)还是只在一段时间之前? 2) 为什么它在 ens33any 之间发生变化?谢谢!
  • 一旦您设置了pcap_t,第 2 层标头大小对于捕获的每个数据包都是相同的。它在“ens33”和“any”之间变化的原因是,当您在所有接口上捕获时,您可能会进入多个第 2 层类型。因此,它们需要标准化。
  • "一旦你设置了pcap_t,,第 2 层报头大小对于捕获的每个数据包都是相同的。"不适用于所有第 2 层类型;例如,IEEE 802.11 有一个可变长度的第 2 层标头。
  • 嗯。我不知道。谢谢!
  • 还有比DLT_LINUX_SLLDLT_EN10MB更多的选择吗?
猜你喜欢
  • 2015-07-24
  • 2012-02-18
  • 1970-01-01
  • 2015-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-27
相关资源
最近更新 更多