Wireshark-dev: Re: [Wireshark-dev] Malformed packet New dissector
From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Sun, 18 Feb 2007 19:50:19 -0800
your highness wrote:

The skeleton of my code that is relevant to this issue is as follows:

static guint
get_condor_pdu_len(tvbuff_t *tvb, int offset)

At least in the current version of Wireshark, a get_pdu_len routine takes three arguments, not two - the first argument is the pinfo pointer. That was changed at the end of October 2006; I don't know what Wireshark release first had that change.

static void
dissect_condor_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
 tcp_dissect_pdus(tvb, pinfo, tree, condor_desegment, 3, get_condor_pdu_len,
    dissect_condor_tcp_pdu);

As already indicated, that should be 4, not 3, as the length part of the first 4 bytes, even though the length itself only takes 3 bytes (the 3 bytes after the first byte).

I am using netcat to send files that contain Condor packets for my
tests. Attached is a captured file that contains condor packets of 42
bytes. The first packet that is tagged Malformed has 2 bytes in the
first TCP packets (0x20 and 0x00) and 40 bytes in the second TCP
packet.

I build a skeleton dissector for Condor, based on your code, with the two changes in question (three arguments to get_condor_pdu_len(), a fixed length value of 4 in the tcp_dissect_pdus() call, and, reading your capture, I don't see any malformed packets.

The TCP segments in frames 4, 6, 8, 10, 12, 14, 16, and 18 have a bunch of Condor packets in them; all but frame 4 also have a bit of the previous TCP segment frame reassembled in.

After that things don't appear to work; that might be a bug in the TCP reassembly code. I've attached the source to my skeleton Condor dissector in case anybody else wants to look at this.
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <stdio.h>
#include <string.h>
#include <memory.h>

#include <glib.h>
#include <epan/packet.h>
#include <epan/emem.h>
#include <epan/ipproto.h>
#include <epan/strutil.h>
#include <epan/dissectors/packet-tcp.h>

static int proto_condor = -1;

static int ett_condor = -1;

static guint
get_condor_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset)
{
  // total packet length in 2nd, 3rd and 4th octets of a Condor packet
fprintf(stderr, "Getting packet length, offset %d\n", offset);
fprintf(stderr, "Packet length  %u\n", tvb_get_ntoh24(tvb, offset+1));
  return tvb_get_ntoh24(tvb, offset+1);
}

static int
dissect_condor_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  if (check_col(pinfo->cinfo, COL_PROTOCOL))
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Condor");

  if (check_col(pinfo->cinfo, COL_INFO))
    col_clear(pinfo->cinfo, COL_INFO);

  if (tree)
    proto_tree_add_item(tree, proto_condor, tvb, 0, -1, FALSE);

  return tvb_length(tvb);
}

static void
dissect_condor_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 4, get_condor_pdu_len,
     dissect_condor_tcp_pdu);
}

void
proto_register_condor(void)
{
  static gint *ett[] = {
    &ett_condor,
  };

  proto_condor = proto_register_protocol("Condor", "Condor", "condor");
  proto_register_subtree_array(ett, array_length(ett));
}

void
proto_reg_handoff_condor(void)
{
  dissector_handle_t condor_handle;

  condor_handle = create_dissector_handle(dissect_condor_tcp, proto_condor);

  dissector_add("tcp.port", 12100, condor_handle);
}