/src/wireshark/epan/dissectors/packet-h224.c
Line | Count | Source |
1 | | /* packet-h224.c |
2 | | * Routines for H.224 dissection |
3 | | * Copyright 2022, Anders Broman <anders.broman@ericsson.com> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | */ |
11 | | |
12 | | /* |
13 | | RFC description H.224 in SDP: RFC4573 https://www.rfc-editor.org/rfc/rfc4573.html |
14 | | H.281 - FECC protocol H.281 https://www.itu.int/rec/T-REC-H.281/en |
15 | | H.224 - transport encapsulation for FECC H.224 https://www.itu.int/rec/T-REC-H.224-200501-I/en |
16 | | H.323 Annex Q - packing description H.224 in RTP H.323 https://www.itu.int/rec/T-REC-H.323-202203-I |
17 | | */ |
18 | | |
19 | | #include <config.h> |
20 | | |
21 | | #include <wsutil/array.h> |
22 | | #include <epan/packet.h> |
23 | | #include <epan/proto.h> |
24 | | #include <epan/t35.h> |
25 | | #include <epan/tfs.h> |
26 | | //#include <epan/expert.h> |
27 | | //#include <epan/prefs.h> |
28 | | |
29 | | /* Prototypes */ |
30 | | void proto_reg_handoff_h224(void); |
31 | | void proto_register_h224(void); |
32 | | |
33 | | /* Initialize the protocol and registered fields */ |
34 | | static int proto_h224; |
35 | | static int hf_h224_q922_dlci_priority; |
36 | | static int hf_h224_q922_ctl; |
37 | | static int hf_h224_dta; |
38 | | static int hf_h224_sta; |
39 | | static int hf_h224_reserved; |
40 | | static int hf_h224_standard_client_id; |
41 | | static int hf_h224_extended_client_id_list; |
42 | | static int hf_h224_non_standard_client; |
43 | | static int hf_h224_extended_client_id; |
44 | | static int hf_h224_country_code; |
45 | | static int hf_h224_extension; |
46 | | static int hf_h224_manufacturer_code; |
47 | | static int hf_h224_client_id_manufacturer; |
48 | | |
49 | | static int hf_h224_es_b7; |
50 | | static int hf_h224_bs_b6; |
51 | | static int hf_h224_c1_b5; |
52 | | static int hf_h224_c2_b4; |
53 | | static int hf_h224_seg_b3b0; |
54 | | static int hf_h224_other_client_data; |
55 | | |
56 | | static int hf_h224_client_list_code; |
57 | | static int hf_h224_extra_caps_code; |
58 | | static int hf_h224_response_code; |
59 | | static int hf_h224_number_of_clients; |
60 | | static int hf_h224_ex_caps_bit; |
61 | | static int hf_h224_caps_reserved; |
62 | | static int hf_h224_brd_svs; |
63 | | static int hf_h224_number_of_presets; |
64 | | static int hf_h224_vs_id; |
65 | | static int hf_h224_vs_reserved_b3; |
66 | | static int hf_h224_vs_reserved_b3b0; |
67 | | static int hf_h224_motion_video; |
68 | | static int hf_h224_norm_res_si; |
69 | | static int hf_h224_dbl_res_si; |
70 | | static int hf_h224_pan_cap; |
71 | | static int hf_h224_tilt_cap; |
72 | | static int hf_h224_zoom_cap; |
73 | | static int hf_h224_focus_cap; |
74 | | static int hf_h224_encoded_characters; |
75 | | static int hf_h224_end_octet; |
76 | | static int hf_h224_command_code; |
77 | | static int hf_h224_message_pan; |
78 | | static int hf_h224_message_pan_dir; |
79 | | static int hf_h224_message_tilt; |
80 | | static int hf_h224_message_tilt_dir; |
81 | | static int hf_h224_message_zoom; |
82 | | static int hf_h224_message_zoom_dir; |
83 | | static int hf_h224_message_focus; |
84 | | static int hf_h224_message_focus_dir; |
85 | | static int hf_h224_message_reserved_b7b4; |
86 | | static int hf_h224_message_reserved_b3b2; |
87 | | static int hf_h224_message_reserved_b3b0; |
88 | | static int hf_h224_message_vs_m1; |
89 | | static int hf_h224_message_vs_m0; |
90 | | static int hf_h224_message_timeout; |
91 | | static int hf_h224_message_preset_number; |
92 | | |
93 | | //static expert_field ei_h224_EXPERTABBREV; |
94 | | |
95 | | static dissector_handle_t h224_handle; |
96 | | |
97 | | /* Initialize the subtree pointers */ |
98 | | static int ett_h224; |
99 | | |
100 | | /* Definition of DLCI data priority's masks */ |
101 | 15 | #define H224_DATA_PRI_MASK 0xFCF0 |
102 | | |
103 | 0 | #define FECC_MAX_LENGTH_ASCII_STR 16 |
104 | 0 | #define TIMEOUT_INTERVALS 50 |
105 | 0 | #define MAX_TIMEOUT_VALUE 800 |
106 | | |
107 | | /* Definition of Standard Client IDs */ |
108 | 0 | #define H224_CME_CLIENT_ID 0x00 |
109 | 0 | #define H224_FECC_CLIENT_ID 0x01 |
110 | 0 | #define H224_EXTENDED_CLIENT_ID 0x7E |
111 | 0 | #define H224_NON_STANDARD_CLIENT_ID 0x7F |
112 | | |
113 | | /* definitions of CME messages type */ |
114 | 0 | #define CME_MSG_Client_List_Message 0x0100 |
115 | 0 | #define CME_MSG_Client_List_Command 0x01FF |
116 | 0 | #define CME_MSG_Extra_Capabilities_Message 0x0200 |
117 | 0 | #define CME_MSG_Extra_Capabilities_Command 0x02FF |
118 | | |
119 | | /* definitions of FECC messages type */ |
120 | 0 | #define FECC_MSG_START_ACTION_REQ 0x01 |
121 | 0 | #define FECC_MSG_CONTINUE_ACTION_REQ 0x02 |
122 | 0 | #define FECC_MSG_STOP_ACTION_REQ 0x03 |
123 | 0 | #define FECC_MSG_SELECT_VIDEO_SOURCE_REQ 0x04 |
124 | 0 | #define FECC_MSG_VIDEO_SOURCE_SWITCHED_IND 0x05 |
125 | 0 | #define FECC_MSG_STORE_AS_PRESET_REQ 0x06 |
126 | 0 | #define FECC_MSG_ACTIVATE_PRESET_REQ 0x07 |
127 | | |
128 | | static unsigned dissect_h224_cme_client_data(tvbuff_t* tvb, proto_tree* tree, unsigned offset); |
129 | | static unsigned dissect_h224_fecc_client_data(tvbuff_t* tvb, proto_tree* tree, unsigned offset); |
130 | | static unsigned dissect_h224_extended_client_data(tvbuff_t* tvb, proto_tree* tree, unsigned offset); |
131 | | static unsigned dissect_h224_non_standard_client_data(tvbuff_t* tvb, proto_tree* tree, unsigned offset); |
132 | | |
133 | | typedef struct { |
134 | | int optcode; |
135 | | unsigned (*decode) (tvbuff_t*, proto_tree*, unsigned); |
136 | | } h224_opt_t; |
137 | | |
138 | | static const h224_opt_t h224opt[] = { |
139 | | /* CME */ {H224_CME_CLIENT_ID, dissect_h224_cme_client_data}, |
140 | | /* FECC */ {H224_FECC_CLIENT_ID, dissect_h224_fecc_client_data}, |
141 | | /* EXTENDED */ {H224_EXTENDED_CLIENT_ID, dissect_h224_extended_client_data}, |
142 | | /* NON_STANDARD */ {H224_NON_STANDARD_CLIENT_ID, dissect_h224_non_standard_client_data}, |
143 | | {0, NULL} |
144 | | }; |
145 | | |
146 | | /* DLCI address for data priority */ |
147 | | static const value_string h224_data_priority[] = |
148 | | { |
149 | | { 6, "Low Priority Data" }, |
150 | | { 7, "High Priority Data" }, |
151 | | { 0, NULL }, |
152 | | }; |
153 | | |
154 | | static const value_string h224_client_data_type[] = |
155 | | { |
156 | | { H224_CME_CLIENT_ID, "Client Data For CME(Client Management Entity)" }, |
157 | | { H224_FECC_CLIENT_ID, "Client Data For FECC(Far-End Camera Control)" }, |
158 | | { H224_EXTENDED_CLIENT_ID, "Client Data For Extended Client ID list" }, |
159 | | { H224_NON_STANDARD_CLIENT_ID, "Client Data For Non-standard client" }, |
160 | | { 0, NULL} |
161 | | }; |
162 | | |
163 | | static const value_string h224_fecc_message_type[] = |
164 | | { |
165 | | { FECC_MSG_START_ACTION_REQ, "START ACTION Request" }, |
166 | | { FECC_MSG_CONTINUE_ACTION_REQ, "CONTINUE ACTION Request" }, |
167 | | { FECC_MSG_STOP_ACTION_REQ, "STOP ACTION Request" }, |
168 | | { FECC_MSG_SELECT_VIDEO_SOURCE_REQ, "SELECT VIDEO SOURCE Request" }, |
169 | | { FECC_MSG_VIDEO_SOURCE_SWITCHED_IND, "VIDEO SOURCE SWITCHED indication" }, |
170 | | { FECC_MSG_STORE_AS_PRESET_REQ, "STORE AS PRESET Request" }, |
171 | | { FECC_MSG_ACTIVATE_PRESET_REQ, "ACTIVATE PRESET Request" }, |
172 | | { 0, NULL }, |
173 | | }; |
174 | | |
175 | | static const true_false_string tfs_right_left = { "Right", "Left" }; |
176 | | static const true_false_string tfs_in_out = { "In", "Out" }; |
177 | | |
178 | | static value_string_ext h224_client_data_ext = VALUE_STRING_EXT_INIT(h224_client_data_type); |
179 | | |
180 | | static unsigned |
181 | | dissect_h224_standard_clients_ids(tvbuff_t* tvb, proto_tree* tree, unsigned offset, uint8_t client_id) |
182 | 0 | { |
183 | 0 | uint32_t manufacturer_code; |
184 | |
|
185 | 0 | if (client_id == H224_EXTENDED_CLIENT_ID) { |
186 | 0 | proto_tree_add_item(tree, hf_h224_extended_client_id_list, tvb, offset, 1, ENC_NA); |
187 | 0 | offset++; |
188 | 0 | proto_tree_add_item(tree, hf_h224_extended_client_id, tvb, offset, 1, ENC_NA); |
189 | 0 | offset++; |
190 | 0 | } else if (client_id == H224_NON_STANDARD_CLIENT_ID){ |
191 | 0 | proto_tree_add_item(tree, hf_h224_non_standard_client, tvb, offset, 1, ENC_NA); |
192 | 0 | offset++; |
193 | 0 | manufacturer_code = tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN); |
194 | 0 | proto_tree_add_item(tree, hf_h224_country_code, tvb, offset, 1, ENC_BIG_ENDIAN); |
195 | 0 | offset += 1; |
196 | 0 | proto_tree_add_item(tree, hf_h224_extension, tvb, offset, 1, ENC_BIG_ENDIAN); |
197 | 0 | offset += 1; |
198 | 0 | proto_tree_add_uint(tree, hf_h224_manufacturer_code, tvb, offset - 2, 4, manufacturer_code); |
199 | 0 | offset += 2; |
200 | 0 | proto_tree_add_item(tree, hf_h224_client_id_manufacturer, tvb, offset, 1, ENC_NA); |
201 | 0 | offset++; |
202 | 0 | } else { |
203 | 0 | proto_tree_add_item(tree, hf_h224_standard_client_id, tvb, offset, 1, ENC_NA); |
204 | 0 | offset++; |
205 | 0 | } |
206 | 0 | return offset; |
207 | 0 | } |
208 | | |
209 | | static unsigned |
210 | | dissect_h224_cme_client_data(tvbuff_t* tvb, proto_tree* tree, unsigned offset) |
211 | 0 | { |
212 | 0 | uint16_t type; |
213 | 0 | uint8_t num; |
214 | 0 | uint8_t oct; |
215 | 0 | uint8_t source_id; |
216 | 0 | unsigned zero_offset; |
217 | 0 | proto_tree *ext_tree; |
218 | |
|
219 | 0 | ext_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_h224, NULL, |
220 | 0 | val_to_str_ext_const(H224_CME_CLIENT_ID, &h224_client_data_ext, "Unknown field")); |
221 | 0 | type = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
222 | 0 | switch (type) { |
223 | 0 | case CME_MSG_Client_List_Message: |
224 | 0 | proto_tree_add_item(ext_tree, hf_h224_client_list_code, tvb, offset, 1, ENC_BIG_ENDIAN); |
225 | 0 | offset++; |
226 | 0 | proto_tree_add_item(ext_tree, hf_h224_response_code, tvb, offset, 1, ENC_BIG_ENDIAN); |
227 | 0 | offset++; |
228 | 0 | proto_tree_add_item(ext_tree, hf_h224_number_of_clients, tvb, offset, 1, ENC_BIG_ENDIAN); |
229 | 0 | num = tvb_get_uint8(tvb, offset); |
230 | 0 | offset++; |
231 | 0 | proto_tree_add_item(ext_tree, hf_h224_ex_caps_bit, tvb, offset, 1, ENC_BIG_ENDIAN); |
232 | 0 | for (int i = 0; i < num; i++) { |
233 | 0 | oct = tvb_get_uint8(tvb, offset); |
234 | 0 | offset = dissect_h224_standard_clients_ids(tvb, ext_tree, offset, (oct & 0x7f)); |
235 | 0 | } |
236 | 0 | break; |
237 | 0 | case CME_MSG_Client_List_Command: |
238 | 0 | proto_tree_add_item(ext_tree, hf_h224_client_list_code, tvb, offset, 1, ENC_BIG_ENDIAN); |
239 | 0 | offset++; |
240 | 0 | proto_tree_add_item(ext_tree, hf_h224_response_code, tvb, offset, 1, ENC_BIG_ENDIAN); |
241 | 0 | offset++; |
242 | 0 | break; |
243 | 0 | case CME_MSG_Extra_Capabilities_Message: |
244 | 0 | proto_tree_add_item(ext_tree, hf_h224_extra_caps_code, tvb, offset, 1, ENC_BIG_ENDIAN); |
245 | 0 | offset++; |
246 | 0 | proto_tree_add_item(ext_tree, hf_h224_response_code, tvb, offset, 1, ENC_BIG_ENDIAN); |
247 | 0 | offset++; |
248 | 0 | proto_tree_add_item(ext_tree, hf_h224_ex_caps_bit, tvb, offset, 1, ENC_BIG_ENDIAN); |
249 | 0 | oct = tvb_get_uint8(tvb, offset); |
250 | 0 | offset = dissect_h224_standard_clients_ids(tvb, ext_tree, offset, oct); |
251 | 0 | if ((oct & 0x7f) == 0x01) { |
252 | 0 | static int* const fecc_number_of_presets[] = { |
253 | 0 | &hf_h224_caps_reserved, |
254 | 0 | &hf_h224_brd_svs, |
255 | 0 | &hf_h224_number_of_presets, |
256 | 0 | NULL |
257 | 0 | }; |
258 | 0 | proto_tree_add_bitmask_list(ext_tree, tvb, offset, 1, fecc_number_of_presets, ENC_BIG_ENDIAN); |
259 | 0 | offset++; |
260 | 0 | oct = tvb_get_uint8(tvb, offset); |
261 | 0 | static int* const fecc_vrs_capabilities[] = { |
262 | 0 | &hf_h224_vs_id, |
263 | 0 | &hf_h224_vs_reserved_b3, |
264 | 0 | &hf_h224_motion_video, |
265 | 0 | &hf_h224_norm_res_si, |
266 | 0 | &hf_h224_dbl_res_si, |
267 | 0 | NULL |
268 | 0 | }; |
269 | 0 | proto_tree_add_bitmask_list(ext_tree, tvb, offset, 1, fecc_vrs_capabilities, ENC_BIG_ENDIAN); |
270 | 0 | offset++; |
271 | 0 | source_id = (oct & 0xf0) >> 4; |
272 | 0 | if (source_id > 5) { |
273 | 0 | tvb_find_uint8_length(tvb, offset, FECC_MAX_LENGTH_ASCII_STR, 0, &zero_offset); |
274 | 0 | if (zero_offset > offset) { |
275 | 0 | proto_tree_add_item(ext_tree, hf_h224_encoded_characters, tvb, offset, zero_offset - offset, ENC_ASCII); |
276 | 0 | offset = zero_offset; |
277 | 0 | proto_tree_add_item(ext_tree, hf_h224_end_octet, tvb, offset, 1, ENC_NA); |
278 | 0 | offset++; |
279 | 0 | } |
280 | 0 | } |
281 | 0 | static int* const fecc_caps_ability[] = { |
282 | 0 | &hf_h224_pan_cap, |
283 | 0 | &hf_h224_tilt_cap, |
284 | 0 | &hf_h224_zoom_cap, |
285 | 0 | &hf_h224_focus_cap, |
286 | 0 | &hf_h224_vs_reserved_b3b0, |
287 | 0 | NULL |
288 | 0 | }; |
289 | 0 | proto_tree_add_bitmask_list(ext_tree, tvb, offset, 1, fecc_caps_ability, ENC_BIG_ENDIAN); |
290 | 0 | offset++; |
291 | 0 | } |
292 | 0 | break; |
293 | 0 | case CME_MSG_Extra_Capabilities_Command: |
294 | 0 | proto_tree_add_item(ext_tree, hf_h224_extra_caps_code, tvb, offset, 1, ENC_BIG_ENDIAN); |
295 | 0 | offset++; |
296 | 0 | proto_tree_add_item(ext_tree, hf_h224_response_code, tvb, offset, 1, ENC_BIG_ENDIAN); |
297 | 0 | offset++; |
298 | 0 | proto_tree_add_item(ext_tree, hf_h224_ex_caps_bit, tvb, offset, 1, ENC_BIG_ENDIAN); |
299 | 0 | oct = tvb_get_uint8(tvb, offset); |
300 | 0 | offset = dissect_h224_standard_clients_ids(tvb, ext_tree, offset, oct); |
301 | 0 | break; |
302 | 0 | default: |
303 | 0 | break; |
304 | 0 | } |
305 | 0 | return offset; |
306 | 0 | } |
307 | | |
308 | | static unsigned |
309 | | dissect_h224_fecc_client_data(tvbuff_t* tvb, proto_tree* tree, unsigned offset) |
310 | 0 | { |
311 | 0 | uint8_t oct; |
312 | 0 | proto_tree *ext_tree; |
313 | |
|
314 | 0 | ext_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_h224, NULL, |
315 | 0 | val_to_str_ext_const(H224_FECC_CLIENT_ID, &h224_client_data_ext, "Unknown field")); |
316 | 0 | oct = tvb_get_uint8(tvb, offset); |
317 | 0 | proto_tree_add_item(ext_tree, hf_h224_command_code, tvb, offset, 1, ENC_BIG_ENDIAN); |
318 | 0 | offset++; |
319 | 0 | static int* const fecc_message_action[] = { |
320 | 0 | &hf_h224_message_pan, |
321 | 0 | &hf_h224_message_pan_dir, |
322 | 0 | &hf_h224_message_tilt, |
323 | 0 | &hf_h224_message_tilt_dir, |
324 | 0 | &hf_h224_message_zoom, |
325 | 0 | &hf_h224_message_zoom_dir, |
326 | 0 | &hf_h224_message_focus, |
327 | 0 | &hf_h224_message_focus_dir, |
328 | 0 | NULL |
329 | 0 | }; |
330 | 0 | switch(oct) { |
331 | 0 | case FECC_MSG_START_ACTION_REQ: |
332 | 0 | { |
333 | 0 | uint16_t timeout; |
334 | 0 | proto_tree_add_bitmask_list(ext_tree, tvb, offset, 1, fecc_message_action, ENC_BIG_ENDIAN); |
335 | 0 | offset++; |
336 | 0 | proto_tree_add_item(ext_tree, hf_h224_message_reserved_b7b4, tvb, offset, 1, ENC_BIG_ENDIAN); |
337 | 0 | oct = tvb_get_uint8(tvb, offset); |
338 | 0 | timeout = (oct & 0x0f) ? (oct * TIMEOUT_INTERVALS) : MAX_TIMEOUT_VALUE; |
339 | 0 | proto_tree_add_uint_format(ext_tree, hf_h224_message_timeout, tvb, offset, 1, oct,"%u (%u milliseconds)", oct, timeout); |
340 | 0 | offset++; |
341 | 0 | break; |
342 | 0 | } |
343 | 0 | case FECC_MSG_CONTINUE_ACTION_REQ: |
344 | 0 | case FECC_MSG_STOP_ACTION_REQ: |
345 | 0 | proto_tree_add_bitmask_list(ext_tree, tvb, offset, 1, fecc_message_action, ENC_BIG_ENDIAN); |
346 | 0 | offset++; |
347 | 0 | break; |
348 | 0 | case FECC_MSG_SELECT_VIDEO_SOURCE_REQ: |
349 | 0 | case FECC_MSG_VIDEO_SOURCE_SWITCHED_IND: |
350 | 0 | { |
351 | 0 | static int* const fecc_message_m1m0[] = { |
352 | 0 | &hf_h224_vs_id, |
353 | 0 | &hf_h224_message_reserved_b3b2, |
354 | 0 | &hf_h224_message_vs_m1, |
355 | 0 | &hf_h224_message_vs_m0, |
356 | 0 | NULL |
357 | 0 | }; |
358 | 0 | proto_tree_add_bitmask_list(ext_tree, tvb, offset, 1, fecc_message_m1m0, ENC_BIG_ENDIAN); |
359 | 0 | offset++; |
360 | 0 | break; |
361 | 0 | } |
362 | 0 | case FECC_MSG_STORE_AS_PRESET_REQ: |
363 | 0 | case FECC_MSG_ACTIVATE_PRESET_REQ: |
364 | 0 | { |
365 | 0 | static int* const fecc_message_preset_num[] = { |
366 | 0 | &hf_h224_message_preset_number, |
367 | 0 | &hf_h224_message_reserved_b3b0, |
368 | 0 | NULL |
369 | 0 | }; |
370 | 0 | proto_tree_add_bitmask_list(ext_tree, tvb, offset, 1, fecc_message_preset_num, ENC_BIG_ENDIAN); |
371 | 0 | offset++; |
372 | 0 | break; |
373 | 0 | } |
374 | 0 | default: |
375 | 0 | break; |
376 | 0 | } |
377 | 0 | return offset; |
378 | 0 | } |
379 | | |
380 | 0 | static unsigned dissect_h224_extended_client_data(tvbuff_t* tvb, proto_tree* tree, unsigned offset) { |
381 | 0 | proto_tree *ext_tree; |
382 | |
|
383 | 0 | ext_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_h224, NULL, |
384 | 0 | val_to_str_ext_const(H224_EXTENDED_CLIENT_ID, &h224_client_data_ext, "Unknown field")); |
385 | 0 | proto_tree_add_item(ext_tree, hf_h224_other_client_data, tvb, offset, -1, ENC_NA); |
386 | 0 | offset++; |
387 | 0 | return offset; |
388 | 0 | } |
389 | | |
390 | 0 | static unsigned dissect_h224_non_standard_client_data(tvbuff_t* tvb, proto_tree* tree, unsigned offset) { |
391 | 0 | proto_tree *ext_tree; |
392 | |
|
393 | 0 | ext_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_h224, NULL, |
394 | 0 | val_to_str_ext_const(H224_NON_STANDARD_CLIENT_ID, &h224_client_data_ext, "Unknown field")); |
395 | 0 | proto_tree_add_item(ext_tree, hf_h224_other_client_data, tvb, offset, -1, ENC_NA); |
396 | 0 | offset++; |
397 | 0 | return offset; |
398 | 0 | } |
399 | | /* Code to actually dissect the packets */ |
400 | | static int |
401 | | dissect_h224(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_) |
402 | 0 | { |
403 | 0 | proto_item* ti; |
404 | 0 | proto_tree* h224_tree; |
405 | 0 | unsigned offset = 0; |
406 | 0 | uint8_t oct; |
407 | | |
408 | | |
409 | | /* Set the Protocol column in the summary display */ |
410 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "H.224"); |
411 | |
|
412 | 0 | ti = proto_tree_add_item(tree, proto_h224, tvb, offset, -1, ENC_NA); |
413 | 0 | h224_tree = proto_item_add_subtree(ti, ett_h224); |
414 | | |
415 | | /* On IP transport networks, the H.224 protocol octet structure shall be the same as Figure 2/H.224 |
416 | | * except that the HDLC bit stuffing, HDLC flags and HDLC Frame Check Sequence shall be omitted. |
417 | | */ |
418 | | /* The 10-bit DLCI address for data priority */ |
419 | 0 | proto_tree_add_item(h224_tree, hf_h224_q922_dlci_priority, tvb, offset, 2, ENC_BIG_ENDIAN); |
420 | 0 | offset += 2; |
421 | | /* Q.922 UI-Mode format 1 octets */ |
422 | 0 | proto_tree_add_item(h224_tree, hf_h224_q922_ctl, tvb, offset, 1, ENC_BIG_ENDIAN); |
423 | 0 | offset += 1; |
424 | | /* Destination terminal address 2 octets */ |
425 | 0 | proto_tree_add_item(h224_tree, hf_h224_dta, tvb, offset, 2, ENC_BIG_ENDIAN); |
426 | 0 | offset += 2; |
427 | | /* Source terminal address 2 octets */ |
428 | 0 | proto_tree_add_item(h224_tree, hf_h224_sta, tvb, offset, 2, ENC_BIG_ENDIAN); |
429 | 0 | offset += 2; |
430 | 0 | proto_tree_add_item(h224_tree, hf_h224_reserved, tvb, offset, 1, ENC_NA); |
431 | | |
432 | | /* |
433 | | * CLIENT ID: The client to receive the contents of the datagram. The Client ID may be any |
434 | | * of the following formats: |
435 | | * - Standard Client ID - Single octet. |
436 | | * - Extended Client ID - Two octets (0x7E, extended Client ID). |
437 | | * - Non-standard Client ID - Six octets (0x7F, country, manufacturer code, ID) |
438 | | */ |
439 | 0 | oct = tvb_get_uint8(tvb, offset); |
440 | 0 | offset = dissect_h224_standard_clients_ids(tvb, h224_tree, offset, oct); |
441 | |
|
442 | 0 | static int* const h224_flags[] = { |
443 | 0 | &hf_h224_es_b7, |
444 | 0 | &hf_h224_bs_b6, |
445 | 0 | &hf_h224_c1_b5, |
446 | 0 | &hf_h224_c2_b4, |
447 | 0 | &hf_h224_seg_b3b0, |
448 | 0 | NULL |
449 | 0 | }; |
450 | |
|
451 | 0 | proto_tree_add_bitmask_list(h224_tree, tvb, offset, 1, h224_flags, ENC_BIG_ENDIAN); |
452 | 0 | offset++; |
453 | | |
454 | | /* Data */ |
455 | 0 | int i = -1; |
456 | 0 | while (h224opt[++i].decode) { |
457 | 0 | if (h224opt[i].optcode == oct) { |
458 | 0 | h224opt[i].decode(tvb, h224_tree, offset); |
459 | 0 | break; |
460 | 0 | } |
461 | 0 | } |
462 | 0 | return tvb_reported_length(tvb); |
463 | 0 | } |
464 | | |
465 | | /* Register the protocol with Wireshark. */ |
466 | | void |
467 | | proto_register_h224(void) |
468 | 15 | { |
469 | | //module_t *h224_module; |
470 | | //expert_module_t *expert_h224; |
471 | | |
472 | 15 | static hf_register_info hf[] = { |
473 | 15 | { &hf_h224_q922_dlci_priority, |
474 | 15 | { "Q.922 DLCI Priority", "h224.q922_dlci_pri", |
475 | 15 | FT_UINT16, BASE_HEX, VALS(h224_data_priority), H224_DATA_PRI_MASK, |
476 | 15 | NULL, HFILL } |
477 | 15 | }, |
478 | 15 | { &hf_h224_q922_ctl, |
479 | 15 | { "Q.922 Control Octet", "h224.q922_ctl", |
480 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, |
481 | 15 | NULL, HFILL } |
482 | 15 | }, |
483 | 15 | { &hf_h224_dta, |
484 | 15 | { "Destination Terminal Address", "h224.dta", |
485 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, |
486 | 15 | NULL, HFILL } |
487 | 15 | }, |
488 | 15 | { &hf_h224_sta, |
489 | 15 | { "Source Terminal Address", "h224.sta", |
490 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, |
491 | 15 | NULL, HFILL } |
492 | 15 | }, |
493 | 15 | { &hf_h224_reserved, |
494 | 15 | { "Reserved", "h224.reserved", |
495 | 15 | FT_UINT8, BASE_DEC, NULL, 0x80, |
496 | 15 | NULL, HFILL } |
497 | 15 | }, |
498 | 15 | { &hf_h224_standard_client_id, |
499 | 15 | { "Standard Client ID", "h224.standard_client_id", |
500 | 15 | FT_UINT8, BASE_HEX, NULL, 0x7f, |
501 | 15 | NULL, HFILL } |
502 | 15 | }, |
503 | 15 | { &hf_h224_extended_client_id_list, |
504 | 15 | { "Extended Client ID List", "h224.extended_client_id_list", |
505 | 15 | FT_UINT8, BASE_HEX, NULL, 0x7f, |
506 | 15 | NULL, HFILL } |
507 | 15 | }, |
508 | 15 | { &hf_h224_non_standard_client, |
509 | 15 | { "Non-standard Client", "h224.non_standard_client", |
510 | 15 | FT_UINT8, BASE_HEX, NULL, 0x7f, |
511 | 15 | NULL, HFILL } |
512 | 15 | }, |
513 | 15 | { &hf_h224_extended_client_id, |
514 | 15 | { "Extended Client ID", "h224.extended_client_id", |
515 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, |
516 | 15 | NULL, HFILL } |
517 | 15 | }, |
518 | 15 | { &hf_h224_country_code, |
519 | 15 | { "Country code", "h224.country_code", |
520 | 15 | FT_UINT8, BASE_HEX, VALS(T35CountryCode_vals), 0x0, |
521 | 15 | NULL, HFILL } |
522 | 15 | }, |
523 | 15 | { &hf_h224_extension, |
524 | 15 | { "Extension", "h224.Extension", |
525 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, |
526 | 15 | NULL, HFILL } |
527 | 15 | }, |
528 | 15 | { &hf_h224_manufacturer_code, |
529 | 15 | { "Manufacturer code", "h224.manufacturer_code", |
530 | 15 | FT_UINT32, BASE_HEX, VALS(H221ManufacturerCode_vals), 0x0, |
531 | 15 | NULL, HFILL } |
532 | 15 | }, |
533 | 15 | { &hf_h224_client_id_manufacturer, |
534 | 15 | { "Manufacturer Client ID", "h224.manufacturer_client_id", |
535 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, |
536 | 15 | NULL, HFILL } |
537 | 15 | }, |
538 | 15 | { &hf_h224_es_b7, |
539 | 15 | { "Ending Segment(ES)", "h224.flag.es", |
540 | 15 | FT_BOOLEAN, 8, NULL, 0x80, |
541 | 15 | NULL, HFILL } |
542 | 15 | }, |
543 | 15 | { &hf_h224_bs_b6, |
544 | 15 | { "Beginning Segment(BS)", "h224.flag.bs", |
545 | 15 | FT_BOOLEAN, 8, NULL, 0x40, |
546 | 15 | NULL, HFILL } |
547 | 15 | }, |
548 | 15 | { &hf_h224_c1_b5, |
549 | 15 | { "C1", "h224.flag.c1", |
550 | 15 | FT_BOOLEAN, 8, NULL, 0x20, |
551 | 15 | NULL, HFILL } |
552 | 15 | }, |
553 | 15 | { &hf_h224_c2_b4, |
554 | 15 | { "C0", "h224.flag.c0", |
555 | 15 | FT_BOOLEAN, 8, NULL, 0x10, |
556 | 15 | NULL, HFILL } |
557 | 15 | }, |
558 | 15 | { &hf_h224_seg_b3b0, |
559 | 15 | { "Segment number", "h224.flags_seg", |
560 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0f, |
561 | 15 | NULL, HFILL } |
562 | 15 | }, |
563 | 15 | { &hf_h224_client_list_code, |
564 | 15 | { "Client List code", "h224.client_list_code", |
565 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, |
566 | 15 | NULL, HFILL } |
567 | 15 | }, |
568 | 15 | { &hf_h224_extra_caps_code, |
569 | 15 | { "Extra Capabilities code", "h224.ex_caps_code", |
570 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, |
571 | 15 | NULL, HFILL } |
572 | 15 | }, |
573 | 15 | { &hf_h224_response_code, |
574 | 15 | { "Response Code", "h224.response_code", |
575 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, |
576 | 15 | NULL, HFILL } |
577 | 15 | }, |
578 | 15 | { &hf_h224_number_of_clients, |
579 | 15 | { "Number of clients", "h224.number_of_clients", |
580 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
581 | 15 | NULL, HFILL } |
582 | 15 | }, |
583 | 15 | { &hf_h224_ex_caps_bit, |
584 | 15 | { "Extra Capabilities bit", "h224.ex_caps_bit", |
585 | 15 | FT_BOOLEAN, 8, NULL, 0x80, |
586 | 15 | NULL, HFILL } |
587 | 15 | }, |
588 | 15 | { &hf_h224_caps_reserved, |
589 | 15 | { "Preset reserved", "h224.preset_reserved", |
590 | 15 | FT_UINT8, BASE_DEC, NULL, 0xe0, |
591 | 15 | NULL, HFILL } |
592 | 15 | }, |
593 | 15 | { &hf_h224_brd_svs, |
594 | 15 | { "Broadcast switch video sources", "h224.brd_svs", |
595 | 15 | FT_BOOLEAN, 8, NULL, 0x10, |
596 | 15 | NULL, HFILL } |
597 | 15 | }, |
598 | 15 | { &hf_h224_number_of_presets, |
599 | 15 | { "Number of presets", "h224.number_of_presets", |
600 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0f, |
601 | 15 | NULL, HFILL } |
602 | 15 | }, |
603 | 15 | { &hf_h224_vs_id, |
604 | 15 | { "Video source id", "h224.vs_id", |
605 | 15 | FT_UINT8, BASE_DEC, NULL, 0xf0, |
606 | 15 | NULL, HFILL } |
607 | 15 | }, |
608 | 15 | { &hf_h224_vs_reserved_b3, |
609 | 15 | { "Reserved type", "h224.reserved_type", |
610 | 15 | FT_UINT8, BASE_DEC, NULL, 0x08, |
611 | 15 | NULL, HFILL } |
612 | 15 | }, |
613 | 15 | { &hf_h224_vs_reserved_b3b0, |
614 | 15 | { "Reserved Capabilities", "h224.reserved_caps", |
615 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0f, |
616 | 15 | NULL, HFILL } |
617 | 15 | }, |
618 | 15 | { &hf_h224_motion_video, |
619 | 15 | { "Motion video", "h224.motion_video", |
620 | 15 | FT_BOOLEAN, 8, NULL, 0x04, |
621 | 15 | NULL, HFILL } |
622 | 15 | }, |
623 | 15 | { &hf_h224_norm_res_si, |
624 | 15 | { "Normal resolution still image", "h224.norm_res_si", |
625 | 15 | FT_BOOLEAN, 8, NULL, 0x02, |
626 | 15 | NULL, HFILL } |
627 | 15 | }, |
628 | 15 | { &hf_h224_dbl_res_si, |
629 | 15 | { "Double resolution still image", "h224.dbl_res_si", |
630 | 15 | FT_BOOLEAN, 8, NULL, 0x01, |
631 | 15 | NULL, HFILL } |
632 | 15 | }, |
633 | 15 | { &hf_h224_pan_cap, |
634 | 15 | { "Pan Capability", "h224.pan_cap", |
635 | 15 | FT_BOOLEAN, 8, NULL, 0x80, |
636 | 15 | NULL, HFILL } |
637 | 15 | }, |
638 | 15 | { &hf_h224_tilt_cap, |
639 | 15 | { "Tilt Capability", "h224.tilt_cap", |
640 | 15 | FT_BOOLEAN, 8, NULL, 0x40, |
641 | 15 | NULL, HFILL } |
642 | 15 | }, |
643 | 15 | { &hf_h224_zoom_cap, |
644 | 15 | { "Zoom Capability", "h224.zoom_cap", |
645 | 15 | FT_BOOLEAN, 8, NULL, 0x20, |
646 | 15 | NULL, HFILL } |
647 | 15 | }, |
648 | 15 | { &hf_h224_focus_cap, |
649 | 15 | { "Focus Capability", "h224.focus_cap", |
650 | 15 | FT_BOOLEAN, 8, NULL, 0x10, |
651 | 15 | NULL, HFILL } |
652 | 15 | }, |
653 | 15 | { &hf_h224_encoded_characters, |
654 | 15 | { "Ascii String", "h224.ascii_str", |
655 | 15 | FT_STRING, BASE_NONE, NULL, 0, |
656 | 15 | NULL, HFILL } |
657 | 15 | }, |
658 | 15 | { &hf_h224_end_octet, |
659 | 15 | { "End octet", "h224.end_oct", |
660 | 15 | FT_UINT8, BASE_DEC, NULL, 0, |
661 | 15 | NULL, HFILL } |
662 | 15 | }, |
663 | 15 | { &hf_h224_command_code, |
664 | 15 | { "FECC Message Code", "h224.fecc_message_code", |
665 | 15 | FT_UINT8, BASE_HEX, VALS(h224_fecc_message_type), 0, |
666 | 15 | NULL, HFILL } |
667 | 15 | }, |
668 | 15 | { &hf_h224_message_pan, |
669 | 15 | { "Pan action", "h224.pan_action", |
670 | 15 | FT_BOOLEAN, 8, NULL, 0x80, |
671 | 15 | NULL, HFILL } |
672 | 15 | }, |
673 | 15 | { &hf_h224_message_pan_dir, |
674 | 15 | { "Pan direction", "h224.pan_dir", |
675 | 15 | FT_BOOLEAN, 8, TFS(&tfs_right_left), 0x40, |
676 | 15 | NULL, HFILL } |
677 | 15 | }, |
678 | 15 | { &hf_h224_message_tilt, |
679 | 15 | { "Tilt action", "h224.tilt_action", |
680 | 15 | FT_BOOLEAN, 8, NULL, 0x20, |
681 | 15 | NULL, HFILL } |
682 | 15 | }, |
683 | 15 | { &hf_h224_message_tilt_dir, |
684 | 15 | { "Tilt direction", "h224.tilt_dir", |
685 | 15 | FT_BOOLEAN, 8, TFS(&tfs_up_down), 0x10, |
686 | 15 | NULL, HFILL } |
687 | 15 | }, |
688 | 15 | { &hf_h224_message_zoom, |
689 | 15 | { "Zoom action", "h224.zoom_action", |
690 | 15 | FT_BOOLEAN, 8, NULL, 0x08, |
691 | 15 | NULL, HFILL } |
692 | 15 | }, |
693 | 15 | { &hf_h224_message_zoom_dir, |
694 | 15 | { "Zoom direction", "h224.zoom_dir", |
695 | 15 | FT_BOOLEAN, 8, TFS(&tfs_in_out), 0x04, |
696 | 15 | NULL, HFILL } |
697 | 15 | }, |
698 | 15 | { &hf_h224_message_focus, |
699 | 15 | { "Focus action", "h224.focus_action", |
700 | 15 | FT_BOOLEAN, 8, NULL, 0x02, |
701 | 15 | NULL, HFILL } |
702 | 15 | }, |
703 | 15 | { &hf_h224_message_focus_dir, |
704 | 15 | { "Focus direction", "h224.focus_dir", |
705 | 15 | FT_BOOLEAN, 8, TFS(&tfs_in_out), 0x01, |
706 | 15 | NULL, HFILL } |
707 | 15 | }, |
708 | 15 | { &hf_h224_message_reserved_b7b4, |
709 | 15 | { "Action Reserved", "h224.act_reserved", |
710 | 15 | FT_UINT8, BASE_DEC, NULL, 0xf0, |
711 | 15 | NULL, HFILL } |
712 | 15 | }, |
713 | 15 | { &hf_h224_message_reserved_b3b2, |
714 | 15 | { "Mode Reserved", "h224.mode_reserved", |
715 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0c, |
716 | 15 | NULL, HFILL } |
717 | 15 | }, |
718 | 15 | { &hf_h224_message_reserved_b3b0, |
719 | 15 | { "Activate Preset Reserved", "h224.ap_reserved", |
720 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0f, |
721 | 15 | NULL, HFILL } |
722 | 15 | }, |
723 | 15 | { &hf_h224_message_vs_m1, |
724 | 15 | { "M1", "h224.vs_m1", |
725 | 15 | FT_UINT8, BASE_DEC, NULL, 0x02, |
726 | 15 | NULL, HFILL } |
727 | 15 | }, |
728 | 15 | { &hf_h224_message_vs_m0, |
729 | 15 | { "M0", "h224.vs_m0", |
730 | 15 | FT_UINT8, BASE_DEC, NULL, 0x01, |
731 | 15 | NULL, HFILL } |
732 | 15 | }, |
733 | 15 | { &hf_h224_message_timeout, |
734 | 15 | { "Timeout", "h224.timeout", |
735 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0f, |
736 | 15 | NULL, HFILL } |
737 | 15 | }, |
738 | 15 | { &hf_h224_message_preset_number, |
739 | 15 | { "Preset Number", "h224.preset_number", |
740 | 15 | FT_UINT8, BASE_DEC, NULL, 0xf0, |
741 | 15 | NULL, HFILL } |
742 | 15 | }, |
743 | 15 | { &hf_h224_other_client_data, |
744 | 15 | { "Client data", "h224.client_data", |
745 | 15 | FT_BYTES, BASE_NONE, NULL, 0x0, |
746 | 15 | NULL, HFILL } |
747 | 15 | }, |
748 | 15 | }; |
749 | 15 | static int *ett[] = { |
750 | 15 | &ett_h224 |
751 | 15 | }; |
752 | | |
753 | | /* Setup protocol expert items */ |
754 | | //static ei_register_info ei[] = { |
755 | | // { &ei_h224_EXPERTABBREV, |
756 | | // { "h224.EXPERTABBREV", PI_GROUP, PI_SEVERITY, |
757 | | // "EXPERTDESCR", EXPFILL } |
758 | | // } |
759 | | //}; |
760 | | |
761 | | /* Register the protocol name and description */ |
762 | 15 | proto_h224 = proto_register_protocol("H.224", "H.224", "h224"); |
763 | | |
764 | | /* Register the header fields and subtrees */ |
765 | 15 | proto_register_field_array(proto_h224, hf, array_length(hf)); |
766 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
767 | | |
768 | | /* Register expert items */ |
769 | | // expert_h224 = expert_register_protocol(proto_h224); |
770 | | // expert_register_field_array(expert_h224, ei, array_length(ei)); |
771 | | |
772 | 15 | h224_handle = register_dissector("h224", dissect_h224, proto_h224); |
773 | | |
774 | | |
775 | 15 | } |
776 | | |
777 | | void |
778 | | proto_reg_handoff_h224(void) |
779 | 15 | { |
780 | 15 | dissector_add_string("rtp_dyn_payload_type", "H224", h224_handle); |
781 | 15 | dissector_add_for_decode_as("rtp.pt", h224_handle); |
782 | 15 | } |
783 | | |
784 | | /* |
785 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
786 | | * |
787 | | * Local variables: |
788 | | * c-basic-offset: 4 |
789 | | * tab-width: 8 |
790 | | * indent-tabs-mode: nil |
791 | | * End: |
792 | | * |
793 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
794 | | * :indentSize=4:tabSize=8:noTabs=true: |
795 | | */ |