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