octsdr-2g-wireshark/application/tool/wireshark/plugins/octasic/octsdr/octvocnet_ws/source/packet-vocallonet.c

769 lines
26 KiB
C

/* 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 <gerald@ethereal.com>
* 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 <epan/packet.h>
#include <epan/prefs.h>
#include <epan/expert.h>
#include <epan/ipproto.h>
#include "../include/moduleinfo.h"
#include "../../../include/oct_ws_macro.h"
#include "../../../include/oct_ws_priv.h"
#include <color.h>
#include <color_filters.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gmodule.h>
#include <octvocnet_pkt.h>
/* 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");
}