Wireshark-dev: Re: [Wireshark-dev] malformed packet
From: Brian Oleksa <oleksab@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 03 Mar 2010 15:17:43 -0500
Wiresharkers

I think I may have narrowed down my malformed packet problem....but I am not sure how to fix it.

It appears that my offset is just not correct. I have manually counted the bytes as I went...but I still come up with a different
value than I expected.

If I get a "unknown code"... then the packet becomes malformed. But if the code exists, it dissects the bytes properly and works fine.

Attached is the code.

Any help is greatly appreciated.

Thanks,
Brian




Eloy Paris wrote:
Hi Brian,

I think your message came only to me. Could you resend it and include the wireshark-dev list? That way the changes of getting a response are greater since I am just not seeing what can be wrong :-(

Cheers,

Eloy Paris.-
netexpect.org

On 03/03/2010 03:13 PM, Brian Oleksa wrote:
Eloy / Wiresharkers

I think I may have narrowed down my malformed packet problem....but I am
not sure how to fix it.

It appears that my offset is just not correct. I have manually counted
the bytes as I went...but I still come up with a different
value than I expected.

If I get a "unknown code"... then the packet becomes malformed. But if
the code exists, it dissects the bytes properly and works fine.

Attached is the code.

Any help is greatly appreciated.

Thanks,
Brian



Eloy Paris wrote:
On 03/02/2010 08:48 AM, Brian Oleksa wrote:

Does anybody know why I am getting a malformed packet..??

The data in the wireshark gui looks perfect (I hard coded the packet so
I am seeing what I am expecting to see)...
but at the end of every packet there is this ugly pink "Malformed
Packet".

Anybody have any ideas..??

Without seeing the packet it's hard to say what is malformed about it.
Could be missing data, a field with invalid data, etc. Can you tell us
how you crafted this packet?

Cheers,

Eloy Paris.-
netexpect.org

/* ***** BEGIN LICENSE BLOCK *****
 * Version: DCSPL 1.1
 *
 * The contents of this file are subject to the Dark Corner Software Public
 * License Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License.  You may obtain a copy of the License at
 * http://www.darkcornersoftware.com/DCSPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * The Initial Developer of the Original Code is Dark Corner Software LLC.
 * Portions created by Dark Corner Software LLC are Copyright (C) 2007 Dark
 * Corner Software LLC.  All Rights Reserved.
 *
 * Contributor(s):
 *   None
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <glib.h>
#include <epan/packet.h>
#include <time.h>
#include <string.h>

#define PROTO_TAG_HELEN    "HELEN"

static int proto_helen = -1;

static dissector_handle_t helen_handle;

void dissect_helen(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);

/*The following port is registered with IANA*/
static int helen_port = 5136;

static const char *mon_names[12] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};

static const value_string helen_gps_status[] = {
	{ 0, "Good" },
	{ 1, "No Fix" },
	{ 2, "Bad GPS Read" },
	{ 0, NULL }
};

/*not used*/
static const range_string helen_code[] = {
    {0x8000, 0xfffe, "Experimental"},
    {0xffff, 0xffff, "Encryption Extension"},
    {0, 0, "Tail"},
    {1, 1, "GPS Extension"},
    {2, 2, "Flow Extension"},
    {3, 3, "Host Extension"},
    {4, 4, "File Extension"},
    {5, 999, "Reserved"},
    {1000, 1000, "Minotaur SA Extension"},
    {16000, 32767, "Unassigned"},
    {0, 0, NULL}
};

static gint hf_helen_magic = -1;
static gint hf_helen_checksum = -1;
static gint hf_helen_txTime = -1;

static gint hf_helen = -1;
static gint hf_helen_time = -1;
static gint hf_helen_ipv4 = -1;
static gint hf_helen_ipv6 = -1;
static gint hf_helen_nos = -1;
static gint hf_helen_flowname = -1;
static gint hf_helen_longitude = -1;
static gint hf_helen_latitude = -1;
static gint hf_helen_altitude = -1;
static gint hf_helen_bearing = -1;
static gint hf_helen_speed = -1;
static gint hf_helen_sequence_num = -1;
static gint hf_helen_gpsstatus = -1;
static gint hf_helen_source = -1;

