Hi,

If data is split across packets, how to extract fields (from next packet) in 
continuation with the previous packet?
For example:
My full packet looks like this:
field 1

field 2

field 3

field 4

field 5

field 6

field 7

field 8


Initially, wireshark receives the following fragment only,
field 1

field 2

field 3

field 4


Then it receives this fragment,
field 5

field 6

field 7

field 8


What code changes need to be made (attached code file) to handle such a 
situation, where in parsing has to start from "Field 5" in the second packet.

I have followed all the guidelines for "Packet Reassembly" while coding. Still 
I am not able to parse the packet fragments properly.
Kindly help.


________________________________
This message is confidential and intended only for the addressee. If you have 
received this message in error, please immediately notify the 
postmas...@nds.com and delete it from your system as well as any copies. The 
content of e-mails as well as traffic data may be monitored by NDS for 
employment and security purposes.
To protect the environment please do not print this e-mail unless necessary.

An NDS Group Limited company. www.nds.com
/* packet-dash.c
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

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

#include <stdio.h>
#include <glib.h>
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/reassemble.h>
#include <epan/next_tvb.h>
#include <string.h>

#define PROTO_TAG_DASH  "DASH"
#define DEFAULT_OQTP_UDP_PORT (32772)

/* OQTP Packet Types */
#define OQTP_PACKET_OPCODE_RQ       (1)
#define OQTP_PACKET_OPCODE_BRQ      (2)
#define OQTP_PACKET_OPCODE_DATA     (3)
#define OQTP_PACKET_OPCODE_RESERVED (4)
#define OQTP_PACKET_OPCODE_ERROR    (5)

/* Wireshark ID of the DASH protocol */
static int proto_dash = -1;

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

/* Function prototypes */
void proto_register_dash();
void proto_reg_handoff_dash();
static void msg_init_protocol();
void dissect_dash(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);

static int global_dash_port = DEFAULT_OQTP_UDP_PORT;

static gint hf_oqtp_opcode = -1;
static gint hf_oqtp_msgid = -1;
static gint hf_oqtp_last_packet_flag = -1;
static gint hf_oqtp_response_size = -1;
static gint hf_oqtp_data_packet_block_number = -1;
static gint hf_oqtp_error_code = -1;
static gint hf_oqtp_error_string = -1;
static gint hf_oqtp_root_path = -1;
static gint hf_oqtp_method = -1;
static gint hf_oqtp_reserved = -1;
static gint hf_catalogue_id = -1;
static gint hf_classif_id = -1;
static gint hf_direction = -1;
static gint hf_category_type = -1;
static gint hf_parental_rating = -1;
static gint hf_loc_classif_id = -1;
static gint hf_loc_order_num = -1;
static gint hf_loc_name_length = -1;
static gint hf_loc_name = -1;
static gint hf_request_satisfied = -1;
static gint hf_reserved_for_future_use = -1;
static gint hf_no_extended_pd_syntax = -1;
static gint hf_num_classifications = -1;
static gint hf_order_num = -1;
static gint hf_name_length = -1;
static gint hf_name = -1;
static gint hf_description_length = -1;
static gint hf_description = -1;
static gint hf_private_data_length = -1;
static gint hf_private_data_byte = -1;
static gint hf_x_private_data_length = -1;
static gint hf_x_private_data_byte = -1;
static gint hf_lang = -1;
static gint hf_skip_count = -1;
static gint hf_count = -1;
static gint hf_private_data_len = -1;
static gint hf_reserved_bits = -1;

/* These are the ids of the subtrees that we may be creating */
static gint ett_oqtp_opcode = -1;
static gint ett_oqtp_msgid = -1;
static gint ett_oqtp_last_packet_flag = -1;
static gint ett_oqtp_response_size = -1;
static gint ett_oqtp_data_packet_block_number = -1;
static gint ett_oqtp_error_code = -1;
static gint ett_oqtp_error_string = -1;
static gint ett_oqtp_root_path = -1;
static gint ett_oqtp_method = -1;
static gint ett_oqtp_reserved = -1;
static gint oqtp_subtree_1 = -1;

static const value_string packettypenames[] = {
        { 1, "RQ - Call" },
        { 2, "BRQ - Burst Call" },
        { 3, "DATA" },
        { 4, "RESERVED" },
        { 5, "ERROR" },
    { 0, NULL }
};

