/* 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 * 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/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_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); }