/*not used*/
static gint hf_helen_code = -1;

static gint ett_helen = -1;

void dissect_helen(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {

    proto_item *helen_item = NULL;
    proto_item *helen_sub_item = NULL;
    proto_tree *helen_tree = NULL;
    proto_tree *helen_header_tree = NULL;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_HELEN);
    col_clear(pinfo->cinfo, COL_INFO);

    if (tree) {
        guint32 offset = 0;
        guint32 orig_offset = 18;
        nstime_t t;
		guint64 msecs_since_the_epoch;
		struct tm *tmp;
        helen_item = proto_tree_add_item(tree, proto_helen, tvb, 0, -1, FALSE);
        helen_tree = proto_item_add_subtree(helen_item, ett_helen);
        helen_header_tree = proto_item_add_subtree(helen_item, ett_helen);
        helen_sub_item = proto_tree_add_item(helen_tree, hf_helen_magic, tvb, offset, 2, FALSE);
        offset += 2;
		helen_sub_item = proto_tree_add_item(helen_tree, hf_helen_checksum, tvb, offset, 8, FALSE);
		offset += 8;

		msecs_since_the_epoch = tvb_get_ntoh64(tvb, offset);
		t.secs = msecs_since_the_epoch/1000;
		t.nsecs = (msecs_since_the_epoch%1000)*1000000;	/* milliseconds to nanoseconds */
		tmp = gmtime(&t.secs);

        proto_tree_add_time_format(helen_tree, hf_helen_txTime, tvb, offset, 8, &t,
            "Date: %s %2d, %d %02d:%02d:%02d UTC",mon_names[tmp->tm_mon],tmp->tm_mday,
			tmp->tm_year + 1900,tmp->tm_hour,tmp->tm_min,tmp->tm_sec,(long)t.nsecs);

	/*not used*/
		//proto_tree_add_uint_format(helen_tree, hf_helen_txTime, tvb, offset, 8, msecs_since_the_epoch,
		//	"Date: %s %2d, %d %02d:%02d:%02d UTC",mon_names[tmp->tm_mon],tmp->tm_mday,
		//	tmp->tm_year + 1900,tmp->tm_hour,tmp->tm_min,tmp->tm_sec, msecs_since_the_epoch%1000);

        helen_header_tree = proto_item_add_subtree(helen_sub_item, ett_helen);
        {
            #define MAX_BUFFER 100
			char *buf = (char*)ep_alloc(MAX_BUFFER);
            char * packet_name = "";
            proto_tree *helen_sub_tree = NULL;
            offset = 18;

            for (;;) {
                guint16 code;
                guint16 numBytes = 0;
                guint unknownPacket = 0;
                guint codeOffset;
                offset = orig_offset;
		    	code = tvb_get_ntohs(tvb, offset);
                codeOffset = offset;
                offset += 2;
                numBytes = tvb_get_ntohs(tvb, offset);
                offset += 2;

                switch (code) {
                    case 0: packet_name = "End of Packet";
                        break;
                    case 1: packet_name = "GPS Extension";
                        break;
                    case 2: packet_name = "Flow Extension";
                        break;
                    case 3: packet_name = "Host Extension";
                        break;
                    default: packet_name = "Unknown code";
                        unknownPacket = 1;
                        break;
                }

			/*not used*/
				//proto_tree_add_item(tree, hf_helen_code, tvb, offset, 2, FALSE);

                g_snprintf(buf, MAX_BUFFER, "%s", packet_name);

                if (unknownPacket) {
                    g_snprintf(buf, MAX_BUFFER, "Unknown packet: %d", code);
                }

                helen_item = proto_tree_add_text(tree, tvb, codeOffset, 2, "%s", buf);
                helen_sub_tree = proto_item_add_subtree(helen_item, ett_helen);

                if (code == 0) {
                    break;
                }

                /* GPS: */
                if (code == 1) {
                    guint8 fieldsAvail;
                    fieldsAvail = tvb_get_guint8(tvb, offset);
                    offset += 1;

                    /* Status: */
                    if ((fieldsAvail & 1) != 0) {
                 		proto_tree_add_uint(helen_sub_tree, hf_helen_gpsstatus ,tvb , offset, 1, FALSE);
                        offset += 1;
                    }

                    /* Time: */
                    if ((fieldsAvail & 2) != 0) {
						nstime_t t;
						guint64 msecs_since_the_epoch;
						struct tm *tmp;
					    msecs_since_the_epoch = tvb_get_ntoh64(tvb, offset);
						t.secs = msecs_since_the_epoch/1000;
						t.nsecs = (msecs_since_the_epoch%1000)*1000000;	/* milliseconds to nanoseconds */
						tmp = gmtime(&t.secs);
                        proto_tree_add_time_format(helen_sub_tree, hf_helen_time, tvb, offset, 8, &t,
                                "Date: %s %2d, %d %02d:%02d:%02d UTC",mon_names[tmp->tm_mon],tmp->tm_mday,
								tmp->tm_year + 1900,tmp->tm_hour,tmp->tm_min,tmp->tm_sec,(long)t.nsecs);
                        offset += 8;
                    }

                    /* Longitude: */
                    if ((fieldsAvail & 4) != 0) {
                        proto_tree_add_item(helen_sub_tree, hf_helen_longitude, tvb, offset, 4, FALSE);
                        offset += 4;
                    }

                    /* Latitude: */
                    if ((fieldsAvail & 8) != 0) {
                        proto_tree_add_item(helen_sub_tree, hf_helen_latitude, tvb, offset, 4, FALSE);
                        offset += 4;
                    }

                    /* Altitude: */
                    if ((fieldsAvail & 16) != 0) {
                        proto_tree_add_item(helen_sub_tree, hf_helen_altitude, tvb, offset, 4, FALSE);
                        offset += 4;
                    }

                    /* Bearing: */
                    if ((fieldsAvail & 32) != 0) {
                        proto_tree_add_item(helen_sub_tree, hf_helen_bearing, tvb, offset, 4, FALSE);
                        offset += 4;
                    }

                    /* Speed: */
                    if ((fieldsAvail & 64) != 0) {
                        gfloat speed;
                        speed = tvb_get_ntohieee_float(tvb,offset);;
                        if (speed != 0.0) {
							proto_tree_add_item(helen_sub_tree, hf_helen_speed, tvb, offset, 4, FALSE);
                        }
                        offset += 4;
                    }

                    /* Number of Satellites: */
                    if ((fieldsAvail & 128) != 0) {
                        proto_tree_add_item(helen_sub_tree, hf_helen_nos, tvb, offset, 1, FALSE);
                        offset += 1;
                    }
                }

                /* FLOW: */
                if (code == 2) {
                    proto_tree_add_item(helen_sub_tree, hf_helen_flowname, tvb, offset, 8, FALSE);
                    offset += 8;

                    /* Sequence number: */
        			proto_tree_add_item(helen_sub_tree, hf_helen_sequence_num, tvb, offset, 4, FALSE);
                    offset += 4;

                    if (numBytes == 16) {
					   /* Source: */
					   proto_tree_add_item(helen_sub_tree, hf_helen_source, tvb, offset, 4, FALSE);
					   offset += 4;
                    }
                }

                /* HOST: */
                if (code == 3) {
                    /* Size: */
                    guint8 size;
                    size = tvb_get_guint8(tvb, offset);
                    offset += 1;

                    if (size == 4) {
                        proto_tree_add_item(helen_sub_tree, hf_helen_ipv4, tvb, offset, 4, FALSE);
                        offset += 4;
                    } else
                    {
						proto_tree_add_item(helen_sub_tree, hf_helen_ipv6, tvb, offset, 16, FALSE);
						offset += 16;
					}
			    }
                orig_offset += numBytes + 4;
            }
        }
    }
}

