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