will this finally get rid of the warnigs?
[obnox/wireshark/wip.git] / asn1 / h245 / packet-h245-template.c
1 /* packet-h245_asn1.c
2  * Routines for h245 packet dissection
3  * Copyright 2004, Anders Broman <anders.broman@ericsson.com>
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
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.
15  *
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.
20  *
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.
24  *
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
29  * it will go away."
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.
32  *
33  */
34
35 #ifdef HAVE_CONFIG_H
36 # include "config.h"
37 #endif
38
39 #include <glib.h>
40 #include <epan/packet.h>
41 #include <epan/conversation.h>
42
43 #include <stdio.h>
44 #include <string.h>
45
46 #include <epan/prefs.h>
47 #include <epan/t35.h>
48 #include <epan/emem.h>
49 #include <epan/oid_resolv.h>
50 #include <epan/asn1.h>
51 #include "tap.h"
52 #include "packet-tpkt.h"
53 #include "packet-per.h"
54 #include "packet-h245.h"
55 #include "packet-rtp.h"
56 #include "packet-rtcp.h"
57 #include "packet-t38.h"
58
59 #define PNAME  "MULTIMEDIA-SYSTEM-CONTROL"
60 #define PSNAME "H.245"
61 #define PFNAME "h245"
62
63 static dissector_handle_t rtp_handle=NULL;
64 static dissector_handle_t rtcp_handle=NULL;
65 static dissector_handle_t t38_handle=NULL;
66 static dissector_table_t nsp_object_dissector_table;
67 static dissector_table_t nsp_h221_dissector_table;
68 static dissector_table_t gen_par_dissector_table;
69 static dissector_handle_t nsp_handle;
70 static dissector_handle_t data_handle;
71 static dissector_handle_t h245_handle;
72 static dissector_handle_t MultimediaSystemControlMessage_handle;
73 static dissector_handle_t h263_handle = NULL;
74 static dissector_handle_t amr_handle = NULL;
75
76 static void init_h245_packet_info(h245_packet_info *pi);
77 static int hf_h245_pdu_type = -1;
78 static int hf_h245Manufacturer = -1;
79 static int h245_tap = -1;
80 static int ett_h245 = -1;
81 static int h245dg_tap = -1;
82 h245_packet_info *h245_pi=NULL;
83
84 static gboolean h245_reassembly = TRUE;
85 static gboolean h245_shorttypes = FALSE;
86 static const value_string h245_RequestMessage_short_vals[] = {
87         {  0,   "NSM" },
88         {  1,   "MSD" },
89         {  2,   "TCS" },
90         {  3,   "OLC" },
91         {  4,   "CLC" },
92         {  5,   "RCC" },
93         {  6,   "MES" },
94         {  7,   "RME" },
95         {  8,   "RM" },
96         {  9,   "RTDR" },
97         { 10,   "MLR" },
98         { 11,   "CMR" },
99         { 12,   "CR" },
100         { 13,   "MR" },
101         { 14,   "LCRR" },
102         { 15,   "GR" },
103         {  0, NULL }
104 };
105 static const value_string h245_ResponseMessage_short_vals[] = {
106         {  0,   "NSM" },
107         {  1,   "MSDAck" },
108         {  2,   "MSDReject" },
109         {  3,   "TCSAck" },
110         {  4,   "TCSReject" },
111         {  5,   "OLCAck" },
112         {  6,   "OLCReject" },
113         {  7,   "CLCAck" },
114         {  8,   "RCCAck" },
115         {  9,   "RCCReject" },
116         { 10,   "MESAck" },
117         { 11,   "MESReject" },
118         { 12,   "RMEAck" },
119         { 13,   "RMEReject" },
120         { 14,   "RMAck" },
121         { 15,   "RMReject" },
122         { 16,   "RTDResponse" },
123         { 17,   "MLAck" },
124         { 18,   "MLReject" },
125         { 19,   "CMResponse" },
126         { 20,   "CResponse" },
127         { 21,   "MResponse" },
128         { 22,   "LCRAck" },
129         { 23,   "LCRReject" },
130         { 24,   "GR" },
131         {  0, NULL }
132 };
133 static const value_string h245_IndicationMessage_short_vals[] = {
134         {  0,   "NSM" },
135         {  1,   "FNU" },
136         {  2,   "MSDRelease" },
137         {  3,   "TCSRelease" },
138         {  4,   "OLCConfirm" },
139         {  5,   "RCCRelease" },
140         {  6,   "MESRelease" },
141         {  7,   "RMERelease" },
142         {  8,   "RMRelease" },
143         {  9,   "MI" },
144         { 10,   "JI" },
145         { 11,   "H223SI" },
146         { 12,   "NATMVCI" },
147         { 13,   "UII" },
148         { 14,   "H2250MSI" },
149         { 15,   "MCLI" },
150         { 16,   "CI" },
151         { 17,   "VI" },
152         { 18,   "FNS" },
153         { 19,   "MultilinkIndication" },
154         { 20,   "LCRRelease" },
155         { 21,   "FCIndication" },
156         { 22,   "MMRI" },
157         { 22,   "GI" },
158         {  0, NULL }
159 };
160 static const value_string h245_CommandMessage_short_vals[] = {
161         {  0,   "NSM" },
162         {  1,   "MLOC" },
163         {  2,   "STCS" },
164         {  3,   "EC" },
165         {  4,   "FCC" },
166         {  5,   "ESC" },
167         {  6,   "MC" },
168         {  7,   "CMC" },
169         {  8,   "CC" },
170         {  9,   "H223MR" },
171         { 10,   "NATMVCC" },
172         { 11,   "MMRC" },
173         { 12,   "GC" },
174         {  0, NULL }
175 };
176 static const value_string h245_AudioCapability_short_vals[] = {
177         {  0, "nonStd" },
178         {  1, "g711A" },
179         {  2, "g711A56k" },
180         {  3, "g711U" },
181         {  4, "g711U56k" },
182         {  5, "g722-64k" },
183         {  6, "g722-56k" },
184         {  7, "g722-48k" },
185         {  8, "g7231" },
186         {  9, "g728" },
187         { 10, "g729" },
188         { 11, "g729A" },
189         { 12, "is11172" },
190         { 13, "is13818" },
191         { 14, "g729B" },
192         { 15, "g729AB" },
193         { 16, "g7231C" },
194         { 17, "gsmFR" },
195         { 18, "gsmHR" },
196         { 19, "gsmEFR" },
197         { 20, "generic" },
198         { 21, "g729Ext" },
199         { 22, "vbd" },
200         { 23, "audioTelEvent" },
201         { 24, "audioTone" },
202         {  0, NULL }
203 };
204
205 /* To put the codec type only in COL_INFO when
206    an OLC is read */
207
208 const char* codec_type = NULL;
209 static const char *standard_oid_str;
210 static guint32 ipv4_address;
211 static guint32 ipv4_port;
212 static guint32 rtcp_ipv4_address;
213 static guint32 rtcp_ipv4_port;
214 static gboolean media_channel;
215 static gboolean media_control_channel;
216 static const char *gen_par_prefix;
217 static const char *gen_par_str;
218
219 /* NonStandardParameter */
220 static const char *nsiOID;
221 static guint32 h221NonStandard;
222 static guint32 t35CountryCode;
223 static guint32 t35Extension;
224 static guint32 manufacturerCode;
225
226 static const value_string h245_RFC_number_vals[] = {
227         {  2190,        "RFC 2190 - H.263 Video Streams" },
228         {  2429,        "RFC 2429 - 1998 Version of ITU-T Rec. H.263 Video (H.263+)" },
229         {  3016,        "RFC 3016 - RTP Payload Format for MPEG-4 Audio/Visual Streams" },
230         {  3267,        "RFC 3267 - Adaptive Multi-Rate (AMR) and Adaptive Multi-Rate Wideband (AMR-WB)" },
231         {  0, NULL }
232 };
233
234 /* h223 multiplex codes */
235 static h223_set_mc_handle_t h223_set_mc_handle = NULL;
236 h223_mux_element *h223_me=NULL;
237 guint8 h223_mc=0;
238 void h245_set_h223_set_mc_handle( h223_set_mc_handle_t handle )
239 {
240         h223_set_mc_handle = handle;
241 }
242
243 /* h223 logical channels */
244 typedef struct {
245         h223_lc_params *fw_channel_params;
246         h223_lc_params *rev_channel_params;
247 } h223_pending_olc;
248
249 static GHashTable*          h223_pending_olc_reqs[] = { NULL, NULL };
250 static dissector_handle_t   h245_lc_dissector;
251 static guint16              h245_lc_temp;
252 static guint16              h223_fw_lc_num;
253 static guint16              h223_rev_lc_num;
254 static h223_lc_params      *h223_lc_params_temp;
255 static h223_lc_params      *h223_fw_lc_params;
256 static h223_lc_params      *h223_rev_lc_params;
257 static h223_add_lc_handle_t h223_add_lc_handle = NULL;
258
259 static void h223_lc_init_dir( int dir )
260 {
261         if ( h223_pending_olc_reqs[dir] )
262                 g_hash_table_destroy( h223_pending_olc_reqs[dir] );
263         h223_pending_olc_reqs[dir] = g_hash_table_new( g_direct_hash, g_direct_equal );
264 }
265
266 static void h223_lc_init( void )
267 {
268         h223_lc_init_dir( P2P_DIR_SENT );
269         h223_lc_init_dir( P2P_DIR_RECV );
270         h223_lc_params_temp = NULL;
271         h245_lc_dissector = NULL;
272         h223_fw_lc_num = 0;
273 }
274
275 void h245_set_h223_add_lc_handle( h223_add_lc_handle_t handle )
276 {
277         h223_add_lc_handle = handle;
278 }
279
280 /* Initialize the protocol and registered fields */
281 int proto_h245 = -1;
282 #include "packet-h245-hf.c"
283
284 /* Initialize the subtree pointers */
285 #include "packet-h245-ett.c"
286
287 #include "packet-h245-fn.c"
288
289 static void
290 dissect_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
291 {
292         /*
293          * MultimediaSystemControlMessage_handle is the handle for
294          * dissect_h245_h245, so we don't want to do any h245_pi or tap stuff here.
295          */
296         dissect_tpkt_encap(tvb, pinfo, parent_tree, h245_reassembly, MultimediaSystemControlMessage_handle);
297 }
298
299 static void reset_h245_pi(void *dummy _U_)
300 {
301         h245_pi = NULL; /* Make sure we don't leave ep_alloc()ated memory lying around */
302 }
303
304 static void
305 dissect_h245_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
306 {
307         proto_item *it;
308         proto_tree *tr;
309         guint32 offset=0;
310         asn1_ctx_t asn1_ctx;
311
312         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
313                 col_set_str(pinfo->cinfo, COL_PROTOCOL, PSNAME);
314         }
315
316         it=proto_tree_add_protocol_format(parent_tree, proto_h245, tvb, 0, tvb_length(tvb), PSNAME);
317         tr=proto_item_add_subtree(it, ett_h245);
318
319         /* assume that whilst there is more tvb data, there are more h245 commands */
320         while ( tvb_length_remaining( tvb, offset>>3 )>0 ){
321                 CLEANUP_PUSH(reset_h245_pi, NULL);
322                 h245_pi=ep_alloc(sizeof(h245_packet_info));
323                 init_h245_packet_info(h245_pi);
324                 asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo);
325                 offset = dissect_h245_MultimediaSystemControlMessage(tvb, offset, &asn1_ctx, tr, hf_h245_pdu_type);
326                 tap_queue_packet(h245dg_tap, pinfo, h245_pi);
327                 offset = (offset+0x07) & 0xfffffff8;
328                 CLEANUP_CALL_AND_POP;
329         }
330 }
331
332 void
333 dissect_h245_OpenLogicalChannelCodec(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, char *codec_str) {
334   dissect_OpenLogicalChannel_PDU(tvb, pinfo, tree);
335
336   if (h245_pi != NULL) h245_pi->msg_type = H245_OpenLogChn;
337
338   if (codec_str && codec_type){
339         strncpy(codec_str, codec_type, 50);
340   }
341
342 }
343
344 /*--- proto_register_h245 -------------------------------------------*/
345 void proto_register_h245(void) {
346
347   /* List of fields */
348   static hf_register_info hf[] = {
349     { &hf_h245_pdu_type,
350  { "PDU Type", "h245.pdu_type", FT_UINT32, BASE_DEC,
351                 VALS(h245_MultimediaSystemControlMessage_vals), 0, "Type of H.245 PDU", HFILL }},
352         { &hf_h245Manufacturer,
353                 { "H.245 Manufacturer", "h245.Manufacturer", FT_UINT32, BASE_HEX,
354                 VALS(H221ManufacturerCode_vals), 0, "h245.H.221 Manufacturer", HFILL }},
355 #include "packet-h245-hfarr.c"
356   };
357
358   /* List of subtrees */
359   static gint *ett[] = {
360           &ett_h245,
361 #include "packet-h245-ettarr.c"
362   };
363   module_t *h245_module;
364
365   /* Register protocol */
366   proto_h245 = proto_register_protocol(PNAME, PSNAME, PFNAME);
367   /* Register fields and subtrees */
368   proto_register_field_array(proto_h245, hf, array_length(hf));
369   proto_register_subtree_array(ett, array_length(ett));
370
371   /* From Ronnie Sahlbergs original H245 dissector */
372
373   h245_module = prefs_register_protocol(proto_h245, NULL);
374   prefs_register_bool_preference(h245_module, "reassembly",
375                 "Reassemble H.245 messages spanning multiple TCP segments",
376                 "Whether the H.245 dissector should reassemble messages spanning multiple TCP segments."
377                 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
378                 &h245_reassembly);
379   prefs_register_bool_preference(h245_module, "shorttypes",
380                 "Show short message types",
381                 "Whether the dissector should show short names or the long names from the standard",
382                 &h245_shorttypes);
383   register_dissector("h245dg", dissect_h245_h245, proto_h245);
384   register_dissector("h245", dissect_h245, proto_h245);
385
386   nsp_object_dissector_table = register_dissector_table("h245.nsp.object", "H.245 NonStandardParameter (object)", FT_STRING, BASE_NONE);
387   nsp_h221_dissector_table = register_dissector_table("h245.nsp.h221", "H.245 NonStandardParameter (h221)", FT_UINT32, BASE_HEX);
388   gen_par_dissector_table = register_dissector_table("h245.gen_par", "H.245 GenericParameter", FT_STRING, BASE_NONE);
389
390   h245_tap = register_tap("h245");
391   h245dg_tap = register_tap("h245dg");
392
393   add_oid_str_name("0.0.8.239.1.1","itu-t(0) recommendation(0) h(8) h239(239) generic-capabilities(1) h239ControlCapability(1)");
394   add_oid_str_name("0.0.8.239.1.2","itu-t(0) recommendation(0) h(8) h239(239) generic-capabilities(1) h239ExtendedVideoCapability(2)");
395   add_oid_str_name("0.0.8.239.2","itu-t(0) recommendation(0) h(8) h239(239) generic-message(2)");
396   add_oid_str_name("0.0.8.245.0.3","itu-t(0) recommendation(0) h(8) h245(245) version(0) 3");
397   add_oid_str_name("0.0.8.245.0.4","itu-t(0) recommendation(0) h(8) h245(245) version(0) 4");
398   add_oid_str_name("0.0.8.245.0.5","itu-t(0) recommendation(0) h(8) h245(245) version(0) 5");
399   add_oid_str_name("0.0.8.245.0.6","itu-t(0) recommendation(0) h(8) h245(245) version(0) 6");
400   add_oid_str_name("0.0.8.245.0.7","itu-t(0) recommendation(0) h(8) h245(245) version(0) 7");
401   add_oid_str_name("0.0.8.245.0.8","itu-t(0) recommendation(0) h(8) h245(245) version(0) 8");
402   add_oid_str_name("0.0.8.245.0.9","itu-t(0) recommendation(0) h(8) h245(245) version(0) 9");
403   add_oid_str_name("0.0.8.245.0.10","itu-t(0) recommendation(0) h(8) h245(245) version(0) 10");
404   add_oid_str_name("0.0.8.245.0.11","itu-t(0) recommendation(0) h(8) h245(245) version(0) 11");
405   add_oid_str_name("0.0.8.245.0.12","itu-t(0) recommendation(0) h(8) h245(245) version(0) 12");
406   add_oid_str_name("0.0.8.245.0.13","itu-t(0) recommendation(0) h(8) h245(245) version(0) 13");
407   /* This capability is defined in Annex E. */
408   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");
409   /* This capability is defined in Annex H. */
410   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");
411   /* This capability is defined in Annex I. */  
412   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)");
413   /* This capability is defined in Annex J. */
414   add_oid_str_name("0.0.8.245.1.1.2","itu-t (0) recommendation (0) h (8) 245 genericcapabilities (1) audio (1) acelp (2)");
415   /* This capability is defined in Annex K. */
416   add_oid_str_name("0.0.8.245.1.1.3","itu-t (0) recommendation (0) h (8) 245 genericcapabilities (1) audio (1) us1 (3)");
417   /* This capability is defined in Annex L. */
418   add_oid_str_name("0.0.8.245.1.1.4","itu-t (0) recommendation (0) h (8) 245 genericcapabilities (1) audio (1) is127evrc (4)");
419   /* This capability is defined in Annex M. */
420   add_oid_str_name("0.0.8.245.1.1.5","itu-t (0) recommendation (0) h (8) 245 genericcapabilities (1) audio (1) ISO/IEC 13818-7 (5)");
421   /* This capability is defined in Annex N. */
422   add_oid_str_name("0.0.8.245.1.1.6","itu-t (0) recommendation (0) h (8) 245 genericcapabilities (1) audio (1) rfc3389 (6)");
423   /* This capability is defined in Annex O. */
424   add_oid_str_name("0.0.8.245.1.1.7","itu-t (0) recommendation (0) h (8) 245 genericcapabilities (1) audio (1) L-16 (7)");
425   /* This capability is defined in Annex P. */
426   add_oid_str_name("0.0.8.245.1.1.8","itu-t (0) recommendation (0) h (8) 245 genericcapabilities (1) audio (1) bounded-audio-stream (8)");
427   /* This capability is defined in Annex R. */
428   add_oid_str_name("0.0.8.245.1.1.9","itu-t (0) recommendation (0) h (8) 245 genericcapabilities (1) audio (1) amr-nb (9)");
429   /* This capability is defined in Annex R. */
430   add_oid_str_name("0.0.8.245.1.1.10","itu-t (0) recommendation (0) h (8) 245 genericcapabilities (1) audio (1) amr-wb (10)");
431   /* This capability is defined in Annex S. */
432   add_oid_str_name("0.0.8.245.1.1.11","itu-t (0) recommendation (0) h (8) 245 genericcapabilities (1) audio (1) ilbc (11)");
433   
434   add_oid_str_name("0.0.8.245.1.2.0","itu-t (0) recommendation (0) h (8) 245 genericcapabilities (1) data (2) ISO/IEC 14496-1 (0)");
435   add_oid_str_name("0.0.8.245.1.2.1","itu-t (0) recommendation (0) h (8) 245 genericcapabilities (1) data (2) Nx64 (1)");
436   add_oid_str_name("0.0.8.245.1.3.0","itu-t (0) recommendation (0) h (8) 245 genericcapabilities (1) control (3) logical-channel-bit-ratemanagement(0)");
437   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)");
438
439
440 }
441
442
443 /*--- proto_reg_handoff_h245 ---------------------------------------*/
444 void proto_reg_handoff_h245(void) {
445         rtp_handle = find_dissector("rtp");
446         rtcp_handle = find_dissector("rtcp");
447         t38_handle = find_dissector("t38");
448         data_handle = find_dissector("data");
449         h263_handle = find_dissector("h263data");
450         amr_handle = find_dissector("amr_if2");
451
452
453         h245_handle=create_dissector_handle(dissect_h245, proto_h245);
454         dissector_add_handle("tcp.port", h245_handle);
455         MultimediaSystemControlMessage_handle=create_dissector_handle(dissect_h245_h245, proto_h245);
456         dissector_add_handle("udp.port", MultimediaSystemControlMessage_handle);
457
458         h223_lc_init();
459 }
460
461 static void init_h245_packet_info(h245_packet_info *pi)
462 {
463         if(pi == NULL) {
464                 return;
465         }
466
467         pi->msg_type = H245_OTHER;
468                 pi->frame_label[0] = '\0';
469                 g_snprintf(pi->comment, sizeof(pi->comment), "H245 ");
470 }
471