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
[email protected] 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 <[email protected]>
Archives: http://www.wireshark.org/lists/wireshark-dev
Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev
mailto:[email protected]?subject=unsubscribe