Ethereal-dev: Re: [Ethereal-dev] Prescan packets

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Guy Harris <gharris@xxxxxxxxx>
Date: Sun, 09 Jan 2005 13:20:49 -0800
Jerome Freedman wrote:
I am working on a dissector for RDP. Most of the packets are encrypted, but I have obtained the session keys by a kludge to rdesktop. I have successfully decrypted one packet, but I would like to be able to decrypt all encrypted packets before any packet is displayed. I am keeping the decrypted packet information around in a frame data structure, so when I return to this decrypted packet, I know what to do. I need to prescan the entire packet stream in a linear fashion so that the encryption/decryption tables do not get out of synchronization. How do I do this in ethereal?

Why do you need to decrypt *all* packets before any packet is displayed? Do the contents of a later packet affect the way an *earlier* packet is displayed?

The ideal would be to save, with each frame, enough information to set the decryption engine's state to the state it needs to be in to decrypt that frame.

The way Ethereal works is that:

the file is read in, with each packet being dissected as it is read - there is no guarantee that the "tree" argument to the dissector is non-null, so any work that has to be done in order to dissect subsequent packets, or to generate enough state to properly re-dissect the current packet, must be done regardless of whether the "tree" argument is null or not;

once that's done, if a frame is clicked on, or otherwise dissected (e.g., when printing or exporting to a file, or when filtering, or when running a tap), the dissector is called with that packet, with the "tree" argument non-null if the protocol tree needs to be generated.

The way Tethereal works is that the file is read in (or a capture is done), with each packet being dissected as it's read - whether the protocol tree is generated or not depends on whether a read filter is being used (if so, the protocol tree is generated) or the "-V" flag is used (if so, the protocol tree is generated) or some thing else requires a protocol tree (e.g., at least some taps).

So the way to do decryption is:

on the first pass (which would mean "if there's no per-frame data saved"), start the decryption engine and decrypt each packet, attaching to each frame enough information to allow the frame to be decrypted;

in any subsequent dissection (there won't be any in Tethereal, but there will be in Ethereal), use the saved information to decrypt the packet.

At Sniffer, we had a mechanism for prescanning all packets and saving any per frame data prior to display.

There's no "prescanning" mechanism in Ethereal - and, given the existence of Tethereal (which is strictly a one-pass program, and intended to be such, given that it is intended to be able to dissect packets as they're captured) and of the "Update list of packets in real time" feature, there's no intention of ever giving it one.

Instead, the model for dissectors in Ethereal is that there's an initial dissection of the packet, where the only state information available is state information generated when dissecting previous packets, and in which packets are guaranteed to be dissected in the order in which they appear in the file or are captured, and possibly subsequent dissections, where all state information saved by the initial dissection, including per-frame information saved when a frame was dissected in the first pass, is available, but there's no guarantee in which order packets will be dissected.

The first pass, with the initial dissections, is in some ways similar to the pre-scan - except that it's not necessarily prior to the display of the packet; dissections done in that pass might have to generate column values or a protocol tree.

All of the existing decryption capabilities in Ethereal work with that model; decryption capabilities added in the future should be able to do so as well, as decryption of packet M isn't going to depend on having already dissected packet N if M < N (otherwise, decryption of the packet in an implementation of the receiver of the protocol is going to be a bit difficult - at *most*, you might have to assemble several packets and decrypt them as a unit, but, in that case, an Ethereal dissector would, on the first pass, not try to decrypt packet M, but would just save the data for it using the reassembly mechanism, and, when enough packet data has been reassembled to allow decryption to be done, the decryption would be done on the reassembled data, and all of the packets in the reassembled data would be dissected).