/* packet-vocallonet.c * Routines for vocallonet dissection * Copyright 2004, Ocatasic inc. * * $Id: README.developer 11475 2004-07-23 01:37:35Z guy $ * * Ethereal - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * * 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 #include #include #include #include "../include/moduleinfo.h" #include "../../../include/oct_ws_macro.h" #include "../../../include/oct_ws_priv.h" #include #include #include #include #include #include #include /* Define version if we are not building Wireshark statically */ /* Initialize the protocol and registered fields */ static int proto_vocallonet = -1; static int hf_vocallonet_format = -1; static int hf_vocallonet_trace_flag = -1; static int hf_vocallonet_api_type = -1; static int hf_vocallonet_size = -1; static int proto_vocallonet_control = -1; static int hf_vocallonet_control_destination_fifo_id = -1; static int hf_vocallonet_control_source_fifo_id = -1; static int hf_vocallonet_control_socket_id = -1; /* Packet data external fields (formats a-q) */ static int proto_vocallonet_data = -1; static int hf_vocallonet_data_socket_handle = -1; static int proto_vocallonet_d_frag_data = -1; static int proto_vocallonet_ev_data = -1; static int proto_vocallonet_f_data = -1; /* Packet format A fields (ethernet) */ /* None other than already defined */ /* Packet data fields (formats b-f) */ static int hf_vocallonet_data_logical_object_handle = -1; static int hf_vocallonet_data_packet_port = -1; static int hf_vocallonet_data_dest_fifo_id = -1; /* Packet format D fields (voice) */ static int hf_vocallonet_d_frag_SequenceId = -1; static int hf_vocallonet_d_frag_TransfertTotalSize = -1; static int hf_vocallonet_d_frag_FragmentTotalNum = -1; static int hf_vocallonet_d_frag_FragmentId = -1; static int hf_vocallonet_d_frag_FragmentDataOffset = -1; static int hf_vocallonet_d_frag_FragmentDataSize = -1; static int hf_vocallonet_d_frag_UserId = -1; /* Packet format F fields (raw) */ static int hf_vocallonet_f_timestamp = -1; static int hf_vocallonet_f_subtype = -1; /* fields defining a subtree */ static gint ett_vocallonet = -1; static gint ett_vocallonet_control = -1; static gint ett_vocallonet_data = -1; static gint ett_vocallonet_d_frag_data = -1; static gint ett_vocallonet_f_data = -1; typedef enum { PACKET_F_UNSPECIFIED, PACKET_F_LAPD } Version_Type; static gint packet_f_decode = PACKET_F_UNSPECIFIED; static dissector_handle_t data_handle; static dissector_handle_t lapd_handle; static dissector_handle_t octvc1_ctrl_handle; static dissector_handle_t octvc1_event_handle; static dissector_handle_t octpkt_handle; // TODO #define cOCTVOCNET_PKT_API_TYPE_ENUM_OCTVC1 0 const value_string vocallonet_api_type_vals[] = { { cOCTVOCNET_PKT_API_TYPE_ENUM_OCTVC1, "OCTVC1" }, { 0, NULL }, }; const value_string vocallonet_format_vals[] = { { cOCTVOCNET_PKT_FORMAT_CTRL, "Control packet" }, { cOCTVOCNET_PKT_FORMAT_F, "Format F: Raw Data Packet" }, { cOCTVOCNET_PKT_FORMAT_DATA_FRAGMENT, "Format DATA_FRAGMENT: Data Packet (allow fragment)" }, { 0, NULL }, }; const value_string vocallonet_d_encoding_type_vals[] = { { 0, NULL }, }; const value_string vocallonet_f_subtype_vals[] = { { cOCTVOCNET_PKT_SUBTYPE_UNSPECIFIED, "Unspecified" }, { cOCTVOCNET_PKT_SUBTYPE_API_EVENT, "API Event" }, { cOCTVOCNET_PKT_SUBTYPE_MODULE_DATA, "Module Data" }, { 0, NULL }, }; #define VOCALLONET_TRACE_BIT(octet) ((octet) & 0x80) #define VOCALLONET_TOTAL_PACKET_SIZE(uint16) ((uint16) & 0x07ff) #define VOCALLONET_API_TYPE(octet) (((octet) & 0x78) >> 3 ) #define VOCALLONET_F_SUBTYPE(uint32) ((uint32) & 0x0000000f) #define VOCALLONET_F_EVENT_ID_BASE(uint32) ((uint32) & 0x0fff0000) #define VOCALLONET_F_EVENT_ID_CODE(uint32) ((uint32) & 0x0000ffff) /************************************************************************* * * Code to dissect the Vocallo data packet header * **************************************************************************/ static void dissect_vocallonet_packet_data(tvbuff_t *tvb, proto_item *ti, proto_tree *vocallonet_tree, unsigned int offset) { unsigned int packet_offset = offset; guint32 logical_object_handle; guint32 packet_port; guint32 dest_fifo; proto_tree* vocallonet_data_tree = NULL; unsigned int layer_length = 0; /* dissect the common packet data */ logical_object_handle = tvb_get_ntohl( tvb, packet_offset ); packet_offset += sizeof(logical_object_handle); layer_length += sizeof(logical_object_handle); packet_port = tvb_get_ntohl( tvb, packet_offset ); packet_offset += sizeof(packet_port); layer_length += sizeof(packet_port); dest_fifo = tvb_get_ntohl( tvb, packet_offset ); packet_offset += sizeof(dest_fifo); layer_length += sizeof(dest_fifo); if (vocallonet_tree) { /* Add the subtree for struct tOCTVOCNET_PKT_DATA_HEADER under struct tOCTVOCNET_PKT_HEADER */ ti = proto_tree_add_item( vocallonet_tree, proto_vocallonet_data, tvb, packet_offset-layer_length, packet_offset-offset, FALSE ); vocallonet_data_tree = proto_item_add_subtree( ti, ett_vocallonet_data ); /* Scroll back to the beginning of the packet */ packet_offset = offset; proto_tree_add_uint( vocallonet_data_tree, hf_vocallonet_data_logical_object_handle, tvb, packet_offset, sizeof(logical_object_handle), logical_object_handle ); packet_offset += sizeof(logical_object_handle); proto_tree_add_uint( vocallonet_data_tree, hf_vocallonet_data_packet_port, tvb, packet_offset, sizeof(packet_port), packet_port ); packet_offset += sizeof(packet_port); proto_tree_add_uint( vocallonet_data_tree, hf_vocallonet_data_dest_fifo_id, tvb, packet_offset, sizeof(dest_fifo), dest_fifo ); packet_offset += sizeof(dest_fifo); } } /************************************************************************* * * Code to actually dissect the Vocallo control packet header * **************************************************************************/ static void dissect_vocallonet_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item* ti = NULL; proto_tree* vocallonet_control_tree = NULL; unsigned int packet_offset = 0; guint32 destination_fifo_id; guint32 source_fifo_id; guint32 socket_id; tOctWsPrivateData * pPrivData = (tOctWsPrivateData *)pinfo->private_data; /* Finish dissecting the external packet header */ destination_fifo_id = tvb_get_ntohl( tvb, packet_offset ); packet_offset += sizeof(destination_fifo_id); source_fifo_id = tvb_get_ntohl( tvb, packet_offset ); packet_offset += sizeof(source_fifo_id); socket_id = tvb_get_ntohl( tvb, packet_offset ); packet_offset += sizeof(socket_id); if ( check_col(pinfo->cinfo, COL_PROTOCOL) ) col_set_str(pinfo->cinfo, COL_PROTOCOL, "OCTVOCNET_PKT_FORMAT_CTRL"); if ( tree ) { /* Add the subtree for struct tOCTVOCNET_PKT_CTL_HEADER */ ti = proto_tree_add_item( tree, proto_vocallonet_control, tvb, 0, -1, FALSE ); vocallonet_control_tree = proto_item_add_subtree( ti, ett_vocallonet_control ); /* Scroll back to the beginning of the packet */ packet_offset = 0; proto_tree_add_uint( vocallonet_control_tree, hf_vocallonet_control_destination_fifo_id, tvb, packet_offset, 4, destination_fifo_id ); packet_offset += sizeof(destination_fifo_id); proto_tree_add_uint( vocallonet_control_tree, hf_vocallonet_control_source_fifo_id, tvb, packet_offset, 4, source_fifo_id ); packet_offset += sizeof(source_fifo_id); proto_tree_add_uint( vocallonet_control_tree, hf_vocallonet_control_socket_id, tvb, packet_offset, 4, socket_id ); packet_offset += sizeof(socket_id); } if (tvb_reported_length_remaining(tvb, packet_offset) > 0) { tvb = tvb_new_subset(tvb, packet_offset, -1, -1); switch( pPrivData->api_type ) { case cOCTVOCNET_PKT_API_TYPE_ENUM_OCTVC1: if( octvc1_ctrl_handle ) call_dissector(octvc1_ctrl_handle, tvb, pinfo, vocallonet_control_tree); else call_dissector(data_handle, tvb, pinfo, vocallonet_control_tree); break; default: /* Dump the rest in raw format */ call_dissector(data_handle, tvb, pinfo, vocallonet_control_tree); break; } } } /************************************************************************* * * Code to actually dissect the Vocallo F format data packet header * **************************************************************************/ static void dissect_vocallonet_f_packet(tvbuff_t *tvb, proto_item *ti, packet_info *pinfo, proto_tree *vocallonet_tree, unsigned int offset, proto_tree *vocallonet_tree2 ,guint16 f_padding ) { unsigned int packet_offset = offset; guint32 timestamp; guint32 subtype; proto_tree* vocallonet_control_tree = NULL; unsigned int layer_offset = 0; tOctWsPrivateData * pPrivData = (tOctWsPrivateData *)pinfo->private_data; /* Add summary display for the Vocallonet packet */ if ( check_col( pinfo->cinfo, COL_INFO) ) { col_add_fstr( pinfo->cinfo, COL_INFO, "OCTVOCNET F-packet format(%d), Size=%u bytes%s", pPrivData->format, pPrivData->total_packet_size, pPrivData->trace_flag ? ", Trace" : ""); } /* First, dissect the packet data fields */ dissect_vocallonet_packet_data(tvb, ti, vocallonet_tree2, packet_offset); packet_offset += sizeof(tOCTVOCNET_PKT_DATA_HEADER); // layer_offset = packet_offset; timestamp = tvb_get_ntohl( tvb, packet_offset ); packet_offset += sizeof(timestamp); subtype = tvb_get_ntohl( tvb, packet_offset ); subtype = VOCALLONET_F_SUBTYPE(subtype); packet_offset += sizeof(subtype); if (vocallonet_tree) { /* Add the subtree for struct tOCTVOCNET_PKT_DATA_F_HEADER */ ti = proto_tree_add_item( vocallonet_tree, proto_vocallonet_f_data, tvb, layer_offset, pPrivData->total_packet_size - layer_offset, FALSE ); vocallonet_control_tree = proto_item_add_subtree( ti, ett_vocallonet_control ); /* Scroll back to the beginning of the packet */ packet_offset = offset + sizeof(tOCTVOCNET_PKT_DATA_HEADER); proto_tree_add_uint( vocallonet_control_tree, hf_vocallonet_f_timestamp, tvb, packet_offset, sizeof(timestamp), timestamp ); packet_offset += sizeof(timestamp); proto_tree_add_uint( vocallonet_control_tree, hf_vocallonet_f_subtype, tvb, packet_offset, sizeof(subtype), subtype ); packet_offset += sizeof(subtype); } /* Dissect the rest according to the packet subtype */ switch(subtype) { case cOCTVOCNET_PKT_SUBTYPE_API_EVENT: { if (tvb_reported_length_remaining(tvb, packet_offset) > 0) { tvb = tvb_new_subset(tvb, packet_offset, -1, -1); switch( pPrivData->api_type ) { case cOCTVOCNET_PKT_API_TYPE_ENUM_OCTVC1: if( octvc1_event_handle ) call_dissector(octvc1_event_handle, tvb, pinfo, vocallonet_control_tree); else call_dissector(data_handle, tvb, pinfo, vocallonet_tree); break; default: /* If any bytes remain, send it to the generic data dissector */ call_dissector(data_handle, tvb, pinfo, vocallonet_tree); break; } } } break; case cOCTVOCNET_PKT_SUBTYPE_UNSPECIFIED: if( packet_f_decode == PACKET_F_LAPD ) { guint32 length_remaining = tvb_reported_length_remaining(tvb, packet_offset); if ( length_remaining > 0 ) { tvb = tvb_new_subset(tvb, packet_offset, length_remaining - f_padding, length_remaining - f_padding ); call_dissector(lapd_handle , tvb, pinfo, vocallonet_tree); } } break; case cOCTVOCNET_PKT_SUBTYPE_MODULE_DATA: default: { /* If any bytes remain, send it to the generic data dissector */ if (tvb_reported_length_remaining(tvb, packet_offset) > 0) { tvb = tvb_new_subset(tvb, packet_offset, -1, -1); call_dissector(data_handle, tvb, pinfo, vocallonet_tree); } } break; } } /************************************************************************* * * Code to actually dissect the Vocallo Data_Fragment format data packet header * **************************************************************************/ static void dissect_vocallonet_data_fragment_packet(tvbuff_t *tvb, proto_item *ti, packet_info *pinfo, proto_tree *vocallonet_tree, unsigned int offset, proto_tree *vocallonet_tree2 ,guint16 f_padding ) { unsigned int packet_offset = offset; guint32 ulSequenceId; guint32 ulTransfertTotalSize; guint32 ulFragmentTotalNum; guint32 ulFragmentId; guint32 ulFragmentDataOffset; guint32 ulFragmentDataSize; guint32 ulUserId; proto_tree* vocallonet_control_tree = NULL; unsigned int layer_offset = 0; tOctWsPrivateData * pPrivData = (tOctWsPrivateData *)pinfo->private_data; /* Add summary display for the Vocallonet packet */ if ( check_col( pinfo->cinfo, COL_INFO) ) { col_add_fstr( pinfo->cinfo, COL_INFO, "OCTVOCNET DATA_FRAG-packet format(%d), Size=%u bytes%s", pPrivData->format, pPrivData->total_packet_size, pPrivData->trace_flag ? ", Trace" : ""); } /* First, dissect the packet f fields */ dissect_vocallonet_f_packet(tvb, ti, pinfo, vocallonet_tree, offset, vocallonet_tree2, f_padding); packet_offset += sizeof(tOCTVOCNET_PKT_DATA_F_HEADER); // layer_offset = packet_offset; ulSequenceId = tvb_get_ntohl( tvb, packet_offset ); packet_offset += sizeof(ulSequenceId); ulTransfertTotalSize = tvb_get_ntohl( tvb, packet_offset ); packet_offset += sizeof(ulTransfertTotalSize); ulFragmentTotalNum = tvb_get_ntohl( tvb, packet_offset ); packet_offset += sizeof(ulFragmentTotalNum); ulFragmentId = tvb_get_ntohl( tvb, packet_offset ); packet_offset += sizeof(ulFragmentId); ulFragmentDataOffset = tvb_get_ntohl( tvb, packet_offset ); packet_offset += sizeof(ulFragmentDataOffset); ulFragmentDataSize = tvb_get_ntohl( tvb, packet_offset ); packet_offset += sizeof(ulFragmentDataSize); ulUserId = tvb_get_ntohl( tvb, packet_offset ); packet_offset += sizeof(ulUserId); if (vocallonet_tree) { /* Add the subtree for struct tOCTVOCNET_PKT_DATA_F_HEADER */ ti = proto_tree_add_item( vocallonet_tree, proto_vocallonet_f_data, tvb, layer_offset, pPrivData->total_packet_size - layer_offset, FALSE ); vocallonet_control_tree = proto_item_add_subtree( ti, ett_vocallonet_control ); /* Scroll back to the beginning of the packet */ packet_offset = offset + sizeof(tOCTVOCNET_PKT_DATA_F_HEADER); proto_tree_add_uint( vocallonet_control_tree, hf_vocallonet_d_frag_SequenceId, tvb, packet_offset, sizeof(ulSequenceId), ulSequenceId ); packet_offset += sizeof(ulSequenceId); proto_tree_add_uint( vocallonet_control_tree, hf_vocallonet_d_frag_TransfertTotalSize, tvb, packet_offset, sizeof(ulTransfertTotalSize), ulTransfertTotalSize ); packet_offset += sizeof(ulTransfertTotalSize); proto_tree_add_uint( vocallonet_control_tree, hf_vocallonet_d_frag_FragmentTotalNum, tvb, packet_offset, sizeof(ulFragmentTotalNum), ulFragmentTotalNum ); packet_offset += sizeof(ulFragmentTotalNum); proto_tree_add_uint( vocallonet_control_tree, hf_vocallonet_d_frag_FragmentId, tvb, packet_offset, sizeof(ulFragmentId), ulFragmentId ); packet_offset += sizeof(ulFragmentId); proto_tree_add_uint( vocallonet_control_tree, hf_vocallonet_d_frag_FragmentDataOffset, tvb, packet_offset, sizeof(ulFragmentDataOffset), ulFragmentDataOffset ); packet_offset += sizeof(ulFragmentDataOffset); proto_tree_add_uint( vocallonet_control_tree, hf_vocallonet_d_frag_FragmentDataSize, tvb, packet_offset, sizeof(ulFragmentDataSize), ulFragmentDataSize ); packet_offset += sizeof(ulFragmentDataSize); proto_tree_add_uint( vocallonet_control_tree, hf_vocallonet_d_frag_UserId, tvb, packet_offset, sizeof(ulUserId), ulUserId ); packet_offset += sizeof(ulUserId); } } /************************************************************************* * * Code to actually dissect the Vocallo common packet header * **************************************************************************/ static void dissect_vocallonet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item* ti = NULL; proto_tree* vocallonet_tree = tree; unsigned int offset = 0; guint8 format; tOctWsPrivateData *pPrivData; /* Should be set by octpkt dissector */ if( pinfo->private_data == NULL ) { if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "OCTVOCNET_PKT_FORMAT ERROR" ); expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR, "OCTVOCNET_PKT_FORMAT ERROR" ); call_dissector(data_handle, tvb, pinfo, tree); return; } /* Make entries in Protocol column and Info column on summary display */ if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "OCTVOCNET_PKT_FORMAT" ); pPrivData = (tOctWsPrivateData *)pinfo->private_data; format = pPrivData->format; /* Dissect the relevant packet format */ switch( format ) { case cOCTVOCNET_PKT_FORMAT_CTRL: { /* Append to get funny size...? */ if( pPrivData->total_packet_size ) { tvb = tvb_new_subset(tvb, offset, -1, -1); dissect_vocallonet_control(tvb, pinfo, tree); } } break; case cOCTVOCNET_PKT_FORMAT_DATA_FRAGMENT: { dissect_vocallonet_data_fragment_packet(tvb, ti, pinfo, tree, offset, vocallonet_tree, pPrivData->padding); } break; case cOCTVOCNET_PKT_FORMAT_F: { dissect_vocallonet_f_packet(tvb, ti, pinfo, tree, offset, vocallonet_tree, pPrivData->padding); } break; default: { /* If any bytes remain, send it to the generic data dissector */ if (tvb_reported_length_remaining(tvb, offset) > 0) { tvb = tvb_new_subset(tvb, offset, -1, -1); call_dissector(data_handle, tvb, pinfo, tree); } } break; } } /************************************************************************* * * Code to register the protocol with Wireshark * **************************************************************************/ void proto_register_vocallonet(void) { /* Setup list of header fields */ static hf_register_info hf_vocallonet[] = { { &hf_vocallonet_format, { "Format", "vocallonet.format", FT_UINT32, BASE_HEX, VALS(vocallonet_format_vals), 0xff000000, "Vocallonet packet format", HFILL } }, { &hf_vocallonet_trace_flag, { "Trace", "vocallonet.trace_flag", FT_BOOLEAN, 32, NULL, 0x00800000, "Debug trace flag", HFILL } }, { &hf_vocallonet_api_type, { "API Type", "vocallonet.api_type", FT_UINT32, BASE_HEX, VALS(vocallonet_api_type_vals), 0x00007800, "API Type", HFILL } }, { &hf_vocallonet_size, { "Size", "vocallonet.size_in_bytes", FT_UINT32, BASE_DEC, NULL, 0x000003ff, "Total bit length", HFILL } } }; static hf_register_info hf_vocallonet_data[] = { /* Common packet data fields */ { &hf_vocallonet_data_logical_object_handle, { "Object Handle ", "vocallonet.data.logical_object_handle", FT_UINT32, BASE_HEX, NULL, 0x0, "Logical object handle ", HFILL } }, { &hf_vocallonet_data_packet_port, { "Logical Object Packet Port Packet", "vocallonet.data.packet_port", FT_UINT32, BASE_HEX, NULL, 0x0, "Packet port index", HFILL } }, { &hf_vocallonet_data_dest_fifo_id, { "Destination FIFO ID", "vocallonet.data.dest_fifo_id", FT_UINT32, BASE_HEX, NULL, 0x0, "Destination FIFO ID", HFILL } }, }; static hf_register_info hf_vocallonet_f_data[] = { /* Packet format F fields (raw) */ { &hf_vocallonet_f_timestamp, { "Timestamp", "vocallonet.f.timestamp", FT_UINT32, BASE_HEX, NULL, 0, "Packet timestamp", HFILL } }, { &hf_vocallonet_f_subtype, { "Subtype", "vocallonet.f.subtype", FT_UINT32, BASE_HEX, VALS(vocallonet_f_subtype_vals), 0, "Packet subtype", HFILL } }, }; static hf_register_info hf_vocallonet_d_frag_data[] = { /* Packet format F fields (raw) */ { &hf_vocallonet_d_frag_SequenceId, { "SequenceId", "vocallonet.d_frag.SequenceId", FT_UINT32, BASE_HEX, NULL, 0, "Packet SequenceId", HFILL } }, { &hf_vocallonet_d_frag_TransfertTotalSize, { "TransfertTotalSize", "vocallonet.d_frag.TransfertTotalSize", FT_UINT32, BASE_HEX, NULL, 0, "Packet TransfertTotalSize", HFILL } }, { &hf_vocallonet_d_frag_FragmentTotalNum, { "FragmentTotalNum", "vocallonet.d_frag.FragmentTotalNum", FT_UINT32, BASE_HEX, NULL, 0, "Packet FragmentTotalNum", HFILL } }, { &hf_vocallonet_d_frag_FragmentId, { "FragmentId", "vocallonet.d_frag.FragmentId", FT_UINT32, BASE_HEX, NULL, 0, "Packet FragmentId", HFILL } }, { &hf_vocallonet_d_frag_FragmentDataOffset, { "FragmentDataOffset", "vocallonet.d_frag.FragmentDataOffset", FT_UINT32, BASE_HEX, NULL, 0, "Packet FragmentDataOffset", HFILL } }, { &hf_vocallonet_d_frag_FragmentDataSize, { "FragmentDataSize", "vocallonet.d_frag.FragmentDataSize", FT_UINT32, BASE_HEX, NULL, 0, "Packet FragmentDataSize", HFILL } }, { &hf_vocallonet_d_frag_UserId, { "UserId", "vocallonet.d_frag.UserId", FT_UINT32, BASE_HEX, NULL, 0, "Packet UserId", HFILL } }, }; static hf_register_info hf_vocallonet_control[] = { { &hf_vocallonet_control_destination_fifo_id, { "Destination Fifo Id", "vocallonet.control.destination_fifo_id", FT_UINT32, BASE_HEX, NULL, 0x0, "Destination fifo id", HFILL } }, { &hf_vocallonet_control_source_fifo_id, { "Source Fifo Id", "vocallonet.control.source_fifo_id", FT_UINT32, BASE_HEX, NULL, 0x0, "Source fifo id", HFILL } }, { &hf_vocallonet_control_socket_id, { "Socket Id", "vocallonet.control.socket_id", FT_UINT32, BASE_HEX, NULL, 0x0, "Return socket Id", HFILL } }, }; /* Setup protocol subtree array */ static gint* ett[] = { &ett_vocallonet, &ett_vocallonet_control, &ett_vocallonet_data, &ett_vocallonet_d_frag_data, &ett_vocallonet_f_data, }; module_t *vocallonet_module; static enum_val_t options[] = { { "Unspecified", "Unspecified", PACKET_F_UNSPECIFIED }, { "Lapd", "Lapd", PACKET_F_LAPD }, { NULL, NULL, 0 } }; /* Register the protocol name and description */ proto_vocallonet = proto_register_protocol( "Vocallonet packets", "Octasic Vocallonet", "vocallonet"); proto_vocallonet_control = proto_register_protocol("Vocallo control packets", "Octasic Vocallonet Control", "vocallonet_ctrl"); proto_vocallonet_data = proto_register_protocol( "Vocallo data packet", "Octasic Vocallonet Data", "vocallonet_data"); proto_vocallonet_d_frag_data = proto_register_protocol( "Vocallo Data_Frag format data packet", "Octasic Vocallonet Data_Frag", "vocallonet_frag_data"); proto_vocallonet_f_data = proto_register_protocol( "Vocallo F format data packet", "Octasic Vocallonet F-Data", "vocallonet_f_data"); proto_vocallonet_ev_data = proto_register_protocol( "Vocallo Event format packet", "Octasic Vocallonet Event", "vocallonet_ev_data"); vocallonet_module = prefs_register_protocol(proto_vocallonet, NULL); prefs_register_enum_preference(vocallonet_module, "packet_f", "Packet F unspecified decode", "Type of F packet", &packet_f_decode, options, FALSE); /* Required function calls to register the header fields and subtrees used */ proto_register_field_array( proto_vocallonet, hf_vocallonet, array_length(hf_vocallonet) ); proto_register_field_array( proto_vocallonet_control, hf_vocallonet_control, array_length(hf_vocallonet_control) ); proto_register_field_array( proto_vocallonet_data, hf_vocallonet_data, array_length(hf_vocallonet_data) ); proto_register_field_array( proto_vocallonet_d_frag_data, hf_vocallonet_d_frag_data, array_length(hf_vocallonet_d_frag_data) ); proto_register_field_array( proto_vocallonet_f_data, hf_vocallonet_f_data, array_length(hf_vocallonet_f_data) ); proto_register_subtree_array(ett, array_length(ett)); register_dissector("vocallonet", dissect_vocallonet, proto_vocallonet); } /************************************************************************* * * If this dissector uses sub-dissector registration add a registration routine. * This format is required because a script is used to find these routines and * create the code that calls these routines. * **************************************************************************/ void proto_reg_handoff_vocallonet(void) { data_handle = find_dissector("data"); octvc1_ctrl_handle = find_dissector("Octvc1_Ctrl"); octvc1_event_handle = find_dissector("Octvc1_Event"); octpkt_handle = find_dissector("OctPkt"); }