使用 libpcap 捕获任何接口时无法获取协议
Can't get protocol while capture any interfaces with libpcap
我使用 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";
时,我得到了正确的协议(比如 6 代表 TCP)
这是为什么?
libpcap 有时会根据所选的接口,将第 2 层 header(在本例中为以太网)替换为 Linux cooked header,其长度与以太网 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
}
我使用 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";
时,我得到了正确的协议(比如 6 代表 TCP)
这是为什么?
libpcap 有时会根据所选的接口,将第 2 层 header(在本例中为以太网)替换为 Linux cooked header,其长度与以太网 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
}