static const value_string methodtypenames[] = {
        { 1, "RQ - Call" },
        { 2, "BRQ - Burst Call" },
        { 3, "DATA" },
        { 4, "RESERVED" },
        { 5, "ERROR" },
    { 0, NULL }
};

static const value_string reserved_field_coding[] = {
    { 1, "fragment" },
    { 2, "last_fragment" },
    { 0, NULL }
};

static const value_string direction_field_coding[] = {
    { 0, "Forwards" },
    { 1, "Backwards" }
};

static int hf_msg_fragments = -1;
static int hf_msg_fragment = -1;
static int hf_msg_fragment_overlap = -1;
static int hf_msg_fragment_overlap_conflicts = -1;
static int hf_msg_fragment_multiple_tails = -1;
static int hf_msg_fragment_too_long_fragment = -1;
static int hf_msg_fragment_error = -1;
static int hf_msg_reassembled_in = -1;

static gint ett_msg_fragment = -1;
static gint ett_msg_fragments = -1;

static const fragment_items msg_frag_items = {
        /* Fragment subtrees */
        &ett_msg_fragment,
        &ett_msg_fragments,
        /* Fragment fields */
        &hf_msg_fragments,
        &hf_msg_fragment,
        &hf_msg_fragment_overlap,
        &hf_msg_fragment_overlap_conflicts,
        &hf_msg_fragment_multiple_tails,
        &hf_msg_fragment_too_long_fragment,
        &hf_msg_fragment_error,
        /* Reassembled in field */
        &hf_msg_reassembled_in,
        /* Tag */
        "Message fragments"
};

/* OQTP protocol subtree array */
static gint *oqtp_subtree_array[] = {
        &ett_oqtp_opcode,
        &ett_oqtp_last_packet_flag,
        &ett_oqtp_msgid,
        &ett_oqtp_response_size,
        &ett_oqtp_data_packet_block_number,
        &ett_oqtp_error_code,
        &ett_oqtp_error_string,
        &ett_oqtp_root_path,
        &ett_oqtp_method,
        &ett_oqtp_reserved,
        &oqtp_subtree_1,
        /* Fragment subtrees */
        &ett_msg_fragment,
        &ett_msg_fragments
};

