mfontanini / libtins

High-level, multiplatform C++ network packet sniffing and crafting library.
http://libtins.github.io/
BSD 2-Clause "Simplified" License
1.91k stars 375 forks source link

Is there an easy way to parse L2 but leave L3 in a RawPDU? #344

Closed pallas closed 5 years ago

pallas commented 5 years ago

I was looking to use libtims to modify some L2 traffic, but I don't need to parse L3. Unfortunately, I can't seem to find a great way to ask the library to only parse certain PDU types without just removing them from pdu_from_flag. Is that a feature that would be of interest to anyone else?

mfontanini commented 5 years ago

You can kind of do that already but it involves some manual process. Most PDUs have a extract_metadata static function that will give you a PDU::metadata struct which contains the current header size, current and next PDU types. So you could do something like get the metadata of the current layer (you need to know which layer it is) and then only construct the layer using the size of it rather than the size of the entire packet. e.g.

const vector<uint8_t> packet = ...;
const auto metadata = EthernetII::extract_metadata(packet.data(), packet.size());
// Now only build the ethernet layer
EthernetII layer(packet.data(), metadata.header_size);

The problem with this is it's kind of static in the sense that you need to know which layer you're looking at before you can do it.

pallas commented 5 years ago

What I mean is: a way to tell the parser to generate a RawPDU when it encounters certain types, e.g. stop when you get to IP or IPv6.

mfontanini commented 5 years ago

Yeah, I understood your problem. You can do what I mentioned and then construct the rest of the payload manually using a RawPDU. e.g. following up on the above:

const vector<uint8_t> packet = ...;
const auto metadata = EthernetII::extract_metadata(packet.data(), packet.size());
// Now only build the ethernet layer
EthernetII layer = EthernetII(packet.data(), metadata.header_size) /
                   RawPDU(packet.data() + metadata.header_size,
                          packet.size() - metadata.header_size);

As I said, you can do it but the library won't do it automatically for you.

pallas commented 5 years ago

Thanks for the response. :)