Ethereal-users: Re: [Ethereal-users] Include timestamp with decoded packet

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

From: Guy Harris <guy@xxxxxxxxxx>
Date: Mon, 10 Mar 2003 11:10:47 -0800
On Mon, Mar 10, 2003 at 04:50:03PM +0100, Jonas Harvard wrote:
> How do I translate timestamps pertaining to each packet, from the raw
> data generated by tethereal?

By "raw data generated by Tethereal" do you mean the output writted when
you run Tethereal with the "-w" flag?

If so, then it's just a libpcap-format capture, and you can use
libpcap/WinPcap to read them (i.e., you don't have to write your own
code to understand the file format - just let libpcap do it for you).

This means that you'll call "pcap_open_offline()" to open the file, and
then call "pcap_loop()" to read through the file, and pass to
"pcap_loop()" a pointer to a callback routine which is called for each
packet in the file.

To quote the current CVS version of the libpcap man page:

     pcap_dispatch() is	used to	collect	and process packets.  cnt
     specifies	the  maximum  number of	packets	to process before
     returning.	 This is not a minimum	number;	 when  reading	a
     live  capture,  only  one	bufferful of packets is	read at	a
     time, so fewer than cnt packets may be processed. A  cnt  of
     -1	 processes  all	 the  packets received in one buffer when
     reading a live capture, or	all the	packets	in the file  when
     reading  a	``savefile''.  callback	specifies a routine to be
     called with three arguments:   a  u_char  pointer	which  is
     passed  in	 from pcap_dispatch(), a const struct pcap_pkthdr
     pointer to	a structure with the following members:

	  ts   a struct	timeval	 containing  the  time	when  the
	       packet was captured

	  caplen
	       a bpf_u_int32 giving the	number of  bytes  of  the
	       packet that are available from the capture

	  len  a bpf_u_int32 giving the	length of the packet,  in
	       bytes  (which  might  be	 more  than the	number of
	       bytes available from the	capture, if the	length of
	       the  packet  is	larger than the	maximum	number of
	       bytes to	capture)

     and a const u_char	pointer	to the first caplen (as	given  in
     the  struct  pcap_pkthdr a	pointer	to which is passed to the
     callback routine) bytes of	data from the packet (which won't
     necessarily  be  the  entire  packet;  to capture the entire
     packet, you will have to provide a	value for snaplen in your
     call  to  pcap_open_live()	that is	sufficiently large to get
     all of the	packet's data -	a value	of 65535 should	be suffi-
     cient on most if not all networks).

		...


     pcap_loop() is similar to pcap_dispatch()	except	it  keeps
     reading  packets until cnt	packets	are processed or an error
     occurs.  It does not return when live read	 timeouts  occur.
     Rather,	specifying    a	   non-zero   read   timeout   to
     pcap_open_live() and then calling pcap_dispatch() allows the
     reception and processing of any packets that arrive when the
     timeout occurs.  A	negative cnt causes pcap_loop()	 to  loop
     forever  (or  at  least  until an error occurs).  A negative
     number is returned	on an error; 0	is  returned  if  cnt  is
     exhausted.

so the time stamp is supplied as part of the "struct pcap_pkthdr" a
pointer to which is passed to your callback routine.

A "struct timeval" contains two members: "tv_sec", which is the seconds
portion of the time stamp, in seconds since January 1, 1970, 00:00:00
GMT (GMT, *NOT* local time!), and "tv_usec", which is the microseconds
portion of the time stamp.

To display that time stamp, you'd use "localtime()" (available on all
UNIX systems, as well as in the C library for Windows) to convert the
"tv_sec" to a "struct tm", and print out the members of the "struct tm".
You'd then display the microseconds portion right after the seconds
portion of the time stamp, with a "." or "," between them, and with the
appropriate number of leading zeroes.