Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Wireshark-dev: [Wireshark-dev] question regarding my wireshark dissector code.

From: Brian Oleksa <oleksab@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 02 Jul 2009 14:49:04 -0400

@Wiresharkers

I have created this helen dissector. It has been running great ever since then.

I have some NON-helen packets that I want to dissect. Instead of writing another dissector, I added it to the packet-helen.c code.

As you can see at the top of this file I call a new procedure called:
void proto_reg_handoff_netalive(void)

Which works great and reads in the port # from the file correctly.

I even get into the void dissect_netalive(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) procedure with no problems:

But I am not dissecting anything. The only thing that I get in the wireshark GUI is the word "NETALIVE".

Why I am not seeing the dissection tree under the NETALIVE protocol....??

Basically.......all I did was I mirrored the helen protocol....it compiles fine but I do not see my packets being dissected.

Any thoughts or suggestions...? The latest code is attached.

Thank you very much for your help.

It is greatly appreciated.

Brian


/* packet-helen.c
 */

#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"

#define PROTO_TAG_NETALIVE    "NETALIVE"

/* Wireshark ID of the HELEN protocol */
static int proto_helen = -1;
static int proto_netalive = -1;


/* These are the handles of our subdissectors */
static dissector_handle_t data_handle = NULL;
static dissector_handle_t netalivedata_handle = NULL;

static dissector_handle_t helen_handle;

static dissector_handle_t netalive_handle;

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

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

//You now put your ports in the ports file
//this port can be changed to whatever port SA is running on.
//static int global_helen_port = 7636;

static const value_string packettypenames[] = {
    { 0, "TEXT"
    },
    { 1, "SOMETHING_ELSE"
    },
    { 0, NULL
    }
};

// Declarations:
int numBytesInMode(int numBits);
int numBytesInBitmask(int numBits);


/* The following hf_* variables are used to hold the Wireshark IDs of
 * our header fields; they are filled out when we call
 * proto_register_field_array() in proto_register_helen()
 */
/** Kts attempt at defining the protocol */
static gint hf_helen = -1;
//static gint hf_helen_header = -1;
static gint hf_helen_length = -1;
static gint hf_helen_type = -1;
static gint hf_helen_text = -1;

static gint hf_netalive = -1;
//static gint hf_helen_header = -1;
static gint hf_netalive_length = -1;
static gint hf_netalive_type = -1;
static gint hf_netalive_text = -1;

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

/* These are the ids of the subtrees that we may be creating */
static gint ett_helen = -1;
static gint ett_helen_header = -1;
static gint ett_helen_length = -1;
static gint ett_helen_type = -1;
static gint ett_helen_text = -1;

static gint ett_netalive = -1;
static gint ett_netalive_header = -1;
static gint ett_netalive_length = -1;
static gint ett_netalive_type = -1;
static gint ett_netalive_text = -1;

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

    int portnumber;

    FILE *fp;
#if defined(_WIN32)
    fp = fopen("ports.txt", "r");
#else
	fp = fopen("ports", "r");
#endif

    if (fp == NULL) {
        printf("Can't open the ports file! \n");
        printf("Make sure the file exists where the wireshark executable lives at \n");
        exit(1);
    }

    while (fscanf(fp, "%d\n", &portnumber) != EOF) {

        printf("Port number = %d\n", portnumber);

        if (!initialized) {
            data_handle = find_dissector("data");
            helen_handle = create_dissector_handle(dissect_helen, proto_helen);
            //This is to be used for hard coded ports (see static variable above)
            //dissector_add("udp.port", global_helen_port, helen_handle);

            //This line read the port number from the file.
            dissector_add("udp.port", portnumber, helen_handle);
        }

    }

   fclose(fp);  
}

void proto_reg_handoff_netalive(void) {
    static gboolean isinitialized = FALSE;

    static gboolean isnetalivefilehere = TRUE;
    int netaliveportnumber;

    FILE *fpnetalive;

#if defined(_WIN32)
    fpnetalive = fopen("netaliveport.txt", "r");
#else
    fpnetalive = fopen("netaliveport", "r");
#endif

    if (fpnetalive == NULL) {
        printf("Can't open the netalive ports file! \n");
        printf("Make sure the file exists where the wireshark executable lives at \n");
        isnetalivefilehere = FALSE;
        //exit(1);
    }

//if netalive ports file is there....then go into this loop.
//if it is not there then just continue on.
   if(isnetalivefilehere)
   {
    while (fscanf(fpnetalive, "%d\n", &netaliveportnumber) != EOF) {

        printf("Net Alive Port number = %d\n", netaliveportnumber);

        if (!isinitialized) {
            netalivedata_handle = find_dissector("data");
            netalive_handle = create_dissector_handle(dissect_netalive, proto_netalive);
	    printf("I am here 1\n");
            //This line read the port number from the file.
            dissector_add("udp.port", netaliveportnumber, netalive_handle);
        }

    }
   }
    
    fclose(fpnetalive);

}