void proto_reg_handoff_helen(void) {
    static gboolean initialized = FALSE;

        if (!initialized) {
            helen_handle = create_dissector_handle(dissect_helen, proto_helen);
            dissector_add("udp.port", helen_port, helen_handle);
        }
    initialized = TRUE;
}

void proto_register_helen(void) {
    static hf_register_info hf[] = {
        { &hf_helen,
            { "Data", "helen.data", FT_NONE, BASE_NONE, NULL, 0x0,
                "HELEN PDU", HFILL}},
        { &hf_helen_magic,
            { "Magic Number", "helen.magicNumber", FT_UINT8, BASE_HEX, NULL, 0x0,
                NULL, HFILL}},
        { &hf_helen_checksum,
           { "Checksum", "helen.checksum", FT_UINT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL}},
        { &hf_helen_txTime,
            { "System Tx Time", "helen.SystemTxTime", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
                NULL, HFILL}},
        { &hf_helen_time,
	        { "Time", "helen.time", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
	            NULL, HFILL}},
	    { &hf_helen_ipv4,
			{ "IPv4", "helen.ipv4address", FT_IPv4, BASE_NONE, NULL, 0x0,
	            NULL, HFILL}},
	    { &hf_helen_ipv6,
			{ "IPv6", "helen.ipv6address", FT_IPv6, BASE_NONE, NULL, 0x0,
	            NULL, HFILL}},
        { &hf_helen_sequence_num,
			{ "Sequence Number", "helen.sequenceNumber", FT_UINT32, BASE_DEC, NULL, 0x0,
                NULL, HFILL}},
        { &hf_helen_source,
			{ "Source", "helen.source", FT_UINT32, BASE_DEC, NULL, 0x0,
                NULL, HFILL}},
        { &hf_helen_nos,
			{ "Number of Satellites", "helen.numberOfSatellites", FT_UINT8, BASE_DEC, NULL, 0x0,
			NULL, HFILL}},
		{ &hf_helen_flowname,
			{ "Flowname", "helen.flowname", FT_STRING, BASE_NONE, NULL, 0x0,
			NULL, HFILL}},
		{ &hf_helen_gpsstatus,
			{ "GPS Status", "helen.gpsStatus", FT_UINT8, BASE_DEC, VALS(helen_gps_status), 0x0,
			NULL, HFILL}},
	/*not used*/
		{ &hf_helen_code,
			{ "Packet COde", "helen.packetCode", FT_UINT8, BASE_DEC, VALS(helen_code), 0x0,
			NULL, HFILL}},
	/**/
		{ &hf_helen_longitude,
			{ "Longitude", "helen.longitude", FT_FLOAT, BASE_DEC, NULL, 0x0,
			NULL, HFILL}},
		{ &hf_helen_latitude,
			{ "Latitude", "helen.latitude", FT_FLOAT, BASE_DEC, NULL, 0x0,
			NULL, HFILL}},
		{ &hf_helen_altitude,
			{ "Altitude", "helen.altitude", FT_FLOAT, BASE_DEC, NULL, 0x0,
			NULL, HFILL}},
		{ &hf_helen_bearing,
			{ "Bearing", "helen.bearing", FT_FLOAT, BASE_DEC, NULL, 0x0,
			NULL, HFILL}},
		{ &hf_helen_speed,
			{ "Speed", "helen.speed", FT_FLOAT, BASE_DEC, NULL, 0x0,
			NULL, HFILL}},
    };

    static gint * ett[] = {&ett_helen};

    proto_helen = proto_register_protocol("HELEN", "HELEN", "helen");
    proto_register_field_array(proto_helen, hf, array_length(hf));
    proto_register_subtree_array(ett, array_length(ett));
    register_dissector("helen", dissect_helen, proto_helen);
}