/* OQTP packet fields */
static hf_register_info hf_oqtp[] = {
        {&hf_oqtp_opcode,
        {"Opcode", "oqtp.opcode",FT_UINT16, BASE_DEC,NULL, 0x0,
         "Packet Type --> 1 - RQ ; 2 - BRQ ; 3 - DATA ; 4 - Reserved ; 5 - 
ERROR", HFILL}},
        {&hf_oqtp_reserved,
        {"Reserved", "oqtp.reserved",FT_UINT8, BASE_DEC,NULL, 0x0,
         "Reserved for future use", HFILL}},
        {&hf_oqtp_last_packet_flag,
        {"Last Packet Flag", "oqtp.last_packet_flag",FT_UINT8, BASE_DEC,NULL, 
0x0,
         "Last packet in response group", HFILL}},
        {&hf_oqtp_msgid,
        {"Message ID", "oqtp.msg_id",FT_UINT16, BASE_DEC,NULL, 0x0,
         "Message ID used to match request & response", HFILL}},
        {&hf_oqtp_response_size,
        {"Response Size", "oqtp.response_size",FT_UINT16, BASE_DEC,NULL, 0x0,
         "Response Size for response data to use within DATA responses", 
HFILL}},
        {&hf_oqtp_data_packet_block_number,
        {"Block Number", "oqtp.block_number",FT_UINT16, BASE_DEC,NULL, 0x0,
         "Block Number", HFILL}},
        {&hf_oqtp_error_code,
        {"Error code", "oqtp.error_code",FT_UINT16, BASE_DEC,NULL, 0x0,
         "Error code", HFILL}},
        {&hf_oqtp_error_string,
        {"Error String", "oqtp.error_string",FT_STRINGZ, BASE_CUSTOM,NULL, 0x0,
         "Error String", HFILL}},
        {&hf_oqtp_root_path,
        {"Root Path", "oqtp.root_path",FT_STRING, BASE_CUSTOM,NULL, 0x0,
         "Root Path", HFILL}},
        {&hf_oqtp_method,
        {"Method", "oqtp.method",FT_STRING, BASE_CUSTOM,NULL, 0x0,
         "Class & Method", HFILL}},
        {&hf_catalogue_id,
        {"Catalogue ID","oqtp.catalogue_id",FT_UINT16, BASE_DEC,NULL, 0x0,
         "Catalogue ID", HFILL}},
        {&hf_classif_id,
        {"Classification ID","oqtp.classif_id",FT_UINT16, BASE_DEC,NULL, 0x0,
         "Classification ID", HFILL}},
        {&hf_direction,
        {"Direction","oqtp.direction",FT_UINT8, BASE_DEC,NULL, 0x0,
         "Direction", HFILL}},
        {&hf_category_type,
        {"Category Type","oqtp.category_type",FT_UINT8, BASE_DEC,NULL, 0x0,
         "Category Type", HFILL}},
        {&hf_parental_rating,
        {"Parental Rating","oqtp.parental_rating",FT_UINT8, BASE_DEC,NULL, 0x0,
         "Parental Rating", HFILL}},
        {&hf_loc_classif_id,
        {"Locator Classification ID","oqtp.loc_classif_id",FT_UINT16, 
BASE_DEC,NULL, 0x0,
         "Locator Classification ID", HFILL}},
        {&hf_loc_order_num,
        {"Order Number","oqtp.loc_order_num",FT_UINT8, BASE_DEC,NULL, 0x0,
         "Order Number", HFILL}},
        {&hf_loc_name_length,
        {"Location Name Length","oqtp.loc_name_length",FT_UINT8, BASE_DEC,NULL, 
0x0,
         "Location Name Length", HFILL}},
        {&hf_loc_name,
        {"Location Name","oqtp.loc_name",FT_STRING, BASE_CUSTOM,NULL, 0x0,
         "Location Name", HFILL}},
        {&hf_request_satisfied,
        {"Request Satisfied","oqtp.request_satisfied",FT_UINT8, BASE_DEC, NULL, 
0x0,
         "Request Satisfied", HFILL}},
        {&hf_reserved_for_future_use,
        {"Reserved For Future Use","oqtp.reserved_for_future_use",FT_UINT8, 
BASE_DEC, NULL, 0x0,
         "Request Satisfied", HFILL}},
        {&hf_no_extended_pd_syntax,
        {"No Extended pd syntax","oqtp.no_extended_pd_syntax",FT_UINT8, 
BASE_DEC, NULL, 0x0,
         "No Extended pd syntax", HFILL}},
        {&hf_num_classifications,
        {"Number of classifications","oqtp.num_classifications",FT_UINT8, 
BASE_DEC, NULL, 0x0,
         "Number of classifications", HFILL}},
        {&hf_order_num,
        {"Order Number","oqtp.order_num",FT_UINT8, BASE_DEC, NULL, 0x0,
         "Order Number", HFILL}},
        {&hf_name_length,
        {"Name Length","oqtp.name_length",FT_UINT8, BASE_DEC, NULL, 0x0,
         "Name Length", HFILL}},
        {&hf_name,
        {"Classification Name","oqtp.name",FT_STRING, BASE_CUSTOM, NULL, 0x0,
         "Classification Name", HFILL}},
        {&hf_description_length,
        {"Description Length","oqtp.description_length",FT_UINT16, BASE_DEC, 
NULL, 0x0,
         "Description Length", HFILL}},
        {&hf_description,
        {"Description","oqtp.description",FT_STRING, BASE_CUSTOM, NULL, 0x0,
         "Description", HFILL}},
        {&hf_private_data_length,
        {"Private Data Length","oqtp.private_data_length",FT_UINT8, BASE_DEC, 
NULL, 0x0,
         "Private Data Length", HFILL}},
        {&hf_private_data_byte,
        {"Private Data Byte","oqtp.private_data_byte",FT_UINT8, BASE_DEC, NULL, 
0x0,
         "Private Data Byte", HFILL}},
        {&hf_x_private_data_length,
        {"x Private Data Length","oqtp.x_private_data_length",FT_UINT16, 
BASE_DEC, NULL, 0x0,
         "x Private Data Length", HFILL}},
        {&hf_x_private_data_byte,
        {"Private Data","oqtp.x_private_data_byte",FT_UINT8, BASE_DEC, NULL, 
0x0,
         "Private Data", HFILL}},
        {&hf_lang,
        {"Language Code","oqtp.language_code",FT_STRING, BASE_CUSTOM, NULL, 0x0,
         "Language Code", HFILL}},
        {&hf_skip_count,
        {"Skip Count","oqtp.skip_count",FT_UINT8, BASE_DEC, NULL, 0x0,
         "Skip Count", HFILL}},
        {&hf_count,
        {"Count","oqtp.count",FT_UINT8, BASE_DEC, NULL, 0x0,
         "Count", HFILL}},
        {&hf_private_data_len,
        {"Private Data Length","oqtp.private_data_len",FT_UINT8, BASE_DEC, 
NULL, 0x0,
         "Private Data Length", HFILL}},
        {&hf_reserved_bits,
        {"Reserved Bits","oqtp.reserved_bits",FT_UINT8, BASE_DEC, NULL, 0x0,
         "Reserved Bits", HFILL}},
         /*
         * Short Message fragment reassembly
         */
         {&hf_msg_fragments,
         {"Message fragments", "msg.fragments",
          FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
         {&hf_msg_fragment,
         {"Message fragment", "msg.fragment",
          FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
         {&hf_msg_fragment_overlap,
         {"Message fragment overlap", "msg.fragment.overlap",
          FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
         {&hf_msg_fragment_overlap_conflicts,
         {"Message fragment overlapping with conflicting 
data","msg.fragment.overlap.conflicts",
          FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
         {&hf_msg_fragment_multiple_tails,
         {"Message has multiple tail fragments","msg.fragment.multiple_tails",
          FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
         {&hf_msg_fragment_too_long_fragment,
         {"Message fragment too long", "msg.fragment.too_long_fragment",
          FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
         {&hf_msg_fragment_error,
         {"Message defragmentation error", "msg.fragment.error",
          FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
         {&hf_msg_reassembled_in,
         {"Reassembled in", "msg.reassembled.in",
          FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }

};

/*Hash tables are declared, and these are initialised in the following protocol 
initialisation routine*/
static GHashTable *msg_fragment_table = NULL;
static GHashTable *msg_reassembled_table = NULL;

static void msg_init_protocol(void)
{
        fragment_table_init(&msg_fragment_table);
        reassembled_table_init(&msg_reassembled_table);
}

/* This is called by Wireshark plugin manager when to allow the plugin 
initialise its dissector*/
void proto_reg_handoff_dash(void)
{
        static gboolean initialized=FALSE;

        if (!initialized)
        {
                data_handle = find_dissector("data");
                dash_handle = create_dissector_handle(dissect_dash, proto_dash);
                dissector_add("udp.port", global_dash_port, dash_handle);
                initialized=TRUE;
        }
}

/* This function is called by the Wireshark Plugin manager at start-up to allow
the plugin register itself to wireshark*/
void proto_register_dash (void)
{
        /* A header field is something you can search/filter on.
        * We create 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}}.
        */

        proto_dash = proto_register_protocol ("DASH Protocol", "DASH", "dash");
        proto_register_field_array (proto_dash, hf_oqtp, array_length 
(hf_oqtp));
        proto_register_subtree_array (oqtp_subtree_array, array_length 
(oqtp_subtree_array));
        register_dissector("dash", dissect_dash, proto_dash);

        register_init_routine(msg_init_protocol);
}


static void dissect_dash(tvbuff_t *tvb, packet_info *pkt, proto_tree *tree)
{
        fragment_data *frag_msg = NULL;
    tvbuff_t *new_tvb = NULL;
    tvbuff_t *next_tvb = NULL;

        if (check_col(pkt->cinfo, COL_PROTOCOL))
                col_set_str(pkt->cinfo, COL_PROTOCOL, PROTO_TAG_DASH);

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

        if (tree)
        {
                proto_item *trunk_proto_tree = NULL;
                proto_tree *oqtp_tree = NULL;
                proto_item *opcode_item=NULL;
                proto_item *direction_item=NULL;
                gboolean    save_fragmented;
                int packet_field_offset = 0, block_number = 0, reserved_bits = 
0;
                gint root_path_start_offset = 0, root_path_end_offset = 0, 
oqtp_method_end_offset = 0, gl_method = 0;
                guint8 reserved = 0, last_packet_flag = 0, request_satisfied = 
0, direction = 0, category_type = 0;
                guint8 reserved_for_future_use = 0, no_extended_pd_syntax = 0, 
loc_name_length =0, name_length = 0;
                guint8 private_data_len = 0;
                guint16 opcode = 0, msgid = 0, loc_classif_id = 0, 
private_data_length = 0;
                guint16 num_classifications = 0, description_length = 0, 
x_private_data_length = 0;
                guint16 loop_index = 0, index = 0;

                /* Adding an item for OQTP in the trunk i.e the main branch 
which
                   contains protocols like Ethernet, IP, UDP. OQTP is now 
another sibling
                   here. The trunk_proto_tree contains reference to the main 
tree.
                */
                trunk_proto_tree = proto_tree_add_item(tree, proto_dash, tvb, 
0, -1, FALSE);

                /* Create a sub-tree now, which contains the dissected details 
of the
                   OQTP packets */
                oqtp_tree = proto_item_add_subtree(trunk_proto_tree, 
oqtp_subtree_1);

                /* Now add the fields as items under the sub-tree */
                opcode_item = proto_tree_add_item(oqtp_tree, hf_oqtp_opcode, 
tvb, packet_field_offset, 2, FALSE);

                /* Retrieve the OQTP packet opcode */
                opcode = tvb_get_ntohs(tvb, packet_field_offset);
                packet_field_offset += 2;

                /*Display Opcode type next to the number*/
                proto_item_append_text(opcode_item, ", %s", val_to_str(opcode, 
packettypenames, "Unknown (0x%02x)"));

                /*2-lines commented by darshan. Because, Reserved is 
interpreted in a different way here
                reserved = tvb_get_guint8(tvb, packet_field_offset);
                proto_tree_add_uint(oqtp_tree, hf_oqtp_reserved, tvb, 
packet_field_offset, 1, ((reserved & 0x80) >> 7));*/

                last_packet_flag = tvb_get_guint8(tvb, packet_field_offset);
                proto_tree_add_uint(oqtp_tree, hf_oqtp_last_packet_flag, tvb, 
packet_field_offset, 1, ((last_packet_flag & 0x80) >> 7));

                /* If packet is of OQTP Data packet Type */
                /*if(OQTP_PACKET_OPCODE_DATA == opcode)
                {
                        proto_item_append_text(oqtp_tree, ", %s",
                                                                   
val_to_str(1, reserved_field_coding, "Unknown (0x%02x)"));
                }*/

                /* Extract the msgid field */
                msgid = ((tvb_get_ntohs(tvb, packet_field_offset)) & 0x7FFF);

                /* Set the OQTP message id */
                proto_tree_add_uint(oqtp_tree, hf_oqtp_msgid, tvb, 
packet_field_offset, 2, msgid);
                packet_field_offset += 2;

                switch(opcode)
                {
                        case OQTP_PACKET_OPCODE_RQ:
                        case OQTP_PACKET_OPCODE_BRQ:
                                /* Maximum response size that the requestor can 
handle */
                                proto_tree_add_item(oqtp_tree, 
hf_oqtp_response_size, tvb, packet_field_offset, 2, FALSE);
                                packet_field_offset += 2;

                                /* Parse to find the root path and display as 
/VOD/ for example */
                                root_path_start_offset = tvb_find_guint8(tvb, 
packet_field_offset, -1, '/');
                                root_path_end_offset = tvb_find_guint8(tvb, 
root_path_start_offset + 1, -1, '/');

                                proto_tree_add_item(oqtp_tree, 
hf_oqtp_root_path, tvb, root_path_start_offset, ((root_path_end_offset - 
root_path_start_offset) + 1), FALSE);
                                packet_field_offset = root_path_end_offset + 1;

                                oqtp_method_end_offset = tvb_find_guint8(tvb, 
packet_field_offset, -1, '/');
                                proto_tree_add_item(oqtp_tree, hf_oqtp_method, 
tvb, packet_field_offset, (oqtp_method_end_offset - packet_field_offset), 
FALSE);

                                //gl_method = tvb_find_guint8(tvb, 
packet_field_offset, -1, "GL");
                                if((tvb_strneql(tvb, packet_field_offset, 
"AIGL", 4) == 0) ||
                                   (tvb_strneql(tvb, packet_field_offset, 
"CIGL", 4) == 0))
                                {
                                        packet_field_offset += 5; //move the 
offset of method name. For eg AIGL/

                                        /*CATALOGUE ID*/
                                        proto_tree_add_item(oqtp_tree, 
hf_catalogue_id, tvb, packet_field_offset, 2, FALSE);
                                        packet_field_offset += 2;

                                        /*CLASSIFICATION ID*/
                                        proto_tree_add_item(oqtp_tree, 
hf_classif_id, tvb, packet_field_offset, 2, FALSE);
                                        packet_field_offset += 2;

                                        /*DIRECTION*/
                                        direction = tvb_get_guint8(tvb, 
packet_field_offset);
                                        direction_item = 
proto_tree_add_uint(oqtp_tree, hf_direction, tvb, packet_field_offset, 1, 
((direction & 0x80) >> 7));

                                        /*Category Type*/
                                        category_type = ((tvb_get_ntohs(tvb, 
packet_field_offset)) & 0x7F);
                                        proto_tree_add_uint(oqtp_tree, 
hf_category_type, tvb, packet_field_offset, 1, category_type);
                                        packet_field_offset += 1;

                                        /*Parental Rating*/
                                        proto_tree_add_item(oqtp_tree, 
hf_parental_rating, tvb, packet_field_offset, 1, FALSE);
                                        packet_field_offset += 1;

                                        /*Locator Classification ID*/
                                        proto_tree_add_item(oqtp_tree, 
hf_loc_classif_id, tvb, packet_field_offset, 2, FALSE);
                                        loc_classif_id = tvb_get_ntohs(tvb, 
packet_field_offset);
                                        packet_field_offset += 2;

                                        if(loc_classif_id != 0)
                                        {
                                                /*Order Number*/
                                                proto_tree_add_item(oqtp_tree, 
hf_loc_order_num, tvb, packet_field_offset, 1, FALSE);
                                                packet_field_offset += 1;

                                                /*Location Name Length*/
                                                proto_tree_add_item(oqtp_tree, 
hf_loc_name_length, tvb, packet_field_offset, 1, FALSE);
                                                loc_name_length = 
tvb_get_guint8(tvb, packet_field_offset);
                                                packet_field_offset += 1;

                                                /*Location Name*/
                                                if(loc_name_length != 0)
                                                {
                                                        
proto_tree_add_item(oqtp_tree, hf_loc_name, tvb, packet_field_offset + 1, 
loc_name_length - 1,FALSE);
                                                        packet_field_offset = 
packet_field_offset + loc_name_length;
                                                }
                                                else if(loc_name_length == 0)
                                                {
                                                        
proto_tree_add_item(oqtp_tree, hf_loc_name, tvb, packet_field_offset + 1, 
loc_name_length ,FALSE);
                                                        packet_field_offset = 
packet_field_offset + loc_name_length + 1;
                                                }
                                        }

                                        /*language code*/
                                        proto_tree_add_item(oqtp_tree, hf_lang, 
tvb, packet_field_offset, 3, FALSE);
                                        packet_field_offset += 3;

                                        /*skip_count*/
                                        proto_tree_add_item(oqtp_tree, 
hf_skip_count, tvb, packet_field_offset, 1, FALSE);
                                        packet_field_offset += 1;

                                        /*count*/
                                        proto_tree_add_item(oqtp_tree, 
hf_count, tvb, packet_field_offset, 1, FALSE);
                                        packet_field_offset += 1;

                                        /*Private Data Length*/
                                        proto_tree_add_item(oqtp_tree, 
hf_private_data_len, tvb, packet_field_offset, 1, FALSE);
                                        private_data_len = tvb_get_guint8(tvb, 
packet_field_offset);
                                        packet_field_offset += 1;

                                        for(index = 0 ; index < 
private_data_len; ++index)
                                        {
                                                /*private_data_byte*/
                                                proto_tree_add_item(oqtp_tree, 
hf_private_data_byte, tvb, packet_field_offset, 1, FALSE);
                                                packet_field_offset += 1;
                                        }

                                        /*if((reserved_bits = 
(packet_field_offset % 8)) != 0)
                                        {
                                                
fprintf(stderr,"packet_field_offset: %d\n Reserved bits: 
%d\n",packet_field_offset,reserved_bits );
                                                for(index = 0 ; index < 
reserved_bits; ++index)
                                                {
                                                        //reserved for future 
use
                                                        
proto_tree_add_item(oqtp_tree, hf_reserved_bits, tvb, packet_field_offset, 1, 
FALSE);
                                                        packet_field_offset += 
1;
                                                }
                                        }*/

                                }

                                break;
                        case OQTP_PACKET_OPCODE_DATA:

                                /* Extract the data packet block number */
                                proto_tree_add_item(oqtp_tree, 
hf_oqtp_data_packet_block_number, tvb, packet_field_offset, 2, FALSE);
                                block_number = tvb_get_ntohs(tvb, 
packet_field_offset);
                                packet_field_offset += 2;

                                /*save the fragmented state of this packet, so 
we can restore it later.*/
                                save_fragmented = pkt->fragmented;

                                /* Multiple packets in response - 
last_packet_flag field is the last packet flag */
                                if(((block_number == 0) && (last_packet_flag == 
0)) ||
                                   (block_number > 0))
                                {
                                        /*darshan*/
                                        pkt->fragmented = TRUE;

                                        frag_msg = fragment_add_seq_check(tvb, 
packet_field_offset, pkt,
                                                                                
                          msgid, /* ID for fragments belonging together */
                                                                                
                          msg_fragment_table, /* list of message fragments */
                                                                                
                          msg_reassembled_table, /* list of reassembled 
messages */
                                                                                
                          block_number, /* fragment sequence number */
                                                                                
                          tvb_length_remaining(tvb, packet_field_offset), /* 
fragment length - to the end */
                                                                                
                          !last_packet_flag); /* More fragments? */

                                        new_tvb = process_reassembled_data(tvb, 
packet_field_offset, pkt,
                                                                                
                           "Reassembled OQTP Message",
                                                                                
                           frag_msg,
                                                                                
                           &msg_frag_items,
                                                                                
                           NULL,
                                                                                
                           oqtp_tree);

                                        /* Reassembled */
                                        if (frag_msg)
                                        {
                                                col_append_str(pkt->cinfo, 
COL_INFO,
                                                                           
"(Reassembled OQTP Response)");
                                        }
                                        else
                                        {
                                                /* Not last packet of 
reassembled short message */
                                                col_append_fstr(pkt->cinfo, 
COL_INFO,
                                                                                
"(OQTP fragment %u)", block_number);
                                        }

                                        if (new_tvb) /* take it all */
                                        {
                                                next_tvb = new_tvb;
                                        }
                                        else
                                        {
                                                /* make a new subset */
                                                next_tvb = tvb_new_subset(tvb, 
packet_field_offset, -1, -1);
                                        }
                                }
                                else
                                {
                                        next_tvb = tvb_new_subset(tvb, 
packet_field_offset, -1, -1);
                                }

                                /*restoring fragmented state*/
                                pkt->fragmented = save_fragmented;

                                /*Request Satisfied*/
                                request_satisfied = tvb_get_guint8(tvb, 
packet_field_offset);
                                proto_tree_add_uint(oqtp_tree, 
hf_request_satisfied, tvb, packet_field_offset, 1, ((request_satisfied & 0x80) 
>> 7));

                                /*Reserved_for_future_use*/
                                reserved_for_future_use = ((tvb_get_guint8(tvb, 
packet_field_offset)& 0x7E) >> 1);
                                proto_tree_add_uint(oqtp_tree, 
hf_reserved_for_future_use, tvb, packet_field_offset, 1, 
reserved_for_future_use );

                                /*No Extended pd syntax*/
                                no_extended_pd_syntax = (tvb_get_guint8(tvb, 
packet_field_offset) & 0x1);
                                proto_tree_add_uint(oqtp_tree, 
hf_no_extended_pd_syntax, tvb, packet_field_offset, 1, no_extended_pd_syntax );
                                packet_field_offset += 1;

                                /*Number of classifications*/
                                proto_tree_add_item(oqtp_tree, 
hf_num_classifications, tvb, packet_field_offset, 1, FALSE);
                                num_classifications = tvb_get_guint8(tvb, 
packet_field_offset);
                                packet_field_offset += 1;

                                for(loop_index = 0 ; loop_index < 
num_classifications ; ++loop_index)
                                {
                                        /*CLASSIFICATION ID*/
                                        proto_tree_add_item(oqtp_tree, 
hf_classif_id, tvb, packet_field_offset, 2, FALSE);
                                        packet_field_offset += 2;

                                        /*Category Type*/
                                        proto_tree_add_item(oqtp_tree, 
hf_category_type, tvb, packet_field_offset, 1, FALSE);
                                        packet_field_offset += 1;

                                        /*Order Number*/
                                        proto_tree_add_item(oqtp_tree, 
hf_order_num, tvb, packet_field_offset, 1, FALSE);
                                        packet_field_offset += 1;

                                        /*parental_rating*/
                                        proto_tree_add_item(oqtp_tree, 
hf_parental_rating, tvb, packet_field_offset, 1, FALSE);
                                        packet_field_offset += 1;

                                        /*Name Length*/
                                        proto_tree_add_item(oqtp_tree, 
hf_name_length, tvb, packet_field_offset, 1, FALSE);
                                        name_length = tvb_get_guint8(tvb, 
packet_field_offset);
                                        packet_field_offset += 1;

                                        /*name*/
                                        proto_tree_add_item(oqtp_tree, hf_name, 
tvb, packet_field_offset + 1, name_length ,FALSE);
                                        packet_field_offset = 
packet_field_offset + name_length;

                                        /*Description Length*/
                                        proto_tree_add_item(oqtp_tree, 
hf_description_length, tvb, packet_field_offset, 2, FALSE);
                                        description_length = tvb_get_ntohs(tvb, 
packet_field_offset);
                                        packet_field_offset += 2;

                                        fprintf (stderr, "Description Name 
length:%d\n", description_length);

                                        /*Description*/
                                        proto_tree_add_item(oqtp_tree, 
hf_description, tvb, packet_field_offset + 1, description_length - 1,FALSE);
                                        packet_field_offset = 
packet_field_offset + description_length;

                                        /*private_data_length*/
                                        proto_tree_add_item(oqtp_tree, 
hf_private_data_length, tvb, packet_field_offset, 1, FALSE);
                                        private_data_length = 
tvb_get_guint8(tvb, packet_field_offset);
                                        packet_field_offset += 1;

                                        for(index = 0 ; index < 
private_data_length ; ++index)
                                        {
                                                /*private_data_byte*/
                                                proto_tree_add_item(oqtp_tree, 
hf_private_data_byte, tvb, packet_field_offset, 1, FALSE);
                                                packet_field_offset += 1;
                                        }

                                        if(!no_extended_pd_syntax)
                                        {
                                                /*Private Data Length*/
                                                proto_tree_add_item(oqtp_tree, 
hf_x_private_data_length, tvb, packet_field_offset, 2, FALSE);
                                                x_private_data_length = 
tvb_get_ntohs(tvb, packet_field_offset);
                                                packet_field_offset += 2;

                                                for(index = 0 ; index < 
x_private_data_length ; ++index)
                                                {
                                                        /*x_private_data_byte*/
                                                        
proto_tree_add_item(oqtp_tree, hf_x_private_data_byte, tvb, 
packet_field_offset, 1, FALSE);
                                                        packet_field_offset += 
1;
                                                }

                                        }
                                }

                                break;
                        case OQTP_PACKET_OPCODE_ERROR:
                        {
                                int error_string_length = 0;
                                char *error_string = NULL;

                                /* Extract the error code */
                                proto_tree_add_item(oqtp_tree, 
hf_oqtp_error_code, tvb, packet_field_offset, 2, FALSE);
                                packet_field_offset += 2;

                                /* Get the error string */
                                error_string = tvb_get_stringz(tvb, 
packet_field_offset, &error_string_length);

                                /* Display the error string */
                                if(error_string)
                                        proto_tree_add_string(oqtp_tree, 
hf_oqtp_error_string, tvb, packet_field_offset, error_string_length, (const 
char *)error_string);
                        }
                                break;
                        default:
                                break;
        }

        }
}
___________________________________________________________________________
Sent via:    Wireshark-dev mailing list <wireshark-dev@wireshark.org>
Archives:    http://www.wireshark.org/lists/wireshark-dev
Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev
             mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe

Reply via email to