void proto_register_helen(void) {
    /* A header field is something you can search/filter on.
     *
     * This creates a structure to register our fields. It consists of an
     * array of hf_register_info structures, each of which are of the format
     * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
     */
    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.header", FT_BYTES, BASE_HEX, NULL, 0x0,
                "HELEN Header", HFILL
            }
        },

        { &hf_helen_checksum,
            { "Checksum", "helen.header", FT_UINT64, BASE_DEC, NULL, 0x0,
                "HELEN Header", HFILL
            }
        },

        { &hf_helen_txTime,
            { "System Tx Time", "helen.header", FT_UINT64, BASE_DEC, NULL, 0x0,
                "HELEN Header", HFILL
            }
        },

        { &hf_helen_length,
            { "Package Length2", "helen.len", FT_UINT32, BASE_DEC, NULL, 0x0,
                "Package Length3", HFILL
            }
        },
        { &hf_helen_type,
            { "Type", "helen.type", FT_UINT8, BASE_DEC, VALS(packettypenames), 0x0,
                "Package Type", HFILL
            }
        },
        { &hf_helen_text,
            { "Text", "helen.text", FT_STRING, BASE_NONE, NULL, 0x0,
                "Text", HFILL
            }
        }
    };

    static gint * ett[] = {
        &ett_helen,
        &ett_helen_header,
        &ett_helen_length,
        &ett_helen_type,
        &ett_helen_text,
    };

    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);

}

void proto_register_netalive(void) {
    /* A header field is something you can search/filter on.
     *
     * This creates a structure to register our fields. It consists of an
     * array of hf_register_info structures, each of which are of the format
     * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
     */
    static hf_register_info hf[] = {
        { &hf_netalive,
            { "Data", "netalive.data", FT_NONE, BASE_NONE, NULL, 0x0,
                "NETALIVE PDU", HFILL
            }
        },

        { &hf_netalive_length,
            { "Package Length2", "netalive.len", FT_UINT32, BASE_DEC, NULL, 0x0,
                "Package Length3", HFILL
            }
        },
        { &hf_netalive_type,
            { "Type", "helen.type", FT_UINT8, BASE_DEC, VALS(packettypenames), 0x0,
                "Package Type", HFILL
            }
        },
        { &hf_netalive_text,
            { "Text", "netalive.text", FT_STRING, BASE_NONE, NULL, 0x0,
                "Text", HFILL
            }
        }
    };

    static gint * ett[] = {
        &ett_netalive,
        &ett_netalive_header,
        &ett_netalive_length,
        &ett_netalive_type,
        &ett_netalive_text,
    };
    
    proto_netalive = proto_register_protocol("NETALIVE", "NETALIVE", "netalive");

    proto_register_field_array(proto_netalive, hf, array_length(hf));
    proto_register_subtree_array(ett, array_length(ett));
    register_dissector("netalive", dissect_netalive, proto_netalive);
}

static const value_string helen_vals[] = {
    {1, "GPS"},
    {2, "Flow"},
    {3, "Host"},
    {1000, "Minotaur SA Extension"},
    {1002, "Minotaur SA Status Extension"},
    {1003, "Minotaur SA Redline Aspect Extension"},
    {1013, "Leger Extension"},
    {1024, "Alares Data Extension"},
    {1025, "Alares Control Extension"}
};

guint16 swap16(guint16 in) {
    guint8 high = (in >> 8) & 0xff;
    guint8 low = in & 0xff;
    guint16 newVal = (low << 8) | high;
    return newVal;
}

guint32 swap32(guint32 in) {
    guint8 b1 = (in >> 24) & 0xff;
    guint8 b2 = (in >> 16) & 0xff;
    guint8 b3 = (in >> 8) & 0xff;
    guint8 b4 = in & 0xff;
    guint32 newVal = (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;
    return newVal;
}

//time converter method here
//int txTime()
//{
//   time_t now;
//   struct tm *ts;
//   char buf[80];

//   now = time(NULL);

//   ts = localtime(&now);
//   return strftime(buf, sizeof (buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);

//return value;
//}

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

    proto_item *netalive_item = NULL;
    proto_item *netalive_sub_item = NULL;
    proto_tree *netalive_tree = NULL;
    proto_tree *netalive_header_tree = NULL;
    guint16 type = 0;
printf("I am here 2\n");

    if (check_col(pinfo->cinfo, COL_PROTOCOL))
        col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_NETALIVE);
    /* Clear out stuff in the info column */
    if (check_col(pinfo->cinfo, COL_INFO)) {
        col_clear(pinfo->cinfo, COL_INFO);
    }

    // This is not a good way of dissecting packets.  The tvb length should
    // be sanity checked so we aren't going past the actual size of the buffer.
    type = tvb_get_guint8(tvb, 4); // Get the type byte


    if (check_col(pinfo->cinfo, COL_INFO)) {
        col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d Info Type:[%s]",
                pinfo->srcport, pinfo->destport,
                val_to_str(type, packettypenames, "Unknown Type:0x%02x"));
    }

