wireshark/epan/dissectors/packet-h224.c

792 lines
29 KiB
C
Raw Normal View History

/* 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:
*/