Wireshark-dev: Re: [Wireshark-dev] [RFC] Vendor-specific dissector extension for EtherNet/IP

From: Samuel GROOT <groot.samuel@xxxxxxxxx>
Date: Wed, 30 Aug 2017 14:37:01 +0200
Le 29/08/2017 à 21:34, Michael Mann via Wireshark-dev a écrit :
The answer depends on exactly what you are trying to do, some things will be easier than others. 1. If you want to add vendor specific objects, that can easily be done in Lua because there is a dissector table that you can just register your vendor specific class with ("cip.class.iface").  There should be numerous examples of Lua using a dissector table (just not specifically for CIP).

I have to admit the way dissector tables work is not clear for me.

I registered my dissector for a vendor-specific class, and I observed the following behaviour: - When the service is common (Get_Attribute_List for example), the dissector is not called.
- when the service is vendor-specific, the dissector is then called.

So I can implement the vendor-specific services for vendor-specific classes at least, with a new dissector.

But I don't understand why discriminate dissector in the class dissector table based on the service being known or not, any idea why it was implemented this way?

Since the service is parsed and interpreted before the path (so the class), wouldn't it make more sense to actually make a dissector table based on the service?

2. There is no support currently for "classless" service codes (like those used in Rockwell Automation PLCs), which is what _https://www.wireshark.org/lists/ethereal-dev/200601/msg00174.html_ appears to be talking about.

As I understand it the service codes mentioned in that thread are class specific.

I have never encountered "classless" service codes until now, I didn't even know that existed (as CIP doesn't implement this behaviour, or at least I couldn't find it in the documentation).

2. If you want to add vendor specific services to already supported objects, that would be more difficult to do in Lua because there isn't a dissector table hook for them.  I'm not sure there would be a way to handle the "general" case of registering service + class into a dissector table, but you could add dissector tables (patching packet-cip.c) for specific objects (Identity, ConnectionManager, etc) and submit just that part as a patch for inclusion in base Wireshark code.

Re

3. Vendor specific attributes of an object would have the same difficulty in Lua and would need dissector tables.

Well, there is the cip.data_segment.iface dissector table, but then one would need to check (in every dissector register in this table) the class code, and also the instance id (to determine if it is a class attribute or an instance attribute).

I'm not sure how this dissector table is used though: is it only for attribute data or also service data?

4. I believe Lua will "override" any value registered to a dissector table, so you could write the "vendor specific" portion, for say the Identity object, but then you'd have to duplicate all of the dissection currently being done for it in your Lua script.

I did test with setting a lua dissector for Identity in the cip.class.iface, and on packets with common services it wasn't triggered (I didn't have packets with vendor-specific services call for Identity).

So apparently it does not override the default dissector with the lua one (at least with a common service).

5. Also note that not all "open" objects are supported in packet-cip.c.  It would be appreciated that if you added dissection for any of those, that you provide a patch for integration here: https://code.wireshark.org/review (see https://wiki.wireshark.org/Development/SubmittingPatches for more details).  If you're more familiar with Lua than C, you can put the Lua script here: https://wiki.wireshark.org/Contrib, but I'd probably end up taking it and converting it to C.

If I encounter those I can implement it (in C or lua, both are fine for me), but it is not my priority for now.


The problem I see here is that the system of dissector table does not fit our needs in this context.

Ideally I would see one custom dissector just for the service and path (so service, classes and instances), and one for the payload (attributes and services data).

All the structure would be made in C, and just small portions of lua would need to be used to (dynamically) provide names for classes, services and attributes. Then, a bigger lua script would provide a full dissector for the payload (attributes or services data), based on the previously parsed informations.

How I have no idea if this is possible in wireshark, any thoughts?