I have Scientific Linux 6.0 on my machine and apparently the version of
libpcap that's distributed with it (libpcap-1.0.0-
6.20091201git117cb5.el6.x86_64) has a bug when opening a device with a snaplen
smaller than 13.
Besides, even if the snaplen is greater or equal to 13, the captured packet
size won't match the selected snaplen.
The following message will be displayed when opening a device with a snaplen <
13:
"Error reading the packets: corrupted frame on kernel ring mac offset 70 +
caplen 0 > frame len 64"
Apparently these two bugs have already been fixed in the latest version of
libpcap.
I attached a test application.
Thank you very much
#ifdef _MSC_VER
/*
* we do not want the warnings about the old deprecated and unsecure CRT functions
* since these examples can be compiled under *nix as well
*/
#define _CRT_SECURE_NO_WARNINGS
#endif
#define FIRST_SNAPLEN 13
#define SECOND_SNAPLEN 1
#define THIRD_SNAPLEN 30
#define ITERATIONS 20
#include "pcap.h"
int main()
{
pcap_t *adhandle;
int res;
char errbuf[PCAP_ERRBUF_SIZE];
struct pcap_pkthdr *header;
const u_char *pkt_data;
do
{
/* Open the adapter (Setting a snaplen of FIRST_SNAPLEN)*/
printf("- Opening eth0 with a snaplen of %d bytes and reading packets...\n", FIRST_SNAPLEN);
if ((adhandle= pcap_open_live("eth0", // name of the device
FIRST_SNAPLEN, // portion of the packet to capture.
// 65536 grants that the whole packet will be captured on all the MACs.
1, // promiscuous mode (nonzero means promiscuous)
100, // read timeout
errbuf // error buffer
)) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter eth0\n");
break;
}
/* Retrieve the packets */
int cnt = 0;
while((res = pcap_next_ex( adhandle, &header, &pkt_data)) == 0)
{
if(cnt > ITERATIONS) break;
if(res == 0)
{
/* Timeout elapsed */
cnt ++;
continue;
}
}
if(res == -1)
{
printf("Error reading the packets: %s\n", pcap_geterr(adhandle));
break;
}
else if(res == 0)
{
printf("No packets were received (traffic is needed for this test)\n");
break;
}
printf("OK\n");
}
while(0);
pcap_close(adhandle);
do
{
/* Open the adapter (Setting a snaplen of SECOND_SNAPLEN)*/
printf("- Opening eth0 with a snaplen of %d bytes and reading packets...\n", SECOND_SNAPLEN);
if ((adhandle= pcap_open_live("eth0", // name of the device
SECOND_SNAPLEN, // portion of the packet to capture.
// 65536 grants that the whole packet will be captured on all the MACs.
1, // promiscuous mode (nonzero means promiscuous)
100, // read timeout
errbuf // error buffer
)) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter eth0\n");
break;
}
/* Retrieve the packets */
int cnt = 0;
while((res = pcap_next_ex( adhandle, &header, &pkt_data)) == 0)
{
if(cnt > ITERATIONS) break;
if(res == 0)
{
/* Timeout elapsed */
cnt ++;
continue;
}
}
if(res == -1)
{
printf("Error reading the packets: %s\n", pcap_geterr(adhandle));
break;
}
else if(res == 0)
{
printf("No packets were received (traffic is needed for this test)\n");
break;
}
printf("OK\n");
}
while(0);
pcap_close(adhandle);
do
{
/* Open the adapter (Setting a snaplen of THIRD_SNAPLEN)*/
printf("- Opening eth0 with a snaplen of %d bytes and checking that packets caplen is actually %d...\n", THIRD_SNAPLEN, THIRD_SNAPLEN);
if ((adhandle= pcap_open_live("eth0", // name of the device
THIRD_SNAPLEN, // portion of the packet to capture.
// 65536 grants that the whole packet will be captured on all the MACs.
1, // promiscuous mode (nonzero means promiscuous)
100, // read timeout
errbuf // error buffer
)) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter eth0\n");
break;
}
/* Retrieve the packets */
int cnt = 0;
while((res = pcap_next_ex( adhandle, &header, &pkt_data)) == 0)
{
if(cnt > ITERATIONS) break;
if(res == 0)
{
/* Timeout elapsed */
cnt ++;
continue;
}
}
if(res == -1)
{
printf("Error reading the packets: %s\n", pcap_geterr(adhandle));
break;
}
else if(res == 0)
{
printf("No packets were received (traffic is needed for this test)\n");
break;
}
else if(header->caplen != THIRD_SNAPLEN)
{
printf("Captured length should be %d, instead it's %d\n", THIRD_SNAPLEN, header->caplen);
break;
}
printf("OK\n");
}
while(0);
pcap_close(adhandle);
return 0;
}
|