266 lines
8.1 KiB
C
266 lines
8.1 KiB
C
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|
|
|
|
File: octpkt.c
|
|
|
|
$Octasic_Copyright: $
|
|
|
|
Description:
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as published by
|
|
the Free Software Foundation; either version 3 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 Affero General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
$Octasic_Release: $
|
|
|
|
$Revision: $
|
|
|
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
|
|
|
#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);
|
|
|
|
}
|
|
|