Ethereal-dev: [Ethereal-dev] Re: [Ethereal-users] Netlib SQL decoder crashes

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: Fri, 22 Nov 2002 16:41:24 -0800
On Tue, Nov 19, 2002 at 11:03:12PM +0100, Martin Regner wrote:
> I don't know if the fix Gerald Combs made a few days ago would solve this crash. 
> http://www.ethereal.com/lists/ethereal-cvs/200211/msg00142.html

It doesn't.

I ran Ethereal on the capture, and it crashed.  It doesn't crash when I
run "tethereal" or "tethereal -V" on the same capture.

The stuff to deal with fragmented packets is *REALLY REALLY REALLY
REALLY REALLY* ugly.  It would probably be, at best, difficult to clean
up to work correctly; it might be impossible.

The stuff at

	http://www.freetds.org/tds.html#packet

seems to at least hint that:

	a TDS packet is built from one or more Netlib fragments;

	a Netlib fragment starts with that 8-byte header and has TDS
	payload following the header;

	the last Netlib fragment of a fragmented TDS packet has the
	"last packet indicator" set to 1, and all other fragments have it
	set to 0.

If that's the case, then:

	Netlib fragments can be reassembled using the standard TCP
	reassembly code;

	TDS PDUs can be reassembled from Netlib fragments using the
	"reassemble.c" stuff (probably using "fragment_add_seq_next()",
	as there are no fragment IDs - the assumption is that fragments
	are delivered reliably and in order).

However, the claim was made in

	http://www.ethereal.com/lists/ethereal-dev/200204/msg00144.html

that Netlib packet boundaries are irrelevant to TDS PDU boundaries:

	tcp                 netlib          tds
	+----------+   +-------------+   +----------+
	|          |   |             |   | TDS PDU 1|
	|          |   | netlib      |   +----------+
	|  tcp     |   | packet 1    |   |          | 
	| packet   |   |             |   | TDS PDU 2|
	|          |   +-------------+   |          |
	|          |   |             |   +----------+
	|          |   | netlib      |   |          |
	|          +---+ packet 2    +---+ TDS PDU 3|
	|          |   |             |   |          |
	|          |   +-------------+   |          |
	|          |   |             |   +----------+
	|          |   | netlib      |   | TDS PDU 4|
	|          |   | packet 2    |   +----------+ 
	|          |   | (partial)   |   | TDS PDU 5| 
	|          |   |             |   | (partial)| 
	+----------+   +-------------+   +----------+

I subsequently asked whether that is *really* the case:

	http://www.ethereal.com/lists/ethereal-dev/200204/msg00147.html

asking whether it's more like

	tcp                 netlib          tds
	+----------+   +-------------+   +----------+
	|          |   |             |   | TDS PDU 1|
	|          |   | netlib      |   +----------+
	|  tcp     |   | packet 1    |   |          |
	| packet   |   |             |   | TDS PDU 2|
	|          |   +-------------+   +----------+
	|          |   |             |   |          | 
	|          |   | netlib      |   |          |
	|          +---+ packet 2    +---+ TDS PDU 3|
	|          |   |             |   |          |
	|          |   +-------------+   +----------+
	|          |   |             |   |          |
	|          |   | netlib      |   | TDS PDU 4|
	|          |   | packet 3    |   +----------+  
	|          |   | (partial)   |   | TDS PDU 5|
	|          |   |             |   | (partial)|
	+----------+   +-------------+   +----------+

although it sounds as if that's not a *complete* description of the
possible behaviors - it appears, given the "last fragment" field, that

	tcp                 netlib          tds
	+----------+   +-------------+   +----------+
	|          |   |             |   | TDS PDU 1|
	|          |   | netlib      |   +----------+
	|  tcp     |   | packet 1    |   |          |
	| packet   |   |             |   |          |
	|          |   +-------------+   |          |
	|          |   |             |   | TDS PDU 2| 
	|          |   | netlib      |   |          |
	|          +---+ packet 2    +---+          |
	|          |   |             |   |          |
	|          |   +-------------+   +----------+
	|          |   |             |   |          |
	|          |   | netlib      |   | TDS PDU 4|
	|          |   | packet 3    |   +----------+  
	|          |   | (partial)   |   | TDS PDU 5|
	|          |   |             |   | (partial)|
	+----------+   +-------------+   +----------+

might, for example, also be possible.

However, the code in "dissect_netlib()" seems to assume that TDS PDUs
begin on Netlib packet boundaries - which, given that the Netlib packet
header includes a TDS PDU type, would make sense.

So some questions, to which I've not seen an answer - and that, it
appears, would have to be answered in order for a valid Netlib/TDS
dissector to be implemented! - are:

	1) Can a TDS PDU reside entirely in the *middle* of a Netlib
	   packet (so that the TDS PDU neither starts at the beginning
	   of the Netlib packet nor ends at the end of the Netlib
	   packet)?

	2) Can there be more than one TDS PDU inside a Netlib packet?

	3) What specifies the length of the Netlib packet?  The packet
	   size field in the header?

I turned the capture that was sent out into a Network Monitor capture
file, and read it in; I infer from what it says that the answer to
question 3) is "yes".

I also note that it doesn't show separate Netlib and TDS headers, which
leads me to suspect that you *don't* (at least with MS SQL) get TDS
PDUs randomly straddling Netlib packet boundaries; I suspect that my
original description above:

	a TDS packet is built from one or more Netlib fragments;

	a Netlib fragment starts with that 8-byte header and has TDS
	payload following the header;

	the last Netlib fragment of a fragmented TDS packet has the
	"last packet indicator" set to 1, and all other fragments have it
	set to 0.

is correct.