2 * Routines for h245 packet dissection
3 * Copyright 2004, Anders Broman <anders.broman@ericsson.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 * To quote the author of the previous H245 dissector:
26 * "This is a complete replacement of the previous limitied dissector
27 * that Ronnie was crazy enough to write by hand. It was a lot of time
28 * to hack it by hand, but it is incomplete and buggy and it is good when
30 * Ronnie did a great job and all the VoIP users had made good use of it!
31 * Credit to Tomas Kukosa for developing the asn2wrs compiler.
40 #include <epan/packet.h>
41 #include <epan/conversation.h>
46 #include <epan/prefs.h>
48 #include <epan/emem.h>
49 #include <epan/oid_resolv.h>
51 #include "packet-tpkt.h"
52 #include "packet-per.h"
53 #include "packet-h245.h"
54 #include "packet-rtp.h"
55 #include "packet-rtcp.h"
56 #include "packet-t38.h"
58 #define PNAME "MULTIMEDIA-SYSTEM-CONTROL"
59 #define PSNAME "H.245"
62 static dissector_handle_t rtp_handle=NULL;
63 static dissector_handle_t rtcp_handle=NULL;
64 static dissector_handle_t t38_handle=NULL;
65 static dissector_table_t nsp_object_dissector_table;
66 static dissector_table_t nsp_h221_dissector_table;
67 static dissector_handle_t nsp_handle;
68 static dissector_handle_t data_handle;
69 static dissector_handle_t h245_handle;
70 static dissector_handle_t MultimediaSystemControlMessage_handle;
71 static dissector_handle_t h263_handle = NULL;
72 static dissector_handle_t amr_handle = NULL;
74 static void init_h245_packet_info(h245_packet_info *pi);
75 static int hf_h245_pdu_type = -1;
76 static int hf_h245Manufacturer = -1;
77 static int h245_tap = -1;
78 static int ett_h245 = -1;
79 static int h245dg_tap = -1;
80 h245_packet_info *h245_pi=NULL;
82 static gboolean h245_reassembly = TRUE;
83 static gboolean h245_shorttypes = FALSE;
84 static const value_string h245_RequestMessage_short_vals[] = {
103 static const value_string h245_ResponseMessage_short_vals[] = {
120 { 16, "RTDResponse" },
123 { 19, "CMResponse" },
131 static const value_string h245_IndicationMessage_short_vals[] = {
151 { 19, "MultilinkIndication" },
152 { 20, "LCRRelease" },
153 { 21, "FCIndication" },
158 static const value_string h245_CommandMessage_short_vals[] = {
174 static const value_string h245_AudioCapability_short_vals[] = {
198 { 23, "audioTelEvent" },
203 /* To put the codec type only in COL_INFO when
206 const char* codec_type = NULL;
207 static const char *standard_oid_str;
208 static guint32 ipv4_address;
209 static guint32 ipv4_port;
210 static guint32 rtcp_ipv4_address;
211 static guint32 rtcp_ipv4_port;
212 static gboolean media_channel;
213 static gboolean media_control_channel;
215 /* NonStandardParameter */
216 static const char *nsiOID;
217 static guint32 h221NonStandard;
218 static guint32 t35CountryCode;
219 static guint32 t35Extension;
220 static guint32 manufacturerCode;
222 static const value_string h245_RFC_number_vals[] = {
223 { 2190, "RFC 2190 - H.263 Video Streams" },
224 { 2429, "RFC 2429 - 1998 Version of ITU-T Rec. H.263 Video (H.263+)" },
225 { 3016, "RFC 3016 - RTP Payload Format for MPEG-4 Audio/Visual Streams" },
226 { 3267, "RFC 3267 - Adaptive Multi-Rate (AMR) and Adaptive Multi-Rate Wideband (AMR-WB)" },
230 /* h223 multiplex codes */
231 static h223_set_mc_handle_t h223_set_mc_handle = NULL;
232 h223_mux_element *h223_me=NULL;
234 void h245_set_h223_set_mc_handle( h223_set_mc_handle_t handle )
236 h223_set_mc_handle = handle;
239 /* h223 logical channels */
241 h223_lc_params *fw_channel_params;
242 h223_lc_params *rev_channel_params;
245 static GHashTable* h223_pending_olc_reqs[] = { NULL, NULL };
246 static dissector_handle_t h245_lc_dissector;
247 static guint16 h245_lc_temp;
248 static guint16 h223_fw_lc_num;
249 static guint16 h223_rev_lc_num;
250 static h223_lc_params *h223_lc_params_temp;
251 static h223_lc_params *h223_fw_lc_params;
252 static h223_lc_params *h223_rev_lc_params;
253 static h223_add_lc_handle_t h223_add_lc_handle = NULL;
255 static void h223_lc_init_dir( int dir )
257 if ( h223_pending_olc_reqs[dir] )
258 g_hash_table_destroy( h223_pending_olc_reqs[dir] );
259 h223_pending_olc_reqs[dir] = g_hash_table_new( g_direct_hash, g_direct_equal );
262 static void h223_lc_init( void )
264 h223_lc_init_dir( P2P_DIR_SENT );
265 h223_lc_init_dir( P2P_DIR_RECV );
266 h223_lc_params_temp = NULL;
267 h245_lc_dissector = NULL;
271 void h245_set_h223_add_lc_handle( h223_add_lc_handle_t handle )
273 h223_add_lc_handle = handle;
276 /* Initialize the protocol and registered fields */
278 #include "packet-h245-hf.c"
280 /* Initialize the subtree pointers */
281 #include "packet-h245-ett.c"
283 #include "packet-h245-fn.c"
286 dissect_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
289 * MultimediaSystemControlMessage_handle is the handle for
290 * dissect_h245_h245, so we don't want to do any h245_pi or tap stuff here.
292 dissect_tpkt_encap(tvb, pinfo, parent_tree, h245_reassembly, MultimediaSystemControlMessage_handle);
295 static void reset_h245_pi(void *dummy _U_)
297 h245_pi = NULL; /* Make sure we don't leave ep_alloc()ated memory lying around */
301 dissect_h245_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
308 if (check_col(pinfo->cinfo, COL_PROTOCOL)){
309 col_set_str(pinfo->cinfo, COL_PROTOCOL, PSNAME);
312 it=proto_tree_add_protocol_format(parent_tree, proto_h245, tvb, 0, tvb_length(tvb), PSNAME);
313 tr=proto_item_add_subtree(it, ett_h245);
315 /* assume that whilst there is more tvb data, there are more h245 commands */
316 while ( tvb_length_remaining( tvb, offset>>3 )>0 ){
317 CLEANUP_PUSH(reset_h245_pi, NULL);
318 h245_pi=ep_alloc(sizeof(h245_packet_info));
319 init_h245_packet_info(h245_pi);
320 asn_ctx_init(&asn_ctx, ASN_ENC_PER, TRUE, pinfo);
321 offset = dissect_h245_MultimediaSystemControlMessage(tvb, offset, &asn_ctx, tr, hf_h245_pdu_type);
322 tap_queue_packet(h245dg_tap, pinfo, h245_pi);
323 offset = (offset+0x07) & 0xfffffff8;
324 CLEANUP_CALL_AND_POP;
329 dissect_h245_OpenLogicalChannelCodec(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, char *codec_str) {
330 dissect_OpenLogicalChannel_PDU(tvb, pinfo, tree);
332 if (h245_pi != NULL) h245_pi->msg_type = H245_OpenLogChn;
334 if (codec_str && codec_type){
335 strncpy(codec_str, codec_type, 50);
340 /*--- proto_register_h245 -------------------------------------------*/
341 void proto_register_h245(void) {
344 static hf_register_info hf[] = {
346 { "PDU Type", "h245.pdu_type", FT_UINT32, BASE_DEC,
347 VALS(h245_MultimediaSystemControlMessage_vals), 0, "Type of H.245 PDU", HFILL }},
348 { &hf_h245Manufacturer,
349 { "H.245 Manufacturer", "h245.Manufacturer", FT_UINT32, BASE_HEX,
350 VALS(H221ManufacturerCode_vals), 0, "h245.H.221 Manufacturer", HFILL }},
351 #include "packet-h245-hfarr.c"
354 /* List of subtrees */
355 static gint *ett[] = {
357 #include "packet-h245-ettarr.c"
359 module_t *h245_module;
361 /* Register protocol */
362 proto_h245 = proto_register_protocol(PNAME, PSNAME, PFNAME);
363 /* Register fields and subtrees */
364 proto_register_field_array(proto_h245, hf, array_length(hf));
365 proto_register_subtree_array(ett, array_length(ett));
367 /* From Ronnie Sahlbergs original H245 dissector */
369 h245_module = prefs_register_protocol(proto_h245, NULL);
370 prefs_register_bool_preference(h245_module, "reassembly",
371 "Reassemble H.245 messages spanning multiple TCP segments",
372 "Whether the H.245 dissector should reassemble messages spanning multiple TCP segments."
373 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
375 prefs_register_bool_preference(h245_module, "shorttypes",
376 "Show short message types",
377 "Whether the dissector should show short names or the long names from the standard",
379 register_dissector("h245dg", dissect_h245_h245, proto_h245);
380 register_dissector("h245", dissect_h245, proto_h245);
382 nsp_object_dissector_table = register_dissector_table("h245.nsp.object", "H.245 NonStandardParameter (object)", FT_STRING, BASE_NONE);
383 nsp_h221_dissector_table = register_dissector_table("h245.nsp.h221", "H.245 NonStandardParameter (h221)", FT_UINT32, BASE_HEX);
384 h245_tap = register_tap("h245");
385 h245dg_tap = register_tap("h245dg");
387 add_oid_str_name("0.0.8.239.1.1","itu-t(0) recommendation(0) h(8) h239(239) generic-capabilities(1) h239ControlCapability(1)");
388 add_oid_str_name("0.0.8.239.1.2","itu-t(0) recommendation(0) h(8) h239(239) generic-capabilities(1) h239ExtendedVideoCapability(2)");
389 add_oid_str_name("0.0.8.239.2","itu-t(0) recommendation(0) h(8) h239(239) generic-message(2)");
390 add_oid_str_name("0.0.8.245.0.3","itu-t(0) recommendation(0) h(8) h245(245) version(0) 3");
391 add_oid_str_name("0.0.8.245.0.4","itu-t(0) recommendation(0) h(8) h245(245) version(0) 4");
392 add_oid_str_name("0.0.8.245.0.5","itu-t(0) recommendation(0) h(8) h245(245) version(0) 5");
393 add_oid_str_name("0.0.8.245.0.6","itu-t(0) recommendation(0) h(8) h245(245) version(0) 6");
394 add_oid_str_name("0.0.8.245.0.7","itu-t(0) recommendation(0) h(8) h245(245) version(0) 7");
395 add_oid_str_name("0.0.8.245.0.8","itu-t(0) recommendation(0) h(8) h245(245) version(0) 8");
396 add_oid_str_name("0.0.8.245.0.10","itu-t(0) recommendation(0) h(8) h245(245) version(0) 10");
397 add_oid_str_name("0.0.8.245.1.0.0","itu-t(0) recommendation(0) h(8) h245(245) generic-capabilities(1) video (0) ISO/IEC 14496-2 (0)= MPEG-4 video");
398 add_oid_str_name("0.0.8.245.1.1.0","itu-t(0) recommendation(0) h(8) h245(245) generic-capabilities(1) audio (1) ISO/IEC 14496-3 (0)= MPEG-4 audio");
399 add_oid_str_name("0.0.8.245.1.1.1","itu-t(0) recommendation(0) h(8) h245(245) generic-capabilities(1) audio(1) amr(1)");
401 add_oid_str_name("0.0.8.241.0.0.1","itu-t(0) recommendation(0) h(8) h241(241) specificVideoCodecCapabilities(0) h264(0) generic-capabilities(1)");
407 /*--- proto_reg_handoff_h245 ---------------------------------------*/
408 void proto_reg_handoff_h245(void) {
409 rtp_handle = find_dissector("rtp");
410 rtcp_handle = find_dissector("rtcp");
411 t38_handle = find_dissector("t38");
412 data_handle = find_dissector("data");
413 h263_handle = find_dissector("h263data");
414 amr_handle = find_dissector("amr_if2");
417 h245_handle=create_dissector_handle(dissect_h245, proto_h245);
418 dissector_add_handle("tcp.port", h245_handle);
419 MultimediaSystemControlMessage_handle=create_dissector_handle(dissect_h245_h245, proto_h245);
420 dissector_add_handle("udp.port", MultimediaSystemControlMessage_handle);
425 static void init_h245_packet_info(h245_packet_info *pi)
431 pi->msg_type = H245_OTHER;
432 pi->frame_label[0] = '\0';
433 g_snprintf(pi->comment, sizeof(pi->comment), "H245 ");