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

1391 lines
49 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_a_data = -1;
static int proto_vocallonet_d_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_high = -1;
static int hf_vocallonet_data_logical_object_handle_middle = -1;
static int hf_vocallonet_data_logical_object_handle_low = -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_timestamp = -1;
static int hf_vocallonet_d_marker = -1;
static int hf_vocallonet_d_valid_rtp = -1;
static int hf_vocallonet_d_encoding_type = -1;
static int hf_vocallonet_d_sequence_number = -1;
/* Packet format D fields (voice) when valid_rtp is set to 1 */
static int hf_vocallonet_d_rtp_pad_size = -1;
static int hf_vocallonet_d_rtp_payload_offset = -1;
static int hf_vocallonet_d_rtp_version = -1;
static int hf_vocallonet_d_rtp_padding = -1;
static int hf_vocallonet_d_rtp_extension = -1;
static int hf_vocallonet_d_rtp_csrc_count = -1;
static int hf_vocallonet_d_rtp_payload_type = -1;
static int hf_vocallonet_d_rtp_sync_source = -1;
static int hf_vocallonet_d_VocFlag_BFI = -1;
static int hf_vocallonet_d_VocFlag_TAF = -1;
static int hf_vocallonet_d_VocFlag_SID = -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_a_data = -1;
static gint ett_vocallonet_d_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 rfc4175_yuv_handle;
static dissector_handle_t yuv_extended_handle;
static dissector_handle_t macroblock_handle;
static dissector_handle_t eth_handle;
static dissector_handle_t ip_handle;
static dissector_handle_t lapd_handle;
static dissector_handle_t h263_handle;
static dissector_handle_t h263p_handle;
static dissector_handle_t h264_handle;
static dissector_handle_t hMpeg4_handle;
static dissector_handle_t hT38_handle;
static dissector_handle_t amr_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_A, "Format A: Normal Ethernet Packet (to/from Ethernet ports)" },
{ cOCTVOCNET_PKT_FORMAT_D, "Format D: Voice/Video in a Packet" },
{ cOCTVOCNET_PKT_FORMAT_F, "Format F: Raw Data Packet" },
{ 0, NULL },
};
const value_string vocallonet_d_encoding_type_vals[] =
{
#ifdef cOCTVOCNET_PKT_D_TYPE_ENUM_TONE
{ cOCTVOCNET_PKT_D_TYPE_ENUM_TONE, "Tone event" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_GEN_SID, "Generic SID" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_LINEAR_8KSS, "Linear 16-bits sign extended, 8000Hz sampling" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_LINEAR_16KSS, "Linear 16-bit, 16000Hz sampling" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_PCM_U_LAW, "G.711 PCM, U-law" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_PCM_A_LAW, "G.711 PCM, A-law" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_PCM_U_LAW_VBD, "G.711 PCM, U-law, Voiceband data" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_PCM_A_LAW_VBD, "G.711 PCM, A-law, Voiceband data" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G726_16, "G.726 ADPCM, 16kbps (AAL2)" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G726_24, "G.726 ADPCM, 24kbps (AAL2)" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G726_32, "G.726 ADPCM, 32kbps (AAL2)" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G726_40, "G.726 ADPCM, 40kbps (AAL2)" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G726_16_RTP, "G.726 ADPCM, 16kbps (RTP)" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G726_24_RTP, "G.726 ADPCM, 24kbps (RTP)" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G726_32_RTP, "G.726 ADPCM, 32kbps (RTP)" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G726_40_RTP, "G.726 ADPCM, 40kbps (RTP)" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G722_48, "G.722 , 48kbps" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G722_56, "G.722 , 56kbps" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G722_64, "G.722 , 64kbps" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G723_1, "G.723.1" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G729A, "G.729a" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G729AB_8, "G.729ab, 8kbps" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_AMR, "AMR" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_AMR_RTP, "AMR (IETF RFC 3267)" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_EFR, "EFR" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_EFR_RTP, "EFR (IETF RFC 3267)" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_AMR_WB, "Wideband AMR" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_AMR_WB_RTP, "Wideband AMR (IETF RFC 3267)" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_ILBC, "ILBC (ITEF RFC 3951)" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G722_1_24, "G.722.1, 24kbps" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_G722_1_32, "G.722.1, 32kbps" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_T38_UDPTL, "T.38 over UDPTL" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_T38_RTP, "T.38 over RTP" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_VOX, "VOX" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_YUV_RTP_RFC4175, "YUV uncompressed video data (IETF RFC 4175)" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_RAW_YUV, "YUV uncompressed video data" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_RAW_YUV_EXTENDED, "YUV EXTENDED uncompressed video data" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_H263_RTP_RFC2190, "H.263 compressed video data (IETF RFC 2190)" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_H263_RTP_RFC2190_BYTE_BOUNDARY, "H.263 compressed video data (IETF RFC 2190). Packetized at Byte boundaries." },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_H263_RTP_RFC2429, "H.263 compressed video data (IETF RFC 2429 or RFC 4629) )" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_MPEG4_RTP_RFC3016, "MPEG-4 compressed elementary stream video data (IETF RFC 3016)" },
{ cOCTVOCNET_PKT_D_TYPE_ENUM_H264_RTP_RFC3984, "H.264 Video (IETF RFC 3984)" },
#endif /* cOCTVOCNET_PKT_D_TYPE_ENUM_TONE */
{ 0, NULL },
};
const value_string vocallonet_f_subtype_vals[] =
{
{ cOCTVOCNET_PKT_SUBTYPE_UNSPECIFIED, "Unspecified" },
{ cOCTVOCNET_PKT_SUBTYPE_API_EVENT, "API Event" },
{ cOCTVOCNET_PKT_SUBTYPE_ETH, "Ethernet" },
{ cOCTVOCNET_PKT_SUBTYPE_IP, "IP" },
{ cOCTVOCNET_PKT_SUBTYPE_UDP_PAYLOAD, "UDP Payload" },
{ cOCTVOCNET_PKT_SUBTYPE_TCP_PAYLOAD, "TCP Payload" },
#ifdef cOCTVOCNET_PKT_SUBTYPE_VIDEO_IMAGE_DESCRIPTOR
{ cOCTVOCNET_PKT_SUBTYPE_VIDEO_IMAGE_DESCRIPTOR, "Video Image Descriptor" },
#endif /* cOCTVOCNET_PKT_SUBTYPE_VIDEO_IMAGE_DESCRIPTOR */
{ 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_B_NUM_CELL(octet) ((octet) & 0x3f)
#define VOCALLONET_D_VALID_RTP(uint32) ((uint32) & 0x80000000)
#define VOCALLONET_D_ENCODING_TYPE(uint32) ((uint32) & 0x7fc00000)
#define VOCALLONET_D_RTP_PAD_SIZE(uint32) ((uint32) & 0x003fc000)
#define VOCALLONET_D_RTP_PAYLOAD_OFFSET(uint32) ((uint32) & 0x00003fff)
#define VOCALLONET_D_RTP_VERSION(uint32) ((uint32) & 0xc0000000) >> 16
#define VOCALLONET_D_RTP_PADDING(uint32) ((uint32) & 0x20000000) >> 16
#define VOCALLONET_D_RTP_EXTENSION(uint32) ((uint32) & 0x10000000) >> 16
#define VOCALLONET_D_RTP_CSRC_COUNT(uint32) ((uint32) & 0x0f000000) >> 16
#define VOCALLONET_D_RTP_MARKER(uint32) ((uint32) & 0x00800000) >> 16
#define VOCALLONET_D_RTP_PAYLOAD_TYPE(uint32) ((uint32) & 0x007f0000) >> 16
#define VOCALLONET_D_RTP_SEQ_NUMBER(uint32) ((uint32) & 0x0000ffff)
#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_high;
guint32 logical_object_handle_middle;
guint32 logical_object_handle_low;
guint32 packet_port;
guint32 dest_fifo;
proto_tree* vocallonet_data_tree = NULL;
unsigned int layer_length = 0;
/* dissect the common packet data */
// packet_offset += 2; Sygag : check if the two first bytes are reserved
// logical_object_handle_high = tvb_get_ntohs( tvb, packet_offset );
logical_object_handle_high = tvb_get_ntohl( tvb, packet_offset );
packet_offset += sizeof(logical_object_handle_high);
layer_length += sizeof(logical_object_handle_high);
logical_object_handle_middle = tvb_get_ntohl( tvb, packet_offset );
packet_offset += sizeof(logical_object_handle_middle);
layer_length += sizeof(logical_object_handle_middle);
logical_object_handle_low = tvb_get_ntohl( tvb, packet_offset );
packet_offset += sizeof(logical_object_handle_low);
layer_length += sizeof(logical_object_handle_low);
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;
// packet_offset += 2; Sygag : check if the two first bytes are reserved
proto_tree_add_uint( vocallonet_data_tree, hf_vocallonet_data_logical_object_handle_high, tvb,
packet_offset, sizeof(logical_object_handle_high), logical_object_handle_high );
packet_offset += sizeof(logical_object_handle_high);
proto_tree_add_uint( vocallonet_data_tree, hf_vocallonet_data_logical_object_handle_middle, tvb,
packet_offset, sizeof(logical_object_handle_middle), logical_object_handle_middle );
packet_offset += sizeof(logical_object_handle_middle);
proto_tree_add_uint( vocallonet_data_tree, hf_vocallonet_data_logical_object_handle_low, tvb,
packet_offset, sizeof(logical_object_handle_low), logical_object_handle_low );
packet_offset += sizeof(logical_object_handle_low);
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 A format data packet header
*
**************************************************************************/
static void dissect_vocallonet_a_packet(tvbuff_t *tvb, packet_info *pinfo,
proto_tree *vocallonet_tree, unsigned int offset)
{
unsigned int packet_offset = offset;
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 A-packet format(%d), Size=%u bytes%s",
pPrivData->format,
pPrivData->total_packet_size,
pPrivData->trace_flag ? ", Trace" : "");
}
/* Remaining bytes are an ethernet packet */
if (tvb_reported_length_remaining(tvb, packet_offset) > 0)
{
tvb = tvb_new_subset(tvb, packet_offset, -1, -1);
call_dissector(eth_handle, tvb, pinfo, vocallonet_tree);
}
}
/*************************************************************************
*
* Code to actually dissect the Vocallo D format data packet header
*
**************************************************************************/
static void dissect_vocallonet_d_packet(tvbuff_t *tvb, proto_item *ti, packet_info *pinfo,
proto_tree *vocallonet_tree, unsigned int offset, proto_tree *vocallonet_tree2)
{
proto_tree* vocallonet_data_tree = NULL;
unsigned int packet_offset = offset;
unsigned int ulReserved_LocalTimestamp;
unsigned int ul_Rtp_PktType_Pad_Offset;
unsigned int ulRtpHeader;
proto_tree* vocallonet_d_tree = NULL;
unsigned int layer_offset = 0;
tOctWsPrivateData * pPrivData = (tOctWsPrivateData *)pinfo->private_data;
/* Fields refering to the tOCTVOCNET_PKT_DATA_D_HEADER */
/* ul_Rtp_PktType_Pad_Offset */
guint32 valid_rtp;
guint32 encoding_type;
guint32 rtp_pad_size; /* valid_rtp == 1 */
guint32 rtp_payload_offset; /* valid_rtp == 1 */
/* aulRtp[0] */
guint16 rtp_version; /* valid_rtp == 1 */
guint16 rtp_padding; /* valid_rtp == 1 */
guint16 rtp_extension; /* valid_rtp == 1 */
guint16 rtp_csrc_count; /* valid_rtp == 1 */
guint16 rtp_marker;
guint16 rtp_payload_type; /* valid_rtp == 1 */
guint16 rtp_sequence_number;
/* aulRtp[1] */
guint32 timestamp;
/* aulRtp[2] */
guint32 rtp_sync_source; /* valid_rtp == 1 */
/* Add summary display for the Vocallonet packet */
if ( check_col( pinfo->cinfo, COL_INFO) )
{
col_add_fstr( pinfo->cinfo, COL_INFO,
"OCTVOCNET D-packet format(%d), Size=%u bytes%s",
pPrivData->format,
pPrivData->total_packet_size,
pPrivData->trace_flag ? ", Trace" : "");
}
/* !+! LUTAG TEMP BEFORE TO MAKE CHANGES !!!! */
vocallonet_data_tree = vocallonet_tree;
/* First, dissect the packet data fields */
dissect_vocallonet_packet_data(tvb, ti, vocallonet_tree2, packet_offset);
/* dissect reserved */
packet_offset += 20;
ulReserved_LocalTimestamp = tvb_get_ntohl( tvb, packet_offset );
packet_offset += sizeof(ulReserved_LocalTimestamp);
layer_offset = packet_offset;
/* dissect packet data */
ul_Rtp_PktType_Pad_Offset = tvb_get_ntohl( tvb, packet_offset );
valid_rtp = VOCALLONET_D_VALID_RTP(ul_Rtp_PktType_Pad_Offset);
encoding_type = VOCALLONET_D_ENCODING_TYPE(ul_Rtp_PktType_Pad_Offset);
rtp_pad_size = VOCALLONET_D_RTP_PAD_SIZE(ul_Rtp_PktType_Pad_Offset);
rtp_payload_offset = VOCALLONET_D_RTP_PAYLOAD_OFFSET(ul_Rtp_PktType_Pad_Offset);
packet_offset += sizeof(ul_Rtp_PktType_Pad_Offset);
ulRtpHeader = tvb_get_ntohl( tvb, packet_offset );
rtp_version = VOCALLONET_D_RTP_VERSION(ulRtpHeader);
rtp_padding = VOCALLONET_D_RTP_PADDING(ulRtpHeader);
rtp_extension = VOCALLONET_D_RTP_EXTENSION(ulRtpHeader);
rtp_csrc_count = VOCALLONET_D_RTP_CSRC_COUNT(ulRtpHeader);
rtp_marker = VOCALLONET_D_RTP_MARKER(ulRtpHeader);
rtp_payload_type = VOCALLONET_D_RTP_PAYLOAD_TYPE(ulRtpHeader);
rtp_sequence_number = VOCALLONET_D_RTP_SEQ_NUMBER(ulRtpHeader);
if (rtp_marker)
{
if ( check_col( pinfo->cinfo, COL_INFO) )
{
col_append_str( pinfo->cinfo, COL_INFO, ", Mark ");
}
}
packet_offset += sizeof(ulRtpHeader);
timestamp = tvb_get_ntohl( tvb, packet_offset );
packet_offset += sizeof(timestamp);
rtp_sync_source = tvb_get_ntohl( tvb, packet_offset );
packet_offset += sizeof(rtp_sync_source);
if ( vocallonet_data_tree )
{
proto_tree* sub_tree2;
/* Add the subtree for struct tOCTVOCNET_PKT_DATA_D_HEADER */
ti = proto_tree_add_item( vocallonet_data_tree, proto_vocallonet_d_data, tvb, layer_offset, packet_offset -layer_offset, FALSE );
vocallonet_d_tree = proto_item_add_subtree( ti, ett_vocallonet_d_data );
/* Scroll back to the beginning of the packet */
packet_offset = offset + 24;
ti = proto_tree_add_text(vocallonet_d_tree, tvb, packet_offset,
4, "Encoding Type:%s", val_to_str( (encoding_type>>22), vocallonet_d_encoding_type_vals,
"Unknown (%u)" ) );
sub_tree2 = proto_item_add_subtree(ti, ett_vocallonet_d_data);
proto_tree_add_boolean( sub_tree2, hf_vocallonet_d_valid_rtp, tvb,
packet_offset, 1, valid_rtp );
proto_tree_add_uint( sub_tree2, hf_vocallonet_d_encoding_type, tvb,
packet_offset, 2, encoding_type );
if ( valid_rtp )
{
/* Add the rtp padding length and rtp payload offset */
proto_tree_add_uint( sub_tree2, hf_vocallonet_d_rtp_pad_size, tvb,
packet_offset+2, 1, rtp_pad_size );
proto_tree_add_uint( sub_tree2, hf_vocallonet_d_rtp_payload_offset, tvb,
packet_offset+2, 2, rtp_payload_offset );
}
packet_offset += sizeof(encoding_type);
if ( valid_rtp )
{
ti = proto_tree_add_text(vocallonet_d_tree, tvb, packet_offset,
4, "RTP Payload Type:%d", rtp_payload_type );
sub_tree2 = proto_item_add_subtree(ti, ett_vocallonet_d_data);
/* Add the rtp fields */
proto_tree_add_uint( sub_tree2, hf_vocallonet_d_rtp_version, tvb,
packet_offset, 1, ulRtpHeader );
proto_tree_add_uint( sub_tree2, hf_vocallonet_d_rtp_padding, tvb,
packet_offset, 1, ulRtpHeader );
proto_tree_add_uint( sub_tree2, hf_vocallonet_d_rtp_extension, tvb,
packet_offset, 1, ulRtpHeader );
proto_tree_add_uint( sub_tree2, hf_vocallonet_d_rtp_csrc_count, tvb,
packet_offset, 1, ulRtpHeader );
proto_tree_add_uint( sub_tree2, hf_vocallonet_d_marker, tvb,
packet_offset+1, 1, ulRtpHeader );
proto_tree_add_uint( sub_tree2, hf_vocallonet_d_rtp_payload_type, tvb,
packet_offset+1, 1, ulRtpHeader );
}
else
{
ti = proto_tree_add_text(vocallonet_d_tree, tvb, packet_offset,
4, "Sequence number:0x%x", rtp_sequence_number & 0x0000FFFF );
sub_tree2 = proto_item_add_subtree(ti, ett_vocallonet_d_data);
proto_tree_add_uint( sub_tree2, hf_vocallonet_d_marker, tvb,
packet_offset+1, 1, ulRtpHeader );
}
packet_offset += sizeof(rtp_payload_type);
proto_tree_add_uint( sub_tree2, hf_vocallonet_d_sequence_number, tvb,
packet_offset, sizeof(rtp_sequence_number), rtp_sequence_number );
packet_offset += sizeof(rtp_sequence_number);
proto_tree_add_uint( vocallonet_d_tree, hf_vocallonet_d_timestamp, tvb,
packet_offset, sizeof(timestamp), timestamp );
packet_offset += sizeof(timestamp);
if ( valid_rtp )
{
proto_tree_add_uint( vocallonet_d_tree, hf_vocallonet_d_rtp_sync_source, tvb,
packet_offset, sizeof(rtp_sync_source), rtp_sync_source );
}
else
{
ti = proto_tree_add_text(vocallonet_d_tree, tvb, packet_offset,
4, "Vocoder Flags:0x%x", rtp_sync_source );
sub_tree2 = proto_item_add_subtree(ti, ett_vocallonet_d_data);
proto_tree_add_uint( sub_tree2, hf_vocallonet_d_VocFlag_BFI, tvb,
packet_offset+3, 1, rtp_sync_source );
proto_tree_add_uint( sub_tree2, hf_vocallonet_d_VocFlag_TAF, tvb,
packet_offset+3, 1, rtp_sync_source );
proto_tree_add_uint( sub_tree2, hf_vocallonet_d_VocFlag_SID, tvb,
packet_offset+3, 1, rtp_sync_source );
}
packet_offset += sizeof(rtp_sync_source);
}
/* Dissect the relevant packet format */
switch( encoding_type >> 22)
{
#ifdef cOCTVOCNET_PKT_SUBTYPE_VIDEO_IMAGE_DESCRIPTOR
case cOCTVOCNET_PKT_D_TYPE_ENUM_YUV_RTP_RFC4175:
{
/* 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, "YUV RFC4175" );
/* If any bytes remain, send it to the generic data dissector */
if (pPrivData->total_packet_size - packet_offset > 0)
{
tvb = tvb_new_subset(tvb, packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset);
if( rfc4175_yuv_handle )
call_dissector(rfc4175_yuv_handle, tvb, pinfo, vocallonet_tree);
else
call_dissector(data_handle, tvb, pinfo, vocallonet_tree);
}
}
break;
#endif /* cOCTVOCNET_PKT_SUBTYPE_VIDEO_IMAGE_DESCRIPTOR */
#ifdef cOCTVOCNET_PKT_D_TYPE_ENUM_RAW_YUV
case cOCTVOCNET_PKT_D_TYPE_ENUM_RAW_YUV:
{
/* 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, "YUV RAW" );
/* If any bytes remain, send it to the generic data dissector */
if (pPrivData->total_packet_size - packet_offset > 0)
{
tvb = tvb_new_subset(tvb, packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset);
if( macroblock_handle )
call_dissector(macroblock_handle, tvb, pinfo, vocallonet_tree);
else
call_dissector(data_handle, tvb, pinfo, vocallonet_tree);
}
}
break;
#endif /* cOCTVOCNET_PKT_D_TYPE_ENUM_RAW_YUV */
#ifdef cOCTVOCNET_PKT_D_TYPE_ENUM_RAW_YUV_EXTENDED
case cOCTVOCNET_PKT_D_TYPE_ENUM_RAW_YUV_EXTENDED:
{
/* 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, "YUV_EXTENDED" );
/* If any bytes remain, send it to the generic data dissector */
if (pPrivData->total_packet_size - packet_offset > 0)
{
tvb = tvb_new_subset(tvb, packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset);
if( yuv_extended_handle )
call_dissector(yuv_extended_handle, tvb, pinfo, vocallonet_tree);
else
call_dissector(data_handle, tvb, pinfo, vocallonet_tree);
}
}
break;
#endif /* cOCTVOCNET_PKT_D_TYPE_ENUM_RAW_YUV_EXTENDED */
#ifdef cOCTVOCNET_PKT_D_TYPE_ENUM_T38_UDPTL
case cOCTVOCNET_PKT_D_TYPE_ENUM_T38_UDPTL:
{
/* 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, "T38_UDPTL" );
/* If any bytes remain, send it to the generic data dissector */
if (pPrivData->total_packet_size - packet_offset > 0)
{
tvb = tvb_new_subset(tvb, packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset);
if( hT38_handle )
{
pinfo->ipproto = IP_PROTO_UDP;
call_dissector(hT38_handle, tvb, pinfo, vocallonet_tree);
}
else
{
call_dissector(data_handle, tvb, pinfo, vocallonet_tree);
}
}
}
break;
#endif /* cOCTVOCNET_PKT_D_TYPE_ENUM_T38_UDPTL */
#ifdef cOCTVOCNET_PKT_D_TYPE_ENUM_T38_RTP
case cOCTVOCNET_PKT_D_TYPE_ENUM_T38_RTP:
{
/* 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, "T38_RTP" );
/* If any bytes remain, send it to the generic data dissector */
if (pPrivData->total_packet_size - packet_offset > 0)
{
tvb = tvb_new_subset(tvb, packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset);
if( hT38_handle )
{
pinfo->ipproto = IP_PROTO_TCP;
call_dissector(hT38_handle, tvb, pinfo, vocallonet_tree);
}
else
{
call_dissector(data_handle, tvb, pinfo, vocallonet_tree);
}
}
}
break;
#endif /* cOCTVOCNET_PKT_D_TYPE_ENUM_T38_RTP */
#ifdef cOCTVOCNET_PKT_D_TYPE_ENUM_MPEG4_RTP_RFC3016
case cOCTVOCNET_PKT_D_TYPE_ENUM_MPEG4_RTP_RFC3016:
{
/* 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, "MPEG-4" );
/* If any bytes remain, send it to the generic data dissector */
if (pPrivData->total_packet_size - packet_offset > 0)
{
tvb = tvb_new_subset(tvb, packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset);
if( hMpeg4_handle )
call_dissector(hMpeg4_handle, tvb, pinfo, vocallonet_tree);
else
call_dissector(data_handle, tvb, pinfo, vocallonet_tree);
}
}
break;
#endif /* cOCTVOCNET_PKT_D_TYPE_ENUM_MPEG4_RTP_RFC3016 */
#ifdef cOCTVOCNET_PKT_D_TYPE_ENUM_H263_RTP_RFC2429
case cOCTVOCNET_PKT_D_TYPE_ENUM_H263_RTP_RFC2429:
{
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "H263P" );
if (pPrivData->total_packet_size - packet_offset > 0)
{
tvb = tvb_new_subset(tvb, packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset);
if( h263_handle )
call_dissector(h263p_handle, tvb, pinfo, vocallonet_tree);
else
call_dissector(data_handle, tvb, pinfo, vocallonet_tree);
}
}
break;
#endif /* cOCTVOCNET_PKT_D_TYPE_ENUM_H263_RTP_RFC2429 */
#ifdef cOCTVOCNET_PKT_D_TYPE_ENUM_H263_RTP_RFC2190
case cOCTVOCNET_PKT_D_TYPE_ENUM_H263_RTP_RFC2190:
{
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "H263" );
if (pPrivData->total_packet_size - packet_offset > 0)
{
tvb = tvb_new_subset(tvb, packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset);
if( h263_handle )
call_dissector(h263_handle, tvb, pinfo, vocallonet_tree);
else
call_dissector(data_handle, tvb, pinfo, vocallonet_tree);
}
}
break;
#endif /* cOCTVOCNET_PKT_D_TYPE_ENUM_H263_RTP_RFC2190 */
#ifdef cOCTVOCNET_PKT_D_TYPE_ENUM_H264_RTP_RFC3984
case cOCTVOCNET_PKT_D_TYPE_ENUM_H264_RTP_RFC3984:
{
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "H264" );
if (pPrivData->total_packet_size - packet_offset > 0)
{
tvb = tvb_new_subset(tvb, packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset);
if( h264_handle )
call_dissector(h264_handle, tvb, pinfo, vocallonet_tree);
else
call_dissector(data_handle, tvb, pinfo, vocallonet_tree);
}
}
break;
#endif /* cOCTVOCNET_PKT_D_TYPE_ENUM_H264_RTP_RFC3984 */
#ifdef cOCTVOCNET_PKT_D_TYPE_ENUM_AMR_RTP
case cOCTVOCNET_PKT_D_TYPE_ENUM_AMR_RTP:
case cOCTVOCNET_PKT_D_TYPE_ENUM_AMR_WB_RTP:
{
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "AMR" );
if (pPrivData->total_packet_size - packet_offset > 0)
{
tvb = tvb_new_subset(tvb, packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset,
pPrivData->total_packet_size - pPrivData->pktHdt_size - packet_offset);
if( amr_handle )
call_dissector(amr_handle, tvb, pinfo, vocallonet_tree);
else
call_dissector(data_handle, tvb, pinfo, vocallonet_tree);
}
}
break;
#endif /* cOCTVOCNET_PKT_D_TYPE_ENUM_AMR_RTP */
default:
{
/* Remaining bytes are the packet's data */
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 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 += 20;
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 + 20;
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_ETH:
{
if (tvb_reported_length_remaining(tvb, packet_offset) > 0)
{
tvb = tvb_new_subset(tvb, packet_offset, -1, -1);
call_dissector(eth_handle, tvb, pinfo, vocallonet_tree);
}
}
break;
case cOCTVOCNET_PKT_SUBTYPE_IP:
{
if (tvb_reported_length_remaining(tvb, packet_offset) > 0)
{
tvb = tvb_new_subset(tvb, packet_offset, -1, -1);
call_dissector(ip_handle, tvb, pinfo, vocallonet_tree);
}
}
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;
#ifdef cOCTVOCNET_PKT_SUBTYPE_VIDEO_IMAGE_DESCRIPTOR
case cOCTVOCNET_PKT_SUBTYPE_VIDEO_IMAGE_DESCRIPTOR:
{
guint32 length_remaining = tvb_reported_length_remaining(tvb, packet_offset);
if ( length_remaining > 0 )
{
tvb = tvb_new_subset(tvb, packet_offset, -1, -1);
call_dissector(data_handle, tvb, pinfo, vocallonet_tree);
}
}
break;
#endif /* cOCTVOCNET_PKT_SUBTYPE_VIDEO_IMAGE_DESCRIPTOR */
case cOCTVOCNET_PKT_SUBTYPE_UDP_PAYLOAD:
case cOCTVOCNET_PKT_SUBTYPE_TCP_PAYLOAD:
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 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_A:
{
dissect_vocallonet_a_packet(tvb, pinfo, tree, offset);
}
break;
case cOCTVOCNET_PKT_FORMAT_D:
{
dissect_vocallonet_d_packet(tvb, ti, pinfo, tree, offset, vocallonet_tree);
}
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 external fields (formats a-q) */
{ &hf_vocallonet_data_socket_handle,
{ "Socket Handle", "vocallonet.data.socket_handle",
FT_UINT16, BASE_HEX, NULL, 0x0,
"Socket Handle", HFILL }
},
/* Common packet data fields (formats b-f) */
{ &hf_vocallonet_data_logical_object_handle_high,
{ "Object Handle (high)", "vocallonet.data.logical_object_handle.high",
// FT_UINT16, BASE_HEX, NULL, 0x0, Sygag : check if the two first bytes are reserved
FT_UINT32, BASE_HEX, NULL, 0x0,
"Logical object handle (high nibble)", HFILL }
},
{ &hf_vocallonet_data_logical_object_handle_middle,
{ "Object Handle (middle)", "vocallonet.data.logical_object_handle.middle",
FT_UINT32, BASE_HEX, NULL, 0x0,
"Logical object handle (middle nibble)", HFILL }
},
{ &hf_vocallonet_data_logical_object_handle_low,
{ "Object Handle (low)", "vocallonet.data.logical_object_handle.low",
FT_UINT32, BASE_HEX, NULL, 0x0,
"Logical object handle (low nibble)", 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_d_data[] =
{
/* Packet format D fields (voice) */
{ &hf_vocallonet_d_timestamp,
{ "Timestamp", "vocallonet.d.timestamp",
FT_UINT32, BASE_HEX, NULL, 0x0,
"Packet timestamp", HFILL }
},
{ &hf_vocallonet_d_marker,
{ "Marker", "vocallonet.d.marker",
FT_UINT32, BASE_HEX, NULL, 0x00800000,
"Marker bit", HFILL }
},
{ &hf_vocallonet_d_valid_rtp,
{ "Valid RTP", "vocallonet.d.valid_rtp",
FT_BOOLEAN, 32, NULL, 0x80000000,
"Valid RTP", HFILL }
},
{ &hf_vocallonet_d_encoding_type,
{ "Encoding type", "vocallonet.d.encoding_type",
FT_UINT32, BASE_HEX, VALS(vocallonet_d_encoding_type_vals), 0x7fc00000,
"Encoding type", HFILL }
},
{ &hf_vocallonet_d_sequence_number,
{ "Sequence number", "vocallonet.d.sequence_number",
FT_UINT32, BASE_HEX, NULL, 0x0000ffff,
"Sequence number", HFILL }
},
{ &hf_vocallonet_d_rtp_pad_size,
{ "Rtp padding size", "vocallonet.d.rtp_pad_size",
FT_UINT32, BASE_HEX, NULL, 0x003fc000,
"Rtp padding size", HFILL }
},
{ &hf_vocallonet_d_rtp_payload_offset ,
{ "Rtp payload offset", "vocallonet.d.rtp_payload_offset",
FT_UINT32, BASE_HEX, NULL, 0x00003fff,
"Rtp payload offset", HFILL }
},
{ &hf_vocallonet_d_rtp_version,
{ "Rtp version", "vocallonet.d.rtp_version",
FT_UINT32, BASE_HEX, NULL, 0xc0000000,
"Rtp version", HFILL }
},
{ &hf_vocallonet_d_rtp_padding,
{ "Rtp padding", "vocallonet.d.rtp_padding",
FT_UINT32, BASE_HEX, NULL, 0x20000000,
"Rtp padding bit", HFILL }
},
{ &hf_vocallonet_d_rtp_extension,
{ "Rtp extension", "vocallonet.d.rtp_extension",
FT_UINT32, BASE_HEX, NULL, 0x10000000,
"Rtp extension bit", HFILL }
},
{ &hf_vocallonet_d_rtp_csrc_count,
{ "Rtp CSRC count", "vocallonet.d.rtp_csrc_count",
FT_UINT32, BASE_HEX, NULL, 0x0f000000,
"Rtp CSRC count", HFILL }
},
{ &hf_vocallonet_d_rtp_payload_type,
{ "Rtp payload type", "vocallonet.d.rtp_payload_type",
FT_UINT32, BASE_HEX, NULL, 0x007f0000,
"Rtp payload type", HFILL }
},
{ &hf_vocallonet_d_rtp_sync_source,
{ "Rtp synchronisation source identifier", "vocallonet.d.rtp_sync_source",
FT_UINT32, BASE_HEX, NULL, 0x0,
"Rtp synchronisation source identifier", HFILL }
},
{ &hf_vocallonet_d_VocFlag_BFI,
{ "BFI", "vocallonet.d.BFI",
FT_UINT32, BASE_HEX, NULL, 0x00000008,
"BFI bit", HFILL }
},
{ &hf_vocallonet_d_VocFlag_TAF,
{ "TAF", "vocallonet.d.TAF",
FT_UINT32, BASE_HEX, NULL, 0x00000004,
"TAF bit", HFILL }
},
{ &hf_vocallonet_d_VocFlag_SID,
{ "SID", "vocallonet.d.SID",
FT_UINT32, BASE_HEX, NULL, 0x00000003,
"SID bit", 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_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_data,
&ett_vocallonet_f_data,
&ett_vocallonet_a_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_a_data = proto_register_protocol( "Vocallo A format data packet",
"Octasic Vocallonet A-Data", "vocallonet_a_data");
proto_vocallonet_d_data = proto_register_protocol( "Vocallo D format data packet",
"Octasic Vocallonet D-Data", "vocallonet_d_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_data, hf_vocallonet_d_data, array_length(hf_vocallonet_d_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");
rfc4175_yuv_handle = find_dissector("rfc4175_yuv");
yuv_extended_handle = find_dissector("yuv_extended");
octvc1_event_handle = find_dissector("Octvc1_Event");
octpkt_handle = find_dissector("OctPkt");
macroblock_handle = find_dissector("macro_blocks");
eth_handle = find_dissector("eth_withoutfcs");
ip_handle = find_dissector("ip");
lapd_handle = find_dissector("lapd");
h263_handle = find_dissector("h263");
h263p_handle = find_dissector("h263P");
h264_handle = find_dissector("h264");
hMpeg4_handle = find_dissector("mp4ves");
hT38_handle = find_dissector("t38");
amr_handle = find_dissector("amr");
}