printf("I am here 3\n");

    if (tree) { /* we are being asked for details */
        guint32 offset = 0;

        netalive_item = proto_tree_add_item(tree, proto_netalive, tvb, 0, -1, FALSE);

        netalive_tree = proto_item_add_subtree(netalive_item, ett_netalive);
        netalive_header_tree = proto_item_add_subtree(netalive_item, ett_netalive);


        netalive_header_tree = proto_item_add_subtree(netalive_sub_item, ett_netalive);
        {
	        guint8 * ptr = (guint8*) tvb->real_data;
                guint8 * packet_header = ptr;
                proto_tree *netalive_sub_tree = NULL;
                int swap = 1;
	        guint8 designator;
                guint8 version;
                guint8 updaterate;
                guint8 nodeId;
                char buf[100];
                //glong timestamp;
                gfloat longitude;
                gfloat latitude;
                gfloat altitude;
                guint8 altitudetype;
                guint8 radiostatus;
                guint8 networksize;
                guint16 inbound;
                guint16 outbound;
		int numOneBitsInMask;
                char * statusStr = "";
                char * tempStr = "";
                int codeOffset;
                ptr = packet_header;
                offset = (ptr - tvb->real_data);
                codeOffset = offset;

            //guint16 bead;
            //char * packet_name = "";
            
            // Hardcoding to ALWAYS SWAP as we don't know how to detect when to swap!
            
	    //int i;
		printf("I am here 4\n");
            //for (;;) {
	    //if (1==1)	{	
		
		printf("I am here 5\n");

//                if (swap) {
//                    code = swap16(code);
//                }
//
//                ptr += 1;
//                offset += 1;
//                numBytes = *((guint16*) ptr);
//                if (swap) {
//                    numBytes = swap16(numBytes);
//                }
                //NetAlive

               //NetAlive designator
		designator = * ((guint8*) ptr);
                ptr += 1;

                proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 1, 0,
                        "Net Alive Designator : %d", designator);

                offset += 1;

                //NetAlive version
                version = * ((guint8*) ptr);
                ptr += 1;

                proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 1, 0,
                        "Net Alive version : %d", version);

                offset += 1;

                //NetAlive update rate
                updaterate = * ((guint8*) ptr);
                ptr += 1;

                proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 1, 0,
                        "Net Alive update rate : %d", updaterate);

                offset += 1;

                //Source node ID
                nodeId = * ((guint8*) ptr);
                ptr += 1;

                proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 1, 0,
                        "Source Node ID : %d", nodeId);

                offset += 1;


                //Time Stamp....
                //this is just getting system time....and not the time off the radio.
                //However...the radios time should be the same at the system time
                //time_t now;
                //struct tm *ts;
                //char buf[80];
                // now = time(NULL);
                ptr += 8;
                // ts = localtime(&now);
                // strftime(buf, sizeof (buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
                // proto_tree_add_uint_format(netalive_sub_tree, hf_helen_length, tvb, offset, 8, 0,
                //         "%s", buf);
                offset += 8;

                //GPS Latitude
                latitude = *((gfloat*) ptr);
                if (swap) {
                    guint32 temp = *((guint32*) ptr);
                    temp = swap32(temp);
                    latitude = *((gfloat*) & temp);
                }
                ptr += 4;

                proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 4, 0,
                        "Latitude: %f", latitude);
                offset += 4;

                //GPS Longitude
                longitude = *((gfloat*) ptr);
                if (swap) {
                    guint32 temp = *((guint32*) ptr);
                    temp = swap32(temp);
                    longitude = *((gfloat*) & temp);
                }
                ptr += 4;

                proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 4, 0,
                        "Longitude: %f", longitude);
                offset += 4;


                //GPS Altitude:
                altitude = *((gfloat*) ptr);
                if (swap) {
                    guint32 temp = *((guint32*) ptr);
                    temp = swap32(temp);
                    altitude = *((gfloat*) & temp);
                }
                ptr += 4;

                proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 4, 0,
                        "Altitude: %f", altitude);
                offset += 4;

                //GPS Altitude type
                altitudetype = * ((guint8*) ptr);
                if ( (altitudetype & 1) == 0) {
                    statusStr = "Sea Level in ";
                } else {
                    statusStr = "High above ellipsoid (HAE) in ";
                }
                if ( (altitudetype & 2) == 0) {
                    tempStr = "meters";
                } else {
                    tempStr = "feet";
                }

                proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 1, 0,
                        "%s%s", statusStr, tempStr);
                ptr += 1;
                offset += 1;

                //Radio status and alerts
                radiostatus = * ((guint8*) ptr);
                buf[0] = (char)0;
                if ((radiostatus & 1) == 1) {
                    strcat(buf,"BIT Fail,");
                } else if ((radiostatus & 2) == 1) {
                    strcat(buf,"No GPS,");
                } else if ((radiostatus & 4) == 1) {
                    strcat(buf,"Login Alert,");
                }
                // We could rip out the ending comma (if it exists!) by trying the following:
                {
                    char* p2; // Put this at the top!

                    if (strlen(buf) > 0) {
                       p2 = buf + strlen(buf) - 1;
                       *p2 = (char)0;
                    }
                }

                proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 1, 0,
                        "%s", buf);
                ptr += 1;
                offset += 1;

                //Network size
                networksize = * ((guint8*) ptr);
                ptr += 1;

                proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 1, 0,
                        "Network size : %d", networksize);

                offset += 1;

                //SPARE....so I am skipping this slot.

                ptr += 1;
                offset += 1;

                //Inbound throughput
                inbound = * ((guint16*) ptr);
                if (swap) {
                    inbound = swap16(inbound);
                }
                ptr += 2;

                proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 2, 0,
                        "Inbound throughput : %d", inbound);

                offset += 2;

                //Outbound throughput
                outbound = * ((guint16*) ptr);
                if (swap) {
                    outbound = swap16(outbound);
                }
                ptr += 2;

                proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 2, 0,
                        "Outbound throughput : %d", outbound);

                offset += 2;

                //Waveform Bitmask
		numOneBitsInMask = 0;
                {
		    int i;
		    char buf2[10];
		    int numBytes = numBytesInBitmask(networksize);

		    buf[0] = (char)0;
                    for (i = 0; i < numBytes; i++) {
		        guint8 val = *((guint8*)ptr);
			if (val & 1) numOneBitsInMask++;
			if (val & 2) numOneBitsInMask++;
			if (val & 4) numOneBitsInMask++;
			if (val & 8) numOneBitsInMask++;
			if (val & 16) numOneBitsInMask++;
			if (val & 32) numOneBitsInMask++;
			if (val & 64) numOneBitsInMask++;
			if (val & 128) numOneBitsInMask++;
			sprintf(buf2,"%x",val);
			strcat(buf,buf2);
			ptr++;
		    }
                    proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, numBytes, 0,
                        "Waveform Bitmask : %s", buf);
		    offset += numBytes;
                }


                //Waveform Mode
                {
		    int i;
		    char buf2[10];
		    int numBytes = numBytesInMode(numOneBitsInMask);

		    buf[0] = (char)0;
                    for (i = 0; i < numBytes; i++) {
		        guint8 val = *((guint8*)ptr);
		        // This would be nice:
		        //  17: BPSK 4
			sprintf(buf2,"%x",val);
			strcat(buf,buf2);
			ptr++;
		    }
                    proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, numBytes, 0,
                        "Waveform Mode : %s", buf);
		    offset += numBytes;
		    printf("I am here... 6\n");
                }

            //}
        }
    }
}

