977f0f49efcc16f4e8b63946fbac85c5516c7a40
[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 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include "packet-h248.h"
33 #include <epan/tap.h>
34 #include "packet-tpkt.h"
35 #include <ctype.h>
36
37 #define PNAME  "H.248 MEGACO"
38 #define PSNAME "H248"
39 #define PFNAME "h248"
40
41 #define GATEWAY_CONTROL_PROTOCOL_USER_ID 14
42
43
44 /* Initialize the protocol and registered fields */
45 static int proto_h248                   = -1;
46 static int hf_h248_mtpaddress_ni        = -1;
47 static int hf_h248_mtpaddress_pc        = -1;
48 static int hf_h248_pkg_name             = -1;
49 static int hf_248_pkg_param             = -1;
50 static int hf_h248_event_name           = -1;
51 static int hf_h248_signal_name          = -1;
52 static int hf_h248_signal_code          = -1;
53 static int hf_h248_event_code           = -1;
54 static int hf_h248_pkg_bcp_BNCChar_PDU  = -1;
55
56
57
58 static int hf_h248_context_id = -1;
59 static int hf_h248_error_code = -1;
60 static int hf_h248_term_wild_type = -1;
61 static int hf_h248_term_wild_level = -1;
62 static int hf_h248_term_wild_position = -1;
63
64 static int hf_h248_no_pkg = -1;
65 static int hf_h248_no_sig = -1;
66 static int hf_h248_no_evt = -1;
67 static int hf_h248_param = -1;
68
69 static int hf_h248_serviceChangeReasonStr = -1;
70
71 /* h248v1 support */
72 static int hf_h248_auditValueReplyV1 = -1;
73
74 #include "packet-h248-hf.c"
75
76 /* Initialize the subtree pointers */
77 static gint ett_h248 = -1;
78 static gint ett_mtpaddress = -1;
79 static gint ett_packagename = -1;
80 static gint ett_codec = -1;
81 static gint ett_wildcard = -1;
82
83 static gint ett_h248_no_pkg = -1;
84 static gint ett_h248_no_sig = -1;
85 static gint ett_h248_no_evt = -1;
86
87 static int h248_tap = -1;
88
89 static gcp_hf_ett_t h248_arrel = {{-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1}};
90
91 #include "packet-h248-ett.c"
92
93 static dissector_handle_t h248_term_handle;
94
95 static emem_tree_t* msgs = NULL;
96 static emem_tree_t* trxs = NULL;
97 static emem_tree_t* ctxs_by_trx = NULL;
98 static emem_tree_t* ctxs = NULL;
99
100 static gboolean keep_persistent_data = FALSE;
101 static guint    global_udp_port = 2945;
102 static guint    global_tcp_port = 2945;
103 static gboolean h248_desegment = TRUE;
104
105
106
107 static proto_tree *h248_tree;
108 static tvbuff_t* h248_tvb;
109
110 static dissector_handle_t h248_handle;
111 static dissector_handle_t h248_term_handle;
112 static dissector_handle_t h248_tpkt_handle;
113
114 /* Forward declarations */
115 static int dissect_h248_ServiceChangeReasonStr(gboolean implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index);
116
117 /* h248v1 support */
118 static int dissect_h248_AuditReplyV1(gboolean implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index);
119 static int dissect_h248_ValueV1(gboolean implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index);
120 static int dissect_h248_EventParameterV1(gboolean implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index);
121 static int dissect_h248_PropertyParmV1(gboolean implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index);
122 static int dissect_h248_SigParameterV1(gboolean implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index);
123
124 /* 2010-11-15: New entries added based on: http://www.iana.org/assignments/megaco-h248 last updated 2010-10-01 */
125 static const value_string package_name_vals[] = {
126     {   0x0000, "Media stream properties H.248.1 Annex C" },
127     {   0x0001, "Generic H.248.1 Annex E" },
128     {   0x0002, "root H.248.1 Annex E" },
129     {   0x0003, "tonegen H.248.1 Annex E" },
130     {   0x0004, "tonedet H.248.1 Annex E" },
131     {   0x0005, "dg H.248.1 Annex E" },
132     {   0x0006, "dd H.248.1 Annex E" },
133     {   0x0007, "cg H.248.1 Annex E" },
134     {   0x0008, "cd H.248.1 Annex E" },
135     {   0x0009, "al H.248.1 Annex E" },
136     {   0x000a, "ct H.248.1 Annex E" },
137     {   0x000b, "nt H.248.1 Annex E" },
138     {   0x000c, "rtp H.248.1 Annex E" },
139     {   0x000d, "tdmc H.248.1 Annex E" },
140     {   0x000e, "ftmd H.248.1 Annex E" },
141     {   0x000f, "txc H.248.2" },                                          /* H.248.2 */
142     {   0x0010, "txp H.248.2" },
143     {   0x0011, "ctyp H.248.2" },
144     {   0x0012, "fax H.248.2" },
145     {   0x0013, "ipfax H.248.2" },
146     {   0x0014, "dis H.248.3" },                                          /* H.248.3 */
147     {   0x0015, "key H.248.3" },
148     {   0x0016, "kp H.248.3" },
149     {   0x0017, "labelkey H.248.3" },
150     {   0x0018, "kf H.248.3" },
151     {   0x0019, "ind H.248.3" },
152     {   0x001a, "ks H.248.3" },
153     {   0x001b, "anci H.248.3" },
154     {   0x001c, "dtd H.248.6" },                                              /* H.248.6 */
155     {   0x001d, "an H.248.7" },                                               /* H.248.7 */
156     {   0x001e, "Bearer Characteristics Q.1950 Annex A" },                    /* Q.1950 Annex A */
157     {   0x001f, "Bearer Network Connection Cut Q.1950 Annex A" },
158     {   0x0020, "Reuse Idle Q.1950 Annex A" },
159     {   0x0021, "Generic Bearer Connection Q.1950 Annex A" },
160     {   0x0022, "Bearer Control Tunnelling Q.1950 Annex A" },
161     {   0x0023, "Basic Call Progress Tones Q.1950 Annex A" },
162     {   0x0024, "Expanded Call Progress Tones Q.1950 Annex A" },
163     {   0x0025, "Basic Services Tones Q.1950 Annex A" },
164     {   0x0026, "Expanded Services Tones Q.1950 Annex A" },
165     {   0x0027, "Intrusion Tones Q.1950 Annex A" },
166     {   0x0028, "Business Tones Q.1950 Annex A" },
167     {   0x0029, "Media Gateway Resource Congestion Handling H.248.10" },      /* H.248.10 */
168     {   0x002a, "H245 package H248.12" },                                     /* H.248.12 */
169     {   0x002b, "H323 bearer control package H.248.12" },                     /* H.248.12 */
170     {   0x002c, "H324 package H.248.12" },                                    /* H.248.12 */
171     {   0x002d, "H245 command package H.248.12" },                            /* H.248.12 */
172     {   0x002e, "H245 indication package H.248.12" },                         /* H.248.12 */
173     {   0x002f, "3G User Plane" },                                            /* 3GPP TS 29.232 v4.1.0 */
174     {   0x0030, "3G Circuit Switched Data" },
175     {   0x0031, "3G TFO Control" },
176     {   0x0032, "3G Expanded Call Progress Tones" },
177     {   0x0033, "Advanced Audio Server (AAS Base)" },                         /* H.248.9 */
178     {   0x0034, "AAS Digit Collection" },                                     /* H.248.9 */
179     {   0x0035, "AAS Recording" },                                            /* H.248.9 */
180     {   0x0036, "AAS Segment Management" },                                   /* H.248.9 */
181     {   0x0037, "Quality Alert Ceasing" },                                    /* H.248.13 */
182     {   0x0038, "Conferencing Tones Generation" },                            /* H.248.27 */
183     {   0x0039, "Diagnostic Tones Generation" },                              /* H.248.27 */
184     {   0x003a, "Carrier Tones Generation Package H.248.23" },                /* H.248.27 */
185     {   0x003b, "Enhanced Alerting Package H.248.23" },                       /* H.248.23 */
186     {   0x003c, "Analog Display Signalling Package H.248.23" },               /* H.248.23 */
187     {   0x003d, "Multi-Frequency Tone Generation Package H.248.24" },         /* H.248.24 */
188     {   0x003e, "H.248.23Multi-Frequency Tone Detection Package H.248.24" },  /* H.248.24 */
189     {   0x003f, "Basic CAS Package H.248.25" },                               /* H.248.25 */
190     {   0x0040, "Robbed Bit Signalling Package H.248.25" },                   /* H.248.25 */
191     {   0x0041, "Operator Services and Emergency Services Package H.248.25" },
192     {   0x0042, "Operator Services Extension Package H.248.25" },
193     {   0x0043, "Extended Analog Line Supervision Package H.248.26" },
194     {   0x0044, "Automatic Metering Package H.248.26" },
195     {   0x0045, "Inactivity Timer Package H.248.14" },
196     {   0x0046, "3G Modification of Link Characteristics Bearer Capability" }, /* 3GPP TS 29.232 v4.4.0 */
197     {   0x0047, "Base Announcement Syntax H.248.9" },
198     {   0x0048, "Voice Variable Syntax H.248.9" },
199     {   0x0049, "Announcement Set Syntax H.248.9" },
200     {   0x004a, "Phrase Variable Syntax H.248.9" },
201     {   0x004b, "Basic NAS package" },
202     {   0x004c, "NAS incoming package" },
203     {   0x004d, "NAS outgoing package" },
204     {   0x004e, "NAS control package" },
205     {   0x004f, "NAS root package" },
206     {   0x0050, "Profile Handling Package H.248.18" },
207     {   0x0051, "Media Gateway Overload Control Package H.248.11" },
208     {   0x0052, "Extended DTMF Detection Package H.248.16" },
209     {   0x0053, "Quiet Termination Line Test" },
210     {   0x0054, "Loopback Line Test Response" },                              /* H.248.17 */
211     {   0x0055, "ITU 404Hz Line Test" },                                      /* H.248.17 */
212     {   0x0056, "ITU 816Hz Line Test" },                                      /* H.248.17 */
213     {   0x0057, "ITU 1020Hz Line Test" },                                     /* H.248.17 */
214     {   0x0058, "ITU 2100Hz Disable Tone Line Test" },                        /* H.248.17 */
215     {   0x0059, "ITU 2100Hz Disable Echo Canceller Tone Line Test" },         /* H.248.17 */
216     {   0x005a, "ITU 2804Hz Tone Line Test" },                                /* H.248.17 */
217     {   0x005b, "ITU Noise Test Tone Line Test" },                            /* H.248.17 */
218     {   0x005c, "ITU Digital Pseudo Random Test Line Test" },                 /* H.248.17 */
219     {   0x005d, "ITU ATME No.2 Test Line Response" },                         /* H.248.17 */
220     {   0x005e, "ANSI 1004Hz Test Tone Line Test" },                          /* H.248.17 */
221     {   0x005f, "ANSI Test Responder Line Test" },                            /* H.248.17 */
222     {   0x0060, "ANSI 2225Hz Test Progress Tone Line Test" },                 /* H.248.17 */
223     {   0x0061, "ANSI Digital Test Signal Line Test" },                       /* H.248.17 */
224     {   0x0062, "ANSI Inverting Loopback Line Test Response" },               /* H.248.17 */
225     {   0x0063, "Extended H.324 Packages H.248.12 Annex A" },
226     {   0x0064, "Extended H.245 Command Package H.248.12 Annex A" },
227     {   0x0065, "Extended H.245 Indication Package H.248.12 Annex A" },
228     {   0x0066, "Enhanced DTMF Detection Package H.248.16" },
229     {   0x0067, "Connection Group Identity Package Q.1950 Annex E" },
230     {   0x0068, "CTM Text Transport 3GPP TS 29.232 v5.2.0" },
231     {   0x0069, "SPNE Control Package Q.115.0" },
232     {   0x006a, "Semi-permanent Connection Package H.248.21" },
233     {   0x006b, "Shared Risk Group Package H.248.22" },
234     {   0x006c, "isuptn Annex B of ITU-T Rec. J.171" },
235     {   0x006d, "Basic CAS Addressing Package H.248.25" },
236     {   0x006e, "Floor Control Package H.248.19" },
237     {   0x006f, "Indication of Being Viewed Package H.248.19" },
238     {   0x0070, "Volume Control Package H.248.19" },
239     {   0x0071, "UNASSIGNED" },
240     {   0x0072, "Volume Detection Package H.248.19" },
241     {   0x0073, "Volume Level Mixing Package H.248.19" },
242     {   0x0074, "Mixing Volume Level Control Package H.248.19" },
243     {   0x0075, "Voice Activated Video Switch Package H.248.19" },
244     {   0x0076, "Lecture Video Mode Package H.248.19" },
245     {   0x0077, "Contributing Video Source Package H.248.19" },
246     {   0x0078, "Video Window Package H.248.19" },
247     {   0x0079, "Tiled Window Package H.248.19" },
248     {   0x007a, "Adaptive Jitter Buffer Package H.248.31" },
249     {   0x007b, "International CAS Package H.248.28" },
250     {   0x007c, "CAS Blocking Package H.248.28" },
251     {   0x007d, "International CAS Compelled Package H.248.29" },
252     {   0x007e, "International CAS Compelled with Overlap Package H.248.29" },
253     {   0x007f, "International CAS Compelled with End-to-end Package H.248.29" },
254     {   0x0080, "RTCP XR Package H.248.30" },
255     {   0x0081, "RTCP XR Burst Metrics Package H.248.30" },
256     {   0x0082, "threegcsden 3G Circuit Switched Data" },                     /* 3GPP TS 29.232 v5.6.0 */
257     {   0x0083, "threegiptra 3G Circuit Switched Data" },                     /* 3GPP TS 29.232 v5.6.0 */
258     {   0x0084, "threegflex 3G Circuit Switched Data" },                      /* 3GPP TS 29.232 v5.6.0 */
259     {   0x0085, "H.248 PCMSB" },
260     {   0x008a, "TIPHON Extended H.248/MEGACO Package" },                     /* ETSI specification TS 101 3 */
261     {   0x008b, "Differentiated Services Package" },                          /* Annex A of ETSI TS 102 333 */
262     {   0x008c, "Gate Management Package" },                                  /* Annex B of ETSI TS 102 333 */
263     {   0x008d, "Traffic Management Package" },                               /* Annex C of ETSI TS 102 333 */
264     {   0x008e, "Gate Recovery Information Package" },                        /* Annex D of ETSI TS 102 333 */
265     {   0x008f, "NAT Traversal Package" },                                    /* Annex E of ETSI TS 102 333 */
266     {   0x0090, "MPLS Package" },                                             /* Annex F of ETSI TS 102 333 */
267     {   0x0091, "VLAN Package" },                                             /* Annex G of ETSI TS 102 333 */
268     {   0x0092, "Detailed Congestion Reporting Package" },                    /* H.248.32 */
269     {   0x0093, "Stimulus Analogue Lines Package" },                          /* H.248.34 */
270     {   0x0094, "icascgen" },                                                 /* H.248.29 Annex B */
271     {   0x0095, "Coin Operated Phone Control Package" },                      /* H.248.35 */
272     {   0x0096, "Metering Pulse Detection Package" },                         /* H.248.26 Amendment 1 */
273     {   0x0097, "Trace Package" },                                            /* 3GPP TS 29.232 v6.3.0 */
274     {   0x0098, "Hanging Termination Package" },                              /* H.248.36 */
275     {   0x0099, "IP NAPT Traversal Package" },                                /* H.248.37 */
276     {   0x009a, "Notification Behaviour Package" },                           /* H.248.1v3 */
277     {   0x009b, "Base Context Package" },                                     /* H.248.38 */
278     {   0x009c, "Application Data Inactivity Detection Package" },            /* H.248.40 */
279     {   0x009d, "Domain Connection Package " },                               /* H.248.41 */
280     {   0x009e, "Digital Circuit Multiplication Equipment Package" },         /* H.248.42 */
281     {   0x009f, "Multi-level Precedence and Pre-emption Package" },           /* H.248.44 */
282     {   0x00a0, "MGC Information Package" },                                  /* H.248.45 */
283     {   0x00a1, "Text Overlay Package" },                                     /* H.248.19 Amendment 1 */
284     {   0x00a2, "Border and Background Package" },                            /* H.248.19 Amendment 1 */
285     {   0x00a3, "Segmentation Package" },                                     /* H.248.1v3 */
286     {   0x00a4, "ETSI notification behaviour package" },                      /* ETSI ES 283 039-3 */
287     {   0x00a5, "ETSI notification rate package" },                           /* ETSI ES 283 039-4 */
288     {   0x00a6, "Automatic Speech Recognition Package" },                     /* H.248.9 Amendment 1 */
289     {   0x00a7, "Set extension to basic syntax for TTS enhancement Package" },/* H.248.9 Amendment 1 */
290     {   0x00a8, "Advanced audio server base package for TTS enhancement" },   /* H.248.9 Amendment 1 */
291     {   0x00a9, "Multimedia Play Package" },                                  /* H.248.9 Amendment 1 */
292     {   0x00aa, "Floor Status Detection Package" },                           /* H.248.19 Amendment 2 */
293     {   0x00ab, "Floor Control Policy Package" },                             /* H.248.19 Amendment 2 */
294     {   0x00ac, "Address Reporting Package" },                                /* H.248.37 Amendment 1 */
295     {   0x00ad, "Connection Capability Control Package" },                    /* H.248.46 */
296     {   0x00ae, "Statistic Conditional Reporting Package" },                  /* H.248.47 Amendment 1 */
297     {   0x00af, "RTCP HR QoS Statistics Package" },                           /* H.248.48 */
298     {   0x00b0, "Received RTCP XR Package" },                                 /* H.248.30 (01/2007) */
299     {   0x00b1, "Received RTCP XR Burst Metrics Package" },                   /* H.248.30 (01/2007) */
300     {   0x00b2, "ASCI Group call package" },                                  /* 3GPP TS 29.232 v7.4.0 */
301     {   0x00b3, "Multimedia Recording Package" },                             /* H.248.9 Amendment 1 */
302     {   0x00b4, "H.245 Transport Package" },                                  /* H.248.12 Amendment 2 */
303     {   0x00b5, "RTCP Handling package" },                                    /* H.248.57 */
304     {   0x00b6, "Gate Management - Outgoing Destination Address/Port Filtering Package" },/* H.248.43 */
305     {   0x00b7, "Gate Management - Incoming Protocol Filtering Package" },    /* H.248.43 */
306     {   0x00b8, "Gate Management - Outgoing Protocol Filtering Package" },    /* H.248.43 */
307     {   0x00b9, "Gate Management - Incoming Filtering Behaviour Package" },   /* H.248.43 */
308     {   0x00ba, "Gate Management - Outgoing Filtering Behaviour Package" },   /* H.248.43 */
309     {   0x00bb, "Session Description Protocol RFC Package" },                 /* H.248.49 */
310     {   0x00bc, "Session Description Protocol Capabilities Package" },        /* H.248.49 */
311     {   0x00bd, "NAT Traversal Toolkit - STUN Base Package" },                /* H.248.50 */
312     {   0x00be, "NAT Traversal Toolkit - MG STUN Client Package" },           /* H.248.50 */
313     {   0x00bf, "NAT Traversal Toolkit - MG TURN Client Package" },           /* H.248.50 */
314     {   0x00c0, "NAT Traversal Toolkit - MGC STUN Client Package" },          /* H.248.50 */
315     {   0x00c1, "NAT Traversal Toolkit - STUN Information Package" },         /* H.248.50 */
316     {   0x00c2, "NAT Traversal Toolkit - MG Act-as STUN Server Package" },    /* H.248.50 */
317     {   0x00c3, "NAT Traversal Toolkit - Originate STUN Continuity Check Package" },  /* H.248.50 */
318     {   0x00c4, "NAT Traversal Toolkit - MGC Originated STUN Request Package" },      /* H.248.50 */
319     {   0x00c5, "NAT Traversal Toolkit - RTP NOOP Request Package" },         /* H.248.50 */
320     {   0x00c6, "Termination Connection Model Package" },                     /* H.248.51 */
321     {   0x00c7, "QoS Class Package" },                                        /* H.248.52 */
322     {   0x00c8, "Traffic Policing Statistics Package" },                      /* H.248.53 */
323     {   0x00c9, "Packet Size Package" },                                      /* H.248.53 */
324     {   0x00ca, "Pull Mode Package" },                                        /* H.248.55 */
325     {   0x00cb, "RTP Application Data Package" },                             /* H.248.58 */
326     {   0x00cc, "Event Timestamp Notification Package" },                     /* H.248.59 */
327     {   0x00cd, "Resource Management Rules Package" },                        /* H.248.63 */
328     {   0x00ce, "Resource Management Configuration Package" },                /* H.248.63 */
329     {   0x00cf, "Abstract Resource Management Packages" },                    /* H.248.63 */
330
331     {   0x00d0, "IP layer octets count statistics Package" },                 /* H.248.61 */
332     {   0x00d1, "Content of Communication Identity Package" },                /* H.248.60 */
333     {   0x00d2, "RSVP extension package" },                                   /* H.248.65 */
334     {   0x00d3, "GCP Transport Mode Indication Package" },                    /* H.248.67 */
335     {   0x00d4, "IP Router Package" },                                        /* H.248.64 */
336     {   0x00d5, "Media Resource Identification Package" },                    /* H.248.66 */
337     {   0x00d6, "Range Format Support Package" },                             /* H.248.66 */
338     {   0x00d7, "Media Resource Description Expiry Package" },                /* H.248.66 */
339     {   0x00d8, "Media Block Size Package" },                                 /* H.248.66 */
340     {   0x00d9, "RTSP Media Resource Syntax Package" },                       /* H.248.66 */
341     {   0x00da, "RTSP Play Package" },                                        /* H.248.66 */
342     {   0x00db, "Signal Pause Package" },                                     /* H.248.66 */
343     {   0x00dc, "Data Delivery Speed Adjustme Package" },                     /* H.248.66 */
344     {   0x00dd, "Playback Relative Scale Adjustment Package" },               /* H.248.66 */
345     {   0x00de, "RTP Information Package" },                                  /* H.248.66 */
346     {   0x00df, "RTP Interleaving Package" },                                 /* H.248.66 */
347     {   0x00e0, "IP Realm Availability Package" },                            /* H.248.41 Amendment 1 */
348     {   0x00e1, "General IP Header QoS Octet Package" },                      /* H.248.52  */
349     {   0x00e2, "Re-answer Package" },                                        /* H.248.62  */
350     {   0x00e3, "3G Interface Type package" },                                /* 3GPP TS 29.232 v8.4.0 */
351     {   0x00e4, "Latch Statistics Package" },                                 /* H.248.37 */
352     {   0x00e5, "Floor Control Signalling Package" },                         /* H.248.19 Amendment 2 */
353     {   0x00e6, "Include Participant in Mix Package" },                       /* H.248.19 Amendment 2 */
354     {   0x00e7, "Speaker Reporting Package" },                                /* H.248.19 Amendment 2 */
355     {   0x00e8, "IP Layer Packet Count Statistics Package" },                 /* H.248.61 */
356     {   0x00e9, "Removal of Digits and Tones Package" },                      /* H.248.68 */
357     {   0x00ea, "MSRP Statistics Package" },                                  /* H.248.69 */
358     {   0x00eb, "MSRP Connection Status Package" },                           /* H.248.69 */
359     {   0x00ec, "Play Message Package" },                                     /* H.248.69 */
360     {   0x00ed, "Delete Stored Message Package" },                            /* H.248.69 */
361     {   0x00ee, "Message Session Information Package" },                      /* H.248.69 */
362     {   0x00ef, "Message Filtering Package" },                                /* H.248.69 */
363     {   0x00f0, "Stored Message Information Package" },                       /* H.248.69 */
364     {   0x00f1, "Record Message Package" },                                   /* H.248.69 */
365     {   0x00f2, "Digit Dialling Method Information Package" },                /* H.248.70 */
366     {   0x00f3, "Digit Dialling Method Information for Extended Digitmap Detection Package" }, /* H.248.70 */
367     {   0x00f4, "Digit Dialling Method Information for Enhanced Digitmap Detection Package" }, /* H.248.70 */
368     {   0x00f5, "Received RTCP Package " },                                   /* H.248.71 */
369     {   0x00f6, "RTP Cumulative Loss Package" },                              /* H.248.71 */
370     {   0x00f7, "H.245 Transport Package for SPC use" },                      /* H.248.72 */
371     {   0x00f8, "MONA Preference Package" },                                  /* H.248.72 */
372     {   0x00f9, "TDM Gain Control Package" },                                 /* H.248.73 */
373     {   0x00fa, "Media Start Package" },                                      /* H.248.74 */
374     {   0x00fb, "Trim Package" },                                             /* H.248.74 */
375     {   0x00fc, "Enhanced Recording Package" },                               /* H.248.74 */
376     {   0x00fd, "Enhanced ASR Package" },                                     /* H.248.74      */
377     {   0x00fe, "Enhanced TTS Package" },                                     /* H.248.74 */
378     {   0x00ff, "Play Offset Control Package" },                              /* H.248.74 */
379     {   0x0100, "Enhanced DTMF Detection Package" },                          /* H.248.9 Revised 2009 */
380     {   0x0101, "IP Router NAT Package" },                                    /* H.248.64 */
381     {   0x0102, "Voice Enrolled Grammar Package" },                           /* H.248.74 */
382     {   0x0103, "Filter Group Package" },                                     /* H.248.76 */
383     {   0x0104, "RTCP Source Description Package" },                          /* H.248.71 */
384     {   0x0105, "Speaker Verification and Identification Package" },          /* H.248.74 */
385     {   0x0106, "Package Identifier Publishing and Application Package" },    /* H.248 */
386     {   0x0107, "Secure RTP Package " },                                      /* H.248.77 */
387     {   0x0108, "MGC Controlled Bearer Level ALG Package" },                  /* H.248.78 */
388     {   0x0109, "Enhanced Revised Offer/Answer SDP Support Package" },        /* H.248.80 */
389     {   0x010a, "Enhanced SDP Media Capabilities Negotiation Support Package" }, /* H.248.80 */
390
391     {   0x8000, "Ericsson IU" },
392     {   0x8001, "Ericsson UMTS and GSM Circuit" },
393     {   0x8002, "Ericsson Tone Generator Package" },
394     {   0x8003, "Ericsson Line Test Package" },
395     {   0x8004, "Nokia Advanced TFO Package" },
396     {   0x8005, "Nokia IWF Package" },
397     {   0x8006, "Nokia Root Package" },
398     {   0x8007, "Nokia Trace Package" },
399     {   0x8008, "Ericsson  V5.2 Layer" },
400     {   0x8009, "Ericsson Detailed Termination Information Package" },
401     {   0x800a, "Nokia Bearer Characteristics Package" },
402     {   0x800b, "Nokia Test Call Package" },
403     {   0x800c, "Nokia Extended Continuity Package" },
404     {   0x800d, "Nokia IPnwR Package" },
405     {   0x800e, "Ericsson Tracing Enhancements Package" },
406     {   0x800f, "Ericsson Partially Wildcarded TerminationID Package" },
407     {   0x8010, "SCTP Stream Handling Package" },
408
409     {0,     NULL}
410 };
411 static value_string_ext package_name_vals_ext = VALUE_STRING_EXT_INIT(package_name_vals);
412
413 /*
414  * This table consist of PackageName + EventName and its's corresponding string
415  *
416  */
417 static const value_string event_name_vals[] = {
418     {   0x00000000, "Media stream properties H.248.1 Annex C" },
419     {   0x00010000, "g H.248.1 Annex E" },
420     {   0x00010001, "g/Cause" },
421     {   0x00010002, "g/Signal Completion" },
422     {   0x00040000, "tonedet H.248.1 Annex E" },
423     {   0x00040001, "tonedet/std(Start tone detected)" },
424     {   0x00040002, "tonedet/etd(End tone detected)" },
425     {   0x00040003, "tonedet/ltd(Long tone detected)" },
426     {   0x00060000, "dd H.248.1 Annex E" },
427     {   0x00060001, "dd/std" },
428     {   0x00060002, "dd/etd" },
429     {   0x00060003, "dd/ltd" },
430     {   0x00060004, "dd, DigitMap Completion Event" },
431     {   0x00060010, "dd/d0, DTMF character 0" },
432     {   0x00060011, "dd/d1, DTMF character 1" },
433     {   0x00060012, "dd/d2, DTMF character 2" },
434     {   0x00060013, "dd/d3, DTMF character 3" },
435     {   0x00060014, "dd/d4, DTMF character 4" },
436     {   0x00060015, "dd/d5, DTMF character 5" },
437     {   0x00060016, "dd/d6, DTMF character 6" },
438     {   0x00060017, "dd/d7, DTMF character 7" },
439     {   0x00060018, "dd/d8, DTMF character 8" },
440     {   0x00060019, "dd/d9, DTMF character 9" },
441     {   0x0006001a, "dd/a, DTMF character A" },
442     {   0x0006001b, "dd/b, DTMF character B" },
443     {   0x0006001c, "dd/c, DTMF character C" },
444     {   0x0006001d, "dd/d, DTMF character D" },
445     {   0x00060020, "dd/*, DTMF character *" },
446     {   0x00060021, "dd/#, DTMF character #" },
447     {   0x00080030, "cd, Dial Tone" },
448     {   0x00080031, "cd, Ringing Tone" },
449     {   0x00080032, "cd, Busy Tone" },
450     {   0x00080033, "cd, Congestion Tone" },
451     {   0x00080034, "cd, Special Information Tone" },
452     {   0x00080035, "cd, (Recording) Warning Tone" },
453     {   0x00080036, "cd, Payphone Recognition Tone" },
454     {   0x00080037, "cd, Call Waiting Tone" },
455     {   0x00080038, "cd, Caller Waiting Tone" },
456     {   0x00090004, "al, onhook" },
457     {   0x00090005, "al, offhook" },
458     {   0x00090006, "al, flashhook" },
459     {   0x0009ffff, "al, *" },
460     {   0x000a0005, "ct, Completion of Continuity test" },
461     {   0x000b0005, "nt, network failure" },
462     {   0x000b0006, "nt, quality alert" },
463     {   0x000c0001, "rtp, Payload Transition" },
464     {   0x00210000, "Generic Bearer Connection Q.1950 Annex A" },
465     {   0x00210001, "GB/BNCChange" },
466     {   0x00220001, "BT/TIND (Tunnel Indication)" },
467     {   0x002a0001, "H.245/h245msg (Incoming H.245 Message)" },
468     {   0x002a0004, "H.245/h245ChC (H.245 Channel Closed)" },
469     {   0x00450000, "Inactivity Timer H.248.14" },
470     {   0x00450001, "it/ito" },
471     {   0x00450002, "it/ito" },
472     {   0x00460001, "threegmlc/mod_link_supp (Bearer Modification Support Event)" },
473     {   0x00980000, "Hanging Termination Package" },
474     {   0x00980001, "Termination Heartbeat" },
475     {   0x800a0000, "Nokia Bearer Characteristics Package" },
476     {0,     NULL}
477 };
478 static value_string_ext event_name_vals_ext = VALUE_STRING_EXT_INIT(event_name_vals);
479
480 /*
481  * This table consist of PackageName + SignalName and its's corresponding string
482  */
483 static const value_string signal_name_vals[] = {
484     {   0x00000000, "Media stream properties H.248.1 Annex C" },
485     {   0x00010000, "g H.248.1 Annex E" },
486     {   0x00030001, "tonegen/pt(Play tone)" },
487     {   0x00050010, "dg, DTMF character 0" },
488     {   0x00050011, "dg, DTMF character 1" },
489     {   0x00050012, "dg, DTMF character 2" },
490     {   0x00050013, "dg, DTMF character 3" },
491     {   0x00050014, "dg, DTMF character 4" },
492     {   0x00050015, "dg, DTMF character 5" },
493     {   0x00050016, "dg, DTMF character 6" },
494     {   0x00050017, "dg, DTMF character 7" },
495     {   0x00050018, "dg, DTMF character 8" },
496     {   0x00050019, "dg, DTMF character 9" },
497     {   0x0005001a, "dg, DTMF character A" },
498     {   0x0005001b, "dg, DTMF character B" },
499     {   0x0005001c, "dg, DTMF character C" },
500     {   0x0005001d, "dg, DTMF character D" },
501     {   0x00050020, "dg, DTMF character *" },
502     {   0x00050021, "dg, DTMF character #" },
503     {   0x00070030, "cg, Dial Tone" },
504     {   0x00070031, "cg/rt (Ringing Tone)" },
505     {   0x00070032, "cg, Busy Tone" },
506     {   0x00070033, "cg, Congestion Tone" },
507     {   0x00070034, "cg, Special Information Tone" },
508     {   0x00070035, "cg, (Recording) Warning Tone" },
509     {   0x00070036, "cg, Payphone Recognition Tone" },
510     {   0x00070037, "cg, Call Waiting Tone" },
511     {   0x00070038, "cg, Caller Waiting Tone" },
512     {   0x00090002, "al, ring" },
513     {   0x0009ffff, "al, *" },
514     {   0x000a0003, "ct, Continuity test" },
515     {   0x000a0004, "ct, Continuity respond" },
516     {   0x00210000, "GB Generic Bearer Connection Q.1950 Annex A" },
517     {   0x00210001, "GB/EstBNC(Establish BNC)" },
518     {   0x00210002, "GB/ModBNC (Modify BNC)" },
519     {   0x00210003, "GB/RelBNC(Release BNC)" },
520
521     {   0x002a0001, "H.245/cs (channel state)" },
522     {   0x002a0002, "H.245/termtype (Terminal Type)" },
523
524     {   0x002c0001, "H.324/cmod (Communication mode)" },
525     {   0x002c0002, "H.324/muxlv (Highest Multiplexing level)" },
526     {   0x002c0003, "H.324/demux (Demultiplex)" },
527     {   0x002c0004, "H.324/h223capr (Remote H.223 capability)" },
528     {   0x002c0005, "H.324/muxtbl_in (Incoming Multiplex Table)" },
529     {   0x002c0006, "H.324/muxtbl_out (Outgoing Multiplex Table)" },
530
531     {   0x800a0000, "Nokia Bearer Characteristics Package" },
532     {0,     NULL}
533 };
534 static value_string_ext signal_name_vals_ext = VALUE_STRING_EXT_INIT(signal_name_vals);
535
536 #if 0
537 static const value_string context_id_type[] = {
538     {NULL_CONTEXT,"0 (Null Context)"},
539     {CHOOSE_CONTEXT,"$ (Choose Context)"},
540     {ALL_CONTEXTS,"* (All Contexts)"},
541     {0,NULL}
542 };
543 #endif
544
545
546
547 static const value_string h248_reasons[] = {
548     { 400, "Syntax error in message"},
549     { 401, "Protocol Error"},
550     { 402, "Unauthorized"},
551     { 403, "Syntax error in transaction request"},
552     { 406, "Version Not Supported"},
553     { 410, "Incorrect identifier"},
554     { 411, "The transaction refers to an unknown ContextId"},
555     { 412, "No ContextIDs available"},
556     { 413, "Number of transactions in message exceeds maximum"},    /* [H.248.8 (08/07)] */
557     { 421, "Unknown action or illegal combination of actions"},
558     { 422, "Syntax Error in Action"},
559     { 430, "Unknown TerminationID"},
560     { 431, "No TerminationID matched a wildcard"},
561     { 432, "Out of TerminationIDs or No TerminationID available"},
562     { 433, "TerminationID is already in a Context"},
563     { 434, "Max number of Terminations in a Context exceeded"},
564     { 435, "Termination ID is not in specified Context"},
565     { 440, "Unsupported or unknown Package"},
566     { 441, "Missing Remote or Local Descriptor"},
567     { 442, "Syntax Error in Command"},
568     { 443, "Unsupported or Unknown Command"},
569     { 444, "Unsupported or Unknown Descriptor"},
570     { 445, "Unsupported or Unknown Property"},
571     { 446, "Unsupported or Unknown Parameter"},
572     { 447, "Descriptor not legal in this command"},
573     { 448, "Descriptor appears twice in a command"},
574     { 449, "Unsupported or Unknown Parameter or Property Value"},
575     { 450, "No such property in this package"},
576     { 451, "No such event in this package"},
577     { 452, "No such signal in this package"},
578     { 453, "No such statistic in this package"},
579     { 454, "No such parameter value in this package"},
580     { 455, "Property illegal in this Descriptor"},
581     { 456, "Property appears twice in this Descriptor"},
582     { 457, "Missing parameter in signal or event"},
583     { 458, "Unexpected Event/Request ID"},
584     { 459, "Unsupported or Unknown Profile"},
585     { 460, "Unable to set statistic on stream"},
586     { 461, "Unsupported or Unknown Profile"},                               /*[H.248.18] */
587
588     { 471, "Implied Add for Multiplex failure"},
589     { 472, "Required Information Missing"},                                 /*[H.248.8 (08/07)] */
590     { 473, "Conflicting Property Values"},                                  /*[H.248.8 (08/07)] */
591     { 474, "Invalid SDP Syntax"},                                           /*[H.248.49] */
592     { 475, "Unable to pause the playout of the signal"},                    /*[H.248.66] */
593     { 476, "Unable to adjust the data delivery speed of the Signal"},       /*[H.248.66] */
594
595     { 477, "Unable to adjust the playback relative scale of the signal"},   /*[H.248.66] */
596
597     { 478, "Behaviour Contradicts Resource Rule"},                          /*[H.248.63] */
598
599     { 500, "Internal software Failure in MG"},
600     { 501, "Not Implemented"},
601     { 502, "Not ready"},
602     { 503, "Service Unavailable"},
603     { 504, "Command Received from unauthorized entity"},
604     { 505, "Transaction Request Received before a Service Change Reply has been received"},
605     { 506, "Number of Transaction Pendings Exceeded"},
606     { 510, "Insufficient resources"},
607     { 511, "Temporarily Busy"},                                     /* [H.248.8 (08/07)] */
608     { 512, "Media Gateway unequipped to detect requested Event"},
609     { 513, "Media Gateway unequipped to generate requested Signals"},
610     { 514, "Media Gateway cannot send the specified announcement"},
611     { 515, "Unsupported Media Type"},
612     { 517, "Unsupported or invalid mode"},
613     { 518, "Event buffer full"},
614     { 519, "Out of space to store digit map"},
615     { 520, "Digit Map undefined in the MG"},
616     { 521, "Termination is ServiceChangeing"},
617     { 522, "Functionality Requested in Topology Triple Not Supported"},
618     { 526, "Insufficient bandwidth"},
619     { 529, "Internal hardware failure in MG"},
620     { 530, "Temporary Network failure"},
621     { 531, "Permanent Network failure"},
622     { 532, "Audited Property, Statistic, Event or Signal does not exist"},
623     { 533, "Response exceeds maximum transport PDU size"},
624     { 534, "Illegal write or read only property"},
625     { 540, "Unexpected initial hook state"},
626     { 541, "Unexpected Spare Bit State"},                               /* [H.248.33] */
627     { 542, "Command is not allowed on this termination"},
628     { 543, "MGC requested event detection timestamp not supported"},    /* [H.248.8 (08/07)] */
629     { 581, "Does Not Exist"},
630     { 600, "Illegal syntax within an announcement specification"},
631     { 601, "Variable type not supported"},
632     { 602, "Variable value out of range"},
633     { 603, "Category not supported"},
634     { 604, "Selector type not supported"},
635     { 605, "Selector value not supported"},
636     { 606, "Unknown segment ID"},
637     { 607, "Mismatch between play specification and provisioned data"},
638     { 608, "Provisioning error"},
639     { 609, "Invalid offset"},
640     { 610, "No free segment IDs"},
641     { 611, "Temporary segment not found"},
642     { 612, "Segment in use"},
643     { 613, "ISP port limit overrun"},
644     { 614, "No modems available"},
645     { 615, "Calling number unacceptable"},
646     { 616, "Called number unacceptable"},
647     { 617, "Reserved for H.248.9 return code"},     /* [H.248.9] */
648     { 618, "Reserved for H.248.9 return code"},     /* [H.248.9] */
649     { 622, "Reserved for H.248.9 return code"},     /* [H.248.9] */
650     { 623, "Reserved for H.248.9 return code"},     /* [H.248.9] */
651     { 624, "Reserved for H.248.9 return code"},     /* [H.248.9] */
652     { 625, "Reserved for H.248.9 return code"},     /* [H.248.9 Amendment 1] */
653     { 626, "Reserved for H.248.9 return code"},     /* [H.248.9 Amendment 1] */
654     { 627, "Reserved for H.248.9 return code"},     /* [H.248.9 Amendment 1] */
655     { 628, "Reserved for H.248.9 return code"},     /* [H.248.9 Amendment 1] */
656     { 629, "Reserved for H.248.9 return code"},     /* [H.248.9 Amendment 1] */
657     { 700, "Sieve Script Syntax Error"},            /* [H.248.69] */
658     { 701, "Unsupported Sieve Require Error"},      /* [H.248.69] */
659     { 702, "Sieve Actions Exceeded Error"},         /* [H.248.69] */
660
661     { 900, "Service Restored"},
662     { 901, "Cold Boot"},
663     { 902, "Warm Boot"},
664     { 903, "MGC Directed Change"},
665     { 904, "Termination malfunctioning"},
666     { 905, "Termination taken out of service"},
667     { 906, "Loss of lower layer connectivity (e.g. downstream sync)"},
668     { 907, "Transmission Failure"},
669     { 908, "MG Impending Failure"},
670     { 909, "MGC Impending Failure"},
671     { 910, "Media Capability Failure"},
672     { 911, "Modem Capability Failure"},
673     { 912, "Mux Capability Failure"},
674     { 913, "Signal Capability Failure"},
675     { 914, "Event Capability Failure"},
676     { 915, "State Loss"},
677     { 916, "Packages Change"},
678     { 917, "Capabilities Change"},
679     { 918, "Cancel Graceful"},
680     { 919, "Warm Failover"},
681     { 920, "Cold Failover"},
682     {0,NULL}
683 };
684 static value_string_ext h248_reasons_ext = VALUE_STRING_EXT_INIT(h248_reasons);
685
686 static const value_string wildcard_modes[] = {
687     { 0, "Choose" },
688     { 1, "All" },
689     { 0, NULL }
690 };
691
692 static const value_string wildcard_levels[] = {
693     { 0, "This One Level" },
694     { 1, "This Level and those below" },
695     { 0, NULL }
696 };
697
698 static h248_curr_info_t curr_info = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
699 static guint32 error_code;
700 static guint32 h248_version = 0; /* h248v1 support */
701 static gcp_wildcard_t wild_term;
702 static guint8 wild_card = 0xFF; /* place to store wildcardField */
703
704 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) {
705     asn1_ctx_t asn1_ctx;
706     asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
707     dissect_ber_integer(implicit ? *((gboolean*)implicit) : FALSE, &asn1_ctx, tree, tvb, 0, hfid, NULL);
708 }
709
710 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) {
711     asn1_ctx_t asn1_ctx;
712     asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
713     dissect_ber_octet_string(implicit ? *((gboolean*)implicit) : FALSE, &asn1_ctx, tree, tvb, 0, hfid, NULL);
714 }
715
716 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) {
717     asn1_ctx_t asn1_ctx;
718     asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
719     dissect_ber_boolean(implicit ? *((gboolean*)implicit) : FALSE, &asn1_ctx, tree, tvb, 0, hfid, NULL);
720 }
721
722 extern void h248_param_item(proto_tree* tree,
723                              tvbuff_t* tvb,
724                              packet_info* pinfo _U_,
725                              int hfid,
726                              h248_curr_info_t* h248_info _U_,
727                              void* lenp ) {
728     int len = lenp ? *((int*)lenp) : -1;
729     proto_tree_add_item(tree,hfid,tvb,0,len,FALSE);
730 }
731
732 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) {
733     call_dissector((dissector_handle_t) dissector_hdl,tvb,pinfo,tree);
734 }
735
736
737 static const h248_package_t no_package = { 0xffff, &hf_h248_no_pkg, &ett_h248_no_pkg, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
738 static const h248_pkg_sig_t no_signal = { 0, &hf_h248_no_sig, &ett_h248_no_sig, NULL, NULL };
739 static const h248_pkg_param_t no_param = { 0, &hf_h248_param, h248_param_item,  NULL };
740 static const h248_pkg_evt_t no_event = { 0, &hf_h248_no_evt, &ett_h248_no_evt, NULL, NULL };
741
742 static GPtrArray* packages = NULL;
743
744 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_) {
745     tvbuff_t *new_tvb = NULL;
746     proto_tree *package_tree=NULL;
747     guint16 name_major, name_minor;
748     const h248_package_t* pkg = NULL;
749     guint i;
750     int offset = 0;
751     asn1_ctx_t asn1_ctx;
752     asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
753
754     offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, offset, hfid , &new_tvb);
755
756     if (new_tvb) {
757         /* this field is always 4 bytes  so just read it into two integers */
758         name_major=tvb_get_ntohs(new_tvb, 0);
759         name_minor=tvb_get_ntohs(new_tvb, 2);
760
761         /* do the prettification */
762         proto_item_append_text(asn1_ctx.created_item, "  %s (%04x)",
763                                val_to_str_ext_const(name_major, &package_name_vals_ext, "Unknown Package"),
764                                name_major);
765
766         if(tree){
767             proto_item* pi;
768             const gchar* strval;
769
770             package_tree = proto_item_add_subtree(asn1_ctx.created_item, ett_packagename);
771             proto_tree_add_uint(package_tree, hf_h248_pkg_name, tvb, offset-4, 2, name_major);
772
773             for(i=0; i < packages->len; i++) {
774                 pkg = g_ptr_array_index(packages,i);
775
776                 if (name_major == pkg->id) {
777                     break;
778                 } else {
779                     pkg = NULL;
780                 }
781             }
782
783             if (! pkg ) pkg = &no_package;
784
785
786             pi = proto_tree_add_uint(package_tree, hf_248_pkg_param, tvb, offset-2, 2, name_minor);
787
788             if (pkg->signal_names && ( strval = match_strval(name_minor, pkg->signal_names) )) {
789                 strval = ep_strdup_printf("%s (%d)",strval,name_minor);
790             } else {
791                 strval = ep_strdup_printf("Unknown (%d)",name_minor);
792             }
793
794             proto_item_set_text(pi,"Signal ID: %s", strval);
795         }
796
797     }
798 }
799
800
801 static int dissect_h248_trx_id(gboolean implicit_tag, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, guint32* trx_id_p) {
802     guint64 trx_id = 0;
803     gint8 class;
804     gboolean pc;
805     gint32 tag;
806     guint32 len;
807     guint32 i;
808
809     if(!implicit_tag){
810         offset=dissect_ber_identifier(pinfo, tree, tvb, offset, &class, &pc, &tag);
811         offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL);
812     } else {
813         len=tvb_length_remaining(tvb, offset);
814     }
815
816
817     if (len > 8 || len < 1) {
818         THROW(BoundsError);
819     } else {
820         for(i=1;i<=len;i++){
821             trx_id=(trx_id<<8)|tvb_get_guint8(tvb, offset);
822             offset++;
823         }
824         if (trx_id > 0xffffffff) {
825             proto_item* pi = proto_tree_add_text(tree, tvb, offset-len, len,"transactionId %" G_GINT64_MODIFIER "u", trx_id);
826             proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
827
828             *trx_id_p = 0;
829
830         } else {
831             proto_tree_add_uint(tree, hf_h248_transactionId, tvb, offset-len, len, (guint32)trx_id);
832             *trx_id_p = (guint32)trx_id;
833         }
834     }
835
836     return offset;
837 }
838
839 static int dissect_h248_ctx_id(gboolean implicit_tag, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, guint32* ctx_id_p) {
840     gint8 class;
841     gboolean pc;
842     gint32 tag;
843     guint32 len;
844     guint64 ctx_id = 0;
845     guint32 i;
846
847     if(!implicit_tag){
848         offset=dissect_ber_identifier(pinfo, tree, tvb, offset, &class, &pc, &tag);
849         offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL);
850     } else {
851         len=tvb_length_remaining(tvb, offset);
852     }
853
854
855     if (len > 8 || len < 1) {
856         THROW(BoundsError);
857     } else {
858         for(i=1;i<=len;i++){
859             ctx_id=(ctx_id<<8)|tvb_get_guint8(tvb, offset);
860             offset++;
861         }
862
863         if (ctx_id > 0xffffffff) {
864             proto_item* pi = proto_tree_add_text(tree, tvb, offset-len, len,
865                                                  "contextId: %" G_GINT64_MODIFIER "u", ctx_id);
866             proto_item_set_expert_flags(pi, PI_MALFORMED, PI_WARN);
867
868             *ctx_id_p = 0xfffffffd;
869
870         } else {
871             proto_item* pi = proto_tree_add_uint(tree, hf_h248_context_id, tvb, offset-len, len, (guint32)ctx_id);
872
873             if ( ctx_id ==  NULL_CONTEXT ) {
874                 proto_item_set_text(pi,"contextId: Null Context(0)");
875             } else if ( ctx_id ==  CHOOSE_CONTEXT ) {
876                 proto_item_set_text(pi,"contextId: $ (Choose Context = 0xfffffffe)");
877             } else if ( ctx_id ==  ALL_CONTEXTS ) {
878                 proto_item_set_text(pi,"contextId: * (All Contexts = 0xffffffff)");
879             }
880
881             *ctx_id_p = (guint32) ctx_id;
882         }
883     }
884
885     return offset;
886 }
887
888 void h248_register_package(const h248_package_t* pkg) {
889     if (! packages) packages = g_ptr_array_new();
890
891     g_ptr_array_add(packages,(void*)pkg);
892 }
893
894 static guint32 packageandid;
895
896 static int dissect_h248_PkgdName(gboolean implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) {
897     tvbuff_t *new_tvb = NULL;
898     proto_tree *package_tree=NULL;
899     guint16 name_major, name_minor;
900     const h248_package_t* pkg = NULL;
901     guint i;
902
903     offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &new_tvb);
904
905     if (new_tvb) {
906         /* this field is always 4 bytes  so just read it into two integers */
907         name_major=tvb_get_ntohs(new_tvb, 0);
908         name_minor=tvb_get_ntohs(new_tvb, 2);
909         packageandid=(name_major<<16)|name_minor;
910
911         /* do the prettification */
912         proto_item_append_text(actx->created_item, "  %s (%04x)",
913                                val_to_str_ext_const(name_major, &package_name_vals_ext, "Unknown Package"),
914                                name_major);
915
916         if(tree){
917             package_tree = proto_item_add_subtree(actx->created_item, ett_packagename);
918             proto_tree_add_uint(package_tree, hf_h248_pkg_name, tvb, offset-4, 2, name_major);
919         }
920
921         for(i=0; i < packages->len; i++) {
922             pkg = g_ptr_array_index(packages,i);
923
924             if (name_major == pkg->id) {
925                 break;
926             } else {
927                 pkg = NULL;
928             }
929         }
930
931         if (! pkg ) pkg = &no_package;
932
933         {
934             proto_item* pi = proto_tree_add_uint(package_tree, hf_248_pkg_param, tvb, offset-2, 2, name_minor);
935             const gchar* strval;
936
937             if (pkg->param_names && ( strval = match_strval(name_minor, pkg->param_names) )) {
938                 strval = ep_strdup_printf("%s (%d)",strval,name_minor);
939             } else {
940                 strval = ep_strdup_printf("Unknown (%d)",name_minor);
941             }
942
943             proto_item_set_text(pi,"Parameter: %s", strval);
944         }
945     } else {
946         pkg = &no_package;
947     }
948
949     curr_info.pkg = pkg;
950
951     return offset;
952 }
953
954 static int dissect_h248_EventName(gboolean implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) {
955     tvbuff_t *new_tvb;
956     proto_tree *package_tree=NULL;
957     guint16 name_major, name_minor;
958     const h248_package_t* pkg = NULL;
959     const h248_pkg_evt_t* evt = NULL;
960     guint i;
961
962     offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &new_tvb);
963
964     if (new_tvb) {
965         /* this field is always 4 bytes  so just read it into two integers */
966         name_major=tvb_get_ntohs(new_tvb, 0);
967         name_minor=tvb_get_ntohs(new_tvb, 2);
968         packageandid=(name_major<<16)|name_minor;
969
970         /* do the prettification */
971         proto_item_append_text(actx->created_item, "  %s (%04x)",
972                                val_to_str_ext_const(name_major, &package_name_vals_ext, "Unknown Package"),
973                                name_major);
974         if(tree){
975             package_tree = proto_item_add_subtree(actx->created_item, ett_packagename);
976         }
977         proto_tree_add_uint(package_tree, hf_h248_pkg_name, tvb, offset-4, 2, name_major);
978
979
980         for(i=0; i < packages->len; i++) {
981             pkg = g_ptr_array_index(packages,i);
982
983             if (name_major == pkg->id) {
984                 break;
985             } else {
986                 pkg = NULL;
987             }
988         }
989
990         if (! pkg ) pkg = &no_package;
991
992         curr_info.pkg = pkg;
993
994         if (pkg->events) {
995             for (evt = pkg->events; evt->hfid; evt++) {
996                 if (name_minor == evt->id) {
997                     break;
998                 }
999             }
1000
1001             if (! evt->hfid) evt = &no_event;
1002         } else {
1003             evt = &no_event;
1004         }
1005
1006         curr_info.evt = evt;
1007
1008         {
1009             proto_item* pi = proto_tree_add_uint(package_tree, hf_h248_event_code, tvb, offset-2, 2, name_minor);
1010             const gchar* strval;
1011
1012             if (pkg->event_names && ( strval = match_strval(name_minor, pkg->event_names) )) {
1013                 strval = ep_strdup_printf("%s (%d)",strval,name_minor);
1014             } else {
1015                 strval = ep_strdup_printf("Unknown (%d)",name_minor);
1016             }
1017
1018             proto_item_set_text(pi,"Event ID: %s", strval);
1019         }
1020
1021     } else {
1022         curr_info.pkg = &no_package;
1023         curr_info.evt = &no_event;
1024     }
1025
1026     return offset;
1027 }
1028
1029
1030
1031 static int dissect_h248_SignalName(gboolean implicit_tag , tvbuff_t *tvb, int offset,  asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) {
1032     tvbuff_t *new_tvb;
1033     proto_tree *package_tree=NULL;
1034     guint16 name_major, name_minor;
1035     const h248_package_t* pkg = NULL;
1036     const h248_pkg_sig_t* sig;
1037     guint i;
1038
1039     offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &new_tvb);
1040
1041     if (new_tvb) {
1042         /* this field is always 4 bytes so just read it into two integers */
1043         name_major=tvb_get_ntohs(new_tvb, 0);
1044         name_minor=tvb_get_ntohs(new_tvb, 2);
1045         packageandid=(name_major<<16)|name_minor;
1046
1047         /* do the prettification */
1048         proto_item_append_text(actx->created_item, "  %s (%04x)",
1049                                val_to_str_ext_const(name_major, &package_name_vals_ext, "Unknown Package"),
1050                                name_major);
1051         if(tree){
1052             package_tree = proto_item_add_subtree(actx->created_item, ett_packagename);
1053         }
1054         proto_tree_add_uint(package_tree, hf_h248_pkg_name, tvb, offset-4, 2, name_major);
1055
1056         for(i=0; i < packages->len; i++) {
1057             pkg = g_ptr_array_index(packages,i);
1058
1059             if (name_major == pkg->id) {
1060                 break;
1061             } else {
1062                 pkg = NULL;
1063             }
1064         }
1065
1066         if (! pkg ) pkg = &no_package;
1067
1068         if (pkg->signals) {
1069             for (sig = pkg->signals; sig->hfid; sig++) {
1070                 if (name_minor == sig->id) {
1071                     break;
1072                 }
1073             }
1074
1075             if (! sig->hfid) sig = &no_signal;
1076
1077             curr_info.pkg = pkg;
1078             curr_info.sig = sig;
1079         } else {
1080             curr_info.pkg = &no_package;
1081             curr_info.sig = &no_signal;
1082         }
1083
1084         {
1085             proto_item* pi = proto_tree_add_uint(package_tree, hf_h248_signal_code, tvb, offset-2, 2, name_minor);
1086             const gchar* strval;
1087
1088             if (pkg->signal_names && ( strval = match_strval(name_minor, pkg->signal_names) )) {
1089                 strval = ep_strdup_printf("%s (%d)",strval,name_minor);
1090             } else {
1091                 strval = ep_strdup_printf("Unknown (%d)",name_minor);
1092             }
1093
1094             proto_item_set_text(pi,"Signal ID: %s", strval);
1095         }
1096
1097     } else {
1098         curr_info.pkg = &no_package;
1099         curr_info.sig = &no_signal;
1100     }
1101
1102     return offset;
1103 }
1104
1105 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_) {
1106
1107     gint8 class;
1108     gboolean pc, ind;
1109     gint32 tag;
1110     guint32 len;
1111     /*guint16 name_major;*/
1112     guint16 name_minor;
1113     int end_offset;
1114     tvbuff_t *next_tvb;
1115     const h248_package_t* pkg;
1116     const h248_pkg_param_t* prop;
1117
1118     offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &class, &pc, &tag);
1119     offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind);
1120     end_offset=offset+len;
1121
1122     if( (class!=BER_CLASS_UNI)
1123       ||(tag!=BER_UNI_TAG_OCTETSTRING) ){
1124         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);
1125         return end_offset;
1126     }
1127
1128
1129     next_tvb = tvb_new_subset(tvb, offset , len , len );
1130     /*name_major = packageandid >> 16;*/
1131     name_minor = packageandid & 0xffff;
1132
1133     pkg = (curr_info.pkg) ? curr_info.pkg : &no_package;
1134
1135     if (pkg->properties) {
1136         for (prop = pkg->properties; prop && prop->hfid; prop++) {
1137             if (name_minor == prop->id) {
1138                 break;
1139             }
1140         }
1141     } else {
1142         prop = &no_param;
1143     }
1144
1145     if (prop && prop->hfid ) {
1146         if (!prop->dissector) prop = &no_param;
1147         prop->dissector(tree, next_tvb, actx->pinfo, *(prop->hfid), &curr_info, prop->data);
1148     }
1149
1150     return end_offset;
1151 }
1152
1153
1154 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_) {
1155     tvbuff_t *next_tvb;
1156     guint32 param_id = 0xffffffff;
1157     const h248_pkg_param_t* sigpar;
1158     const gchar* strval;
1159     proto_item* pi;
1160
1161     offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset,  hf_index, &next_tvb);
1162     pi = actx->created_item;
1163
1164     switch(tvb_length(next_tvb)) {
1165         case 4: param_id = tvb_get_ntohl(next_tvb,0); break;
1166         case 3: param_id = tvb_get_ntoh24(next_tvb,0); break;
1167         case 2: param_id = tvb_get_ntohs(next_tvb,0); break;
1168         case 1: param_id = tvb_get_guint8(next_tvb,0); break;
1169         default: break;
1170     }
1171
1172     curr_info.par = &no_param;
1173
1174     if (curr_info.sig && curr_info.sig->parameters) {
1175         for(sigpar = curr_info.sig->parameters; sigpar->hfid; sigpar++) {
1176             if (sigpar->id == param_id) {
1177                 curr_info.par = sigpar;
1178                 break;
1179             }
1180         }
1181     }
1182
1183     if (curr_info.sig && curr_info.sig->param_names && ( strval = match_strval(param_id, curr_info.sig->param_names) )) {
1184         strval = ep_strdup_printf("%s (%d)",strval,param_id);
1185     } else {
1186         strval = ep_strdup_printf("Unknown (%d)",param_id);
1187     }
1188
1189     proto_item_set_text(pi,"Parameter: %s", strval);
1190
1191     return offset;
1192 }
1193
1194 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_) {
1195     tvbuff_t *next_tvb;
1196     int end_offset;
1197     gint8 class;
1198     gboolean pc, ind;
1199     gint32 tag;
1200     guint32 len;
1201
1202     offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &class, &pc, &tag);
1203     offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind);
1204     end_offset=offset+len;
1205
1206     if( (class!=BER_CLASS_UNI)
1207         ||(tag!=BER_UNI_TAG_OCTETSTRING) ){
1208         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);
1209         return end_offset;
1210     }
1211
1212
1213     next_tvb = tvb_new_subset(tvb,offset,len,len);
1214
1215     if ( curr_info.par && curr_info.par->dissector) {
1216         curr_info.par->dissector(tree, next_tvb, actx->pinfo, *(curr_info.par->hfid), &curr_info, curr_info.par->data);
1217     }
1218
1219     return end_offset;
1220 }
1221
1222 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_) {
1223     tvbuff_t *next_tvb;
1224     guint32 param_id = 0xffffffff;
1225     const h248_pkg_param_t* evtpar;
1226     const gchar* strval;
1227     proto_item* pi;
1228
1229     offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &next_tvb);
1230     pi = actx->created_item;
1231
1232     if (next_tvb) {
1233         switch(tvb_length(next_tvb)) {
1234             case 4: param_id = tvb_get_ntohl(next_tvb,0); break;
1235             case 3: param_id = tvb_get_ntoh24(next_tvb,0); break;
1236             case 2: param_id = tvb_get_ntohs(next_tvb,0); break;
1237             case 1: param_id = tvb_get_guint8(next_tvb,0); break;
1238             default: break;
1239         }
1240     }
1241
1242
1243     curr_info.par = &no_param;
1244
1245     if (curr_info.evt && curr_info.evt->parameters) {
1246         for(evtpar = curr_info.evt->parameters; evtpar->hfid; evtpar++) {
1247             if (evtpar->id == param_id) {
1248                 curr_info.par = evtpar;
1249                 break;
1250             }
1251         }
1252     } else {
1253         curr_info.par = &no_param;
1254     }
1255
1256     if (curr_info.evt && curr_info.evt->param_names && ( strval = match_strval(param_id, curr_info.evt->param_names) )) {
1257         strval = ep_strdup_printf("%s (%d)",strval,param_id);
1258     } else {
1259         strval = ep_strdup_printf("Unknown (%d)",param_id);
1260     }
1261
1262     proto_item_set_text(pi,"Parameter: %s", strval);
1263
1264
1265     return offset;
1266 }
1267
1268 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_) {
1269     tvbuff_t *next_tvb;
1270     int end_offset;
1271     gint8 class;
1272     gboolean pc, ind;
1273     gint32 tag;
1274     guint32 len;
1275
1276     offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &class, &pc, &tag);
1277     offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind);
1278     end_offset=offset+len;
1279
1280     if( (class!=BER_CLASS_UNI)
1281         ||(tag!=BER_UNI_TAG_OCTETSTRING) ){
1282         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);
1283         return end_offset;
1284     }
1285
1286
1287     next_tvb = tvb_new_subset(tvb,offset,len,len);
1288
1289     if ( curr_info.par && curr_info.par->dissector) {
1290         curr_info.par->dissector(tree, next_tvb, actx->pinfo, *(curr_info.par->hfid), &curr_info, curr_info.par->data);
1291     }
1292
1293     return end_offset;
1294 }
1295
1296 static int dissect_h248_MtpAddress(gboolean implicit_tag, tvbuff_t *tvb, int offset,  asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) {
1297     tvbuff_t *new_tvb;
1298     proto_tree *mtp_tree=NULL;
1299     guint32 val;
1300     int i, len, old_offset;
1301
1302     old_offset=offset;
1303     offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &new_tvb);
1304
1305     if (new_tvb) {
1306         /* this field is either 2 or 4 bytes  so just read it into an integer */
1307         val=0;
1308         len=tvb_length(new_tvb);
1309         for(i=0;i<len;i++){
1310             val= (val<<8)|tvb_get_guint8(new_tvb, i);
1311         }
1312
1313         /* do the prettification */
1314         proto_item_append_text(actx->created_item, "  NI = %d, PC = %d ( %d-%d )", val&0x03,val>>2,val&0x03,val>>2);
1315         if(tree){
1316             mtp_tree = proto_item_add_subtree(actx->created_item, ett_mtpaddress);
1317         }
1318         proto_tree_add_uint(mtp_tree, hf_h248_mtpaddress_ni, tvb, old_offset, offset-old_offset, val&0x03);
1319         proto_tree_add_uint(mtp_tree, hf_h248_mtpaddress_pc, tvb, old_offset, offset-old_offset, val>>2);
1320     }
1321
1322     return offset;
1323 }
1324
1325 #define H248_TAP() do { if (keep_persistent_data && curr_info.cmd) tap_queue_packet(h248_tap, actx->pinfo, curr_info.cmd); } while(0)
1326
1327 #include "packet-h248-fn.c"
1328
1329 static void dissect_h248_tpkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
1330     dissect_tpkt_encap(tvb, pinfo, tree, h248_desegment, h248_handle);
1331 }
1332
1333 static void
1334 dissect_h248(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1335 {
1336     proto_item *h248_item;
1337     asn1_ctx_t asn1_ctx;
1338     h248_tree = NULL;
1339     h248_tvb = NULL;
1340
1341     asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
1342
1343     curr_info.msg = NULL;
1344     curr_info.trx = NULL;
1345     curr_info.ctx = NULL;
1346     curr_info.cmd = NULL;
1347     curr_info.term = NULL;
1348     curr_info.pkg = NULL;
1349     curr_info.evt = NULL;
1350     curr_info.sig = NULL;
1351     curr_info.stat = NULL;
1352     curr_info.par = NULL;
1353
1354     /* Check if it is actually a text-based H.248 encoding, which we
1355        dissect with the "megaco" dissector in Wireshark.  (Both
1356        encodings are MEGACO (RFC 3015) and both are H.248.)
1357      */
1358     if(tvb_length(tvb)>=6){
1359         if(!tvb_strneql(tvb, 0, "MEGACO", 6)){
1360             static dissector_handle_t megaco_handle=NULL;
1361             if(!megaco_handle){
1362                 megaco_handle = find_dissector("megaco");
1363             }
1364             if(megaco_handle){
1365                 call_dissector(megaco_handle, tvb, pinfo, tree);
1366                 return;
1367             }
1368         }
1369     }
1370
1371     /* Make entry in the Protocol column on summary display */
1372     col_set_str(pinfo->cinfo, COL_PROTOCOL, "H.248");
1373
1374     if (tree) {
1375         h248_item = proto_tree_add_item(tree, proto_h248, tvb, 0, -1, ENC_NA);
1376         h248_tree = proto_item_add_subtree(h248_item, ett_h248);
1377     }
1378
1379     dissect_h248_MegacoMessage(FALSE, tvb, 0, &asn1_ctx, h248_tree, -1);
1380
1381 }
1382
1383 /*--- proto_register_h248 ----------------------------------------------*/
1384 void proto_reg_handoff_h248(void);
1385
1386 void proto_register_h248(void) {
1387
1388     /* List of fields */
1389     static hf_register_info hf[] = {
1390         { &hf_h248_mtpaddress_ni, {
1391                 "NI", "h248.mtpaddress.ni", FT_UINT32, BASE_DEC,
1392                 NULL, 0, NULL, HFILL }},
1393         { &hf_h248_mtpaddress_pc, {
1394                 "PC", "h248.mtpaddress.pc", FT_UINT32, BASE_DEC,
1395                 NULL, 0, NULL, HFILL }},
1396         { &hf_h248_pkg_name, {
1397                 "Package", "h248.package_name", FT_UINT16, BASE_HEX|BASE_EXT_STRING,
1398                 &package_name_vals_ext, 0, NULL, HFILL }},
1399         { &hf_248_pkg_param, {
1400                 "Parameter ID", "h248.package_paramid", FT_UINT16, BASE_HEX,
1401                 NULL, 0, NULL, HFILL }},
1402         { &hf_h248_signal_code, {
1403                 "Signal ID", "h248.package_signalid", FT_UINT16, BASE_HEX,
1404                 NULL, 0, "Parameter ID", HFILL }},
1405         { &hf_h248_event_code, {
1406                 "Event ID", "h248.package_eventid", FT_UINT16, BASE_HEX,
1407                 NULL, 0, "Parameter ID", HFILL }},
1408         { &hf_h248_event_name, {
1409                 "Package and Event name", "h248.event_name", FT_UINT32, BASE_HEX|BASE_EXT_STRING,
1410                 &event_name_vals_ext, 0, "Package", HFILL }},
1411         { &hf_h248_signal_name, {
1412                 "Package and Signal name", "h248.signal_name", FT_UINT32, BASE_HEX|BASE_EXT_STRING,
1413                 &signal_name_vals_ext, 0, "Package", HFILL }},
1414         { &hf_h248_pkg_bcp_BNCChar_PDU,
1415           { "BNCChar", "h248.package_bcp.BNCChar",
1416             FT_UINT32, BASE_DEC, VALS(gcp_term_types), 0,
1417             NULL, HFILL }},
1418
1419         { &hf_h248_error_code,
1420           { "errorCode", "h248.errorCode",
1421             FT_UINT32, BASE_DEC|BASE_EXT_STRING, &h248_reasons_ext, 0,
1422             "ErrorDescriptor/errorCode", HFILL }},
1423         { &hf_h248_context_id,
1424           { "contextId", "h248.contextId",
1425             FT_UINT32, BASE_HEX, NULL, 0,
1426             "Context ID", HFILL }},
1427         { &hf_h248_term_wild_type,
1428           { "Wildcard Mode", "h248.term.wildcard.mode",
1429             FT_UINT8, BASE_DEC, VALS(wildcard_modes), 0x80,
1430             NULL, HFILL }},
1431         { &hf_h248_term_wild_level,
1432           { "Wildcarding Level", "h248.term.wildcard.level",
1433             FT_UINT8, BASE_DEC, VALS(wildcard_levels), 0x40,
1434             NULL, HFILL }},
1435         { &hf_h248_term_wild_position,
1436           { "Wildcarding Position", "h248.term.wildcard.pos",
1437             FT_UINT8, BASE_DEC, NULL, 0x3F,
1438             NULL, HFILL }},
1439
1440         { &hf_h248_no_pkg,
1441           { "Unknown Package", "h248.pkg.unknown",
1442             FT_BYTES, BASE_NONE, NULL, 0,
1443             NULL, HFILL }},
1444         { &hf_h248_no_sig,
1445           { "Unknown Signal", "h248.pkg.unknown.sig",
1446             FT_BYTES, BASE_NONE, NULL, 0,
1447             NULL, HFILL }},
1448         { &hf_h248_no_evt,
1449           { "Unknown Event", "h248.pkg.unknown.evt",
1450             FT_BYTES, BASE_NONE, NULL, 0,
1451             NULL, HFILL }},
1452         { &hf_h248_param,
1453           { "Parameter", "h248.pkg.unknown.param",
1454             FT_BYTES, BASE_NONE, NULL, 0,
1455             NULL, HFILL }},
1456         { &hf_h248_serviceChangeReasonStr,
1457           { "ServiceChangeReasonStr", "h248.serviceChangeReasonstr",
1458             FT_STRING, BASE_NONE, NULL, 0,
1459             "h248.IA5String", HFILL }},
1460
1461 /* h248v1 support */
1462         { &hf_h248_auditValueReplyV1,
1463           { "auditValueReplyV1", "h248.auditValueReplyV1",
1464             FT_NONE, BASE_NONE, NULL, 0,
1465             NULL, HFILL }},
1466
1467 #include "packet-h248-hfarr.c"
1468
1469         GCP_HF_ARR_ELEMS("h248",h248_arrel)
1470
1471     };
1472
1473     /* List of subtrees */
1474     static gint *ett[] = {
1475         &ett_h248,
1476         &ett_mtpaddress,
1477         &ett_packagename,
1478         &ett_codec,
1479         &ett_wildcard,
1480         &ett_h248_no_pkg,
1481         &ett_h248_no_sig,
1482         &ett_h248_no_evt,
1483         GCP_ETT_ARR_ELEMS(h248_arrel),
1484
1485 #include "packet-h248-ettarr.c"
1486     };
1487
1488     module_t *h248_module;
1489
1490
1491     /* Register protocol */
1492     proto_h248 = proto_register_protocol(PNAME, PSNAME, PFNAME);
1493     register_dissector("h248", dissect_h248, proto_h248);
1494     register_dissector("h248.tpkt", dissect_h248_tpkt, proto_h248);
1495
1496     /* Register fields and subtrees */
1497     proto_register_field_array(proto_h248, hf, array_length(hf));
1498     proto_register_subtree_array(ett, array_length(ett));
1499
1500     h248_module = prefs_register_protocol(proto_h248, proto_reg_handoff_h248);
1501     prefs_register_bool_preference(h248_module, "ctx_info",
1502                                    "Track Context",
1503                                    "Mantain relationships between transactions and contexts and display an extra tree showing context data",
1504                                    &keep_persistent_data);
1505     prefs_register_uint_preference(h248_module, "udp_port",
1506                                    "UDP port",
1507                                    "Port to be decoded as h248",
1508                                    10,
1509                                    &global_udp_port);
1510     prefs_register_uint_preference(h248_module, "tcp_port",
1511                                    "TCP port",
1512                                    "Port to be decoded as h248",
1513                                    10,
1514                                    &global_tcp_port);
1515     prefs_register_bool_preference(h248_module, "desegment",
1516                                    "Desegment H.248 over TCP",
1517                                    "Desegment H.248 messages that span more TCP segments",
1518                                    &h248_desegment);
1519
1520     msgs = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "h248_msgs");
1521     trxs = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "h248_trxs");
1522     ctxs_by_trx = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "h248_ctxs_by_trx");
1523     ctxs = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "h248_ctxs");
1524
1525     h248_tap = register_tap("h248");
1526
1527     gcp_init();
1528 }
1529
1530 /*--- proto_reg_handoff_h248 -------------------------------------------*/
1531 void proto_reg_handoff_h248(void) {
1532
1533     static gboolean initialized = FALSE;
1534     static guint32 udp_port;
1535     static guint32 tcp_port;
1536
1537     if (!initialized) {
1538         h248_handle = find_dissector("h248");
1539         h248_tpkt_handle = find_dissector("h248.tpkt");
1540         dissector_add_uint("mtp3.service_indicator", GATEWAY_CONTROL_PROTOCOL_USER_ID, h248_handle);
1541         h248_term_handle = find_dissector("h248term");
1542         initialized = TRUE;
1543     } else {
1544         if (udp_port != 0)
1545             dissector_delete_uint("udp.port", udp_port, h248_handle);
1546
1547         if (tcp_port != 0)
1548             dissector_delete_uint("tcp.port", tcp_port, h248_tpkt_handle);
1549     }
1550
1551     udp_port = global_udp_port;
1552     tcp_port = global_tcp_port;
1553
1554     if (udp_port != 0) {
1555         dissector_add_uint("udp.port", udp_port, h248_handle);
1556     }
1557
1558     if (tcp_port != 0) {
1559         dissector_add_uint("tcp.port", tcp_port, h248_tpkt_handle);
1560     }
1561 }
1562