Ethereal-dev: Re: [Ethereal-dev] Patch 2 for writing Novell LanAlyzer files

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: Wed, 26 Jun 2002 00:04:32 -0700
On Wed, Jun 26, 2002 at 08:12:30AM +0200, Markus Steinmann wrote:
> sorry, I thought my .cvsrc with "diff -u" should be enough.
> Okay, I've now made a "cvs update -Pd" and a
> "cvs diff -u wiretap". Hope this will work.

I just noticed that you used

	#pragma pack(2)

in "lanalyzer.h"; unfortunately, that's compiler-specific - not all
compilers support that, and not even all compilers used to build
Ethereal support that.

An alternative would be to declare 2-byte and 4-byte integral quantities
as arrays of 2 and 4 "guint8"s, with additional guint8's added as
padding.

LANalyzer (BTW, that's how it's capitalized on the Novell Web site - see

	http://support.novell.com/filefinder/6445/indexb.html

and

	http://developer.novell.com/support/sample/tids/lzfwb01/lzfwb01.htm

for example - so that's how it should be capitalized in "file.c"), as
it's a PC program, probably uses little-endian format for multi-byte
integral quantities.

One way to put entries into those 2-byte and 4-byte arrays would to have
a macro that, with shifting and masking, extracts the bytes from a value
and stores them appropriately; for example:

	#define PUT32_LE(b, v) { \
		(b)[0] = (v) & 0xFF; \
		(b)[1] = ((v) >> 8) & 0xFF; \
		(b)[2] = ((v) >> 16) & 0xFF; \
		(b)[3] = ((v) >> 24) & 0xFF; \
		}

which stores its second argument into the array given by the first
argument, as a 32-bit little-endian number.  (The equivalent macro for a
16-bit quantity is left as an exercise for the reader.)

That way, you

	1) get unaligned quantities in the structures without needing to
	   use a compiler-specific mechanism;

	2) store values into those fields in the correct byte order for
	   LANalyzer files even on big-endian machines.

Another alternative would be to use "swrite()" to write each field of a
record individually, and to write padding, rather than filling in a
structure and writing the entire structure out in one "swrite()" call. 
You'd still have to put stuff out in the right byte order; however, you
could do that by using the "htoles()" and "htolel()" macros from
"wtap-int.h", storing the result into a "guint16" or "guint32" variable,
and writing that variable out.

In addition, "lanalyzer_dump()" is using "guint64"; on most platforms on
which Ethereal is built, the compiler supports 64-bit integral types,
but on at least one platform on which Ethereal has been built (some
versions of SINIX on Siemens
Nixdorf^H^H^H^H^H^H^H^H^H^H^H^H^H^H^HFujitsu Siemens MIPS machines,
using the native compiler), the compiler doesn't support them.  That's
why 64-bit arithmetic is done using doubles rather than guint64's in
various files in the wiretap directory.

Also, you should probably replace all occurrences of

	REC_TRACE_HEADER		with RT_HeaderRegular
	REC_CYCLIC_TRACE_HEADER		with RT_HeaderCyclic
	REC_TRACE_SUMMARY		with RT_Summary
	REC_TRACE_PACKET_DATA		with RT_PacketData

and get rid of the definitions of those 4 REC_ values, so that the same
#defines are used for record types throughout "lanalyzer.c".

You might also want to have "lanalyzer_dump()" return EFBIG rather than
WTAP_ERR_SHORT_WRITE if the record being written to the file would
exceed the maximum size of a LANalyzer file.