1

I captured some packets with pcapplusplus on our Ubuntu server, and wrote to .pcap files, then I read the .pcap files, it just worked fine; but when I set the filter with BPF Syntax,it could not read from the .pcap files, the filter is just a tcp string, and it worked well with the example input.pcap, but not work with my pcap files,

pcpp::IFileReaderDevice* reader = pcpp::IFileReaderDevice::getReader("input.pcap");

// verify that a reader interface was indeed created
if (reader == NULL)
{   
    printf("Cannot determine reader for file type\n");
    exit(1);
}   

// open the reader for reading
if (!reader->open())
{   
    printf("Cannot open input.pcap for reading\n");
    exit(1);
}   

// create a pcap file writer. Specify file name and link type of all packets that
// will be written to it
pcpp::PcapFileWriterDevice pcapWriter("output.pcap", pcpp::LINKTYPE_ETHERNET);

// try to open the file for writing
if (!pcapWriter.open())
{   
    printf("Cannot open output.pcap for writing\n");
    exit(1);
}   

// create a pcap-ng file writer. Specify file name. Link type is not necessary because
// pcap-ng files can store multiple link types in the same file
pcpp::PcapNgFileWriterDevice pcapNgWriter("output.pcapng");

// try to open the file for writing
if (!pcapNgWriter.open())
{   
    printf("Cannot open output.pcapng for writing\n");
    exit(1);
}   

// set a BPF filter for the reader - only packets that match the filter will be read
if (!reader->setFilter("tcp"))
{   
    printf("Cannot set filter for file reader\n");
    exit(1);
}   

// the packet container
pcpp::RawPacket rawPacket;

// a while loop that will continue as long as there are packets in the input file
// matching the BPF filter
while (reader->getNextPacket(rawPacket))
{
    // write each packet to both writers
    printf("matched ...\n");
    pcapWriter.writePacket(rawPacket);
    pcapNgWriter.writePacket(rawPacket);
}

Here are some packets:[enter image description here][1]

[1]: https://i.stack.imgur.com/phYA0.png , Anyone can help ?

  • Please share all details, including BPF filters used and what exactly you are trying to achieve. Right now, we can't help you. – pchaigno Feb 24 '22 at 08:57
  • The filter is quite simple , I used the setFilter("tcp") to filter tcp packets 。It seemed that .pcap file which contains vlan protocol doesn't support BPF , if I do set the tcp filter, it just filtered nothing . – The dream of salt fish Feb 24 '22 at 09:32
  • I see. The `tcp` tcpdump filter doesn't seem to support VLAN tags. It reads the Ethertype field as if there was no VLAN tag. Could you try with filter `vlan and tcp`? – pchaigno Feb 24 '22 at 10:50
  • Thanks @pchaigno, this is a good method and have sovled my problem. – The dream of salt fish Feb 25 '22 at 07:50
  • Glad I could help! Could you accept the answer below? – pchaigno Feb 27 '22 at 15:48

2 Answers2

1

TL;DR. You need to use the filter vlan and tcp to catch TCP packets with a VLAN tag.


Explanations

We can look at what BPF filter is generated when using only tcp:

$ tcpdump -d -i eth0 tcp
(000) ldh      [12]
(001) jeq      #0x86dd          jt 2    jf 7
(002) ldb      [20]
(003) jeq      #0x6             jt 10   jf 4
(004) jeq      #0x2c            jt 5    jf 11
(005) ldb      [54]
(006) jeq      #0x6             jt 10   jf 11
(007) jeq      #0x800           jt 8    jf 11
(008) ldb      [23]
(009) jeq      #0x6             jt 10   jf 11
(010) ret      #262144
(011) ret      #0

We can see 2 bytes are first loaded from offset 12 in the packet. That corresponds to the Ethertype in the Ethernet header. It is then used to check if we are parsing an IPv6 (jeq #0x86dd) or IPv4 (jeq #0x800) packet.

However, when there is a VLAN tag, the Ethertype field is shifted by 4 bytes (the length of the VLAN tag field). For packets with a VLAN tag, we should therefore be reading the Ethertype at offset 16.

Using filter vlan and tcp implements this change, by first checking that there is a VLAN tag and then taking it into account when reading the Ethertype. Therefore, to filter TCP packets regardless of whether they have a VLAN tag, you'll need tcp or (vlan and tcp).

pchaigno
  • 11,313
  • 2
  • 29
  • 54
0

@pchaigno is correct; you need to do vlan and tcp or, to catch both VLAN-encapsulated and non-VLAN-encapsulated TCP packets, tcp or (vlan and tcp).

user16139739
  • 862
  • 3
  • 5