octsdr-2g-wireshark/application/tool/wireshark/plugins/octasic/octpkt_ws/source/octpkt.c

264 lines
8.2 KiB
C

/* octpkt.c
* Routines for octpkt 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 "../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 <octpkt_hdr.h>
/* Define version if we are not building Wireshark statically */
/* Initialize the protocol and registered fields */
static int proto_octpkt = -1;
static int hf_octpkt_format = -1;
static int hf_octpkt_trace_flag = -1;
static int hf_octpkt_api_type = -1;
static int hf_octpkt_size = -1;
static dissector_handle_t data_handle;
static dissector_handle_t vocallonet_handle;
static dissector_handle_t octmfa_handle;
/* fields defining a subtree */
static gint ett_octpkt = -1;
const value_string octpkt_api_type_vals[] =
{
{ cOCTPKT_HDR_CONTROL_PROTOCOL_TYPE_ENUM_OCTVOCNET, "OCTVOCNET" },
{ cOCTPKT_HDR_CONTROL_PROTOCOL_TYPE_ENUM_OCTMFA, "OCTMFA" },
{ 0, NULL },
};
#define OCTPKT_TRACE_BIT(octet) ((octet) & 0x80)
#define OCTPKT_TOTAL_PACKET_SIZE(uint16) ((uint16) & 0x07ff)
#define OCTPKT_API_TYPE(octet) (((octet) & 0x78) >> 3 )
/*************************************************************************
*
* Code to actually dissect the Vocallo common packet header
*
**************************************************************************/
static void dissect_octpkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item* ti = NULL;
proto_tree* octpkt_tree = NULL;
unsigned int offset = 0;
gboolean trace_flag;
guint32 format_trace_proto_len = 0;
tOctWsPrivateData *pPrivData;
/* 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, "OCTPKT_FORMAT" );
if( pinfo->private_data == NULL )
pinfo->private_data = ep_alloc( sizeof( tOctWsPrivateData ) );
pPrivData = (tOctWsPrivateData *)pinfo->private_data;
format_trace_proto_len = tvb_get_ntohl( tvb, offset );
offset += sizeof(format_trace_proto_len);
/* Get the format field [bit 24 to 31] */
pPrivData->format = (format_trace_proto_len & cOCTPKT_HDR_FORMAT_PROTO_TYPE_LEN_MASK_FORMAT ) >> cOCTPKT_HDR_FORMAT_PROTO_TYPE_LEN_MASK_FORMAT_BIT_OFFSET;
trace_flag = (format_trace_proto_len & cOCTPKT_HDR_FORMAT_PROTO_TYPE_LEN_MASK_TRACE ) >> cOCTPKT_HDR_FORMAT_PROTO_TYPE_LEN_MASK_TRACE_BIT_OFFSET;
pPrivData->api_type = (format_trace_proto_len & cOCTPKT_HDR_FORMAT_PROTO_TYPE_LEN_MASK_CONTROL_PROTOCOL_TYPE ) >> cOCTPKT_HDR_FORMAT_PROTO_TYPE_LEN_MASK_CONTROL_PROTOCOL_TYPE_BIT_OFFSET;
pPrivData->total_packet_size = (format_trace_proto_len & cOCTPKT_HDR_FORMAT_PROTO_TYPE_LEN_MASK_LENGTH ) >> cOCTPKT_HDR_FORMAT_PROTO_TYPE_LEN_MASK_LENGTH_BIT_OFFSET;
pPrivData->pktHdt_size = offset;
pPrivData->trace_flag = trace_flag;
if( pPrivData->total_packet_size < 46 )
pPrivData->padding = 46 - pPrivData->total_packet_size;
else
pPrivData->padding = 0;
/* Add summary display for the Vocallonet packet */
if ( check_col( pinfo->cinfo, COL_INFO) )
{
col_add_fstr( pinfo->cinfo, COL_INFO,
"Format=%d, Size=%u bytes%s",
pPrivData->format,
pPrivData->total_packet_size,
pPrivData->trace_flag ? ", Trace" : "");
}
if ( tree )
{
/* create display subtree for the protocol */
ti = proto_tree_add_item( tree, proto_octpkt, tvb, 0, offset, FALSE );
octpkt_tree = proto_item_add_subtree(ti, ett_octpkt);
/* Scroll back to the beginning of the header*/
offset -= sizeof(format_trace_proto_len);
/* add the VocalloNet common fields to the UI */
proto_tree_add_uint( octpkt_tree, hf_octpkt_format, tvb,
offset, 1, format_trace_proto_len );
offset++;
proto_tree_add_boolean( octpkt_tree, hf_octpkt_trace_flag, tvb,
offset, 1, format_trace_proto_len );
offset++;
proto_tree_add_uint( octpkt_tree, hf_octpkt_api_type, tvb,
offset, 1, format_trace_proto_len );
proto_tree_add_uint( octpkt_tree, hf_octpkt_size, tvb,
offset, 2, format_trace_proto_len );
offset+=2;
}
if (tvb_reported_length_remaining(tvb, offset) > 0)
{
tvb = tvb_new_subset(tvb, offset, -1, -1);
switch( pPrivData->api_type )
{
case cOCTPKT_HDR_CONTROL_PROTOCOL_TYPE_ENUM_OCTVOCNET:
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "OCTVOCNET" );
if( vocallonet_handle )
call_dissector(vocallonet_handle, tvb, pinfo, tree);
else
call_dissector(data_handle, tvb, pinfo, tree);
break;
case cOCTPKT_HDR_CONTROL_PROTOCOL_TYPE_ENUM_OCTMFA:
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "OCTMFA" );
if( octmfa_handle )
call_dissector(octmfa_handle, tvb, pinfo, tree);
else
call_dissector(data_handle, tvb, pinfo, tree);
break;
default:
/* Dump the rest in raw format */
call_dissector(data_handle, tvb, pinfo, tree);
break;
}
}
}
/*************************************************************************
*
* Code to register the protocol with Wireshark
*
**************************************************************************/
void proto_register_octpkt(void)
{
/* Setup list of header fields */
static hf_register_info hf_octpkt[] =
{
{ &hf_octpkt_format,
{ "Format", "octpkt.format",
FT_UINT32, BASE_HEX, NULL, 0xff000000,
"Packet format", HFILL }
},
{ &hf_octpkt_trace_flag,
{ "Trace", "octpkt.trace_flag",
FT_BOOLEAN, 32, NULL, 0x00800000,
"Debug trace flag", HFILL }
},
{ &hf_octpkt_api_type,
{ "API Type", "octpkt.api_type",
FT_UINT32, BASE_HEX, VALS(octpkt_api_type_vals), 0x00007800,
"API Type", HFILL }
},
{ &hf_octpkt_size,
{ "Size", "octpkt.size_in_bytes",
FT_UINT32, BASE_DEC, NULL, 0x000007ff,
"Total bit length", HFILL }
}
};
/* Setup protocol subtree array */
static gint* ett[] =
{
&ett_octpkt,
};
/* Register the protocol name and description */
proto_octpkt = proto_register_protocol( "OCTPKT Packets", "Octasic Packets", "octpkt");
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array( proto_octpkt, hf_octpkt, array_length(hf_octpkt) );
proto_register_subtree_array(ett, array_length(ett));
}
/*************************************************************************
*
* 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_octpkt(void)
{
dissector_handle_t octpkt_handle;
data_handle = find_dissector("data");
vocallonet_handle = find_dissector("vocallonet");
octmfa_handle = find_dissector("octmfa");
octpkt_handle = create_dissector_handle(dissect_octpkt, proto_octpkt);
dissector_add_uint("ethertype", cOCTPKT_HDR_ETHERTYPE, octpkt_handle);
}