Use G_GINT64_MODIFIER, rather than the PRI[douxX]64 macros, for GLib
[obnox/wireshark/wip.git] / asn1 / h248 / packet-h248-template.c
1 /* packet-h248.c
2  * Routines for H.248/MEGACO packet dissection
3  *
4  * Ronnie Sahlberg 2004
5  *
6  * Luis Ontanon 2005 - Context and Transaction Tracing
7  *
8  * $Id$
9  *
10  * Wireshark - Network traffic analyzer
11  * By Gerald Combs <gerald@wireshark.org>
12  * Copyright 1998 Gerald Combs
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 #include "packet-h248.h"
29 #include "tap.h"
30 #include "packet-tpkt.h"
31
32 #define PNAME  "H.248 MEGACO"
33 #define PSNAME "H248"
34 #define PFNAME "h248"
35
36 #define GATEWAY_CONTROL_PROTOCOL_USER_ID 14
37
38
39 /* Initialize the protocol and registered fields */
40 static int proto_h248                           = -1;
41 static int hf_h248_mtpaddress_ni        = -1;
42 static int hf_h248_mtpaddress_pc        = -1;
43 static int hf_h248_pkg_name             = -1;
44 static int hf_248_pkg_param = -1;
45 static int hf_h248_event_name           = -1;
46 static int hf_h248_signal_name          = -1;
47 static int hf_h248_signal_code          = -1;
48 static int hf_h248_event_code           = -1;
49 static int hf_h248_pkg_bcp_BNCChar_PDU = -1;
50
51
52
53 static int hf_h248_context_id = -1;
54 static int hf_h248_error_code = -1;
55 static int hf_h248_term_wild_type = -1;
56 static int hf_h248_term_wild_level = -1;
57 static int hf_h248_term_wild_position = -1;
58
59 static int hf_h248_no_pkg = -1;
60 static int hf_h248_no_sig = -1;
61 static int hf_h248_no_evt = -1;
62 static int hf_h248_param = -1;
63
64 static int hf_h248_serviceChangeReasonStr = -1;
65
66 #include "packet-h248-hf.c"
67
68 /* Initialize the subtree pointers */
69 static gint ett_h248 = -1;
70 static gint ett_mtpaddress = -1;
71 static gint ett_packagename = -1;
72 static gint ett_codec = -1;
73 static gint ett_wildcard = -1;
74
75 static gint ett_h248_no_pkg = -1;
76 static gint ett_h248_no_sig = -1;
77 static gint ett_h248_no_evt = -1;
78
79 static int h248_tap = -1;
80
81 static gcp_hf_ett_t h248_arrel = {{-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1}};
82
83 #include "packet-h248-ett.c"
84
85 static dissector_handle_t h248_term_handle;
86
87 static emem_tree_t* msgs = NULL;
88 static emem_tree_t* trxs = NULL;
89 static emem_tree_t* ctxs_by_trx = NULL;
90 static emem_tree_t* ctxs = NULL;
91
92 static gboolean h248_prefs_initialized = FALSE;
93 static gboolean keep_persistent_data = FALSE;
94 static guint32 udp_port = 2945;
95 static guint32 temp_udp_port = 2945;
96 static guint32 tcp_port = 2945;
97 static guint32 temp_tcp_port = 2945;
98 static gboolean h248_desegment = TRUE;
99
100
101
102 static proto_tree *h248_tree;
103 static tvbuff_t* h248_tvb;
104
105 static dissector_handle_t h248_handle;
106 static dissector_handle_t h248_term_handle;
107 static dissector_handle_t h248_tpkt_handle;
108
109 /* Forward declarations */
110 static int dissect_h248_ServiceChangeReasonStr(gboolean implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index);
111
112 static const value_string package_name_vals[] = {
113   {   0x0000, "Media stream properties H.248.1 Annex C" },
114   {   0x0001, "Generic H.248.1 Annex E" },
115   {   0x0002, "root H.248.1 Annex E" },
116   {   0x0003, "tonegen H.248.1 Annex E" },
117   {   0x0004, "tonedet H.248.1 Annex E" },
118   {   0x0005, "dg H.248.1 Annex E" },
119   {   0x0006, "dd H.248.1 Annex E" },
120   {   0x0007, "cg H.248.1 Annex E" },
121   {   0x0008, "cd H.248.1 Annex E" },
122   {   0x0009, "al H.248.1 Annex E" },
123   {   0x000a, "ct H.248.1 Annex E" },
124   {   0x000b, "nt H.248.1 Annex E" },
125   {   0x000c, "rtp H.248.1 Annex E" },
126   {   0x000d, "tdmc H.248.1 Annex E" },
127   {   0x000e, "ftmd H.248.1 Annex E" },
128   {   0x000f, "txc H.248.2" },                                                                                  /* H.248.2 */
129   {   0x0010, "txp H.248.2" },
130   {   0x0011, "ctyp H.248.2" },
131   {   0x0012, "fax H.248.2" },
132   {   0x0013, "ipfax H.248.2" },
133   {   0x0014, "dis H.248.3" },                                                                                  /* H.248.3 */
134   {   0x0015, "key H.248.3" },
135   {   0x0016, "kp H.248.3" },
136   {   0x0017, "labelkey H.248.3" },
137   {   0x0018, "kf H.248.3" },
138   {   0x0019, "ind H.248.3" },
139   {   0x001a, "ks H.248.3" },
140   {   0x001b, "anci H.248.3" },
141   {   0x001c, "dtd H.248.6" },                                                                                  /* H.248.6 */
142   {   0x001d, "an H.248.7" },                                                                                   /* H.248.7 */
143   {   0x001e, "Bearer Characteristics Q.1950 Annex A" },                                /* Q.1950 Annex A */
144   {   0x001f, "Bearer Network Connection Cut Q.1950 Annex A" },
145   {   0x0020, "Reuse Idle Q.1950 Annex A" },
146   {   0x0021, "Generic Bearer Connection Q.1950 Annex A" },
147   {   0x0022, "Bearer Control Tunnelling Q.1950 Annex A" },
148   {   0x0023, "Basic Call Progress Tones Q.1950 Annex A" },
149   {   0x0024, "Expanded Call Progress Tones Q.1950 Annex A" },
150   {   0x0025, "Basic Services Tones Q.1950 Annex A" },
151   {   0x0026, "Expanded Services Tones Q.1950 Annex A" },
152   {   0x0027, "Intrusion Tones Q.1950 Annex A" },
153   {   0x0028, "Business Tones Q.1950 Annex A" },
154   {   0x0029, "Media Gateway Resource Congestion Handling H.248.10" },  /* H.248.10 */
155   {   0x002a, "H245 package H248.12" },                                                                 /* H.248.12 */
156   {   0x002b, "H323 bearer control package H.248.12" },                                 /* H.248.12 */
157   {   0x002c, "H324 package H.248.12" },                                                                /* H.248.12 */
158   {   0x002d, "H245 command package H.248.12" },                                                /* H.248.12 */
159   {   0x002e, "H245 indication package H.248.12" },                                             /* H.248.12 */
160   {   0x002f, "3G User Plane" },                                                                                /* 3GPP TS 29.232 v4.1.0 */
161   {   0x0030, "3G Circuit Switched Data" },
162   {   0x0031, "3G TFO Control" },
163   {   0x0032, "3G Expanded Call Progress Tones" },
164   {   0x0033, "Advanced Audio Server (AAS Base)" },                                             /* H.248.9 */
165   {   0x0034, "AAS Digit Collection" },                                                                 /* H.248.9 */
166   {   0x0035, "AAS Recording" },                                                                                /* H.248.9 */
167   {   0x0036, "AAS Segment Management" },                                                               /* H.248.9 */
168   {   0x0037, "Quality Alert Ceasing" },                                                                /* H.248.13 */
169   {   0x0038, "Conferencing Tones Generation" },                                                /* H.248.27 */
170   {   0x0039, "Diagnostic Tones Generation" },                                                  /* H.248.27 */
171   {   0x003a, "Carrier Tones Generation Package H.248.23" },                    /* H.248.27 */
172   {   0x003b, "Enhanced Alerting Package H.248.23" },                                   /* H.248.23 */
173   {   0x003c, "Analog Display Signalling Package H.248.23" },                   /* H.248.23 */
174   {   0x003d, "Multi-Frequency Tone Generation Package H.248.24" },             /* H.248.24 */
175   {   0x003e, "H.248.23Multi-Frequency Tone Detection Package H.248.24" }, /* H.248.24 */
176   {   0x003f, "Basic CAS Package H.248.25" },                                                   /* H.248.25 */
177   {   0x0040, "Robbed Bit Signalling Package H.248.25" },                       /* H.248.25 */
178   {   0x0041, "Operator Services and Emgergency Services Package H.248.25" },
179   {   0x0042, "Operator Services Extension Package H.248.25" },
180   {   0x0043, "Extended Analog Line Supervision Package H.248.26" },
181   {   0x0044, "Automatic Metering Package H.248.26" },
182   {   0x0045, "Inactivity Timer Package H.248.14" },
183   {   0x0046, "3G Modification of Link Characteristics Bearer Capability" }, /* 3GPP TS 29.232 v4.4.0 */
184   {   0x0047, "Base Announcement Syntax H.248.9" },
185   {   0x0048, "Voice Variable Syntax H.248.9" },
186   {   0x0049, "Announcement Set Syntax H.248.9" },
187   {   0x004a, "Phrase Variable Syntax H.248.9" },
188   {   0x004b, "Basic NAS package" },
189   {   0x004c, "NAS incoming package" },
190   {   0x004d, "NAS outgoing package" },
191   {   0x004e, "NAS control package" },
192   {   0x004f, "NAS root package" },
193   {   0x0050, "Profile Handling Package H.248.18" },
194   {   0x0051, "Media Gateway Overload Control Package H.248.11" },
195   {   0x0052, "Extended DTMF Detection Package H.248.16" },
196   {   0x0053, "Quiet Termination Line Test" },
197   {   0x0054, "Loopback Line Test Response" },                                                  /* H.248.17 */
198   {   0x0055, "ITU 404Hz Line Test" },                                                                  /* H.248.17 */
199   {   0x0056, "ITU 816Hz Line Test" },                                                                  /* H.248.17 */
200   {   0x0057, "ITU 1020Hz Line Test" },                                                                 /* H.248.17 */
201   {   0x0058, "ITU 2100Hz Disable Tone Line Test" },                                    /* H.248.17 */
202   {   0x0059, "ITU 2100Hz Disable Echo Canceller Tone Line Test" },             /* H.248.17 */
203   {   0x005a, "ITU 2804Hz Tone Line Test" },                                                    /* H.248.17 */
204   {   0x005b, "ITU Noise Test Tone Line Test" },                                                /* H.248.17 */
205   {   0x005c, "ITU Digital Pseudo Random Test Line Test" },                             /* H.248.17 */
206   {   0x005d, "ITU ATME No.2 Test Line Response" },                                             /* H.248.17 */
207   {   0x005e, "ANSI 1004Hz Test Tone Line Test" },                                              /* H.248.17 */
208   {   0x005f, "ANSI Test Responder Line Test" },                                                /* H.248.17 */
209   {   0x0060, "ANSI 2225Hz Test Progress Tone Line Test" },                             /* H.248.17 */
210   {   0x0061, "ANSI Digital Test Signal Line Test" },                                   /* H.248.17 */
211   {   0x0062, "ANSI Inverting Loopback Line Test Repsonse" },                   /* H.248.17 */
212   {   0x0063, "Extended H.324 Packages H.248.12 Annex A" },
213   {   0x0064, "Extended H.245 Command Package H.248.12 Annex A" },
214   {   0x0065, "Extended H.245 Indication Package H.248.12 Annex A" },
215   {   0x0066, "Enhanced DTMF Detection Package H.248.16" },
216   {   0x0067, "Connection Group Identity Package Q.1950 Annex E" },
217   {   0x0068, "CTM Text Transport 3GPP TS 29.232 v5.2.0" },
218   {   0x0069, "SPNE Control Package Q.115.0" },
219   {   0x006a, "Semi-permanent Connection Package H.248.21" },
220   {   0x006b, "Shared Risk Group Package H.248.22" },
221   {   0x006c, "isuptn Annex B of ITU-T Rec. J.171" },
222   {   0x006d, "Basic CAS Addressing Package H.248.25" },
223   {   0x006e, "Floor Control Package H.248.19" },
224   {   0x006f, "Indication of Being Viewed Package H.248.19" },
225   {   0x0070, "Volume Control Package H.248.19" },
226   {   0x0071, "UNASSIGNED" },
227   {   0x0072, "Volume Detection Package H.248.19" },
228   {   0x0073, "Volume Level Mixing Package H.248.19" },
229   {   0x0074, "Mixing Volume Level Control Package H.248.19" },
230   {   0x0075, "Voice Activated Video Switch Package H.248.19" },
231   {   0x0076, "Lecture Video Mode Package H.248.19" },
232   {   0x0077, "Contributing Video Source Package H.248.19" },
233   {   0x0078, "Video Window Package H.248.19" },
234   {   0x0079, "Tiled Window Package H.248.19" },
235   {   0x007a, "Adaptive Jitter Buffer Package H.248.31" },
236   {   0x007b, "International CAS Package H.248.28" },
237   {   0x007c, "CAS Blocking Package H.248.28" },
238   {   0x007d, "International CAS Compelled Package H.248.29" },
239   {   0x007e, "International CAS Compelled with Overlap Package H.248.29" },
240   {   0x007f, "International CAS Compelled with End-to-end Package H.248.29" },
241   {   0x0080, "RTCP XR Package H.248.30" },
242   {   0x0081, "RTCP XR Burst Metrics Package H.248.30" },
243   {   0x0082, "threegcsden 3G Circuit Switched Data" },                         /* 3GPP TS 29.232 v5.6.0 */
244   {   0x0083, "threegiptra 3G Circuit Switched Data" },                         /* 3GPP TS 29.232 v5.6.0 */
245   {   0x0084, "threegflex 3G Circuit Switched Data" },                          /* 3GPP TS 29.232 v5.6.0 */
246   {   0x0085, "H.248 PCMSB" },
247   {   0x008a, "TIPHON Extended H.248/MEGACO Package" },                         /* ETSI specification TS 101 3 */
248   {   0x008b, "Differentiated Services Package" },                                      /* Annex A of ETSI TS 102 333 */
249   {   0x008c, "Gate Management Package" },                                                      /* Annex B of ETSI TS 102 333 */
250   {   0x008d, "Traffic Management Package" },                                           /* Annex C of ETSI TS 102 333 */
251   {   0x008e, "Gate Recovery Information Package" },                            /* Annex D of ETSI TS 102 333 */
252   {   0x008f, "NAT Traversal Package" },                                                        /* Annex E of ETSI TS 102 333 */
253   {   0x0090, "MPLS Package" },                                                                         /* Annex F of ETSI TS 102 333 */
254   {   0x0091, "VLAN Package" },                                                                         /* Annex G of ETSI TS 102 333 */
255   {   0x8000, "Ericsson IU" },
256   {   0x8001, "Ericsson UMTS and GSM Circuit" },
257   {   0x8002, "Ericsson Tone Generator Package" },
258   {   0x8003, "Ericsson Line Test Package" },
259   {   0x8004, "Nokia Advanced TFO Package" },
260   {   0x8005, "Nokia IWF Package" },
261   {   0x8006, "Nokia Root Package" },
262   {   0x8007, "Nokia Trace Package" },
263   {   0x8008, "Ericsson  V5.2 Layer" },
264   {   0x8009, "Ericsson Detailed Termination Information Package" },
265   {   0x800a, "Nokia Bearer Characteristics Package" },
266         {0,     NULL}
267 };
268 /*
269  * This table consist of PackageName + EventName and its's corresponding string
270  *
271  */
272 static const value_string event_name_vals[] = {
273   {   0x00000000, "Media stream properties H.248.1 Annex C" },
274   {   0x00010000, "g H.248.1 Annex E" },
275   {   0x00010001, "g/Cause" },
276   {   0x00010002, "g/Signal Completion" },
277   {   0x00040000, "tonedet H.248.1 Annex E" },
278   {   0x00040001, "tonedet/std(Start tone detected)" },
279   {   0x00040002, "tonedet/etd(End tone detected)" },
280   {   0x00040003, "tonedet/ltd(Long tone detected)" },
281   {   0x00060000, "dd H.248.1 Annex E" },
282   {   0x00060001, "dd/std" },
283   {   0x00060002, "dd/etd" },
284   {   0x00060003, "dd/ltd" },
285   {   0x00060004, "dd, DigitMap Completion Event" },
286   {   0x00060010, "dd/d0, DTMF character 0" },
287   {   0x00060011, "dd/d1, DTMF character 1" },
288   {   0x00060012, "dd/d2, DTMF character 2" },
289   {   0x00060013, "dd/d3, DTMF character 3" },
290   {   0x00060014, "dd/d4, DTMF character 4" },
291   {   0x00060015, "dd/d5, DTMF character 5" },
292   {   0x00060016, "dd/d6, DTMF character 6" },
293   {   0x00060017, "dd/d7, DTMF character 7" },
294   {   0x00060018, "dd/d8, DTMF character 8" },
295   {   0x00060019, "dd/d9, DTMF character 9" },
296   {   0x0006001a, "dd/a, DTMF character A" },
297   {   0x0006001b, "dd/b, DTMF character B" },
298   {   0x0006001c, "dd/c, DTMF character C" },
299   {   0x0006001d, "dd/d, DTMF character D" },
300   {   0x00060020, "dd/*, DTMF character *" },
301   {   0x00060021, "dd/#, DTMF character #" },
302   {   0x00080030, "cd, Dial Tone" },
303   {   0x00080031, "cd, Ringing Tone" },
304   {   0x00080032, "cd, Busy Tone" },
305   {   0x00080033, "cd, Congestion Tone" },
306   {   0x00080034, "cd, Special Information Tone" },
307   {   0x00080035, "cd, (Recording) Warning Tone" },
308   {   0x00080036, "cd, Payphone Recognition Tone" },
309   {   0x00080037, "cd, Call Waiting Tone" },
310   {   0x00080038, "cd, Caller Waiting Tone" },
311   {   0x00090004, "al, onhook" },
312   {   0x00090005, "al, offhook" },
313   {   0x00090006, "al, flashhook" },
314   {   0x0009ffff, "al, *" },
315   {   0x000a0005, "ct, Completion of Continuity test" },
316   {   0x000b0005, "nt, network failure" },
317   {   0x000b0006, "nt, quality alert" },
318   {   0x000c0001, "rtp, Payload Transition" },
319   {   0x00210000, "Generic Bearer Connection Q.1950 Annex A" },
320   {   0x00210001, "GB/BNCChange" },
321   {   0x00220001, "BT/TIND (Tunnel Indication)" },
322   {   0x002a0001, "H.245/h245msg (Incoming H.245 Message)" },
323   {   0x002a0004, "H.245/h245ChC (H.245 Channel Closed)" },
324   {   0x00450000, "Inactivity Timer H.248.14" },
325   {   0x00450001, "it/ito" },
326   {   0x00450002, "it/ito" },
327   {   0x00460001, "threegmlc/mod_link_supp (Bearer Modification Support Event)" },
328   {   0x800a0000, "Nokia Bearer Characteristics Package" },
329         {0,     NULL}
330 };
331
332 /*
333  * This table consist of PackageName + SignalName and its's corresponding string
334  */
335 static const value_string signal_name_vals[] = {
336   {   0x00000000, "Media stream properties H.248.1 Annex C" },
337   {   0x00010000, "g H.248.1 Annex E" },
338   {   0x00030001, "tonegen/pt(Play tone)" },
339   {   0x00050010, "dg, DTMF character 0" },
340   {   0x00050011, "dg, DTMF character 1" },
341   {   0x00050012, "dg, DTMF character 2" },
342   {   0x00050013, "dg, DTMF character 3" },
343   {   0x00050014, "dg, DTMF character 4" },
344   {   0x00050015, "dg, DTMF character 5" },
345   {   0x00050016, "dg, DTMF character 6" },
346   {   0x00050017, "dg, DTMF character 7" },
347   {   0x00050018, "dg, DTMF character 8" },
348   {   0x00050019, "dg, DTMF character 9" },
349   {   0x0005001a, "dg, DTMF character A" },
350   {   0x0005001b, "dg, DTMF character B" },
351   {   0x0005001c, "dg, DTMF character C" },
352   {   0x0005001d, "dg, DTMF character D" },
353   {   0x00050020, "dg, DTMF character *" },
354   {   0x00050021, "dg, DTMF character #" },
355   {   0x00070030, "cg, Dial Tone" },
356   {   0x00070031, "cg/rt (Ringing Tone)" },
357   {   0x00070032, "cg, Busy Tone" },
358   {   0x00070033, "cg, Congestion Tone" },
359   {   0x00070034, "cg, Special Information Tone" },
360   {   0x00070035, "cg, (Recording) Warning Tone" },
361   {   0x00070036, "cg, Payphone Recognition Tone" },
362   {   0x00070037, "cg, Call Waiting Tone" },
363   {   0x00070038, "cg, Caller Waiting Tone" },
364   {   0x00090002, "al, ring" },
365   {   0x0009ffff, "al, *" },
366   {   0x000a0003, "ct, Continuity test" },
367   {   0x000a0004, "ct, Continuity respond" },
368   {   0x00210000, "GB Generic Bearer Connection Q.1950 Annex A" },
369   {   0x00210001, "GB/EstBNC(Establish BNC)" },
370   {   0x00210002, "GB/ModBNC (Modify BNC)" },
371   {   0x00210003, "GB/RelBNC(Release BNC)" },
372
373   {   0x002a0001, "H.245/cs (channel state)" },
374   {   0x002a0002, "H.245/termtype (Terminal Type)" },
375
376   {   0x002c0001, "H.324/cmod (Communication mode)" },
377   {   0x002c0002, "H.324/muxlv (Highest Multiplexing level)" },
378   {   0x002c0003, "H.324/demux (Demultiplex)" },
379   {   0x002c0004, "H.324/h223capr (Remote H.223 capability)" },
380   {   0x002c0005, "H.324/muxtbl_in (Incoming Multiplex Table)" },
381   {   0x002c0006, "H.324/muxtbl_out (Outgoing Multiplex Table)" },
382
383   {   0x800a0000, "Nokia Bearer Characteristics Package" },
384   {0,     NULL}
385 };
386
387
388 #if 0
389 static const value_string context_id_type[] = {
390         {NULL_CONTEXT,"0 (Null Context)"},
391         {CHOOSE_CONTEXT,"$ (Choose Context)"},
392         {ALL_CONTEXTS,"* (All Contexts)"},
393         {0,NULL}
394 };
395 #endif
396
397 static const value_string h248_reasons[] = {
398     { 400, "Syntax error in message"},
399     { 401, "Protocol Error"},
400     { 402, "Unauthorized"},
401     { 403, "Syntax error in transaction request"},
402     { 406, "Version Not Supported"},
403     { 410, "Incorrect identifier"},
404     { 411, "The transaction refers to an unknown ContextId"},
405     { 412, "No ContextIDs available"},
406     { 421, "Unknown action or illegal combination of actions"},
407     { 422, "Syntax Error in Action"},
408     { 430, "Unknown TerminationID"},
409     { 431, "No TerminationID matched a wildcard"},
410     { 432, "Out of TerminationIDs or No TerminationID available"},
411     { 433, "TerminationID is already in a Context"},
412     { 434, "Max number of Terminations in a Context exceeded"},
413     { 435, "Termination ID is not in specified Context"},
414     { 440, "Unsupported or unknown Package"},
415     { 441, "Missing Remote or Local Descriptor"},
416     { 442, "Syntax Error in Command"},
417     { 443, "Unsupported or Unknown Command"},
418     { 444, "Unsupported or Unknown Descriptor"},
419     { 445, "Unsupported or Unknown Property"},
420     { 446, "Unsupported or Unknown Parameter"},
421     { 447, "Descriptor not legal in this command"},
422     { 448, "Descriptor appears twice in a command"},
423     { 449, "Unsupported or Unknown Parameter or Property Value"},
424     { 450, "No such property in this package"},
425     { 451, "No such event in this package"},
426     { 452, "No such signal in this package"},
427     { 453, "No such statistic in this package"},
428     { 454, "No such parameter value in this package"},
429     { 455, "Property illegal in this Descriptor"},
430     { 456, "Property appears twice in this Descriptor"},
431     { 457, "Missing parameter in signal or event"},
432     { 458, "Unexpected Event/Request ID"},
433     { 459, "Unsupported or Unknown Profile"},
434     { 460, "Unable to set statistic on stream"},
435     { 471, "Implied Add for Multiplex failure"},
436     { 500, "Internal software Failure in MG"},
437     { 501, "Not Implemented"},
438     { 502, "Not ready"},
439     { 503, "Service Unavailable"},
440     { 504, "Command Received from unauthorized entity"},
441     { 505, "Transaction Request Received before a Service Change Reply has been received"},
442     { 506, "Number of Transaction Pendings Exceeded"},
443     { 510, "Insufficient resources"},
444     { 512, "Media Gateway unequipped to detect requested Event"},
445     { 513, "Media Gateway unequipped to generate requested Signals"},
446     { 514, "Media Gateway cannot send the specified announcement"},
447     { 515, "Unsupported Media Type"},
448     { 517, "Unsupported or invalid mode"},
449     { 518, "Event buffer full"},
450     { 519, "Out of space to store digit map"},
451     { 520, "Digit Map undefined in the MG"},
452     { 521, "Termination is ServiceChangeing"},
453     { 522, "Functionality Requested in Topology Triple Not Supported"},
454     { 526, "Insufficient bandwidth"},
455     { 529, "Internal hardware failure in MG"},
456     { 530, "Temporary Network failure"},
457     { 531, "Permanent Network failure"},
458     { 532, "Audited Property, Statistic, Event or Signal does not exist"},
459     { 533, "Response exceeds maximum transport PDU size"},
460     { 534, "Illegal write or read only property"},
461     { 540, "Unexpected initial hook state"},
462     { 542, "Command is not allowed on this termination"},
463     { 581, "Does Not Exist"},
464     { 600, "Illegal syntax within an announcement specification"},
465     { 601, "Variable type not supported"},
466     { 602, "Variable value out of range"},
467     { 603, "Category not supported"},
468     { 604, "Selector type not supported"},
469     { 605, "Selector value not supported"},
470     { 606, "Unknown segment ID"},
471     { 607, "Mismatch between play specification and provisioned data"},
472     { 608, "Provisioning error"},
473     { 609, "Invalid offset"},
474     { 610, "No free segment IDs"},
475     { 611, "Temporary segment not found"},
476     { 612, "Segment in use"},
477     { 613, "ISP port limit overrun"},
478     { 614, "No modems available"},
479     { 615, "Calling number unacceptable"},
480     { 616, "Called number unacceptable"},
481     { 900, "Service Restored"},
482     { 901, "Cold Boot"},
483     { 902, "Warm Boot"},
484     { 903, "MGC Directed Change"},
485     { 904, "Termination malfunctioning"},
486     { 905, "Termination taken out of service"},
487     { 906, "Loss of lower layer connectivity (e.g. downstream sync)"},
488     { 907, "Transmission Failure"},
489     { 908, "MG Impending Failure"},
490     { 909, "MGC Impending Failure"},
491     { 910, "Media Capability Failure"},
492     { 911, "Modem Capability Failure"},
493     { 912, "Mux Capability Failure"},
494     { 913, "Signal Capability Failure"},
495     { 914, "Event Capability Failure"},
496     { 915, "State Loss"},
497     { 916, "Packages Change"},
498     { 917, "Capabilities Change"},
499     { 918, "Cancel Graceful"},
500     { 919, "Warm Failover"},
501     { 920, "Cold Failover"},
502         {0,NULL}
503 };
504
505 static const value_string wildcard_modes[] = {
506     { 0, "Choose" },
507     { 1, "All" },
508     { 0, NULL }
509 };
510
511 static const value_string wildcard_levels[] = {
512     { 0, "This One Level" },
513     { 1, "This Level and those below" },
514     { 0, NULL }
515 };
516
517 static h248_curr_info_t curr_info = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
518 static guint32 error_code;
519 static gcp_wildcard_t wild_term;
520
521
522 extern void h248_param_ber_integer(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, int hfid, h248_curr_info_t* u _U_, void* implicit) {
523         asn1_ctx_t asn1_ctx;
524         asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
525         dissect_ber_integer(implicit ? *((gboolean*)implicit) : FALSE, &asn1_ctx, tree, tvb, 0, hfid, NULL);
526 }
527
528 extern void h248_param_ber_octetstring(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, int hfid, h248_curr_info_t* u _U_, void* implicit) {
529         asn1_ctx_t asn1_ctx;
530         asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
531         dissect_ber_octet_string(implicit ? *((gboolean*)implicit) : FALSE, &asn1_ctx, tree, tvb, 0, hfid, NULL);
532 }
533
534 extern void h248_param_ber_boolean(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, int hfid, h248_curr_info_t* u _U_, void* implicit) {
535         asn1_ctx_t asn1_ctx;
536         asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
537         dissect_ber_boolean(implicit ? *((gboolean*)implicit) : FALSE, &asn1_ctx, tree, tvb, 0, hfid);
538 }
539
540 extern void h248_param_item(proto_tree* tree,
541                                                          tvbuff_t* tvb,
542                                                          packet_info* pinfo _U_,
543                                                          int hfid,
544                                                          h248_curr_info_t* h248_info _U_,
545                                                          void* lenp ) {
546         int len = lenp ? *((int*)lenp) : -1;
547         proto_tree_add_item(tree,hfid,tvb,0,len,FALSE);
548 }
549
550 extern void h248_param_external_dissector(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo , int hfid _U_, h248_curr_info_t* u _U_, void* dissector_hdl) {
551         call_dissector((dissector_handle_t) dissector_hdl,tvb,pinfo,tree);
552 }
553
554
555 static const h248_package_t no_package = { 0xffff, &hf_h248_no_pkg, &ett_h248_no_pkg, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
556 static const h248_pkg_sig_t no_signal = { 0, &hf_h248_no_sig, &ett_h248_no_sig, NULL, NULL };
557 static const h248_pkg_param_t no_param = { 0, &hf_h248_param, h248_param_item,  NULL };
558 static const h248_pkg_evt_t no_event = { 0, &hf_h248_no_evt, &ett_h248_no_evt, NULL, NULL };
559
560 static GPtrArray* packages = NULL;
561
562 extern void h248_param_PkgdName(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo , int hfid _U_, h248_curr_info_t* u1 _U_, void* u2 _U_) {
563   tvbuff_t *new_tvb = NULL;
564   proto_tree *package_tree=NULL;
565   guint16 name_major, name_minor;
566   int old_offset;
567   const h248_package_t* pkg = NULL;
568   guint i;
569   int offset = 0;
570   asn1_ctx_t asn1_ctx;
571   asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
572  
573         old_offset=offset;
574         offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, offset, hfid , &new_tvb);
575         
576   if (new_tvb) {
577     /* this field is always 4 bytes  so just read it into two integers */
578     name_major=tvb_get_ntohs(new_tvb, 0);
579     name_minor=tvb_get_ntohs(new_tvb, 2);
580
581     /* do the prettification */
582     proto_item_append_text(ber_last_created_item, "  %s (%04x)", val_to_str(name_major, package_name_vals, "Unknown Package"), name_major);
583
584     if(tree){
585         proto_item* pi;
586         const gchar* strval;
587             
588         package_tree = proto_item_add_subtree(ber_last_created_item, ett_packagename);
589         proto_tree_add_uint(package_tree, hf_h248_pkg_name, tvb, offset-4, 2, name_major);
590
591         for(i=0; i < packages->len; i++) {
592                 pkg = g_ptr_array_index(packages,i);
593
594                 if (name_major == pkg->id) {
595                         break;
596                 } else {
597                         pkg = NULL;
598                 }
599         }
600
601         if (! pkg ) pkg = &no_package;
602
603
604         pi = proto_tree_add_uint(package_tree, hf_248_pkg_param, tvb, offset-2, 2, name_minor);
605         
606         if (pkg->signal_names && ( strval = match_strval(name_minor, pkg->signal_names) )) {
607                 strval = ep_strdup_printf("%s (%d)",strval,name_minor);
608         } else {
609                 strval = ep_strdup_printf("Unknown (%d)",name_minor);
610         }
611
612         proto_item_set_text(pi,"Signal ID: %s", strval);
613         }
614         
615   }
616 }
617
618
619 static int dissect_h248_trx_id(gboolean implicit_tag, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, guint32* trx_id_p) {
620         guint64 trx_id = 0;
621         gint8 class;
622         gboolean pc;
623         gint32 tag;
624         guint32 len;
625         guint32 i;
626
627         if(!implicit_tag){
628                 offset=dissect_ber_identifier(pinfo, tree, tvb, offset, &class, &pc, &tag);
629                 offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL);
630         } else {
631                 len=tvb_length_remaining(tvb, offset);
632         }
633
634
635         if (len > 8 || len < 1) {
636                 THROW(BoundsError);
637         } else {
638                 for(i=1;i<=len;i++){
639                         trx_id=(trx_id<<8)|tvb_get_guint8(tvb, offset);
640                         offset++;
641                 }
642                 if (trx_id > 0xffffffff) {
643                         proto_item* pi = proto_tree_add_text(tree, tvb, offset-len, len,"transactionId %" G_GINT64_MODIFIER "u", trx_id);
644             proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
645
646             *trx_id_p = 0;
647
648                 } else {
649                         proto_tree_add_uint(tree, hf_h248_transactionId, tvb, offset-len, len, (guint32)trx_id);
650             *trx_id_p = (guint32)trx_id;
651                 }
652         }
653
654     return offset;
655 }
656
657 static int dissect_h248_ctx_id(gboolean implicit_tag, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, guint32* ctx_id_p) {
658         gint8 class;
659         gboolean pc;
660         gint32 tag;
661         guint32 len;
662         guint64 ctx_id = 0;
663         guint32 i;
664
665         if(!implicit_tag){
666                 offset=dissect_ber_identifier(pinfo, tree, tvb, offset, &class, &pc, &tag);
667                 offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL);
668         } else {
669                 len=tvb_length_remaining(tvb, offset);
670         }
671
672
673         if (len > 8 || len < 1) {
674                 THROW(BoundsError);
675         } else {
676                 for(i=1;i<=len;i++){
677                         ctx_id=(ctx_id<<8)|tvb_get_guint8(tvb, offset);
678                         offset++;
679                 }
680
681                 if (ctx_id > 0xffffffff) {
682                         proto_item* pi = proto_tree_add_text(tree, tvb, offset-len, len,
683                                                  "contextId: %" G_GINT64_MODIFIER "u", ctx_id);
684             proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
685
686             *ctx_id_p = 0xfffffffd;
687
688                 } else {
689                         proto_item* pi = proto_tree_add_uint(tree, hf_h248_context_id, tvb, offset-len, len, (guint32)ctx_id);
690
691             if ( ctx_id ==  NULL_CONTEXT ) {
692                 proto_item_set_text(pi,"contextId: Null Context(0)");
693             } else if ( ctx_id ==  CHOOSE_CONTEXT ) {
694                 proto_item_set_text(pi,"contextId: $ (Choose Context = 0xfffffffe)");
695             } else if ( ctx_id ==  ALL_CONTEXTS ) {
696                 proto_item_set_text(pi,"contextId: * (All Contexts = 0xffffffff)");
697             }
698
699             *ctx_id_p = (guint32) ctx_id;
700                 }
701         }
702
703         return offset;
704 }
705
706 void h248_register_package(const h248_package_t* pkg) {
707         if (! packages) packages = g_ptr_array_new();
708
709         g_assert(pkg != NULL);
710
711         g_ptr_array_add(packages,(void*)pkg);
712 }
713
714 static guint32 packageandid;
715
716 static int dissect_h248_PkgdName(gboolean implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) {
717   tvbuff_t *new_tvb = NULL;
718   proto_tree *package_tree=NULL;
719   guint16 name_major, name_minor;
720   int old_offset;
721   const h248_package_t* pkg = NULL;
722   guint i;
723
724   old_offset=offset;
725   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &new_tvb);
726
727   if (new_tvb) {
728     /* this field is always 4 bytes  so just read it into two integers */
729     name_major=tvb_get_ntohs(new_tvb, 0);
730     name_minor=tvb_get_ntohs(new_tvb, 2);
731     packageandid=(name_major<<16)|name_minor;
732
733     /* do the prettification */
734     proto_item_append_text(ber_last_created_item, "  %s (%04x)", val_to_str(name_major, package_name_vals, "Unknown Package"), name_major);
735
736     if(tree){
737                 package_tree = proto_item_add_subtree(ber_last_created_item, ett_packagename);
738                 proto_tree_add_uint(package_tree, hf_h248_pkg_name, tvb, offset-4, 2, name_major);
739     }
740
741         for(i=0; i < packages->len; i++) {
742                 pkg = g_ptr_array_index(packages,i);
743
744                 if (name_major == pkg->id) {
745                         break;
746                 } else {
747                         pkg = NULL;
748                 }
749         }
750
751         if (! pkg ) pkg = &no_package;
752                 
753         {
754                 proto_item* pi = proto_tree_add_uint(package_tree, hf_248_pkg_param, tvb, offset-2, 2, name_minor);
755                 const gchar* strval;
756                 
757                 if (pkg->param_names && ( strval = match_strval(name_minor, pkg->param_names) )) {
758                         strval = ep_strdup_printf("%s (%d)",strval,name_minor);
759                 } else {
760                         strval = ep_strdup_printf("Unknown (%d)",name_minor);
761                 }
762         
763                 proto_item_set_text(pi,"Parameter: %s", strval);
764         }
765   } else {
766           pkg = &no_package;
767   }
768
769   curr_info.pkg = pkg;
770
771   return offset;
772 }
773
774 static int dissect_h248_EventName(gboolean implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) {
775   tvbuff_t *new_tvb;
776   proto_tree *package_tree=NULL;
777   guint16 name_major, name_minor;
778   int old_offset;
779   const h248_package_t* pkg = NULL;
780   const h248_pkg_evt_t* evt = NULL;
781   guint i;
782
783   old_offset=offset;
784   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &new_tvb);
785
786   if (new_tvb) {
787     /* this field is always 4 bytes  so just read it into two integers */
788     name_major=tvb_get_ntohs(new_tvb, 0);
789     name_minor=tvb_get_ntohs(new_tvb, 2);
790     packageandid=(name_major<<16)|name_minor;
791
792     /* do the prettification */
793     proto_item_append_text(ber_last_created_item, "  %s (%04x)", val_to_str(name_major, package_name_vals, "Unknown Package"), name_major);
794     if(tree){
795       package_tree = proto_item_add_subtree(ber_last_created_item, ett_packagename);
796     }
797     proto_tree_add_uint(package_tree, hf_h248_pkg_name, tvb, offset-4, 2, name_major);
798
799
800         for(i=0; i < packages->len; i++) {
801                 pkg = g_ptr_array_index(packages,i);
802
803                 if (name_major == pkg->id) {
804                         break;
805                 } else {
806                         pkg = NULL;
807                 }
808         }
809
810         if (! pkg ) pkg = &no_package;
811
812         curr_info.pkg = pkg;
813
814         if (pkg->events) {
815                 for (evt = pkg->events; evt->hfid; evt++) {
816                         if (name_minor == evt->id) {
817                                 break;
818                         }
819                 }
820
821                 if (! evt->hfid) evt = &no_event;
822         } else {
823                 evt = &no_event;
824         }
825
826         curr_info.evt = evt;
827
828         {
829                 proto_item* pi = proto_tree_add_uint(package_tree, hf_h248_event_code, tvb, offset-2, 2, name_minor);
830                 const gchar* strval;
831         
832                 if (pkg->event_names && ( strval = match_strval(name_minor, pkg->event_names) )) {
833                         strval = ep_strdup_printf("%s (%d)",strval,name_minor);
834                 } else {
835                         strval = ep_strdup_printf("Unknown (%d)",name_minor);
836                 }
837         
838                 proto_item_set_text(pi,"Event ID: %s", strval);
839         }
840
841   } else {
842           curr_info.pkg = &no_package;
843           curr_info.evt = &no_event;
844   }
845
846   return offset;
847 }
848
849
850
851 static int dissect_h248_SignalName(gboolean implicit_tag , tvbuff_t *tvb, int offset,  asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) {
852   tvbuff_t *new_tvb;
853   proto_tree *package_tree=NULL;
854   guint16 name_major, name_minor;
855   int old_offset;
856   const h248_package_t* pkg = NULL;
857   const h248_pkg_sig_t* sig;
858   guint i;
859
860   old_offset=offset;
861   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &new_tvb);
862
863   if (new_tvb) {
864     /* this field is always 4 bytes so just read it into two integers */
865     name_major=tvb_get_ntohs(new_tvb, 0);
866     name_minor=tvb_get_ntohs(new_tvb, 2);
867     packageandid=(name_major<<16)|name_minor;
868
869     /* do the prettification */
870     proto_item_append_text(ber_last_created_item, "  %s (%04x)", val_to_str(name_major, package_name_vals, "Unknown Package"), name_major);
871     if(tree){
872       package_tree = proto_item_add_subtree(ber_last_created_item, ett_packagename);
873     }
874     proto_tree_add_uint(package_tree, hf_h248_pkg_name, tvb, offset-4, 2, name_major);
875
876     for(i=0; i < packages->len; i++) {
877                 pkg = g_ptr_array_index(packages,i);
878
879                 if (name_major == pkg->id) {
880                         break;
881                 } else {
882                         pkg = NULL;
883                 }
884         }
885
886         if (! pkg ) pkg = &no_package;
887
888         if (pkg->signals) {
889                 for (sig = pkg->signals; sig->hfid; sig++) {
890                         if (name_minor == sig->id) {
891                                 break;
892                         }
893                 }
894
895                 if (! sig->hfid) sig = &no_signal;
896
897                 curr_info.pkg = pkg;
898                 curr_info.sig = sig;
899         } else {
900                 curr_info.pkg = &no_package;
901                 curr_info.sig = &no_signal;
902         }
903
904         {
905                 proto_item* pi = proto_tree_add_uint(package_tree, hf_h248_signal_code, tvb, offset-2, 2, name_minor);
906                 const gchar* strval;
907         
908                 if (pkg->signal_names && ( strval = match_strval(name_minor, pkg->signal_names) )) {
909                         strval = ep_strdup_printf("%s (%d)",strval,name_minor);
910                 } else {
911                         strval = ep_strdup_printf("Unknown (%d)",name_minor);
912                 }
913         
914                 proto_item_set_text(pi,"Signal ID: %s", strval);
915         }
916
917   } else {
918           curr_info.pkg = &no_package;
919           curr_info.sig = &no_signal;
920   }
921
922   return offset;
923 }
924
925 static int dissect_h248_PropertyID(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,  asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_) {
926
927         gint8 class;
928         gboolean pc, ind;
929         gint32 tag;
930         guint32 len;
931         guint16 name_major;
932         guint16 name_minor;
933         int old_offset, end_offset;
934         tvbuff_t *next_tvb;
935         const h248_package_t* pkg;
936         const h248_pkg_param_t* prop;
937
938         old_offset=offset;
939         offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &class, &pc, &tag);
940         offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind);
941         end_offset=offset+len;
942
943         if( (class!=BER_CLASS_UNI)
944           ||(tag!=BER_UNI_TAG_OCTETSTRING) ){
945                 proto_tree_add_text(tree, tvb, offset-2, 2, "H.248 BER Error: OctetString expected but Class:%d PC:%d Tag:%d was unexpected", class, pc, tag);
946                 return end_offset;
947         }
948
949
950         next_tvb = tvb_new_subset(tvb, offset , len , len );
951         name_major = packageandid >> 16;
952         name_minor = packageandid & 0xffff;
953
954         pkg = (curr_info.pkg) ? curr_info.pkg : &no_package;
955
956         if (pkg->properties) {
957                 for (prop = pkg->properties; prop && prop->hfid; prop++) {
958                         if (name_minor == prop->id) {
959                                 break;
960                         }
961                 }
962         } else {
963                 prop = &no_param;
964         }
965
966         if (prop && prop->hfid ) {
967                 if (!prop->dissector) prop = &no_param;
968                 prop->dissector(tree, next_tvb, actx->pinfo, *(prop->hfid), &curr_info, prop->data);
969         }
970
971         return end_offset;
972 }
973
974
975 static int dissect_h248_SigParameterName(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,  asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_) {
976         tvbuff_t *next_tvb;
977         guint32 param_id = 0xffffffff;
978         const h248_pkg_param_t* sigpar;
979         const gchar* strval;
980         proto_item* pi;
981         
982         offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset,  hf_index, &next_tvb);
983         pi = get_ber_last_created_item();
984         
985         switch(tvb_length(next_tvb)) {
986                 case 4: param_id = tvb_get_ntohl(next_tvb,0); break;
987                 case 3: param_id = tvb_get_ntoh24(next_tvb,0); break;
988                 case 2: param_id = tvb_get_ntohs(next_tvb,0); break;
989                 case 1: param_id = tvb_get_guint8(next_tvb,0); break;
990                 default: break;
991         }
992
993         curr_info.par = &no_param;
994
995         if (curr_info.sig && curr_info.sig->parameters) {
996                 for(sigpar = curr_info.sig->parameters; sigpar->hfid; sigpar++) {
997                         if (sigpar->id == param_id) {
998                                 curr_info.par = sigpar;
999                                 break;
1000                         }
1001                 }
1002         }
1003
1004         if (curr_info.sig && curr_info.sig->param_names && ( strval = match_strval(param_id, curr_info.sig->param_names) )) {
1005                 strval = ep_strdup_printf("%s (%d)",strval,param_id);
1006         } else {
1007                 strval = ep_strdup_printf("Unknown (%d)",param_id);
1008         }
1009         
1010         proto_item_set_text(pi,"Parameter: %s", strval);
1011
1012         return offset;
1013 }
1014
1015 static int dissect_h248_SigParamValue(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,  asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_) {
1016         tvbuff_t *next_tvb;
1017         int old_offset, end_offset;
1018         gint8 class;
1019         gboolean pc, ind;
1020         gint32 tag;
1021         guint32 len;
1022
1023         old_offset=offset;
1024         offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &class, &pc, &tag);
1025         offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind);
1026         end_offset=offset+len;
1027
1028         if( (class!=BER_CLASS_UNI)
1029                 ||(tag!=BER_UNI_TAG_OCTETSTRING) ){
1030                 proto_tree_add_text(tree, tvb, offset-2, 2, "H.248 BER Error: OctetString expected but Class:%d PC:%d Tag:%d was unexpected", class, pc, tag);
1031                 return end_offset;
1032         }
1033
1034
1035         next_tvb = tvb_new_subset(tvb,offset,len,len);
1036
1037         if ( curr_info.par && curr_info.par->dissector) {
1038                 curr_info.par->dissector(tree, next_tvb, actx->pinfo, *(curr_info.par->hfid), &curr_info, curr_info.par->data);
1039         }
1040
1041         return end_offset;
1042 }
1043
1044 static int dissect_h248_EventParameterName(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,  asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_) {
1045         tvbuff_t *next_tvb;
1046         guint32 param_id = 0xffffffff;
1047         const h248_pkg_param_t* evtpar;
1048         const gchar* strval;
1049         proto_item* pi;
1050
1051         offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &next_tvb);
1052         pi = get_ber_last_created_item();
1053
1054         if (next_tvb) {
1055                 switch(tvb_length(next_tvb)) {
1056                         case 4: param_id = tvb_get_ntohl(next_tvb,0); break;
1057                         case 3: param_id = tvb_get_ntoh24(next_tvb,0); break;
1058                         case 2: param_id = tvb_get_ntohs(next_tvb,0); break;
1059                         case 1: param_id = tvb_get_guint8(next_tvb,0); break;
1060                         default: break;
1061                 }
1062         }
1063
1064
1065         curr_info.par = &no_param;
1066
1067         if (curr_info.evt && curr_info.evt->parameters) {
1068                 for(evtpar = curr_info.evt->parameters; evtpar->hfid; evtpar++) {
1069                         if (evtpar->id == param_id) {
1070                                 curr_info.par = evtpar;
1071                                 break;
1072                         }
1073                 }
1074         } else {
1075                 curr_info.par = &no_param;
1076         }
1077         
1078         if (curr_info.evt && curr_info.evt->param_names && ( strval = match_strval(param_id, curr_info.evt->param_names) )) {
1079                 strval = ep_strdup_printf("%s (%d)",strval,param_id);
1080         } else {
1081                 strval = ep_strdup_printf("Unknown (%d)",param_id);
1082         }
1083         
1084         proto_item_set_text(pi,"Parameter: %s", strval);
1085
1086         
1087         return offset;
1088 }
1089
1090 static int dissect_h248_EventParamValue(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,  asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_) {
1091         tvbuff_t *next_tvb;
1092         int old_offset, end_offset;
1093         gint8 class;
1094         gboolean pc, ind;
1095         gint32 tag;
1096         guint32 len;
1097
1098         old_offset=offset;
1099         offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &class, &pc, &tag);
1100         offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind);
1101         end_offset=offset+len;
1102
1103         if( (class!=BER_CLASS_UNI)
1104                 ||(tag!=BER_UNI_TAG_OCTETSTRING) ){
1105                 proto_tree_add_text(tree, tvb, offset-2, 2, "H.248 BER Error: OctetString expected but Class:%d PC:%d Tag:%d was unexpected", class, pc, tag);
1106                 return end_offset;
1107         }
1108
1109
1110         next_tvb = tvb_new_subset(tvb,offset,len,len);
1111
1112         if ( curr_info.par && curr_info.par->dissector) {
1113                 curr_info.par->dissector(tree, next_tvb, actx->pinfo, *(curr_info.par->hfid), &curr_info, curr_info.par->data);
1114         }
1115
1116         return end_offset;
1117 }
1118
1119 static int dissect_h248_MtpAddress(gboolean implicit_tag, tvbuff_t *tvb, int offset,  asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) {
1120   tvbuff_t *new_tvb;
1121   proto_tree *mtp_tree=NULL;
1122   guint32 val;
1123   int i, len, old_offset;
1124
1125   old_offset=offset;
1126   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &new_tvb);
1127
1128   if (new_tvb) {
1129     /* this field is either 2 or 4 bytes  so just read it into an integer */
1130     val=0;
1131     len=tvb_length(new_tvb);
1132     for(i=0;i<len;i++){
1133       val= (val<<8)|tvb_get_guint8(new_tvb, i);
1134     }
1135
1136     /* do the prettification */
1137     proto_item_append_text(ber_last_created_item, "  NI = %d, PC = %d ( %d-%d )", val&0x03,val>>2,val&0x03,val>>2);
1138     if(tree){
1139       mtp_tree = proto_item_add_subtree(ber_last_created_item, ett_mtpaddress);
1140     }
1141     proto_tree_add_uint(mtp_tree, hf_h248_mtpaddress_ni, tvb, old_offset, offset-old_offset, val&0x03);
1142     proto_tree_add_uint(mtp_tree, hf_h248_mtpaddress_pc, tvb, old_offset, offset-old_offset, val>>2);
1143   }
1144
1145   return offset;
1146 }
1147
1148 #define H248_TAP() do { if (keep_persistent_data && curr_info.cmd) tap_queue_packet(h248_tap, actx->pinfo, curr_info.cmd); } while(0)
1149
1150 #include "packet-h248-fn.c"
1151
1152 static void dissect_h248_tpkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
1153         dissect_tpkt_encap(tvb, pinfo, tree, h248_desegment, h248_handle);
1154 }
1155
1156 static void
1157 dissect_h248(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1158 {
1159     proto_item *h248_item;
1160         asn1_ctx_t asn1_ctx;
1161     h248_tree = NULL;
1162     h248_tvb = NULL;
1163
1164         asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
1165
1166     curr_info.msg = NULL;
1167     curr_info.trx = NULL;
1168     curr_info.ctx = NULL;
1169     curr_info.cmd = NULL;
1170     curr_info.term = NULL;
1171     curr_info.pkg = NULL;
1172     curr_info.evt = NULL;
1173     curr_info.sig = NULL;
1174     curr_info.stat = NULL;
1175     curr_info.par = NULL;
1176
1177     /* Check if it is actually a text-based H.248 encoding, which we
1178        dissect with the "megaco" dissector in Wireshark.  (Both
1179        encodings are MEGACO (RFC 3015) and both are H.248.)
1180      */
1181     if(tvb_length(tvb)>=6){
1182         if(!tvb_strneql(tvb, 0, "MEGACO", 6)){
1183             static dissector_handle_t megaco_handle=NULL;
1184             if(!megaco_handle){
1185                 megaco_handle = find_dissector("megaco");
1186             }
1187             if(megaco_handle){
1188                 call_dissector(megaco_handle, tvb, pinfo, tree);
1189                 return;
1190             }
1191         }
1192     }
1193
1194     /* Make entry in the Protocol column on summary display */
1195     if (check_col(pinfo->cinfo, COL_PROTOCOL))
1196         col_set_str(pinfo->cinfo, COL_PROTOCOL, "H.248");
1197
1198     if (tree) {
1199         h248_item = proto_tree_add_item(tree, proto_h248, tvb, 0, -1, FALSE);
1200         h248_tree = proto_item_add_subtree(h248_item, ett_h248);
1201     }
1202
1203     dissect_h248_MegacoMessage(FALSE, tvb, 0, &asn1_ctx, h248_tree, -1);
1204
1205 }
1206
1207
1208 static void h248_init(void)  {
1209
1210     if (!h248_prefs_initialized) {
1211                 h248_prefs_initialized = TRUE;
1212     } else {
1213         if ( udp_port )
1214             dissector_delete("udp.port", udp_port, h248_handle);
1215                 
1216                 if ( tcp_port)
1217             dissector_delete("tcp.port", tcp_port, h248_tpkt_handle);
1218         }
1219
1220     udp_port = temp_udp_port;
1221     tcp_port = temp_tcp_port;
1222         
1223     if ( udp_port ) {
1224                 dissector_add("udp.port", udp_port, h248_handle);
1225         }
1226
1227         if ( tcp_port) {
1228                 dissector_add("tcp.port", tcp_port, h248_tpkt_handle);
1229         }
1230         
1231         if (!h248_term_handle){
1232                 h248_term_handle = find_dissector("h248term");
1233         }
1234
1235 }
1236
1237 /*--- proto_register_h248 ----------------------------------------------*/
1238 void proto_register_h248(void) {
1239
1240   /* List of fields */
1241   static hf_register_info hf[] = {
1242     { &hf_h248_mtpaddress_ni, {
1243       "NI", "h248.mtpaddress.ni", FT_UINT32, BASE_DEC,
1244       NULL, 0, "NI", HFILL }},
1245     { &hf_h248_mtpaddress_pc, {
1246       "PC", "h248.mtpaddress.pc", FT_UINT32, BASE_DEC,
1247       NULL, 0, "PC", HFILL }},
1248     { &hf_h248_pkg_name, {
1249       "Package", "h248.package_name", FT_UINT16, BASE_HEX,
1250       VALS(package_name_vals), 0, "Package", HFILL }},
1251     { &hf_248_pkg_param, {
1252       "Parameter ID", "h248.package_paramid", FT_UINT16, BASE_HEX,
1253       NULL, 0, "Parameter ID", HFILL }},
1254     { &hf_h248_signal_code, {
1255       "Signal ID", "h248.package_signalid", FT_UINT16, BASE_HEX,
1256       NULL, 0, "Parameter ID", HFILL }},
1257     { &hf_h248_event_code, {
1258       "Event ID", "h248.package_eventid", FT_UINT16, BASE_HEX,
1259       NULL, 0, "Parameter ID", HFILL }},
1260     { &hf_h248_event_name, {
1261       "Package and Event name", "h248.event_name", FT_UINT32, BASE_HEX,
1262       VALS(event_name_vals), 0, "Package", HFILL }},
1263   { &hf_h248_signal_name, {
1264       "Package and Signal name", "h248.signal_name", FT_UINT32, BASE_HEX,
1265       VALS(signal_name_vals), 0, "Package", HFILL }},
1266         { &hf_h248_pkg_bcp_BNCChar_PDU,
1267       { "BNCChar", "h248.package_bcp.BNCChar",
1268         FT_UINT32, BASE_DEC, VALS(gcp_term_types), 0,
1269         "BNCChar", HFILL }},
1270
1271   { &hf_h248_error_code,
1272   { "errorCode", "h248.errorCode",
1273       FT_UINT32, BASE_DEC, VALS(h248_reasons), 0,
1274       "ErrorDescriptor/errorCode", HFILL }},
1275   { &hf_h248_context_id,
1276   { "contextId", "h248.contextId",
1277       FT_UINT32, BASE_HEX, NULL, 0,
1278       "Context ID", HFILL }},
1279   { &hf_h248_term_wild_type,
1280   { "Wildcard Mode", "h248.term.wildcard.mode",
1281       FT_UINT8, BASE_DEC, VALS(wildcard_modes), 0x80,
1282       "", HFILL }},
1283   { &hf_h248_term_wild_level,
1284   { "Wildcarding Level", "h248.term.wildcard.level",
1285       FT_UINT8, BASE_DEC, VALS(wildcard_levels), 0x40,
1286       "", HFILL }},
1287   { &hf_h248_term_wild_position,
1288   { "Wildcarding Position", "h248.term.wildcard.pos",
1289       FT_UINT8, BASE_DEC, NULL, 0x3F,
1290       "", HFILL }},
1291
1292   { &hf_h248_no_pkg,
1293   { "Unknown Package", "h248.pkg.unknown",
1294           FT_BYTES, BASE_HEX, NULL, 0,
1295           "", HFILL }},
1296   { &hf_h248_no_sig,
1297   { "Unknown Signal", "h248.pkg.unknown.sig",
1298           FT_BYTES, BASE_HEX, NULL, 0,
1299           "", HFILL }},
1300   { &hf_h248_no_evt,
1301   { "Unknown Event", "h248.pkg.unknown.evt",
1302           FT_BYTES, BASE_HEX, NULL, 0,
1303           "", HFILL }},
1304   { &hf_h248_param,
1305   { "Parameter", "h248.pkg.unknown.param",
1306           FT_BYTES, BASE_HEX, NULL, 0,
1307           "", HFILL }},
1308   { &hf_h248_serviceChangeReasonStr,
1309       { "ServiceChangeReasonStr", "h248.serviceChangeReasonstr",
1310         FT_STRING, BASE_NONE, NULL, 0,
1311         "h248.IA5String", HFILL }},
1312
1313 #include "packet-h248-hfarr.c"
1314
1315         GCP_HF_ARR_ELEMS("h248",h248_arrel)
1316
1317   };
1318
1319   /* List of subtrees */
1320   static gint *ett[] = {
1321     &ett_h248,
1322     &ett_mtpaddress,
1323     &ett_packagename,
1324     &ett_codec,
1325     &ett_wildcard,
1326     &ett_h248_no_pkg,
1327     &ett_h248_no_sig,
1328     &ett_h248_no_evt,
1329         GCP_ETT_ARR_ELEMS(h248_arrel),
1330           
1331 #include "packet-h248-ettarr.c"
1332   };
1333
1334   module_t *h248_module;
1335
1336
1337   /* Register protocol */
1338   proto_h248 = proto_register_protocol(PNAME, PSNAME, PFNAME);
1339   register_dissector("h248", dissect_h248, proto_h248);
1340   register_dissector("h248.tpkt", dissect_h248_tpkt, proto_h248);
1341
1342   /* Register fields and subtrees */
1343   proto_register_field_array(proto_h248, hf, array_length(hf));
1344   proto_register_subtree_array(ett, array_length(ett));
1345
1346   h248_module = prefs_register_protocol(proto_h248, h248_init);
1347   prefs_register_bool_preference(h248_module, "ctx_info",
1348                                  "Track Context",
1349                                  "Mantain relationships between transactions and contexts and display an extra tree showing context data",
1350                                  &keep_persistent_data);
1351   prefs_register_uint_preference(h248_module, "udp_port",
1352                                  "UDP port",
1353                                  "Port to be decoded as h248",
1354                                  10,
1355                                  &temp_udp_port);
1356   prefs_register_uint_preference(h248_module, "tcp_port",
1357                                  "TCP port",
1358                                  "Port to be decoded as h248",
1359                                  10,
1360                                  &temp_tcp_port);
1361   prefs_register_bool_preference(h248_module, "desegment",
1362                                  "Desegment H.248 over TCP",
1363                                  "Desegment H.248 messages that span more TCP segments",
1364                                  &h248_desegment);
1365   
1366   
1367   register_init_routine( &h248_init );
1368
1369   msgs = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "h248_msgs");
1370   trxs = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "h248_trxs");
1371   ctxs_by_trx = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "h248_ctxs_by_trx");
1372   ctxs = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "h248_ctxs");
1373
1374   h248_tap = register_tap("h248");
1375
1376   gcp_init();
1377 }
1378
1379 /*--- proto_reg_handoff_h248 -------------------------------------------*/
1380 void proto_reg_handoff_h248(void) {
1381
1382   h248_handle = find_dissector("h248");
1383   h248_tpkt_handle = find_dissector("h248.tpkt");
1384
1385   dissector_add("mtp3.service_indicator", GATEWAY_CONTROL_PROTOCOL_USER_ID, h248_handle);
1386   dissector_add("udp.port", udp_port, h248_handle);
1387   dissector_add("tcp.port", tcp_port, h248_tpkt_handle);
1388 }
1389
1390
1391