792 lines
29 KiB
C
792 lines
29 KiB
C
/* packet-h224.c
|
||
* Routines for H.224 dissection
|
||
* Copyright 2022, Anders Broman <anders.broman@ericsson.com>
|
||
*
|
||
* Wireshark - Network traffic analyzer
|
||
* By Gerald Combs <gerald@wireshark.org>
|
||
* Copyright 1998 Gerald Combs
|
||
*
|
||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||
*/
|
||
|
||
/*
|
||
RFC description H.224 in SDP: RFC4573 https://www.rfc-editor.org/rfc/rfc4573.html
|
||
H.281 - FECC protocol H.281 https://www.itu.int/rec/T-REC-H.281/en
|
||
H.224 - transport encapsulation for FECC H.224 https://www.itu.int/rec/T-REC-H.224-200501-I/en
|
||
H.323 Annex Q - packing description H.224 in RTP H.323 https://www.itu.int/rec/T-REC-H.323-202203-I
|
||
*/
|
||
|
||
#include <config.h>
|
||
|
||
|
||
#include <epan/packet.h>
|
||
#include <epan/proto.h>
|
||
#include <epan/t35.h>
|
||
//#include <epan/expert.h>
|
||
//#include <epan/prefs.h>
|
||
|
||
/* Prototypes */
|
||
void proto_reg_handoff_h224(void);
|
||
void proto_register_h224(void);
|
||
|
||
/* Initialize the protocol and registered fields */
|
||
static int proto_h224 = -1;
|
||
static int hf_h224_q922_dlci_priority = -1;
|
||
static int hf_h224_q922_ctl = -1;
|
||
static int hf_h224_dta = -1;
|
||
static int hf_h224_sta = -1;
|
||
static int hf_h224_reserved = -1;
|
||
static int hf_h224_standard_client_id = -1;
|
||
static int hf_h224_extended_client_id_list = -1;
|
||
static int hf_h224_non_standard_client = -1;
|
||
static int hf_h224_extended_client_id = -1;
|
||
static int hf_h224_country_code = -1;
|
||
static int hf_h224_extension = -1;
|
||
static int hf_h224_manufacturer_code = -1;
|
||
static int hf_h224_client_id_manufacturer = -1;
|
||
|
||
static int hf_h224_es_b7 = -1;
|
||
static int hf_h224_bs_b6 = -1;
|
||
static int hf_h224_c1_b5 = -1;
|
||
static int hf_h224_c2_b4 = -1;
|
||
static int hf_h224_seg_b3b0 = -1;
|
||
static int hf_h224_other_client_data = -1;
|
||
|
||
static int hf_h224_client_list_code = -1;
|
||
static int hf_h224_extra_caps_code = -1;
|
||
static int hf_h224_response_code = -1;
|
||
static int hf_h224_number_of_clients = -1;
|
||
static int hf_h224_ex_caps_bit = -1;
|
||
static int hf_h224_caps_reserved = -1;
|
||
static int hf_h224_brd_svs = -1;
|
||
static int hf_h224_number_of_presets = -1;
|
||
static int hf_h224_vs_id = -1;
|
||
static int hf_h224_vs_reserved_b3 = -1;
|
||
static int hf_h224_vs_reserved_b3b0 = -1;
|
||
static int hf_h224_motion_video = -1;
|
||
static int hf_h224_norm_res_si = -1;
|
||
static int hf_h224_dbl_res_si = -1;
|
||
static int hf_h224_pan_cap = -1;
|
||
static int hf_h224_tilt_cap = -1;
|
||
static int hf_h224_zoom_cap = -1;
|
||
static int hf_h224_focus_cap = -1;
|
||
static int hf_h224_encoded_characters = -1;
|
||
static int hf_h224_end_octet = -1;
|
||
static int hf_h224_command_code = -1;
|
||
static int hf_h224_message_pan = -1;
|
||
static int hf_h224_message_pan_dir = -1;
|
||
static int hf_h224_message_tilt = -1;
|
||
static int hf_h224_message_tilt_dir = -1;
|
||
static int hf_h224_message_zoom = -1;
|
||
static int hf_h224_message_zoom_dir = -1;
|
||
static int hf_h224_message_focus = -1;
|
||
static int hf_h224_message_focus_dir = -1;
|
||
static int hf_h224_message_reserved_b7b4 = -1;
|
||
static int hf_h224_message_reserved_b3b2 = -1;
|
||
static int hf_h224_message_reserved_b3b0 = -1;
|
||
static int hf_h224_message_vs_m1 = -1;
|
||
static int hf_h224_message_vs_m0 = -1;
|
||
static int hf_h224_message_timeout = -1;
|
||
static int hf_h224_message_preset_number = -1;
|
||
|
||
//static expert_field ei_h224_EXPERTABBREV = EI_INIT;
|
||
|
||
static dissector_handle_t h224_handle;
|
||
|
||
/* Initialize the subtree pointers */
|
||
static gint ett_h224 = -1;
|
||
|
||
/* Definition of DLCI data priority's masks */
|
||
#define H224_DATA_PRI_MASK 0xFCF0
|
||
|
||
#define FECC_MAX_LENGTH_ASCII_STR 16
|
||
#define TIMEOUT_INTERVALS 50
|
||
#define MAX_TIMEOUT_VALUE 800
|
||
|
||
/* Definition of Standard Client IDs */
|
||
#define H224_CME_CLIENT_ID 0x00
|
||
#define H224_FECC_CLIENT_ID 0x01
|
||
#define H224_EXTENED_CLIENT_ID 0x7E
|
||
#define H224_NON_STANDARD_CLIENT_ID 0x7F
|
||
|
||
/* definitions of CME messages type */
|
||
#define CME_MSG_Client_List_Message 0x0100
|
||
#define CME_MSG_Client_List_Command 0x01FF
|
||
#define CME_MSG_Extra_Capabilities_Message 0x0200
|
||
#define CME_MSG_Extra_Capabilities_Command 0x02FF
|
||
|
||
/* definitions of FECC messages type */
|
||
#define FECC_MSG_START_ACTION_REQ 0x01
|
||
#define FECC_MSG_CONTINUE_ACTION_REQ 0x02
|
||
#define FECC_MSG_STOP_ACTION_REQ 0x03
|
||
#define FECC_MSG_SELECT_VIDEO_SOURCE_REQ 0x04
|
||
#define FECC_MSG_VIDEO_SOURCE_SWITCHED_IND 0x05
|
||
#define FECC_MSG_STORE_AS_PRESET_REQ 0x06
|
||
#define FECC_MSG_ACTIVATE_PRESET_REQ 0x07
|
||
|
||
static guint dissect_h224_cme_client_data(tvbuff_t* tvb, proto_tree* tree, guint offset);
|
||
static guint dissect_h224_fecc_client_data(tvbuff_t* tvb, proto_tree* tree, guint offset);
|
||
static guint dissect_h224_extended_client_data(tvbuff_t* tvb, proto_tree* tree, guint offset);
|
||
static guint dissect_h224_non_standard_client_data(tvbuff_t* tvb, proto_tree* tree, guint offset);
|
||
|
||
typedef struct {
|
||
int optcode;
|
||
guint (*decode) (tvbuff_t*, proto_tree*, guint);
|
||
} h224_opt_t;
|
||
|
||
static const h224_opt_t h224opt[] = {
|
||
/* CME */ {H224_CME_CLIENT_ID, dissect_h224_cme_client_data},
|
||
/* FECC */ {H224_FECC_CLIENT_ID, dissect_h224_fecc_client_data},
|
||
/* EXTENED */ {H224_EXTENED_CLIENT_ID, dissect_h224_extended_client_data},
|
||
/* NON_STANDARD */ {H224_NON_STANDARD_CLIENT_ID, dissect_h224_non_standard_client_data},
|
||
{0, NULL}
|
||
};
|
||
|
||
/* DLCI address for data priority */
|
||
static const value_string h224_data_priority[] =
|
||
{
|
||
{ 6, "Low Priority Data" },
|
||
{ 7, "High Priority Data" },
|
||
{ 0, NULL },
|
||
};
|
||
|
||
static const value_string h224_client_data_type[] =
|
||
{
|
||
{ H224_CME_CLIENT_ID, "Client Data For CME(Client Management Entity)" },
|
||
{ H224_FECC_CLIENT_ID, "Client Data For FECC(Far-End Camera Control)" },
|
||
{ H224_EXTENED_CLIENT_ID, "Client Data For Extended Client ID list" },
|
||
{ H224_NON_STANDARD_CLIENT_ID, "Client Data For Non-standard client" },
|
||
{ 0, NULL}
|
||
};
|
||
|
||
static const value_string h224_fecc_message_type[] =
|
||
{
|
||
{ FECC_MSG_START_ACTION_REQ, "START ACTION Request" },
|
||
{ FECC_MSG_CONTINUE_ACTION_REQ, "CONTINUE ACTION Request" },
|
||
{ FECC_MSG_STOP_ACTION_REQ, "STOP ACTION Request" },
|
||
{ FECC_MSG_SELECT_VIDEO_SOURCE_REQ, "SELECT VIDEO SOURCE Request" },
|
||
{ FECC_MSG_VIDEO_SOURCE_SWITCHED_IND, "VIDEO SOURCE SWITCHED indication" },
|
||
{ FECC_MSG_STORE_AS_PRESET_REQ, "STORE AS PRESET Request" },
|
||
{ FECC_MSG_ACTIVATE_PRESET_REQ, "ACTIVATE PRESET Request" },
|
||
{ 0, NULL },
|
||
};
|
||
|
||
static value_string_ext h224_client_data_ext = VALUE_STRING_EXT_INIT(h224_client_data_type);
|
||
|
||
static guint
|
||
dissect_h224_standard_clients_ids(tvbuff_t* tvb, proto_tree* tree, guint offset, guint8 client_id)
|
||
{
|
||
guint32 manufacturer_code;
|
||
|
||
if (client_id == H224_EXTENED_CLIENT_ID) {
|
||
proto_tree_add_item(tree, hf_h224_extended_client_id_list, tvb, offset, 1, ENC_NA);
|
||
offset++;
|
||
proto_tree_add_item(tree, hf_h224_extended_client_id, tvb, offset, 1, ENC_NA);
|
||
offset++;
|
||
} else if (client_id == H224_NON_STANDARD_CLIENT_ID){
|
||
proto_tree_add_item(tree, hf_h224_non_standard_client, tvb, offset, 1, ENC_NA);
|
||
offset++;
|
||
manufacturer_code = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
|
||
proto_tree_add_item(tree, hf_h224_country_code, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
offset += 1;
|
||
proto_tree_add_item(tree, hf_h224_extension, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
offset += 1;
|
||
proto_tree_add_uint(tree, hf_h224_manufacturer_code, tvb, offset - 2, 4, manufacturer_code);
|
||
offset += 2;
|
||
proto_tree_add_item(tree, hf_h224_client_id_manufacturer, tvb, offset, 1, ENC_NA);
|
||
offset++;
|
||
} else {
|
||
proto_tree_add_item(tree, hf_h224_standard_client_id, tvb, offset, 1, ENC_NA);
|
||
offset++;
|
||
}
|
||
return offset;
|
||
}
|
||
|
||
static guint
|
||
dissect_h224_cme_client_data(tvbuff_t* tvb, proto_tree* tree, guint offset)
|
||
{
|
||
guint16 type;
|
||
guint8 num;
|
||
guint8 oct;
|
||
guint8 source_id;
|
||
guint8 zero_offset;
|
||
proto_tree *ext_tree;
|
||
|
||
ext_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_h224, NULL,
|
||
val_to_str_ext_const(H224_CME_CLIENT_ID, &h224_client_data_ext, "Unknown field"));
|
||
type = tvb_get_guint16(tvb, offset, ENC_BIG_ENDIAN);
|
||
switch (type) {
|
||
case CME_MSG_Client_List_Message:
|
||
proto_tree_add_item(ext_tree, hf_h224_client_list_code, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
proto_tree_add_item(ext_tree, hf_h224_response_code, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
proto_tree_add_item(ext_tree, hf_h224_number_of_clients, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
num = tvb_get_guint8(tvb, offset);
|
||
offset++;
|
||
proto_tree_add_item(ext_tree, hf_h224_ex_caps_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
for (int i = 0; i < num; i++) {
|
||
oct = tvb_get_guint8(tvb, offset);
|
||
offset = dissect_h224_standard_clients_ids(tvb, ext_tree, offset, (oct & 0x7f));
|
||
}
|
||
break;
|
||
case CME_MSG_Client_List_Command:
|
||
proto_tree_add_item(ext_tree, hf_h224_client_list_code, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
proto_tree_add_item(ext_tree, hf_h224_response_code, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
break;
|
||
case CME_MSG_Extra_Capabilities_Message:
|
||
proto_tree_add_item(ext_tree, hf_h224_extra_caps_code, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
proto_tree_add_item(ext_tree, hf_h224_response_code, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
proto_tree_add_item(ext_tree, hf_h224_ex_caps_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
oct = tvb_get_guint8(tvb, offset);
|
||
offset = dissect_h224_standard_clients_ids(tvb, ext_tree, offset, oct);
|
||
if ((oct & 0x7f) == 0x01) {
|
||
static int* const fecc_number_of_presets[] = {
|
||
&hf_h224_caps_reserved,
|
||
&hf_h224_brd_svs,
|
||
&hf_h224_number_of_presets,
|
||
NULL
|
||
};
|
||
proto_tree_add_bitmask_list(ext_tree, tvb, offset, 1, fecc_number_of_presets, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
oct = tvb_get_guint8(tvb, offset);
|
||
static int* const fecc_vrs_capabilities[] = {
|
||
&hf_h224_vs_id,
|
||
&hf_h224_vs_reserved_b3,
|
||
&hf_h224_motion_video,
|
||
&hf_h224_norm_res_si,
|
||
&hf_h224_dbl_res_si,
|
||
NULL
|
||
};
|
||
proto_tree_add_bitmask_list(ext_tree, tvb, offset, 1, fecc_vrs_capabilities, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
source_id = (oct & 0xf0) >> 4;
|
||
if (source_id > 5) {
|
||
zero_offset = tvb_find_guint8(tvb, offset, FECC_MAX_LENGTH_ASCII_STR, 0);
|
||
if (zero_offset > offset) {
|
||
proto_tree_add_item(ext_tree, hf_h224_encoded_characters, tvb, offset, zero_offset - offset, ENC_ASCII);
|
||
offset = zero_offset;
|
||
proto_tree_add_item(ext_tree, hf_h224_end_octet, tvb, offset, 1, ENC_NA);
|
||
offset++;
|
||
}
|
||
}
|
||
static int* const fecc_caps_ability[] = {
|
||
&hf_h224_pan_cap,
|
||
&hf_h224_tilt_cap,
|
||
&hf_h224_zoom_cap,
|
||
&hf_h224_focus_cap,
|
||
&hf_h224_vs_reserved_b3b0,
|
||
NULL
|
||
};
|
||
proto_tree_add_bitmask_list(ext_tree, tvb, offset, 1, fecc_caps_ability, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
}
|
||
break;
|
||
case CME_MSG_Extra_Capabilities_Command:
|
||
proto_tree_add_item(ext_tree, hf_h224_extra_caps_code, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
proto_tree_add_item(ext_tree, hf_h224_response_code, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
proto_tree_add_item(ext_tree, hf_h224_ex_caps_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
oct = tvb_get_guint8(tvb, offset);
|
||
offset = dissect_h224_standard_clients_ids(tvb, ext_tree, offset, oct);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return offset;
|
||
}
|
||
|
||
static guint
|
||
dissect_h224_fecc_client_data(tvbuff_t* tvb, proto_tree* tree, guint offset)
|
||
{
|
||
guint8 oct;
|
||
proto_tree *ext_tree;
|
||
|
||
ext_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_h224, NULL,
|
||
val_to_str_ext_const(H224_FECC_CLIENT_ID, &h224_client_data_ext, "Unknown field"));
|
||
oct = tvb_get_guint8(tvb, offset);
|
||
proto_tree_add_item(ext_tree, hf_h224_command_code, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
static int* const fecc_message_action[] = {
|
||
&hf_h224_message_pan,
|
||
&hf_h224_message_pan_dir,
|
||
&hf_h224_message_tilt,
|
||
&hf_h224_message_tilt_dir,
|
||
&hf_h224_message_zoom,
|
||
&hf_h224_message_zoom_dir,
|
||
&hf_h224_message_focus,
|
||
&hf_h224_message_focus_dir,
|
||
NULL
|
||
};
|
||
switch(oct) {
|
||
case FECC_MSG_START_ACTION_REQ:
|
||
{
|
||
guint16 timeout;
|
||
proto_tree_add_bitmask_list(ext_tree, tvb, offset, 1, fecc_message_action, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
proto_tree_add_item(ext_tree, hf_h224_message_reserved_b7b4, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
oct = tvb_get_guint8(tvb, offset);
|
||
timeout = (oct & 0x0f) ? (oct * TIMEOUT_INTERVALS) : MAX_TIMEOUT_VALUE;
|
||
proto_tree_add_uint_format(ext_tree, hf_h224_message_timeout, tvb, offset, 1, oct,"%u (%u milliseconds)", oct, timeout);
|
||
offset++;
|
||
break;
|
||
}
|
||
case FECC_MSG_CONTINUE_ACTION_REQ:
|
||
case FECC_MSG_STOP_ACTION_REQ:
|
||
proto_tree_add_bitmask_list(ext_tree, tvb, offset, 1, fecc_message_action, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
break;
|
||
case FECC_MSG_SELECT_VIDEO_SOURCE_REQ:
|
||
case FECC_MSG_VIDEO_SOURCE_SWITCHED_IND:
|
||
{
|
||
static int* const fecc_message_m1m0[] = {
|
||
&hf_h224_vs_id,
|
||
&hf_h224_message_reserved_b3b2,
|
||
&hf_h224_message_vs_m1,
|
||
&hf_h224_message_vs_m0,
|
||
NULL
|
||
};
|
||
proto_tree_add_bitmask_list(ext_tree, tvb, offset, 1, fecc_message_m1m0, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
break;
|
||
}
|
||
case FECC_MSG_STORE_AS_PRESET_REQ:
|
||
case FECC_MSG_ACTIVATE_PRESET_REQ:
|
||
{
|
||
static int* const fecc_message_preset_num[] = {
|
||
&hf_h224_message_preset_number,
|
||
&hf_h224_message_reserved_b3b0,
|
||
NULL
|
||
};
|
||
proto_tree_add_bitmask_list(ext_tree, tvb, offset, 1, fecc_message_preset_num, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
return offset;
|
||
}
|
||
|
||
static guint dissect_h224_extended_client_data(tvbuff_t* tvb, proto_tree* tree, guint offset) {
|
||
proto_tree *ext_tree;
|
||
|
||
ext_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_h224, NULL,
|
||
val_to_str_ext_const(H224_EXTENED_CLIENT_ID, &h224_client_data_ext, "Unknown field"));
|
||
proto_tree_add_item(ext_tree, hf_h224_other_client_data, tvb, offset, -1, ENC_NA);
|
||
offset++;
|
||
return offset;
|
||
}
|
||
|
||
static guint dissect_h224_non_standard_client_data(tvbuff_t* tvb, proto_tree* tree, guint offset) {
|
||
proto_tree *ext_tree;
|
||
|
||
ext_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_h224, NULL,
|
||
val_to_str_ext_const(H224_NON_STANDARD_CLIENT_ID, &h224_client_data_ext, "Unknown field"));
|
||
proto_tree_add_item(ext_tree, hf_h224_other_client_data, tvb, offset, -1, ENC_NA);
|
||
offset++;
|
||
return offset;
|
||
}
|
||
/* Code to actually dissect the packets */
|
||
static int
|
||
dissect_h224(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
|
||
{
|
||
proto_item* ti;
|
||
proto_tree* h224_tree;
|
||
guint offset = 0;
|
||
guint8 oct;
|
||
|
||
|
||
/* Set the Protocol column in the summary display */
|
||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "H.224");
|
||
|
||
ti = proto_tree_add_item(tree, proto_h224, tvb, offset, -1, ENC_NA);
|
||
h224_tree = proto_item_add_subtree(ti, ett_h224);
|
||
|
||
/* On IP transport networks, the H.224 protocol octet structure shall be the same as Figure 2/H.224
|
||
* except that the HDLC bit stuffing, HDLC flags and HDLC Frame Check Sequence shall be omitted.
|
||
*/
|
||
/* The 10-bit DLCI address for data priority */
|
||
proto_tree_add_item(h224_tree, hf_h224_q922_dlci_priority, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||
offset += 2;
|
||
/* Q.922 UI-Mode format 1 octets */
|
||
proto_tree_add_item(h224_tree, hf_h224_q922_ctl, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||
offset += 1;
|
||
/* Destination terminal address 2 octets */
|
||
proto_tree_add_item(h224_tree, hf_h224_dta, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||
offset += 2;
|
||
/* Source terminal address 2 octets */
|
||
proto_tree_add_item(h224_tree, hf_h224_sta, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||
offset += 2;
|
||
proto_tree_add_item(h224_tree, hf_h224_reserved, tvb, offset, 1, ENC_NA);
|
||
|
||
/*
|
||
* CLIENT ID: The client to receive the contents of the datagram. The Client ID may be any
|
||
* of the following formats:
|
||
* - Standard Client ID – Single octet.
|
||
* - Extended Client ID – Two octets (0x7E, extended Client ID).
|
||
* - Non-standard Client ID – Six octets (0x7F, country, manufacturer code, ID)
|
||
*/
|
||
oct = tvb_get_guint8(tvb, offset);
|
||
offset = dissect_h224_standard_clients_ids(tvb, h224_tree, offset, oct);
|
||
|
||
static int* const h224_flags[] = {
|
||
&hf_h224_es_b7,
|
||
&hf_h224_bs_b6,
|
||
&hf_h224_c1_b5,
|
||
&hf_h224_c2_b4,
|
||
&hf_h224_seg_b3b0,
|
||
NULL
|
||
};
|
||
|
||
proto_tree_add_bitmask_list(h224_tree, tvb, offset, 1, h224_flags, ENC_BIG_ENDIAN);
|
||
offset++;
|
||
|
||
/* Data */
|
||
int i = -1;
|
||
while (h224opt[++i].decode) {
|
||
if (h224opt[i].optcode == oct) {
|
||
h224opt[i].decode(tvb, h224_tree, offset);
|
||
break;
|
||
}
|
||
}
|
||
return tvb_reported_length(tvb);
|
||
}
|
||
|
||
/* Register the protocol with Wireshark. */
|
||
void
|
||
proto_register_h224(void)
|
||
{
|
||
//module_t *h224_module;
|
||
//expert_module_t *expert_h224;
|
||
|
||
static hf_register_info hf[] = {
|
||
{ &hf_h224_q922_dlci_priority,
|
||
{ "Q.922 DLCI Priority", "h224.q922_dlci_pri",
|
||
FT_UINT16, BASE_HEX, VALS(h224_data_priority), H224_DATA_PRI_MASK,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_q922_ctl,
|
||
{ "Q.922 Control Octet", "h224.q922_ctl",
|
||
FT_UINT8, BASE_HEX, NULL, 0x0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_dta,
|
||
{ "Destination Terminal Address", "h224.dta",
|
||
FT_UINT16, BASE_DEC, NULL, 0x0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_sta,
|
||
{ "Source Terminal Address", "h224.sta",
|
||
FT_UINT16, BASE_DEC, NULL, 0x0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_reserved,
|
||
{ "Reserved", "h224.reserved",
|
||
FT_UINT8, BASE_DEC, NULL, 0x80,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_standard_client_id,
|
||
{ "Standard Client ID", "h224.standard_client_id",
|
||
FT_UINT8, BASE_HEX, NULL, 0x7f,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_extended_client_id_list,
|
||
{ "Extended Client ID List", "h224.extended_client_id_list",
|
||
FT_UINT8, BASE_HEX, NULL, 0x7f,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_non_standard_client,
|
||
{ "Non-standard Client", "h224.non_standard_client",
|
||
FT_UINT8, BASE_HEX, NULL, 0x7f,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_extended_client_id,
|
||
{ "Extended Client ID", "h224.extended_client_id",
|
||
FT_UINT8, BASE_HEX, NULL, 0x0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_country_code,
|
||
{ "Country code", "h224.country_code",
|
||
FT_UINT8, BASE_HEX, VALS(T35CountryCode_vals), 0x0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_extension,
|
||
{ "Extension", "h224.Extension",
|
||
FT_UINT8, BASE_HEX, NULL, 0x0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_manufacturer_code,
|
||
{ "Manufacturer code", "h224.manufacturer_code",
|
||
FT_UINT32, BASE_HEX, VALS(H221ManufacturerCode_vals), 0x0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_client_id_manufacturer,
|
||
{ "Manufacturer Client ID", "h224.manufacturer_client_id",
|
||
FT_UINT8, BASE_HEX, NULL, 0x0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_es_b7,
|
||
{ "Ending Segment(ES)", "h224.flag.es",
|
||
FT_BOOLEAN, 8, NULL, 0x80,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_bs_b6,
|
||
{ "Beginning Segment(BS)", "h224.flag.bs",
|
||
FT_BOOLEAN, 8, NULL, 0x40,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_c1_b5,
|
||
{ "C1", "h224.flag.c1",
|
||
FT_BOOLEAN, 8, NULL, 0x20,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_c2_b4,
|
||
{ "C0", "h224.flag.c0",
|
||
FT_BOOLEAN, 8, NULL, 0x10,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_seg_b3b0,
|
||
{ "Segment number", "h224.flags_seg",
|
||
FT_UINT8, BASE_DEC, NULL, 0x0f,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_client_list_code,
|
||
{ "Client List code", "h224.client_list_code",
|
||
FT_UINT8, BASE_HEX, NULL, 0x0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_extra_caps_code,
|
||
{ "Extra Capabilities code", "h224.ex_caps_code",
|
||
FT_UINT8, BASE_HEX, NULL, 0x0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_response_code,
|
||
{ "Response Code", "h224.response_code",
|
||
FT_UINT8, BASE_HEX, NULL, 0x0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_number_of_clients,
|
||
{ "Number of clients", "h224.number_of_clients",
|
||
FT_UINT8, BASE_DEC, NULL, 0x0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_ex_caps_bit,
|
||
{ "Extra Capabilities bit", "h224.ex_caps_bit",
|
||
FT_BOOLEAN, 8, NULL, 0x80,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_caps_reserved,
|
||
{ "Preset reserved", "h224.preset_reserved",
|
||
FT_UINT8, BASE_DEC, NULL, 0xe0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_brd_svs,
|
||
{ "Broadcast switch video sources", "h224.brd_svs",
|
||
FT_BOOLEAN, 8, NULL, 0x10,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_number_of_presets,
|
||
{ "Number of presets", "h224.number_of_presets",
|
||
FT_UINT8, BASE_DEC, NULL, 0x0f,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_vs_id,
|
||
{ "Video source id", "h224.vs_id",
|
||
FT_UINT8, BASE_DEC, NULL, 0xf0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_vs_reserved_b3,
|
||
{ "Reserved type", "h224.reserved_type",
|
||
FT_UINT8, BASE_DEC, NULL, 0x08,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_vs_reserved_b3b0,
|
||
{ "Reserved Capabilities", "h224.reserved_caps",
|
||
FT_UINT8, BASE_DEC, NULL, 0x0f,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_motion_video,
|
||
{ "Motion video", "h224.motion_video",
|
||
FT_BOOLEAN, 8, NULL, 0x04,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_norm_res_si,
|
||
{ "Normal resolution still image", "h224.norm_res_si",
|
||
FT_BOOLEAN, 8, NULL, 0x02,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_dbl_res_si,
|
||
{ "Double resolution still image", "h224.dbl_res_si",
|
||
FT_BOOLEAN, 8, NULL, 0x01,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_pan_cap,
|
||
{ "Pan Capability", "h224.pan_cap",
|
||
FT_BOOLEAN, 8, NULL, 0x80,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_tilt_cap,
|
||
{ "Tilt Capability", "h224.tilt_cap",
|
||
FT_BOOLEAN, 8, NULL, 0x40,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_zoom_cap,
|
||
{ "Zoom Capability", "h224.zoom_cap",
|
||
FT_BOOLEAN, 8, NULL, 0x20,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_focus_cap,
|
||
{ "Focus Capability", "h224.focus_cap",
|
||
FT_BOOLEAN, 8, NULL, 0x10,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_encoded_characters,
|
||
{ "Ascii String", "h224.ascii_str",
|
||
FT_STRING, BASE_NONE, NULL, 0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_end_octet,
|
||
{ "End octet", "h224.end_oct",
|
||
FT_UINT8, BASE_DEC, NULL, 0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_command_code,
|
||
{ "FECC Message Code", "h224.fecc_message_code",
|
||
FT_UINT8, BASE_HEX, VALS(h224_fecc_message_type), 0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_message_pan,
|
||
{ "Pan action", "h224.pan_action",
|
||
FT_BOOLEAN, 8, NULL, 0x80,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_message_pan_dir,
|
||
{ "Pan direction", "h224.pan_dir",
|
||
FT_BOOLEAN, 8, NULL, 0x40,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_message_tilt,
|
||
{ "Tilt action", "h224.tilt_action",
|
||
FT_BOOLEAN, 8, NULL, 0x20,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_message_tilt_dir,
|
||
{ "Tilt direction", "h224.tilt_dir",
|
||
FT_BOOLEAN, 8, NULL, 0x10,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_message_zoom,
|
||
{ "Zoom action", "h224.zoom_action",
|
||
FT_BOOLEAN, 8, NULL, 0x08,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_message_zoom_dir,
|
||
{ "Zoom direction", "h224.zoom_dir",
|
||
FT_BOOLEAN, 8, NULL, 0x04,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_message_focus,
|
||
{ "Focus action", "h224.focus_action",
|
||
FT_BOOLEAN, 8, NULL, 0x02,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_message_focus_dir,
|
||
{ "Focus direction", "h224.focus_dir",
|
||
FT_BOOLEAN, 8, NULL, 0x01,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_message_reserved_b7b4,
|
||
{ "Action Reserved", "h224.act_reserved",
|
||
FT_UINT8, BASE_DEC, NULL, 0xf0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_message_reserved_b3b2,
|
||
{ "Mode Reserved", "h224.mode_reserved",
|
||
FT_UINT8, BASE_DEC, NULL, 0x0c,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_message_reserved_b3b0,
|
||
{ "Activate Preset Reserved", "h224.ap_reserved",
|
||
FT_UINT8, BASE_DEC, NULL, 0x0f,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_message_vs_m1,
|
||
{ "M1", "h224.vs_m1",
|
||
FT_UINT8, BASE_DEC, NULL, 0x02,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_message_vs_m0,
|
||
{ "M0", "h224.vs_m0",
|
||
FT_UINT8, BASE_DEC, NULL, 0x01,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_message_timeout,
|
||
{ "Timeout", "h224.timeout",
|
||
FT_UINT8, BASE_DEC, NULL, 0x0f,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_message_preset_number,
|
||
{ "Preset Number", "h224.preset_number",
|
||
FT_UINT8, BASE_DEC, NULL, 0xf0,
|
||
NULL, HFILL }
|
||
},
|
||
{ &hf_h224_other_client_data,
|
||
{ "Client data", "h224.client_data",
|
||
FT_BYTES, BASE_NONE, NULL, 0x0,
|
||
NULL, HFILL }
|
||
},
|
||
};
|
||
static gint *ett[] = {
|
||
&ett_h224
|
||
};
|
||
|
||
/* Setup protocol expert items */
|
||
//static ei_register_info ei[] = {
|
||
// { &ei_h224_EXPERTABBREV,
|
||
// { "h224.EXPERTABBREV", PI_GROUP, PI_SEVERITY,
|
||
// "EXPERTDESCR", EXPFILL }
|
||
// }
|
||
//};
|
||
|
||
/* Register the protocol name and description */
|
||
proto_h224 = proto_register_protocol("H.224", "H.224", "h224");
|
||
|
||
/* Register the header fields and subtrees */
|
||
proto_register_field_array(proto_h224, hf, array_length(hf));
|
||
proto_register_subtree_array(ett, array_length(ett));
|
||
|
||
/* Register expert items */
|
||
// expert_h224 = expert_register_protocol(proto_h224);
|
||
// expert_register_field_array(expert_h224, ei, array_length(ei));
|
||
|
||
h224_handle = register_dissector("h224", dissect_h224, proto_h224);
|
||
|
||
|
||
}
|
||
|
||
void
|
||
proto_reg_handoff_h224(void)
|
||
{
|
||
dissector_add_string("rtp_dyn_payload_type", "H224", h224_handle);
|
||
dissector_add_for_decode_as("rtp.pt", h224_handle);
|
||
}
|
||
|
||
/*
|
||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||
*
|
||
* Local variables:
|
||
* c-basic-offset: 4
|
||
* tab-width: 8
|
||
* indent-tabs-mode: nil
|
||
* End:
|
||
*
|
||
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
||
* :indentSize=4:tabSize=8:noTabs=true:
|
||
*/
|