Seeking Example for Protocol Encapsulating IPv4

I am attempting to write a dissector for a protocol that fully encapsulates IPv4, and optionally encapsulates eithernet/ipv4 as well. This protocol attaches two headers that precede the (ethernet)/IPv4 headers. Let's call these headers Foo and Foo2.

Foo is 40 bits (5 bytes) long, Foo2 is 8 bits (1 byte) long, and I have coded a device that receives standard ethernet/IPv4 packets and will encapsulate them by adding Foo and Foo2 to the top of the header stack. So, assuming ethernet is present, the order of headers that should be dissected is as follows:

1. Foo
2. Foo2
3. Ethernet
4. Ipv4

There is no designated special port for this encapsulation - it happens to all standard ethernet/IPv4 traffic received on one device and is removed by a different device later. Again, simplifying, let's say I want to parse both Foo and Foo2 and show the fields. Let's say Foo2 has two fields, a 2 bit field and a six bit field - we can call those bar and bar2.

Looking at the example from https://www.wireshark.org/docs/wsdg_h... I see how you could write a Foo protocol that didn't do encapsulation. I don't quite yet fully understand that example, but I can probably, given some more time, understand how to get things recognized for Foo and Foo2, but the big piece that I'm missing is how I can hand dissection off to the built-in ethernet or IPV4 dissectors once Foo2 is dissected.

Additionally, it's unclear to me how to enable this properly in wireshark itself, as when using "Decode As" I don't see any options that I could use to filter by this that make sense. For example, right now, I have a decoder plugin that works for a much more complicated version of the protocol. Wireshark is currently ignoring my subset of that (Foo/Foo2) and parsing the new protocol headers as if they were ethernet, which leads to strange results (wrong source, wrong destination, wireshark stopping dissection as soon as it hits what it thinks is IPV4 because of bogus IPV4 version)

I tried to use decode as, but the options I can use don't seem to have any options I could make use of given that the port is the same and the options should precede ethernet/ipv4 and don't match any built-in protocols. I know that the protocol dissector is enabled, because if I look into the Manage Protocols menu I can see the custom packet type is enabled.

EDIT: Getting it to recognize the protocol needed a combination of editcap and setting up recognition for the protocol on the DLT_USER table under Edit -> Preferences -> Protocol as suggested by Chuckc and discussed in the coments under that answer. Will do an EDIT 2 if/when the part about '[handing] dissection off to the built-in ethernet or IPv4 dissectors" is answered.

edit retag close merge delete

To chain dissectors, create a new tvb for the remaining data using tvb_new_subset_length(), get a handle for the dissector to call using find_dissector("<dissector_name>") where <dissector_name> is the name the target dissector registered with and call it using call_dissector passing in the handle, the new tvb and your pinfo and tree values.

Look at packet-ip.c where in certain circumstances it calls the IPv6 dissector, although in those cases the entire tvb is passed on, not a subset.

( 2020-06-29 15:40:16 +0000 )edit

Sort by » oldest newest most voted

Values in the range 147 through 162 are reserved for private use; if you have some link-layer header type that you want to use within your organization, with the capture files using that link-layer header type not ever be sent outside your organization, you can use one or more these values. No libpcap release will use these for any purpose, nor will any tcpdump release use them, either.


LINKTYPE_USER0-LINKTYPE-USER15  147-162 DLT_USER0-DLT_USER15    Reserved for private use; see above.


There is some background info in this ASK question and a dissector using WTAP_ENCAP_USER0

more

And one more from the old Q&A site.

( 2020-06-23 19:59:04 +0000 )edit

I'll try this and get back to you if it works, or add another comment if it doesn't. Thank you for your answer.

( 2020-06-25 15:24:30 +0000 )edit

So looking at the reg_handoff, I notice that the dissector example I have ust adds a handle to udp.port and adds the option to find the dissector. It seems that I'll have to change that to use the custom user type that was mentioned, and set up that user type in Wireshark. I'm unclear if there are any other steps that need to be taken - looking at the proto_register_foo() method, a lot seems similar to the example listed, though there are a couple of options missing but many others that are not in the example. I guess I'll start with just the first part and see if that works.

( 2020-06-25 15:31:57 +0000 )edit

Do I need to take another capture? I'm not really seeing any changes at the moment, though I may not have changed the setup correctly - based on some of the information from links, I went to Edit -> Preferences -> Protocol -> DLT_USER -> Edit Encapsulations Table and added a DTL User 0 entry.

I then typed the name of my protocol for the header, and added header size. It's unclear to me from any documentation if this 'size' is in bits or bytes, though, so I went with bytes to start. It doesn't seem to have changed anything, unfortunately..

EDIT: I rebuilt but it still seems to want to latch onto UDP. So I set the UDP port to 0 and that did create a change - it's being recognized as IPV4 now, but it's still being misread and just lumps together everything as "data ...(more)

( 2020-06-25 17:02:06 +0000 )edit

Here is a walk through with a single packet of HTTP data.

The Data Link Type can be modified with the editcap option -T <encapsulation type>.
Default output format is pcapng which can be set back to pcap with -F <file format>

\$ editcap -T user1 ./httpresp.pcap ./httpresp_1.pcap

( 2020-06-26 03:19:43 +0000 )edit

You mention "ports", but you don't say anything about Foo or Foo2 having port numbers; neither Ethernet nor IPv4 have port numbers.

If the Foo headers are truly at the very beginning of the packet, then the equivalent of an "Ethernet type" or a "IP protocol number" or a "port number" would be the encapsulation type in the capture file. See @Chuckc's answer there; the pcap file format has the encapsulation type in the file header, while the pcapng file format has one or more Interface Description Blocks, one per interface, giving the encapsulation type for that interface.

The encapsulation types used in those file formats are listed on the tcpdump.org link-layer header types page; that's the document @Chuckc was quoting. You can use one of the "user-defined" types, which would let you set a Wireshark preference to decode it with your dissector; bear in mind that others may use a given user-defined type for their own purpose - there is no registry that prevents collisions.

If your captures are not in pcap or pcapng format, you've either used an existing file format other than pcap or pcapng or have defined your own; in the first case, you'd have to modify the Wireshark libwiretap code for that format to handle your encapsulation (and hope that you haven't used an encapsulation type that will be used in that file format in the future) and, in the second case, you'll have to write code to read those files and add that code to libwiretap.

more

The only point I wanted to make by mentioning ports was that I can't necessarily just use port number as a condition for using Foo dissection. They are indeed at the very beginning of the packet. They're just standard pcaps, so the last paragraph isn't relevant in this case.

( 2020-06-25 15:23:33 +0000 )edit