Ethereal-dev: Re: [Ethereal-dev] tvb and dissector question.

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

From: "Ronnie Sahlberg" <rsahlber@xxxxxxxxxxxxxx>
Date: Wed, 21 Mar 2001 19:09:15 +1100
Hi,

----- Original Message -----
From: "Gilbert Ramirez" <gilramir@xxxxxxxxx>
To: "Ronnie Sahlberg" <rsahlber@xxxxxxxxxxxxxx>
Cc: <ethereal-dev@xxxxxxxxxxxx>
Sent: Wednesday, March 21, 2001 3:37 AM
Subject: Re: [Ethereal-dev] tvb and dissector question.


> Ronnie Sahlberg wrote:
> >
> >
> > Question:
> > Assuming I have a complete IP-packet in a buffer.
> > How can I create proper tvb,pinfo,tree structures so I can call
dissect_ip()
> > (or any other dissector)?
> > I want this packet to be displayed in the top-tree view, not as a
subtree
> > inside the ip-tree for a fragmented ip-packet.
> > Help me with this and you will have defragmentation in the ip-layer in
> > ethereal.
> > End Question.
>
> You can't do this from inside a dissector. I think the right approach
> is, from
> a higher level, to create a new frame_data list, or at least augment
> this
> list by *adding* your new packet. You'd have to add new fields to
> frame_data
> to be able to differentiate packets from a file and these reconstructed
> packets.
>
> >
> > (the buffer is almost, but not really a proper IP-packet. eg MF-bit in
flags
> > is cleared, offset is set to 0,
> > the checksum is set to 0 (I will indicate to dissect_ip() that this is a
> > magic packet which should not
> > care for these fields))
>
> An alternate approach would be to create a new protocol for this
> "reconstructed" IP
> packet. The only information that really makes sense in this RECON_IP
> header is:
> Protocol, Source Address, and Destination Address. You might add a new
> Total Length,
> too. But the rest can be thrown away.

I like this approach best.
Though I think it makes sense to keep as many fields as possible from the
original fragments.
E.g.  the id-field would be nice since a filter on this would get all the
fragments as received
from the interface and also the reconstructed ip packet.
I planned to use the same dissect_ip() dissector to dissect the
reconstructed ip-packet as
is used for the individual fragments.
Though the reconstructed packet is not encapsulated within any
ehternet/atm/framerelay/whatever link protocol.


>
> Furthermore, the lower-level protocols (ethernet) don't make sense for
> this
> RECON_IP packet either. Besides making RECON_IP a new protocol, I
> propose
> using it at the bottom-most layer (the link-layer). That is, we could
> either
> set aside a range of WTAP_ENCAP_* numbers for application-defined
> protocols,
> or we could add it to Wiretap. The new packet would *start* with a
> RECON_IP
> header, and thus, have a WTAP_ENCAP_RECON_IP encapsulation type.
>
> The dissect_recon_ip() dissector would exist *inside* packet-ip.c, so
> that
> it could easily use the hf_ip_* fields, *but*, it would register itself
> to the "wtap_encap" dissector table (see dissect_frame()), not to
> anything
> else.
>
> Thoughts?

As I understand the source, read_packet() is the function which reads all
frames from the child process
which writes structures of one or more frames through the pipe in the
filedescriptor which
read_packet() get as a parameter.
My current thoughts are to rename read_packet() to, say, process_packet()
and extend process_packet()
by using a few extra arguments to be able to either work as before (by
reading the packet(s) from the pipe),
or as an alternative read the packet from a preallocated buffer.
This might also need a new feature for wtap_phdr(x); so it knows that this
is a raw ip packet with no encapsulation.
process_packet() would, I guess, create all the nessesary stuff and make
sure the right dissector were called
as if it were a normal ip packet.

I would then create a new read_packet() using the same parameters as the
original one, and which would call process_packet()
in such a way that the original behaviour was invoked.
When process_packet() returns to the new read_packet(), read_packet() would
check a global variable to see if the calls
to process_packets() resulted in any artificial packets were produced, if
so, read_packet() would call process_packet() again, but this time
in such a way so that process_packet() took the data from the supplied
buffer instead of the filehandle.
This would, I think, guarantee that the new packet were not dissected until
the entire previous packet was completely dissected
and had returned to read_packet().
(I dont know, but I assume som dissectors might othervise be "upset" if
suddenly the pinfo and tree and tvb structures had
fields that was changed while calling a dissector (I think of dissectors
which call other dissectors and when they return, continue to
dissect the current packet (ehternet? where ethernet frame data is sometimes
both before and also after the ip protocol data)))
By waiting until the previous packet has completely dissected the enbtire
frame and returned to read_packet() before
injecting our artificial packets, I think this would not be an issue. Could
be wrong.

Also I thought of adding a new function, inject_packet() which would queue a
newly constructed artificial packet somewhere
so that read_packet() can inject these new packet(s) when finished
dissecting the current real packet.

Does this make sense?
Could it work?
Did I explain it in an understandable way?