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