Ethereal-dev: Re: [Ethereal-dev] RTP Analysis: How to get raw RTP packet offset and size

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

From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Wed, 19 Nov 2003 10:04:30 -0800
On Wed, Nov 19, 2003 at 02:03:41PM +0100, Lars Ruoff wrote:
> what exactly are
> typedef struct _frame_data {
>   ...
>   guint32      pkt_len;     /* Packet length */

The length of the packet as it appeared "on the wire" (or, for 802.11,
"on the air" :-)), as reported by the driver.

>   guint32      cap_len;     /* Amount actually captured */

The amount of that packet data that was copied up to libpcap and thus to
Ethereal.

> struct _rtp_info {
>     ...
>     guint  info_data_len;
>     guint  info_payload_offset;
>     guint  info_payload_len;
> };
> 
> in packet-rtp.c, info_data_len is defined as
>  rtp_info.info_data_len = tvb_reported_length_remaining( tvb, offset
);

That's based on the "reported length", which is, in turn, based on
"pkt_len", not "cap_len".

Note that if "tvb_reported_length_remaining(tvb, offset)" is greater
than "tvb_length_remaining(tvb, offset)", you do *NOT* have the full
payload.

> currently, i'm getting a pointer to the raw RTP packet by doing a
>  sample.frame = cfile.pd + pinfo->fd->pkt_len - rtpinfo->info_data_len;

	...

> And what about fragmentation?

If the "raw RTP packet" is constructed from multiple link-layer packets,
that won't work.  "cfile.pd" points to a link-layer packet as read from
the capture file.

It should be possible to just put into the "struct _rtp_info" a "const
guint8 *" whose value is set in "dissect_rtp_data()" to

	tvb_get_ptr(newtvb, 0, -1)

so that you get a *pointer* to the raw data, not some *offset* into
something you might not be able to get a handle on.  That should be safe
because the "epan_dissect_t" constructed for the packet has not yet been
freed when the taps are called (destroying the "epan_dissect_t" will end
up freeing all the tvbuffs and hence invalidating pointers to their
data), because, in "add_packet_to_packet_list()", it calls
"tap_push_tapped_queue()" immediately after calling
"epan_dissect_run()", and well before calling "epan_dissect_free()".