int numBytesInBitmask(int numBits){
  int q = numBits / 8;
  int extraBits = numBits % 8;
//printf("I am here... 7\n");
  if (extraBits > 0) {
    q++;
  }
  return q;
}

int numBytesInMode(int numBits){
  int q = numBits / 2;
  int extraBits = numBits % 2;

  if (extraBits > 0) {
    q++;
  }
  return q;
}


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;
    guint16 type = 0;
    printf("Inside dissect_helen 1\n");

    if (check_col(pinfo->cinfo, COL_PROTOCOL))
        col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_HELEN);
    /* Clear out stuff in the info column */
    if (check_col(pinfo->cinfo, COL_INFO)) {
        col_clear(pinfo->cinfo, COL_INFO);
    }

    // This is not a good way of dissecting packets.  The tvb length should
    // be sanity checked so we aren't going past the actual size of the buffer.
    type = tvb_get_guint8(tvb, 4); // Get the type byte


    if (check_col(pinfo->cinfo, COL_INFO)) {
        col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d Info Type:[%s]",
                pinfo->srcport, pinfo->destport,
                val_to_str(type, packettypenames, "Unknown Type:0x%02x"));
    }

    if (tree) { /* we are being asked for details */
        guint32 offset = 0;

	printf("Inside dissect_helen 2\n");

        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_header, tvb, offset, -1, FALSE);
        helen_sub_item = proto_tree_add_item(helen_tree, hf_helen_magic, tvb, 0, 2, FALSE);
        helen_sub_item = proto_tree_add_item(helen_tree, hf_helen_checksum, tvb, 2, 8, FALSE);

        //helen_sub_item = proto_tree_add_item(helen_tree, hf_helen_txTime, tvb, 10, 8, FALSE);
        //need to format the time..!!
        helen_sub_item = proto_tree_add_item(helen_tree, hf_helen_txTime, tvb, 10, 8, FALSE);

        helen_header_tree = proto_item_add_subtree(helen_sub_item, ett_helen);

        {
            guint8 * ptr = (guint8*) tvb->real_data;
            guint8 * packet_header = ptr;
            guint16 bead;
            char buf[100];
            char * packet_name = "";
            proto_tree *helen_sub_tree = NULL;
            int swap = 0;

            bead = *((guint16*) packet_header);
            if (bead != 0xBEAD) {
                swap = 1;
            }

            offset += 18;
            ptr += 18; /* Skip the header.*/
            packet_header = ptr;

		printf("Inside dissect_helen 3\n");

            for (;;) {
                guint16 code = *((guint16*) packet_header);
                guint16 numBytes = 0;
                int unknownPacket = 0;
                int codeOffset;
                ptr = packet_header;
                // Must re-set the offset because of Flow control messages that specify only 12 bytes, but actually contain 16:
                offset = (ptr - tvb->real_data);
                codeOffset = offset;

		printf("Inside dissect_helen 4\n");

                if (swap) {
                    code = swap16(code);
                }

                ptr += 2;
                offset += 2;
                numBytes = *((guint16*) ptr);
                if (swap) {
                    numBytes = swap16(numBytes);
                }

                ptr += 2;
                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;
                    case 1000: packet_name = "Minotaur SA";
                        break;
                    case 1002: packet_name = "Minotaur SA Status Ext";
                        break;
                    case 1003: packet_name = "Minotaur SA Redline Aspect Ext";
                        break;
                    case 1013: packet_name = "Leger Ext";
                        break;
                    case 1024: packet_name = "Alares Data Ext";
                        break;
                    case 1025: packet_name = "Alares Control Ext";
                        break;
                    default: packet_name = "Unknown code";
                        unknownPacket = 1;
                        break;
                }
                //strcpy(buf, "Packet Code ");
                strcpy(buf, " ");
                strcat(buf, packet_name);
                if (unknownPacket) {
                    sprintf(buf, "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 = *((guint8*) ptr);
                    ptr += 1;
                    offset += 1;

                    //printf("%s \n", "This is the GPS Extension");

                    // Status:
                    if ((fieldsAvail & 1) != 0) {
                        guint8 status;
                        char * statusStr = "";
                        status = *((guint8*) ptr);
                        if (status == 0) {
                            statusStr = "Good";
                        } else if (status == 1) {
                            statusStr = "No Fix";
                        } else if (status == 2) {
                            statusStr = "Bad GPS Read";
                        }
                        proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 1, 0,
                                "%s", statusStr);
                        ptr += 1;
                        offset += 1;
                    }

                    // Time: ...This is the first attempt at time
                    //if ( (fieldsAvail & 2) != 0) {
                    //guint32 halfTime1, halfTime2;
                    //halfTime1 = *((guint32*)ptr);
                    //ptr += 4;
                    //halfTime2 = *((guint32*)ptr);
                    //ptr += 4;

                    //scanf("%X",halfTime1);
                    //printf("%f",halfTime1);

                    //proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 8, 0,
                    //  "Time: %X %X", halfTime1, halfTime2);
                    //offset += 8;
                    //}




                    // Time:
                    //this is just getting system time....and not the time of the GPS.
                    //However...the GPS time should be the same at the system time
                    if ((fieldsAvail & 2) != 0) {
                        time_t now;
                        struct tm *ts;
                        char buf[80];
                        now = time(NULL);
                        ptr += 8;
                        ts = localtime(&now);
                        strftime(buf, sizeof (buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
                        proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 8, 0,
                                "%s", buf);
                        offset += 8;
                    }


                    // Longitude:
                    if ((fieldsAvail & 4) != 0) {
                        gfloat longitude;
                        longitude = *((gfloat*) ptr);
                        if (swap) {
                            guint32 temp = *((guint32*) ptr);
                            temp = swap32(temp);
                            longitude = *((gfloat*) & temp);
                        }
                        ptr += 4;

                        proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                                "Longitude: %f", longitude);
                        offset += 4;
                    }

                    // Latitude:
                    if ((fieldsAvail & 8) != 0) {
                        gfloat latitude;
                        latitude = *((gfloat*) ptr);
                        if (swap) {
                            guint32 temp = *((guint32*) ptr);
                            temp = swap32(temp);
                            latitude = *((gfloat*) & temp);
                        }
                        ptr += 4;

                        proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                                "Latitude: %f", latitude);
                        offset += 4;
                    }

                    // Altitude:
                    if ((fieldsAvail & 16) != 0) {
                        gfloat altitude;
                        altitude = *((gfloat*) ptr);
                        if (swap) {
                            guint32 temp = *((guint32*) ptr);
                            temp = swap32(temp);
                            altitude = *((gfloat*) & temp);
                        }
                        ptr += 4;

                        proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                                "Altitude: %f", altitude);
                        offset += 4;
                    }

                    // Bearing:
                    if ((fieldsAvail & 32) != 0) {
                        gfloat bearing;
                        bearing = *((gfloat*) ptr);
                        if (swap) {
                            guint32 temp = *((guint32*) ptr);
                            temp = swap32(temp);
                            bearing = *((gfloat*) & temp);
                        }
                        ptr += 4;

                        proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                                "Bearing: %f", bearing);
                        offset += 4;
                    }

                    // Speed:
                    if ((fieldsAvail & 64) != 0) {
                        gfloat speed;
                        speed = *((gfloat*) ptr);
                        if (swap) {
                            guint32 temp = *((guint32*) ptr);
                            temp = swap32(temp);
                            speed = *((gfloat*) & temp);
                        }
                        ptr += 4;
                        //If speed is NOT available or less than or equal to zero...then do not display it.
                        if (speed != 0.0) {
                            proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                                    "Speed: %f", speed);
                        }
                        offset += 4;
                    }

                    // Number of Satellites:
                    if ((fieldsAvail & 128) != 0) {
                        guint8 nos;
                        nos = *((guint8*) ptr);

                        proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 1, 0,
                                "Number of Satellites: %d", nos);
                        ptr += 1;
                        offset += 1;
                    }

                }


                // FLOW:
                if (code == 2) {
                    char flowname[9];
                    guint32 seq;
                    guint32 src;

                    //printf("This is the Flow Extension\n");

                    strncpy(flowname, ptr, 8);
                    flowname[8] = '\0';
                    ptr += 8;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 8, 0,
                            "Flowname: %s", flowname);
                    offset += 8;

                    // Sequence number:
                    seq = *((guint32*) ptr);
                    if (swap) {
                        seq = swap32(seq);
                    }
                    ptr += 4;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                            "Sequence #: %d", seq);
                    offset += 4;

                    // need to verify if this works (test with leger)
                    if (numBytes == 16) {
                        // Source:
                        src = *((guint32*) ptr);
                        if (swap) {
                            src = swap32(src);
                        }
                        ptr += 4;

                        proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                                "Source : %d", src);
                        offset += 4;
                    }

                }

                // HOST:
                if (code == 3) {
                    guint8 size;

                    //printf("%s \n", "This is the Host Extension");

                    // Size:
                    size = *((guint8*) ptr);
                    ptr += 1;
                    offset += 1;

                    if (size == 4) {
                        guint32 addr;

                        addr = *((guint32*) ptr);
                        if (swap) {
                            addr = swap32(addr);
                        }
                        ptr += 4;

                        proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                                "Address: %d.%d.%d.%d", addr >> 24, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff);
                        offset += 4;
                    }

                        //I was board so I added the IPv6 address translation here in this else statement....However..I cannot test it..but it should work.
                    else {
                        guint32 addr1, addr2, addr3, addr4;

                        addr1 = *((guint32*) ptr);
                        ptr += 4;
                        addr2 = *((guint32*) ptr);
                        ptr += 4;
                        addr3 = *((guint32*) ptr);
                        ptr += 4;
                        addr4 = *((guint32*) ptr);
                        ptr += 4;
                        if (swap) {
                            addr1 = swap32(addr1);
                            addr2 = swap32(addr2);
                            addr3 = swap32(addr3);
                            addr4 = swap32(addr4);
                        }

                        proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 16, 0,
                                "Address: %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d",
                                addr1 >> 24, (addr1 >> 16) & 0xff, (addr1 >> 8) & 0xff, addr1 & 0xff,
                                addr2 >> 24, (addr2 >> 16) & 0xff, (addr2 >> 8) & 0xff, addr2 & 0xff,
                                addr3 >> 24, (addr3 >> 16) & 0xff, (addr3 >> 8) & 0xff, addr3 & 0xff,
                                addr4 >> 24, (addr4 >> 16) & 0xff, (addr4 >> 8) & 0xff, addr4 & 0xff
                                );
                        offset += 16;

                    }

                }

                //Minotaur SA Ext:
                if (code == 1000) {
                    guint32 id;
                    //printf("%s \n", "This is the Minotaur SA Ext");
                    id = *((guint32*) ptr);
                    if (swap) {
                        id = swap32(id);
                    }
                    ptr += 4;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                            "Harmonice ID #: %d", id);
                    offset += 4;
                }

                //Minotaur SA Status Ext:
                if (code == 1002) {
                    guint32 stuff;
                    //printf("%s \n", "This is the Minotaur SA Status Ext");
                    stuff = *((guint32*) ptr);
                    //if (swap){
                    //    id = swap32(id);
                    //}
                    ptr += 4;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, numBytes, 0,
                            "Minotaur Status Ext:");
                    offset += numBytes;
                }

                //Minotaur SA Redline Aspect Ext:
                //Need more info.. Need size and data types
                if (code == 1003) {
                    guint32 stuff;
                    //printf("%s \n", "This is the Minotaur SA Redline Aspect Ext");
                    stuff = *((guint32*) ptr);
                    //if (swap){
                    //    id = swap32(id);
                    //}
                    ptr += 4;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                            "Minotaur SA Redline Aspect:");
                    offset += 4;
                }

                //Leger Ext:
                //Need more info.. Need size and data types
                if (code == 1013) {
                    guint32 stuff;
                    printf("%s \n", "This is the Leger Ext");
                    stuff = *((guint32*) ptr);
                    //if (swap){
                    //    id = swap32(id);
                    //}
                    ptr += 4;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                            "Leger Ext:");
                    offset += 4;
                }

                //Alares Data Ext:
                if (code == 1024) {
                    glong key;
                    guint32 id;
                    guint32 messageId;
                    guint32 totalBlks;
                    guint32 blockId;
                    glong theTime;
                    guint8 repairStatus;
                    char * repairStatusStr = "";

                    //time_t rightnow;
                    //struct tme *tss;
                    //char buff[80];
                    //rightnow = time(NULL);
                    //tss = localtime(&rightnow);

                    //printf("%s \n", "This is the Alares Data Ext");


                    //Alares Session Key
                    if (swap) {
                        // 64-bit swap, done as 2 32-bit swaps in the
                        guint32 temp = *((guint32*) ptr);
                        temp = swap32(temp);
                        *((guint32*) ptr) = temp;

                        temp = *((guint32*) (ptr + 4));
                        temp = swap32(temp);
                        *((guint32*) ptr + 4) = temp;
                    }
                    key = *((glong*) ptr);
                    ptr += 8;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 8, 0,
                            "Alares Session Key: %ld", key);
                    offset += 8;


                    //ID for Source
                    id = *((guint32*) ptr);
                    if (swap) {
                        id = swap32(id);
                    }
                    ptr += 4;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                            "ID for source #: %d", id);
                    offset += 4;


                    //Message ID
                    messageId = *((guint32*) ptr);
                    if (swap) {
                        messageId = swap32(messageId);
                    }
                    ptr += 4;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                            "Message ID: %d", messageId);
                    offset += 4;


                    //Total Blocks
                    totalBlks = *((guint32*) ptr);
                    if (swap) {
                        totalBlks = swap32(totalBlks);
                    }
                    ptr += 4;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                            "Total Blocks: %d", totalBlks);
                    offset += 4;


                    //Tx Time
                    if (swap) {
                        // 64-bit swap, done as 2 32-bit swaps in the
                        guint32 temp = *((guint32*) ptr);
                        temp = swap32(temp);
                        *((guint32*) ptr) = temp;

                        temp = *((guint32*) (ptr + 4));
                        temp = swap32(temp);
                        *((guint32*) ptr + 4) = temp;
                    }
                    theTime = *((glong*) ptr);
                    ptr += 8;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 8, 0,
                            "Tx Time: %ld", theTime);
                    offset += 8;


                    //Block ID
                    blockId = *((guint32*) ptr);
                    if (swap) {
                        blockId = swap32(blockId);
                    }
                    ptr += 4;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                            "Block ID #: %d", blockId);
                    offset += 4;


                    //Is Repair
                    repairStatus = *((guint8*) ptr);
                    if (repairStatus == 0) {
                        repairStatusStr = "Not Repair";
                    } else if (repairStatus == 1) {
                        repairStatusStr = "Repair";
                    }
                    ptr += 1;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 1, 0,
                            "%s", repairStatusStr);

                    offset += 1;

                }


		//Need sizes for each variable
		   //Chat
		    if (code == 2014)
			{
			    //guint16 id;
			    //char * user;
			    //glong txtime;
			    //glong rxtime;
			    //guint16 messageid;
			    //glong session;
			}

                //Wave Relay
                if (code == 2013) {
                    guint8 status;
                    guint32 mac;
                    guint8 numofrec;
                    //guint32 nodeinfo;
		    guint32 macaddr;
		    guint32 snr;
                    char * statusStr = "";
		    int i;


                    //printf("%s \n", "This is the Wave Relay Ext");

                    //status
                    status = * ((guint8*) ptr);
                    if (status == 0) {
                        statusStr = "Good";
                    } else if (status == 1) {
                        statusStr = "Stale / Not Read";
                    }

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 1, 0,
                            "%s", statusStr);
                    ptr += 1;
                    offset += 1;

                    //MAC
                    mac = * ((guint32*) (ptr - 1));
		    mac >>= 8;
                    ptr += 3;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 3, 0,
                            "MAC : %d", mac);

                    offset += 3;

                    //Number of records
                    numofrec = * ((guint8*) ptr);
                    ptr += 1;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 1, 0,
                            "Number of Records : %d", numofrec);

                    offset += 1;


		    //OLSR Node Information
		    for (i = 0; i < numofrec; i++) {

		        //MAC address
                        macaddr = * ((guint32*) ptr);
			macaddr = macaddr & 0xffffff;
                        ptr += 3;

                        proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 3, 0,
                                "MAC Address: %d", macaddr);

                        offset += 3;

    		        //SNR
    		        snr = * ((guint32*) ptr);
                        ptr += 4;

                        proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                                "SNR : %d", snr);

                        offset += 4;
		    }

                }

                //Alares Control Ext:
                if (code == 1025) {
                    glong key;
                    guint32 id;
                    //guint32 healFac;
                    gdouble healFac;
                    guint8 noem;
                    guint8 noe;
                    guint32 src;
                    guint32 message;
                    guint32 start;
                    guint32 end;
                    int index1, index2;

                    //printf("%s \n", "This is the Alares Control Ext");


                    //Alares Session Key
                    if (swap) {
                        // 64-bit swap, done as 2 32-bit swaps in the
                        guint32 temp = *((guint32*) ptr);
                        temp = swap32(temp);
                        *((guint32*) ptr) = temp;

                        temp = *((guint32*) (ptr + 4));
                        temp = swap32(temp);
                        *((guint32*) ptr + 4) = temp;
                    }
                    key = *((glong*) ptr);
                    ptr += 8;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 8, 0,
                            "Alares Session Key: %ld", key);
                    offset += 8;



                    //Unique ID for Source
                    id = *((guint32*) ptr);
                    if (swap) {
                        id = swap32(id);
                    }
                    ptr += 4;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                            "Unique ID for source: %d", id);
                    offset += 4;


                    //Healing Factor
                    if (swap) {
                        guint32 temp = *((guint32*) ptr);
                        temp = swap32(temp);
                        *((guint32*) ptr) = temp;

                        temp = *((guint32*) (ptr + 4));
                        temp = swap32(temp);
                        *((guint32*) ptr + 4) = temp;
                    }
                    healFac = *((gdouble*) ptr);

                    ptr += 8;

                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 8, 0,
                            "Healing Factor: %e", healFac);

                    offset += 8;


                    //Number of Erasures in Message
                    noem = *((guint8*) ptr);
                    proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 1, 0,
                            "Number of Erasures in Message: %d", noem);
                    ptr += 1;
                    offset += 1;

                    for (index1 = 0; index1 < noem; index1++) {
                        //Missing Data

                        //Source
                        src = *((guint32*) ptr);
                        if (swap) {
                            src = swap32(src);
                        }
                        ptr += 4;

                        proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                                "Source of Missing Data: %d", src);
                        offset += 4;


                        //Message
                        //guint32 stuff;
                        message = *((guint32*) ptr);
                        printf("%s \n", "This is the Missing Data Message");

                        ptr += 4;

                        proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, numBytes, 0,
                                "Missing Data Message:");
                        offset += numBytes;

                        //message = *((guint32*) ptr);
                        //if (swap) {
                        //    message = swap32(message);
                        //}
                        //ptr += 4;

                        //proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                        //        "Missing Data Message: %d", message);
                        //offset += 4;
                        //offset += numBytes;


                        //Number of Erasures
                        noe = *((guint8*) ptr);
                        proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 1, 0,
                                "Number of Erasures: %d", noe);
                        ptr += 1;
                        offset += 1;

                        for (index2 = 0; index2 < noe; index2++) {
                            //Erasures

                            //Starting Block
                            start = *((guint32*) ptr);
                            if (swap) {
                                start = swap32(start);
                            }
                            ptr += 4;

                            proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                                    "Starting Block: %d", start);
                            offset += 4;

                            //Ending Block
                            end = *((guint32*) ptr);
                            if (swap) {
                                end = swap32(end);
                            }
                            ptr += 4;

                            proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
                                    "Ending Block: %d", end);
                            offset += 4;

                        } // end of for j

                    } /* end of for i */
                }

                packet_header += numBytes + 4;

            }

        }

        offset += 4;

        offset += 1;
    }
}