QSIG fully implemented
[obnox/wireshark/wip.git] / epan / dissectors / packet-q931.c
1 /* packet-q931.c
2  * Routines for Q.931 frame disassembly
3  * Guy Harris <guy@alum.mit.edu>
4  *
5  * $Id$
6  *
7  * Modified by Andreas Sikkema for possible use with H.323
8  *
9  * Wireshark - Network traffic analyzer
10  * By Gerald Combs <gerald@wireshark.org>
11  * Copyright 1998
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
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 <stdio.h>
33 #include <glib.h>
34 #include <string.h>
35 #include <epan/packet.h>
36 #include <epan/tap.h>
37 #include <epan/strutil.h>
38 #include <epan/nlpid.h>
39 #include "packet-q931.h"
40 #include "packet-e164.h"
41 #include <epan/prefs.h>
42 #include <epan/reassemble.h>
43 #include <epan/emem.h>
44
45 #include <epan/lapd_sapi.h>
46 #include "packet-tpkt.h"
47
48 #ifndef min
49 #define min(a,b) (((a)<(b))?(a):(b))
50 #endif
51
52 /* Q.931 references:
53  *
54  * http://www.acacia-net.com/Clarinet/Protocol/q9313svn.htm
55  * http://www.acacia-net.com/Clarinet/Protocol/q9311sc3.htm
56  * http://www.acacia-net.com/Clarinet/Protocol/q9317oz7.htm
57  * http://www.protocols.com/pbook/isdn.htm
58  * http://freesoft.org/CIE/Topics/126.htm
59  * http://noc.comstar.ru/miscdocs/ascend-faq-cause-codes.html
60  * http://www.andrews-arnold.co.uk/isdn/q931cause.html
61  * http://www.tulatelecom.ru/staff/german/DSSHelp/MessList/InfEl/InfElList.html
62  */
63 static void reset_q931_packet_info(q931_packet_info *pi);
64 static gboolean have_valid_q931_pi=FALSE;
65 static q931_packet_info *q931_pi=NULL;
66 static int q931_tap = -1;
67
68 static int proto_q931                                   = -1;
69 static int hf_q931_discriminator                        = -1;
70 static int hf_q931_coding_standard                      = -1;
71 static int hf_q931_information_transfer_capability      = -1;
72 static int hf_q931_transfer_mode                        = -1;
73 static int hf_q931_information_transfer_rate            = -1;
74 static int hf_q931_uil1                                 = -1;
75 static int hf_q931_call_ref_len                         = -1;
76 static int hf_q931_call_ref_flag                        = -1;
77 static int hf_q931_call_ref                             = -1;
78 static int hf_q931_message_type                         = -1;
79 static int hf_q931_segment_type                         = -1;
80 static int hf_q931_cause_location                       = -1;
81 static int hf_q931_cause_value                          = -1;
82 static int hf_q931_number_type                          = -1;
83 static int hf_q931_numbering_plan                       = -1;
84 static int hf_q931_extension_ind                        = -1;
85 static int hf_q931_calling_party_number                 = -1;
86 static int hf_q931_called_party_number                  = -1;
87 static int hf_q931_connected_number                     = -1;
88 static int hf_q931_redirecting_number                   = -1;
89 static int hf_q931_screening_ind                                = -1;
90 static int hf_q931_presentation_ind                             = -1;
91
92 /* fields for Channel Indentification IE */
93 static int hf_q931_channel_interface_explicit           = -1;
94 static int hf_q931_channel_interface_type               = -1;
95 static int hf_q931_channel_exclusive                    = -1;
96 static int hf_q931_channel_dchan                        = -1;
97 static int hf_q931_channel_selection_bri                = -1;
98 static int hf_q931_channel_selection_pri                = -1;
99 static int hf_q931_channel_map                          = -1;
100 static int hf_q931_channel_element_type                 = -1;
101 static int hf_q931_channel_number                       = -1;
102
103
104 static int hf_q931_segments = -1;
105 static int hf_q931_segment = -1;
106 static int hf_q931_segment_overlap = -1;
107 static int hf_q931_segment_overlap_conflict = -1;
108 static int hf_q931_segment_multiple_tails = -1;
109 static int hf_q931_segment_too_long_segment = -1;
110 static int hf_q931_segment_error = -1;
111 static int hf_q931_reassembled_in = -1; 
112
113 static gint ett_q931                                    = -1;
114 static gint ett_q931_ie                                 = -1;
115
116 static gint ett_q931_segments = -1;
117 static gint ett_q931_segment = -1;
118
119 static const fragment_items q931_frag_items = {
120         &ett_q931_segment,
121         &ett_q931_segments,
122
123         &hf_q931_segments,
124         &hf_q931_segment,
125         &hf_q931_segment_overlap,
126         &hf_q931_segment_overlap_conflict,
127         &hf_q931_segment_multiple_tails,
128         &hf_q931_segment_too_long_segment,
129         &hf_q931_segment_error,
130         &hf_q931_reassembled_in,
131         "segments"
132 };
133
134 /* Tables for reassembly of fragments. */
135 static GHashTable *q931_fragment_table = NULL;
136 static GHashTable *q931_reassembled_table = NULL;
137
138 /* Preferences */
139 static gboolean q931_reassembly = TRUE;
140
141 static dissector_table_t codeset_dissector_table;
142 static dissector_table_t ie_dissector_table;
143
144 /* desegmentation of Q.931 over TPKT over TCP */
145 static gboolean q931_desegment = TRUE;
146
147 static dissector_handle_t h225_handle;
148 static dissector_handle_t q931_tpkt_handle;
149 static dissector_handle_t q931_tpkt_pdu_handle;
150
151 static void
152 dissect_q931_IEs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *root_tree,
153     proto_tree *q931_tree, gboolean is_tpkt, int offset, int initial_codeset);
154
155 const value_string q931_message_type_vals[] = {
156         { Q931_ESCAPE,                  "ESCAPE" },
157         { Q931_ALERTING,                "ALERTING" },
158         { Q931_CALL_PROCEEDING,         "CALL PROCEEDING" },
159         { Q931_CONNECT,                 "CONNECT" },
160         { Q931_CONNECT_ACK,             "CONNECT ACKNOWLEDGE" },
161         { Q931_PROGRESS,                "PROGRESS" },
162         { Q931_SETUP,                   "SETUP" },
163         { Q931_SETUP_ACK,               "SETUP ACKNOWLEDGE" },
164         { Q931_HOLD,                    "HOLD" },
165         { Q931_HOLD_ACK,                "HOLD_ACKNOWLEDGE" },
166         { Q931_HOLD_REJECT,             "HOLD_REJECT" },
167         { Q931_RESUME,                  "RESUME" },
168         { Q931_RESUME_ACK,              "RESUME ACKNOWLEDGE" },
169         { Q931_RESUME_REJECT,           "RESUME REJECT" },
170         { Q931_RETRIEVE,                "RETRIEVE" },
171         { Q931_RETRIEVE_ACK,            "RETRIEVE ACKNOWLEDGE" },
172         { Q931_RETRIEVE_REJECT,         "RETRIEVE REJECT" },
173         { Q931_SUSPEND,                 "SUSPEND" },
174         { Q931_SUSPEND_ACK,             "SUSPEND ACKNOWLEDGE" },
175         { Q931_SUSPEND_REJECT,          "SUSPEND REJECT" },
176         { Q931_USER_INFORMATION,        "USER INFORMATION" },
177         { Q931_DISCONNECT,              "DISCONNECT" },
178         { Q931_RELEASE,                 "RELEASE" },
179         { Q931_RELEASE_COMPLETE,        "RELEASE COMPLETE" },
180         { Q931_RESTART,                 "RESTART" },
181         { Q931_RESTART_ACK,             "RESTART ACKNOWLEDGE" },
182         { Q931_CONGESTION_CONTROL,      "CONGESTION CONTROL" },
183         { Q931_FACILITY,                "FACILITY" },
184         { Q931_INFORMATION,             "INFORMATION" },
185         { Q931_NOTIFY,                  "NOTIFY" },
186         { Q931_REGISTER,                "REGISTER" },
187         { Q931_SEGMENT,                 "SEGMENT" },
188         { Q931_STATUS,                  "STATUS" },
189         { Q931_STATUS_ENQUIRY,          "STATUS ENQUIRY" },
190         { Q931_VERSION,                 "VERSION" },
191         { Q931_GROUIP_SERVICE,          "GROUP SERVICE" },
192         { Q931_GROUIP_SERVICE_ACK,      "GROUP SERVICE ACK" },
193         { Q931_RESYNC_REQ,              "RESYNC REQ" },
194         { Q931_RESYNC_RESP,             "RESYNC RESP" },
195         { 0,                            NULL }
196 };
197
198 /*
199  * NOTE  For call reference flag (octet 2)
200  * Bit8
201  *      0 The message is sent from the side that originates the call reference
202  *      1 The message is sent to the side that originates the call reference
203  */
204 static const true_false_string tfs_call_ref_flag = {
205         "Message sent to originating side",
206         "Message sent from originating side"
207 };
208
209 static const true_false_string tfs_interface_type = {
210     "Primary rate interface",
211     "Basic rate interface"
212 };
213
214 static const true_false_string tfs_channel_exclusive = {
215         "Exclusive; only the indicated channel is acceptable",
216         "Indicated channel is preferred"
217 };
218
219 static const true_false_string tfs_channel_map = {
220         "Channel indicated by slot map",
221         "Channel indicated by number"
222 };
223
224 /*
225  * Information elements.
226  */
227
228 /* Shifted codeset values */
229 #define CS0 0x000
230 #define CS1 0x100
231 #define CS2 0x200
232 #define CS3 0x300
233 #define CS4 0x400
234 #define CS5 0x500
235 #define CS6 0x600
236 #define CS7 0x700
237
238 #define Q931_IE_SO_MASK 0x80    /* single-octet/variable-length mask */
239 /*
240  * Single-octet IEs.
241  */
242 #define Q931_IE_SO_IDENTIFIER_MASK      0xf0    /* IE identifier mask */
243 #define Q931_IE_SO_IDENTIFIER_SHIFT     4       /* IE identifier shift */
244 #define Q931_IE_SO_IE_MASK              0x0F    /* IE mask */
245
246 #define Q931_IE_SHIFT                   0x90
247 #define Q931_IE_SHIFT_NON_LOCKING       0x08    /* non-locking shift */
248 #define Q931_IE_SHIFT_CODESET           0x07    /* codeset */
249
250 #define Q931_IE_MORE_DATA_OR_SEND_COMP  0xA0    /* More Data or Sending Complete */
251 #define Q931_IE_MORE_DATA               0xA0
252 #define Q931_IE_SENDING_COMPLETE        0xA1
253
254 #define Q931_IE_CONGESTION_LEVEL        0xB0
255 #define Q931_IE_REPEAT_INDICATOR        0xD0
256
257 /*
258  * Variable-length IEs.
259  */
260 #define Q931_IE_VL_EXTENSION            0x80    /* Extension flag */
261 /*      extension bit. The bit value "0" indicates that the octet continues through the         */
262 /*      next octet. The bit value "1" indicates that this octet is the last octet               */
263
264 static const true_false_string q931_extension_ind_value = {
265   "last octet",
266   "information continues through the next octet",
267
268 };
269
270
271 /*
272  * Codeset 0 (default).
273  */
274 #define Q931_IE_SEGMENTED_MESSAGE       0x00
275 #define Q931_IE_BEARER_CAPABILITY       0x04
276 #define Q931_IE_CAUSE                   0x08
277 #define Q931_IE_CALL_IDENTITY           0x10
278 #define Q931_IE_CALL_STATE              0x14
279 #define Q931_IE_CHANNEL_IDENTIFICATION  0x18
280 #define Q931_IE_FACILITY                0x1C
281 #define Q931_IE_PROGRESS_INDICATOR      0x1E
282 #define Q931_IE_NETWORK_SPECIFIC_FACIL  0x20    /* Network Specific Facilities */
283 #define Q931_IE_NOTIFICATION_INDICATOR  0x27
284 #define Q931_IE_DISPLAY                 0x28
285 #define Q931_IE_DATE_TIME               0x29
286 #define Q931_IE_KEYPAD_FACILITY         0x2C
287 #define Q931_IE_INFORMATION_REQUEST     0x32
288 #define Q931_IE_SIGNAL                  0x34
289 #define Q931_IE_SWITCHHOOK              0x36
290 #define Q931_IE_FEATURE_ACTIVATION      0x38
291 #define Q931_IE_FEATURE_INDICATION      0x39
292 #define Q931_IE_ENDPOINT_IDENTIFIER     0x3B
293 #define Q931_IE_SERVICE_PROFILE_ID      0x3A
294 #define Q931_IE_INFORMATION_RATE        0x40
295 #define Q931_IE_E2E_TRANSIT_DELAY       0x42    /* End-to-end Transit Delay */
296 #define Q931_IE_TD_SELECTION_AND_INT    0x43    /* Transit Delay Selection and Indication */
297 #define Q931_IE_PL_BINARY_PARAMETERS    0x44    /* Packet layer binary parameters */
298 #define Q931_IE_PL_WINDOW_SIZE          0x45    /* Packet layer window size */
299 #define Q931_IE_PACKET_SIZE             0x46    /* Packet size */
300 #define Q931_IE_CUG                     0x47    /* Closed user group */
301 #define Q931_IE_REVERSE_CHARGE_IND      0x4A    /* Reverse charging indication */
302 #define Q931_IE_CONNECTED_NUMBER_DEFAULT        0x4C    /* Connected Number */
303 #define Q931_IE_INTERFACE_SERVICE       0x66    /* q931+ Interface Service */
304 #define Q931_IE_CHANNEL_STATUS          0x67    /* q931+ Channel Status */
305 #define Q931_IE_VERSION_INFO            0x68    /* q931+ Version Info */
306 #define Q931_IE_CALLING_PARTY_NUMBER    0x6C    /* Calling Party Number */
307 #define Q931_IE_CALLING_PARTY_SUBADDR   0x6D    /* Calling Party Subaddress */
308 #define Q931_IE_CALLED_PARTY_NUMBER     0x70    /* Called Party Number */
309 #define Q931_IE_CALLED_PARTY_SUBADDR    0x71    /* Called Party Subaddress */
310 #define Q931_IE_REDIRECTING_NUMBER      0x74
311 #define Q931_IE_REDIRECTION_NUMBER      0x76
312 #define Q931_IE_TRANSIT_NETWORK_SEL     0x78    /* Transit Network Selection */
313 #define Q931_IE_RESTART_INDICATOR       0x79
314 #define Q931_IE_LOW_LAYER_COMPAT        0x7C    /* Low-Layer Compatibility */
315 #define Q931_IE_HIGH_LAYER_COMPAT       0x7D    /* High-Layer Compatibility */
316 #define Q931_IE_USER_USER               0x7E    /* User-User */
317 #define Q931_IE_ESCAPE                  0x7F    /* Escape for extension */
318
319 /*
320  * Codeset 0 ETSI.
321  */
322 #define Q931_IE_CONNECTED_NUMBER        0x8C
323 #define Q931_IE_CONNECTED_SUBADDR       0x8D
324
325 /*
326  * Codeset 5 (National-specific) Belgium.
327  */
328 #define Q931_IE_CHARGING_ADVICE         0x1A
329
330 /*
331  * Codeset 5 (National-specific) Bellcore National ISDN.
332  */
333 #define Q931_IE_OPERATOR_SYSTEM_ACCESS  0x1D
334
335 /*
336  * Codeset 6 (Network-specific) Belgium.
337  */
338 /* 0x1A is Charging Advice, as with Codeset 5 */
339 #define Q931_IE_REDIRECTING_NUMBER      0x74
340
341 /*
342  * Codeset 6 (Network-specific) FT-Numeris.
343  */
344 /* 0x1D is User Capability */
345
346 /*
347  * Codeset 6 (Network-specific) Bellcore National ISDN.
348  */
349 #define Q931_IE_REDIRECTING_SUBADDR     0x75    /* Redirecting Subaddress */
350 /* 0x76 is Redirection Number, but that's also Codeset 0 */
351 #define Q931_IE_CALL_APPEARANCE         0x7B
352
353 /* Codeset 0 */
354 static const value_string q931_info_element_vals0[] = {
355         { Q931_IE_SEGMENTED_MESSAGE,            "Segmented message" },
356         { Q931_IE_BEARER_CAPABILITY,            "Bearer capability" },
357         { Q931_IE_CAUSE,                        "Cause" },
358         { Q931_IE_CALL_IDENTITY,                "Call identity" },
359         { Q931_IE_CALL_STATE,                   "Call state" },
360         { Q931_IE_CHANNEL_IDENTIFICATION,       "Channel identification" },
361         { Q931_IE_FACILITY,                     "Facility" },
362         { Q931_IE_PROGRESS_INDICATOR,           "Progress indicator" },
363         { Q931_IE_NETWORK_SPECIFIC_FACIL,       "Network specific facilities" },
364         { Q931_IE_NOTIFICATION_INDICATOR,       "Notification indicator" },
365         { Q931_IE_DISPLAY,                      "Display" },
366         { Q931_IE_DATE_TIME,                    "Date/Time" },
367         { Q931_IE_KEYPAD_FACILITY,              "Keypad facility" },
368         { Q931_IE_INFORMATION_REQUEST,          "Information request" },
369         { Q931_IE_SIGNAL,                       "Signal" },
370         { Q931_IE_SWITCHHOOK,                   "Switchhook" },
371         { Q931_IE_FEATURE_ACTIVATION,           "Feature activation" },
372         { Q931_IE_FEATURE_INDICATION,           "Feature Indication" },
373         { Q931_IE_ENDPOINT_IDENTIFIER,          "Endpoint identifier" },
374         { Q931_IE_SERVICE_PROFILE_ID,           "Service profile ID" },
375         { Q931_IE_INFORMATION_RATE,             "Information rate" },
376         { Q931_IE_E2E_TRANSIT_DELAY,            "End-to-end transit delay" },
377         { Q931_IE_TD_SELECTION_AND_INT,         "Transit delay selection and indication" },
378         { Q931_IE_PL_BINARY_PARAMETERS,         "Packet layer binary parameters" },
379         { Q931_IE_PL_WINDOW_SIZE,               "Packet layer window size" },
380         { Q931_IE_PACKET_SIZE,                  "Packet size" },
381         { Q931_IE_CUG,                          "Closed user group" },
382         { Q931_IE_REVERSE_CHARGE_IND,           "Reverse charging indication" },
383         { Q931_IE_CONNECTED_NUMBER_DEFAULT,     "Connected number" },
384         { Q931_IE_INTERFACE_SERVICE,            "Interface Service" },
385         { Q931_IE_CHANNEL_STATUS,               "Channel Status" },
386         { Q931_IE_VERSION_INFO,                 "Version Info" },
387         { Q931_IE_CALLING_PARTY_NUMBER,         "Calling party number" },
388         { Q931_IE_CALLING_PARTY_SUBADDR,        "Calling party subaddress" },
389         { Q931_IE_CALLED_PARTY_NUMBER,          "Called party number" },
390         { Q931_IE_CALLED_PARTY_SUBADDR,         "Called party subaddress" },
391         { Q931_IE_REDIRECTING_NUMBER,           "Redirecting number" },
392         { Q931_IE_REDIRECTION_NUMBER,           "Redirection number" },
393         { Q931_IE_TRANSIT_NETWORK_SEL,          "Transit network selection" },
394         { Q931_IE_RESTART_INDICATOR,            "Restart indicator" },
395         { Q931_IE_LOW_LAYER_COMPAT,             "Low-layer compatibility" },
396         { Q931_IE_HIGH_LAYER_COMPAT,            "High-layer compatibility" },
397         { Q931_IE_USER_USER,                    "User-user" },
398         { Q931_IE_ESCAPE,                       "Escape" },
399         { Q931_IE_CONNECTED_NUMBER,             "Connected number" },
400         { Q931_IE_CONNECTED_SUBADDR,            "Connected subaddress" },
401         { 0,                                    NULL }
402 };
403 /* Codeset 1 */
404 static const value_string q931_info_element_vals1[] = {
405         { 0,                                    NULL }
406 };
407 /* Codeset 2 */
408 static const value_string q931_info_element_vals2[] = {
409         { 0,                                    NULL }
410 };
411 /* Codeset 3 */
412 static const value_string q931_info_element_vals3[] = {
413         { 0,                                    NULL }
414 };
415 /* Codeset 4 */
416 static const value_string q931_info_element_vals4[] = {
417         { 0,                                    NULL }
418 };
419 /* Codeset 5 */
420 static const value_string q931_info_element_vals5[] = {
421         { Q931_IE_CHARGING_ADVICE,              "Charging advice" },
422         { Q931_IE_OPERATOR_SYSTEM_ACCESS,       "Operator system access" },
423         { 0,                                    NULL }
424 };
425 /* Codeset 6 */
426 static const value_string q931_info_element_vals6[] = {
427         { Q931_IE_REDIRECTING_NUMBER,           "Redirecting number" },
428         { Q931_IE_REDIRECTING_SUBADDR,          "Redirecting subaddress" },
429         { Q931_IE_CALL_APPEARANCE,              "Call appearance" },
430         { Q931_IE_DISPLAY,                      "Avaya Display" }, /* if Avaya codeset to send display = 6 */
431         { 0,                                    NULL }
432 };
433 /* Codeset 7 */
434 static const value_string q931_info_element_vals7[] = {
435         { 0,                                    NULL }
436 };
437
438 /* Codeset array */
439 #define NUM_INFO_ELEMENT_VALS   (Q931_IE_SHIFT_CODESET+1)
440 static const value_string *q931_info_element_vals[NUM_INFO_ELEMENT_VALS] = {
441   q931_info_element_vals0,
442   q931_info_element_vals1,
443   q931_info_element_vals2,
444   q931_info_element_vals3,
445   q931_info_element_vals4,
446   q931_info_element_vals5,
447   q931_info_element_vals6,
448   q931_info_element_vals7,
449 };
450
451 static const value_string q931_congestion_level_vals[] = {
452         { 0x0, "Receiver ready" },
453         { 0xF, "Receiver not ready" },
454         { 0,   NULL }
455 };
456
457 static const value_string q931_repeat_indication_vals[] = {
458         { 0x2, "Prioritized list" },
459         { 0,   NULL }
460 };
461
462 /*
463  * ITU-standardized coding.
464  */
465 #define Q931_ITU_STANDARDIZED_CODING    0x00
466
467 /*
468  * Dissect a Segmented message information element.
469  */
470 static void
471 dissect_q931_segmented_message_ie(tvbuff_t *tvb, int offset, int len,
472     proto_tree *tree)
473 {
474         if (len != 2) {
475                 proto_tree_add_text(tree, tvb, offset, len,
476                     "Segmented message: length is %d, should be 2", len);
477                 return;
478         }
479         if (tvb_get_guint8(tvb, offset) & 0x80) {
480                 proto_tree_add_text(tree, tvb, offset, 1,
481                     "First segment: %u segments remaining",
482                     tvb_get_guint8(tvb, offset) & 0x7F);
483         } else {
484                 proto_tree_add_text(tree, tvb, offset, 1,
485                     "Not first segment: %u segments remaining",
486                     tvb_get_guint8(tvb, offset) & 0x7F);
487         }
488         proto_tree_add_item(tree, hf_q931_segment_type, tvb, offset + 1, 1, FALSE);
489 }
490
491 /*
492  * Dissect a Bearer capability or Low-layer compatibility information element.
493  */
494 static const value_string q931_coding_standard_vals[] = {
495         { 0x0, "ITU-T standardized coding" },
496         { 0x1, "ISO/IEC standard" },
497         { 0x2, "National standard" },
498         { 0x3, "Standard defined for this particular network" },
499         { 0,    NULL }
500 };
501
502 static const value_string q931_information_transfer_capability_vals[] = {
503         { 0x00, "Speech" },
504         { 0x08, "Unrestricted digital information" },
505         { 0x09, "Restricted digital information" },
506         { 0x10, "3.1 kHz audio" },
507         { 0x11, "Unrestricted digital information with tones/announcements" },
508         { 0x18, "Video" },
509         { 0,    NULL }
510 };
511
512 static const value_string q931_transfer_mode_vals[] = {
513         { 0x00, "Circuit mode" },
514         { 0x02, "Packet mode" },
515         { 0,    NULL }
516 };
517
518 #define Q931_IT_RATE_MULTIRATE  0x18
519
520 static const value_string q931_information_transfer_rate_vals[] = {
521         { 0x00,                         "Packet mode" },
522         { 0x10,                         "64 kbit/s" },
523         { 0x11,                         "2 x 64 kbit/s" },
524         { 0x13,                         "384 kbit/s" },
525         { 0x15,                         "1536 kbit/s" },
526         { 0x17,                         "1920 kbit/s" },
527         { Q931_IT_RATE_MULTIRATE,       "Multirate (64 kbit/s base rate)" },
528         { 0,                            NULL }
529 };
530
531 static const value_string q931_uil1_vals[] = {
532         { 0x01, "V.110/I.460/X.30 rate adaption" },
533         { 0x02, "Recommendation G.711 u-law" },
534         { 0x03, "Recommendation G.711 A-law" },
535         { 0x04, "Recommendation G.721 32 kbit/s ADPCM and Recommendation I.460" },
536         { 0x05, "Recommendation H.221 and H.242" },
537         { 0x06, "Recommendation H.223 and H.245" },
538         { 0x07, "Non-ITU-T-standardized rate adaption" },
539         { 0x08, "V.120 rate adaption" },
540         { 0x09, "X.31 HDLC flag stuffing" },
541         { 0,    NULL }
542 };
543
544 static const value_string q931_l1_user_rate_vals[] = {
545         { 0x00, "Rate indicated by E-bits" },
546         { 0x01, "0.6 kbit/s" },
547         { 0x02, "1.2 kbit/s" },
548         { 0x03, "2.4 kbit/s" },
549         { 0x04, "3.6 kbit/s" },
550         { 0x05, "4.8 kbit/s" },
551         { 0x06, "7.2 kbit/s" },
552         { 0x07, "8 kbit/s" },
553         { 0x08, "9.6 kbit/s" },
554         { 0x09, "14.4 kbit/s" },
555         { 0x0A, "16 kbit/s" },
556         { 0x0B, "19.2 kbit/s" },
557         { 0x0C, "32 kbit/s" },
558         { 0x0E, "48 kbit/s" },
559         { 0x0F, "56 kbit/s" },
560         { 0x10, "64 kbit/s "},
561         { 0x15, "0.1345 kbit/s" },
562         { 0x16, "0.100 kbit/s" },
563         { 0x17, "0.075/1.2 kbit/s" },
564         { 0x18, "1.2/0.075 kbit/s" },
565         { 0x19, "0.050 kbit/s" },
566         { 0x1A, "0.075 kbit/s" },
567         { 0x1B, "0.110 kbit/s" },
568         { 0x1C, "0.150 kbit/s" },
569         { 0x1D, "0.200 kbit/s" },
570         { 0x1E, "0.300 kbit/s" },
571         { 0x1F, "12 kbit/s" },
572         { 0,    NULL }
573 };
574
575 static const value_string q931_l1_intermediate_rate_vals[] = {
576         { 0x20, "8 kbit/s" },
577         { 0x40, "16 kbit/s" },
578         { 0x60, "32 kbit/s" },
579         { 0,    NULL }
580 };
581
582 static const value_string q931_l1_stop_bits_vals[] = {
583         { 0x20, "1" },
584         { 0x40, "1.5" },
585         { 0x60, "2" },
586         { 0,    NULL }
587 };
588
589 static const value_string q931_l1_data_bits_vals[] = {
590         { 0x08, "5" },
591         { 0x10, "7" },
592         { 0x18, "8" },
593         { 0,    NULL }
594 };
595
596 static const value_string q931_l1_parity_vals[] = {
597         { 0x00, "Odd" },
598         { 0x02, "Even" },
599         { 0x03, "None" },
600         { 0x04, "Forced to 0" },
601         { 0x05, "Forced to 1" },
602         { 0,    NULL }
603 };
604
605 static const value_string q931_l1_modem_type_vals[] = {
606         { 0x11, "V.21" },
607         { 0x12, "V.22" },
608         { 0x13, "V.22 bis" },
609         { 0x14, "V.23" },
610         { 0x15, "V.26" },
611         { 0x16, "V.26 bis" },
612         { 0x17, "V.26 ter" },
613         { 0x18, "V.27" },
614         { 0x19, "V.27 bis" },
615         { 0x1A, "V.27 ter" },
616         { 0x1B, "V.29" },
617         { 0x1C, "V.32" },
618         { 0x1E, "V.34" },
619         { 0,    NULL }
620 };
621
622 #define Q931_UIL2_USER_SPEC     0x10
623
624 static const value_string q931_uil2_vals[] = {
625         { 0x01,                 "Basic mode ISO 1745" },
626         { 0x02,                 "Q.921/I.441" },        /* LAPD */
627         { 0x06,                 "X.25, link layer" },   /* LAPB */
628         { 0x07,                 "X.25 multilink" },     /* or 0x0F? */
629         { 0x08,                 "T.71 Extended LAPB" },
630         { 0x09,                 "HDLC ARM" },
631         { 0x0A,                 "HDLC NRM" },
632         { 0x0B,                 "HDLC ABM" },
633         { 0x0C,                 "ISO 8802/2 LLC" },
634         { 0x0D,                 "X.75 Single Link Procedure" },
635         { 0x0E,                 "Q.922" },
636         { 0x0F,                 "Core aspects of Q.922" },
637         { Q931_UIL2_USER_SPEC,  "User-specified" },
638         { 0x11,                 "ISO 7776 DTE-DTE operation" },
639         { 0,                    NULL }
640 };
641
642 static const value_string q931_mode_vals[] = {
643         { 0x20, "Normal mode" },
644         { 0x40, "Extended mode" },
645         { 0,    NULL }
646 };
647
648 #define Q931_UIL3_X25_PL        0x06
649 #define Q931_UIL3_ISO_8208      0x07    /* X.25-based */
650 #define Q931_UIL3_X223          0x08    /* X.25-based */
651 #define Q931_UIL3_TR_9577       0x0B
652 #define Q931_UIL3_USER_SPEC     0x10
653
654 static const value_string q931_uil3_vals[] = {
655         { 0x02,                 "Q.931/I.451" },
656         { Q931_UIL3_X25_PL,     "X.25, packet layer" },
657         { Q931_UIL3_ISO_8208,   "ISO/IEC 8208" },
658         { Q931_UIL3_X223,       "X.223/ISO 8878" },
659         { 0x09,                 "ISO/IEC 8473" },
660         { 0x0A,                 "T.70" },
661         { Q931_UIL3_TR_9577,    "ISO/IEC TR 9577" },
662         { Q931_UIL3_USER_SPEC,  "User-specified" },
663         { 0,                    NULL }
664 };
665
666 static void
667 dissect_q931_protocol_discriminator(tvbuff_t *tvb, int offset, proto_tree *tree)
668 {
669         unsigned int discriminator = tvb_get_guint8(tvb, offset);
670
671         if (discriminator == NLPID_Q_931) {
672                 proto_tree_add_uint_format(tree, hf_q931_discriminator,
673                          tvb, offset, 1, discriminator,
674                          "Protocol discriminator: Q.931");
675         } else if (discriminator == NLPID_Q_2931) {
676                 proto_tree_add_uint_format(tree, hf_q931_discriminator,
677                          tvb, offset, 1, discriminator,
678                          "Protocol discriminator: Q.2931");
679         } else if ((discriminator >= 16 && discriminator < 63)
680             || ((discriminator >= 80) && (discriminator < 254))) {
681                 proto_tree_add_uint_format(tree, hf_q931_discriminator,
682                     tvb, offset, 1, discriminator,
683                     "Protocol discriminator: Network layer or layer 3 protocol (0x%02X)",
684                     discriminator);
685         } else if (discriminator >= 64 && discriminator <= 79) {
686                 proto_tree_add_uint_format(tree, hf_q931_discriminator,
687                     tvb, offset, 1, discriminator,
688                     "Protocol discriminator: National use (0x%02X)",
689                     discriminator);
690         } else {
691                 proto_tree_add_uint_format(tree, hf_q931_discriminator,
692                     tvb, offset, 1, discriminator,
693                     "Protocol discriminator: Reserved (0x%02X)",
694                     discriminator);
695         }
696 }
697
698 void
699 dissect_q931_bearer_capability_ie(tvbuff_t *tvb, int offset, int len,
700     proto_tree *tree)
701 {
702         guint8 octet;
703         guint8 coding_standard;
704         guint8 it_rate;
705         guint8 modem_type;
706         guint8 uil2_protocol;
707         guint8 uil3_protocol;
708         guint8 add_l3_info;
709
710         if (len == 0)
711                 return;
712         octet = tvb_get_guint8(tvb, offset);
713         coding_standard = octet & 0x60;
714         if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
715                 /*
716                  * We don't know how the bearer capability is encoded,
717                  * so just dump it as data and be done with it.
718                  */
719                 proto_tree_add_text(tree, tvb, offset,
720                     len, "Data: %s",
721                     tvb_bytes_to_str(tvb, offset, len));
722                 proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
723                 proto_tree_add_uint(tree, hf_q931_coding_standard, tvb, offset, 1, octet);
724                 return;
725         }
726         proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
727         proto_tree_add_uint(tree, hf_q931_coding_standard, tvb, offset, 1, octet);
728         proto_tree_add_uint(tree, hf_q931_information_transfer_capability, tvb, offset, 1, octet);
729         offset += 1;
730         len -= 1;
731
732         /*
733          * XXX - only in Low-layer compatibility information element.
734          */
735         if (!(octet & Q931_IE_VL_EXTENSION)) {
736                 if (len == 0)
737                         return;
738                 octet = tvb_get_guint8(tvb, offset);
739                 proto_tree_add_text(tree, tvb, offset, 1,
740                     "Out-band negotiation %spossible",
741                     (octet & 0x40) ? "" : "not ");
742                 offset += 1;
743                 len -= 1;
744         }
745
746         if (len == 0)
747                 return;
748         octet = tvb_get_guint8(tvb, offset);
749         proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
750         proto_tree_add_uint(tree, hf_q931_transfer_mode, tvb, offset, 1, octet);
751         proto_tree_add_uint(tree, hf_q931_information_transfer_rate, tvb, offset, 1, octet);
752         it_rate = octet & 0x1F;
753         offset += 1;
754         len -= 1;
755
756         if (it_rate == Q931_IT_RATE_MULTIRATE) {
757                 if (len == 0)
758                         return;
759                 proto_tree_add_text(tree, tvb, offset, 1, "Rate multiplier: %u", tvb_get_guint8(tvb, offset));
760                 offset += 1;
761                 len -= 1;
762         }
763
764         if (len == 0)
765                 return;
766         octet = tvb_get_guint8(tvb, offset);
767         if ((octet & 0x60) == 0x20) {
768                 /*
769                  * Layer 1 information.
770                  */
771                 proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
772                 proto_tree_add_uint(tree, hf_q931_uil1, tvb, offset, 1, octet);
773                 offset += 1;
774                 len -= 1;
775
776                 if (octet & Q931_IE_VL_EXTENSION)
777                         goto l1_done;
778                 if (len == 0)
779                         return;
780                 octet = tvb_get_guint8(tvb, offset);
781                 proto_tree_add_text(tree, tvb, offset, 1,
782                     "Layer 1 is %s",
783                     (octet & 0x40) ? "Asynchronous" : "Synchronous");
784                 proto_tree_add_text(tree, tvb, offset, 1,
785                     "Layer 1 in-band negotiation is %spossible",
786                     (octet & 0x20) ? "" : "not ");
787                 proto_tree_add_text(tree, tvb, offset, 1,
788                     "User rate: %s",
789                     val_to_str(octet & 0x1F, q931_l1_user_rate_vals,
790                       "Unknown (0x%02X)"));
791                 offset += 1;
792                 len -= 1;
793
794                 if (octet & Q931_IE_VL_EXTENSION)
795                         goto l1_done;
796                 if (len == 0)
797                         return;
798                 octet = tvb_get_guint8(tvb, offset);
799                 proto_tree_add_text(tree, tvb, offset, 1,
800                     "Intermediate rate: %s",
801                       val_to_str(octet & 0x60, q931_l1_intermediate_rate_vals,
802                        "Unknown (0x%X)"));
803                 proto_tree_add_text(tree, tvb, offset, 1,
804                     "%s to send data with network independent clock",
805                     (octet & 0x10) ? "Required" : "Not required");
806                 proto_tree_add_text(tree, tvb, offset, 1,
807                     "%s accept data with network independent clock",
808                     (octet & 0x08) ? "Can" : "Cannot");
809                 proto_tree_add_text(tree, tvb, offset, 1,
810                     "%s to send data with flow control mechanism",
811                     (octet & 0x04) ? "Required" : "Not required");
812                 proto_tree_add_text(tree, tvb, offset, 1,
813                     "%s accept data with flow control mechanism",
814                     (octet & 0x02) ? "Can" : "Cannot");
815                 offset += 1;
816                 len -= 1;
817
818                 if (octet & Q931_IE_VL_EXTENSION)
819                         goto l1_done;
820                 if (len == 0)
821                         return;
822                 octet = tvb_get_guint8(tvb, offset);
823                 proto_tree_add_text(tree, tvb, offset, 1,
824                     "Rate adaption header %sincluded",
825                     (octet & 0x40) ? "" : "not ");
826                 proto_tree_add_text(tree, tvb, offset, 1,
827                     "Multiple frame establishment %ssupported",
828                     (octet & 0x20) ? "" : "not ");
829                 proto_tree_add_text(tree, tvb, offset, 1,
830                     "%s mode of operation",
831                     (octet & 0x10) ? "Protocol sensitive" : "Bit transparent");
832                 proto_tree_add_text(tree, tvb, offset, 1,
833                     (octet & 0x08) ?
834                       "Full protocol negotiation" : "LLI = 256 only");
835                 proto_tree_add_text(tree, tvb, offset, 1,
836                     "Message originator is %s",
837                     (octet & 0x04) ? "Assignor only" : "Default assignee");
838                 proto_tree_add_text(tree, tvb, offset, 1,
839                     "Negotiation is done %s",
840                     (octet & 0x02) ? "in-band" : "out-of-band");
841                 offset += 1;
842                 len -= 1;
843
844                 if (octet & Q931_IE_VL_EXTENSION)
845                         goto l1_done;
846                 if (len == 0)
847                         return;
848                 octet = tvb_get_guint8(tvb, offset);
849                 proto_tree_add_text(tree, tvb, offset, 1,
850                     "Stop bits: %s",
851                       val_to_str(octet & 0x60, q931_l1_stop_bits_vals,
852                        "Unknown (0x%X)"));
853                 proto_tree_add_text(tree, tvb, offset, 1,
854                     "Data bits: %s",
855                       val_to_str(octet & 0x18, q931_l1_data_bits_vals,
856                        "Unknown (0x%X)"));
857                 proto_tree_add_text(tree, tvb, offset, 1,
858                     "Parity: %s",
859                       val_to_str(octet & 0x07, q931_l1_parity_vals,
860                        "Unknown (0x%X)"));
861
862                 if (octet & Q931_IE_VL_EXTENSION)
863                         goto l1_done;
864                 if (len == 0)
865                         return;
866                 octet = tvb_get_guint8(tvb, offset);
867                 proto_tree_add_text(tree, tvb, offset, 1,
868                     "%s duplex",
869                     (octet & 0x40) ? "Full" : "Half");
870                 modem_type = octet & 0x3F;
871                 if (modem_type <= 0x5 ||
872                     (modem_type >= 0x20 && modem_type <= 0x2F)) {
873                         proto_tree_add_text(tree, tvb, offset, 1,
874                             "Modem type: National use 0x%02X", modem_type);
875                 } else if (modem_type >= 0x30) {
876                         proto_tree_add_text(tree, tvb, offset, 1,
877                             "Modem type: User specified 0x%02X", modem_type);
878                 } else {
879                         proto_tree_add_text(tree, tvb, offset, 1,
880                             "Modem type: %s",
881                               val_to_str(modem_type, q931_l1_modem_type_vals,
882                               "Unknown (0x%02X)"));
883                 }
884                 offset += 1;
885                 len -= 1;
886         }
887 l1_done:
888         ;
889
890         if (len == 0)
891                 return;
892         octet = tvb_get_guint8(tvb, offset);
893         if ((octet & 0x60) == 0x40) {
894                 /*
895                  * Layer 2 information.
896                  */
897                 uil2_protocol = octet & 0x1F;
898                 proto_tree_add_text(tree, tvb, offset, 1,
899                     "User information layer 2 protocol: %s",
900                     val_to_str(uil2_protocol, q931_uil2_vals,
901                       "Unknown (0x%02X)"));
902                 offset += 1;
903                 len -= 1;
904
905                 /*
906                  * XXX - only in Low-layer compatibility information element.
907                  */
908                 if (octet & Q931_IE_VL_EXTENSION)
909                         goto l2_done;
910                 if (len == 0)
911                         return;
912                 octet = tvb_get_guint8(tvb, offset);
913                 if (uil2_protocol == Q931_UIL2_USER_SPEC) {
914                         proto_tree_add_text(tree, tvb, offset, 1,
915                             "User-specified layer 2 protocol information: 0x%02X",
916                             octet & 0x7F);
917                 } else {
918                         proto_tree_add_text(tree, tvb, offset, 1,
919                             "Mode: %s",
920                             val_to_str(octet & 0x60, q931_mode_vals,
921                               "Unknown (0x%02X)"));
922                 }
923                 offset += 1;
924                 len -= 1;
925
926                 if (octet & Q931_IE_VL_EXTENSION)
927                         goto l2_done;
928                 if (len == 0)
929                         return;
930                 octet = tvb_get_guint8(tvb, offset);
931                 proto_tree_add_text(tree, tvb, offset, 1,
932                     "Window size: %u k", octet & 0x7F);
933                 offset += 1;
934                 len -= 1;
935         }
936 l2_done:
937         ;
938
939         if (len == 0)
940                 return;
941         octet = tvb_get_guint8(tvb, offset);
942         if ((octet & 0x60) == 0x60) {
943                 /*
944                  * Layer 3 information.
945                  */
946                 uil3_protocol = octet & 0x1F;
947                 proto_tree_add_text(tree, tvb, offset, 1,
948                     "User information layer 3 protocol: %s",
949                     val_to_str(uil3_protocol, q931_uil3_vals,
950                       "Unknown (0x%02X)"));
951                 offset += 1;
952                 len -= 1;
953
954
955                 /*
956                  * XXX - only in Low-layer compatibility information element.
957                  */
958                 if (octet & Q931_IE_VL_EXTENSION)
959                         goto l3_done;
960                 if (len == 0)
961                         return;
962                 octet = tvb_get_guint8(tvb, offset);
963                 switch (uil3_protocol) {
964
965                 case Q931_UIL3_X25_PL:
966                 case Q931_UIL3_ISO_8208:
967                 case Q931_UIL3_X223:
968                         proto_tree_add_text(tree, tvb, offset, 1,
969                             "Mode: %s",
970                             val_to_str(octet & 0x60, q931_mode_vals,
971                               "Unknown (0x%02X)"));
972                         offset += 1;
973                         len -= 1;
974
975                         if (octet & Q931_IE_VL_EXTENSION)
976                                 goto l3_done;
977                         if (len == 0)
978                                 return;
979                         octet = tvb_get_guint8(tvb, offset);
980                         proto_tree_add_text(tree, tvb, offset, 1,
981                             "Default packet size: %u", octet & 0x0F);
982                         offset += 1;
983                         len -= 1;
984
985                         if (octet & Q931_IE_VL_EXTENSION)
986                                 goto l3_done;
987                         if (len == 0)
988                                 return;
989                         octet = tvb_get_guint8(tvb, offset);
990                         proto_tree_add_text(tree, tvb, offset, 1,
991                             "Packet window size: %u", octet & 0x7F);
992                         offset += 1;
993                         len -= 1;
994                         break;
995
996                 case Q931_UIL3_USER_SPEC:
997                         proto_tree_add_text(tree, tvb, offset, 1,
998                             "Default packet size: %u octets",
999                             1 << (octet & 0x0F));
1000                         offset += 1;
1001                         len -= 1;
1002                         break;
1003
1004                 case Q931_UIL3_TR_9577:
1005                         add_l3_info = (octet & 0x0F) << 4;
1006                         if (octet & Q931_IE_VL_EXTENSION)
1007                                 goto l3_done;
1008                         if (len == 0)
1009                                 return;
1010                         octet = tvb_get_guint8(tvb, offset + 1);
1011                         add_l3_info |= (octet & 0x0F);
1012                         proto_tree_add_text(tree, tvb, offset, 2,
1013                             "Additional layer 3 protocol information: %s",
1014                             val_to_str(add_l3_info, nlpid_vals,
1015                               "Unknown (0x%02X)"));
1016                         offset += 2;
1017                         len -= 2;
1018                         break;
1019                 }
1020         }
1021 l3_done:
1022         ;
1023 }
1024
1025 /*
1026  * Dissect a Cause information element.
1027  */
1028
1029
1030 const value_string q931_cause_location_vals[] = {
1031         { 0x00, "User (U)" },
1032         { 0x01, "Private network serving the local user (LPN)" },
1033         { 0x02, "Public network serving the local user (LN)" },
1034         { 0x03, "Transit network (TN)" },
1035         { 0x04, "Public network serving the remote user (RLN)" },
1036         { 0x05, "Private network serving the remote user (RPN)" },
1037         { 0x07, "International network (INTL)" },
1038         { 0x0A, "Network beyond interworking point (BI)" },
1039         { 0,    NULL }
1040 };
1041
1042 static const value_string q931_cause_recommendation_vals[] = {
1043         { 0x00, "Q.931" },
1044         { 0x03, "X.21" },
1045         { 0x04, "X.25" },
1046         { 0x05, "Q.1031/Q.1051" },
1047         { 0,    NULL }
1048 };
1049
1050 /*
1051  * Cause codes for Cause.
1052  */
1053 #define Q931_CAUSE_UNALLOC_NUMBER       0x01
1054 #define Q931_CAUSE_NO_ROUTE_TO_DEST     0x03
1055 #define Q931_CAUSE_CALL_REJECTED        0x15
1056 #define Q931_CAUSE_NUMBER_CHANGED       0x16
1057 #define Q931_CAUSE_ACCESS_INFO_DISC     0x2B
1058 #define Q931_CAUSE_QOS_UNAVAILABLE      0x31
1059 #define Q931_CAUSE_CHAN_NONEXISTENT     0x52
1060 #define Q931_CAUSE_INCOMPATIBLE_DEST    0x58
1061 #define Q931_CAUSE_MAND_IE_MISSING      0x60
1062 #define Q931_CAUSE_MT_NONEX_OR_UNIMPL   0x61
1063 #define Q931_CAUSE_IE_NONEX_OR_UNIMPL   0x63
1064 #define Q931_CAUSE_INVALID_IE_CONTENTS  0x64
1065 #define Q931_CAUSE_MSG_INCOMPAT_W_CS    0x65
1066 #define Q931_CAUSE_REC_TIMER_EXP        0x66
1067
1068 const value_string q931_cause_code_vals[] = {
1069         { 0x00,                         "Valid cause code not yet received" },
1070         { Q931_CAUSE_UNALLOC_NUMBER,    "Unallocated (unassigned) number" },
1071         { 0x02,                         "No route to specified transit network" },
1072         { Q931_CAUSE_NO_ROUTE_TO_DEST,  "No route to destination" },
1073         { 0x04,                         "Send special information tone" },
1074         { 0x05,                         "Misdialled trunk prefix" },
1075         { 0x06,                         "Channel unacceptable" },
1076         { 0x07,                         "Call awarded and being delivered in an established channel" },
1077         { 0x08,                         "Prefix 0 dialed but not allowed" },
1078                                         /* Q.850 - "Preemption" */
1079         { 0x09,                         "Prefix 1 dialed but not allowed" },
1080                                         /* Q.850 - "Preemption - circuit reserved for reuse" */
1081         { 0x0A,                         "Prefix 1 dialed but not required" },
1082         { 0x0B,                         "More digits received than allowed, call is proceeding" },
1083         { 0x0E,                         "QoR: ported number" },
1084         { 0x10,                         "Normal call clearing" },
1085         { 0x11,                         "User busy" },
1086         { 0x12,                         "No user responding" },
1087         { 0x13,                         "No answer from user (user alerted)" },
1088         { 0x14,                         "Subscriber absent" },
1089         { Q931_CAUSE_CALL_REJECTED,     "Call rejected" },
1090         { Q931_CAUSE_NUMBER_CHANGED,    "Number changed" },
1091         { 0x17,                         "Reverse charging rejected" },
1092                                         /* Q.850 - "Redirection to new destination" */
1093         { 0x18,                         "Call suspended" },
1094                                         /* Q.850 Amendment 1 - "Call rejected due to feature at the destination" */
1095         { 0x19,                         "Call resumed" },
1096                                         /* Q.850 - "Exchange routing error */
1097         { 0x1A,                         "Non-selected user clearing" },
1098         { 0x1B,                         "Destination out of order" },
1099         { 0x1C,                         "Invalid number format (incomplete number)" },
1100         { 0x1D,                         "Facility rejected" },
1101         { 0x1E,                         "Response to STATUS ENQUIRY" },
1102         { 0x1F,                         "Normal unspecified" },
1103         { 0x21,                         "Circuit out of order" },
1104         { 0x22,                         "No circuit/channel available" },
1105         { 0x23,                         "Destination unattainable" },
1106         { 0x25,                         "Degraded service" },
1107         { 0x26,                         "Network out of order" },
1108         { 0x27,                         "Transit delay range cannot be achieved" },
1109                                         /* Q.850 - "Permanent frame mode connection out of service" */
1110         { 0x28,                         "Throughput range cannot be achieved" },
1111                                         /* Q.850 - "Permanent frame mode connection operational" */
1112         { 0x29,                         "Temporary failure" },
1113         { 0x2A,                         "Switching equipment congestion" },
1114         { Q931_CAUSE_ACCESS_INFO_DISC,  "Access information discarded" },
1115         { 0x2C,                         "Requested circuit/channel not available" },
1116         { 0x2D,                         "Pre-empted" },
1117         { 0x2E,                         "Precedence call blocked" },
1118         { 0x2F,                         "Resources unavailable, unspecified" },
1119         { Q931_CAUSE_QOS_UNAVAILABLE,   "Quality of service unavailable" },
1120         { 0x32,                         "Requested facility not subscribed" },
1121         { 0x33,                         "Reverse charging not allowed" },
1122         { 0x34,                         "Outgoing calls barred" },
1123         { 0x35,                         "Outgoing calls barred within CUG" },
1124         { 0x36,                         "Incoming calls barred" },
1125         { 0x37,                         "Incoming calls barred within CUG" },
1126         { 0x38,                         "Call waiting not subscribed" },
1127         { 0x39,                         "Bearer capability not authorized" },
1128         { 0x3A,                         "Bearer capability not presently available" },
1129         { 0x3E,                         "Inconsistency in designated outgoing access information and subscriber class" },
1130         { 0x3F,                         "Service or option not available, unspecified" },
1131         { 0x41,                         "Bearer capability not implemented" },
1132         { 0x42,                         "Channel type not implemented" },
1133         { 0x43,                         "Transit network selection not implemented" },
1134         { 0x44,                         "Message not implemented" },
1135         { 0x45,                         "Requested facility not implemented" },
1136         { 0x46,                         "Only restricted digital information bearer capability is available" },
1137         { 0x4F,                         "Service or option not implemented, unspecified" },
1138         { 0x51,                         "Invalid call reference value" },
1139         { Q931_CAUSE_CHAN_NONEXISTENT,  "Identified channel does not exist" },
1140         { 0x53,                         "Call identity does not exist for suspended call" },
1141         { 0x54,                         "Call identity in use" },
1142         { 0x55,                         "No call suspended" },
1143         { 0x56,                         "Call having the requested call identity has been cleared" },
1144         { 0x57,                         "Called user not member of CUG" },
1145         { Q931_CAUSE_INCOMPATIBLE_DEST, "Incompatible destination" },
1146         { 0x59,                         "Non-existent abbreviated address entry" },
1147         { 0x5A,                         "Destination address missing, and direct call not subscribed" },
1148                                         /* Q.850 - "Non-existent CUG" */
1149         { 0x5B,                         "Invalid transit network selection (national use)" },
1150         { 0x5C,                         "Invalid facility parameter" },
1151         { 0x5D,                         "Mandatory information element is missing" },
1152         { 0x5F,                         "Invalid message, unspecified" },
1153         { Q931_CAUSE_MAND_IE_MISSING,   "Mandatory information element is missing" },
1154         { Q931_CAUSE_MT_NONEX_OR_UNIMPL,"Message type non-existent or not implemented" },
1155         { 0x62,                         "Message not compatible with call state or message type non-existent or not implemented" },
1156         { Q931_CAUSE_IE_NONEX_OR_UNIMPL,"Information element nonexistant or not implemented" },
1157         { Q931_CAUSE_INVALID_IE_CONTENTS,"Invalid information element contents" },
1158         { Q931_CAUSE_MSG_INCOMPAT_W_CS, "Message not compatible with call state" },
1159         { Q931_CAUSE_REC_TIMER_EXP,     "Recovery on timer expiry" },
1160         { 0x67,                         "Parameter non-existent or not implemented - passed on" },
1161         { 0x6E,                         "Message with unrecognized parameter discarded" },
1162         { 0x6F,                         "Protocol error, unspecified" },
1163         { 0x7F,                         "Internetworking, unspecified" },
1164         { 0,                            NULL }
1165 };
1166
1167 static const value_string q931_cause_condition_vals[] = {
1168         { 0x00, "Unknown" },
1169         { 0x01, "Permanent" },
1170         { 0x02, "Transient" },
1171         { 0x00, NULL }
1172 };
1173
1174 #define Q931_REJ_USER_SPECIFIC          0x00
1175 #define Q931_REJ_IE_MISSING             0x04
1176 #define Q931_REJ_IE_INSUFFICIENT        0x08
1177
1178 static const value_string q931_rejection_reason_vals[] = {
1179         { 0x00, "User specific" },
1180         { 0x04, "Information element missing" },
1181         { 0x08, "Information element contents are not sufficient" },
1182         { 0x00, NULL }
1183 };
1184
1185 void
1186 dissect_q931_cause_ie(tvbuff_t *tvb, int offset, int len,
1187     proto_tree *tree, int hf_cause_value, guint8 *cause_value)
1188 {
1189         guint8 octet;
1190         guint8 coding_standard;
1191         guint8 rejection_reason;
1192
1193         if (len == 0)
1194                 return;
1195         octet = tvb_get_guint8(tvb, offset);
1196         coding_standard = octet & 0x60;
1197         if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
1198                 /*
1199                  * We don't know how the cause is encoded,
1200                  * so just dump it as data and be done with it.
1201                  */
1202                 proto_tree_add_uint(tree, hf_q931_coding_standard, tvb, offset, 1, octet);
1203                 proto_tree_add_text(tree, tvb, offset,
1204                     len, "Data: %s",
1205                     tvb_bytes_to_str(tvb, offset, len));
1206                 return;
1207         }
1208         proto_tree_add_uint(tree, hf_q931_cause_location, tvb, offset, 1, octet);
1209         proto_tree_add_uint(tree, hf_q931_coding_standard, tvb, offset, 1, octet);
1210         proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
1211         offset += 1;
1212         len -= 1;
1213
1214         if (!(octet & Q931_IE_VL_EXTENSION)) {
1215                 if (len == 0)
1216                         return;
1217                 octet = tvb_get_guint8(tvb, offset);
1218                 proto_tree_add_text(tree, tvb, offset, 1,
1219                     "Recommendation: %s",
1220                     val_to_str(octet & 0x7F, q931_cause_recommendation_vals,
1221                       "Unknown (0x%02X)"));
1222                 proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
1223                 offset += 1;
1224                 len -= 1;
1225         }
1226
1227         if (len == 0)
1228                 return;
1229         octet = tvb_get_guint8(tvb, offset);
1230         *cause_value = octet & 0x7F;
1231
1232         /* add cause value to packet info for use in tap */
1233         if(have_valid_q931_pi) {
1234                 q931_pi->cause_value = *cause_value;
1235         }
1236
1237         proto_tree_add_uint(tree, hf_cause_value, tvb, offset, 1, *cause_value);
1238         proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
1239         offset += 1;
1240         len -= 1;
1241
1242         if (len == 0)
1243                 return;
1244         switch (*cause_value) {
1245
1246         case Q931_CAUSE_UNALLOC_NUMBER:
1247         case Q931_CAUSE_NO_ROUTE_TO_DEST:
1248         case Q931_CAUSE_QOS_UNAVAILABLE:
1249                 octet = tvb_get_guint8(tvb, offset);
1250                 proto_tree_add_text(tree, tvb, offset, 1,
1251                     "Network service: %s",
1252                     (octet & 0x80) ? "User" : "Provider");
1253                 proto_tree_add_text(tree, tvb, offset, 1,
1254                     "%s",
1255                     (octet & 0x40) ? "Abnormal" : "Normal");
1256                 proto_tree_add_text(tree, tvb, offset, 1,
1257                     "Condition: %s",
1258                     val_to_str(octet & 0x03, q931_cause_condition_vals,
1259                       "Unknown (0x%X)"));
1260                 break;
1261
1262         case Q931_CAUSE_CALL_REJECTED:
1263                 rejection_reason = octet & 0x7C;
1264                 proto_tree_add_text(tree, tvb, offset, 1,
1265                     "Rejection reason: %s",
1266                     val_to_str(octet & 0x7C, q931_rejection_reason_vals,
1267                       "Unknown (0x%X)"));
1268                 proto_tree_add_text(tree, tvb, offset, 1,
1269                     "Condition: %s",
1270                     val_to_str(octet & 0x03, q931_cause_condition_vals,
1271                       "Unknown (0x%X)"));
1272                 offset += 1;
1273                 len -= 1;
1274
1275                 if (len == 0)
1276                         return;
1277                 switch (rejection_reason) {
1278
1279                 case Q931_REJ_USER_SPECIFIC:
1280                         proto_tree_add_text(tree, tvb, offset, len,
1281                             "User specific diagnostic: %s",
1282                             tvb_bytes_to_str(tvb, offset, len));
1283                         break;
1284
1285                 case Q931_REJ_IE_MISSING:
1286                         proto_tree_add_text(tree, tvb, offset, 1,
1287                             "Missing information element: %s",
1288                             val_to_str(tvb_get_guint8(tvb, offset), q931_info_element_vals0,
1289                               "Unknown (0x%02X)"));
1290                         break;
1291
1292                 case Q931_REJ_IE_INSUFFICIENT:
1293                         proto_tree_add_text(tree, tvb, offset, 1,
1294                             "Insufficient information element: %s",
1295                             val_to_str(tvb_get_guint8(tvb, offset), q931_info_element_vals0,
1296                               "Unknown (0x%02X)"));
1297                         break;
1298
1299                 default:
1300                         proto_tree_add_text(tree, tvb, offset, len,
1301                             "Diagnostic: %s",
1302                             tvb_bytes_to_str(tvb, offset, len));
1303                         break;
1304                 }
1305                 break;
1306
1307         case Q931_CAUSE_ACCESS_INFO_DISC:
1308         case Q931_CAUSE_INCOMPATIBLE_DEST:
1309         case Q931_CAUSE_MAND_IE_MISSING:
1310         case Q931_CAUSE_IE_NONEX_OR_UNIMPL:
1311         case Q931_CAUSE_INVALID_IE_CONTENTS:
1312                 do {
1313                         proto_tree_add_text(tree, tvb, offset, 1,
1314                             "Information element: %s",
1315                             val_to_str(tvb_get_guint8(tvb, offset), q931_info_element_vals0,
1316                               "Unknown (0x%02X)"));
1317                         offset += 1;
1318                         len -= 1;
1319                 } while (len != 0);
1320                 break;
1321
1322         case Q931_CAUSE_MT_NONEX_OR_UNIMPL:
1323         case Q931_CAUSE_MSG_INCOMPAT_W_CS:
1324                 proto_tree_add_text(tree, tvb, offset, 1,
1325                     "Message type: %s",
1326                     val_to_str(tvb_get_guint8(tvb, offset), q931_message_type_vals,
1327                       "Unknown (0x%02X)"));
1328                 break;
1329
1330         case Q931_CAUSE_REC_TIMER_EXP:
1331                 if (len < 3)
1332                         return;
1333                 proto_tree_add_text(tree, tvb, offset, 3,
1334                     "Timer: %.3s", tvb_get_ptr(tvb, offset, 3));
1335                 break;
1336
1337         default:
1338                 proto_tree_add_text(tree, tvb, offset, len,
1339                     "Diagnostics: %s",
1340                     tvb_bytes_to_str(tvb, offset, len));
1341         }
1342 }
1343
1344 /*
1345  * Dissect a Call state information element.
1346  */
1347 static const value_string q931_call_state_vals[] = {
1348         { 0x00, "Null" },
1349         { 0x01, "Call initiated" },
1350         { 0x02, "Overlap sending" },
1351         { 0x03, "Outgoing call proceeding" },
1352         { 0x04, "Call delivered" },
1353         { 0x06, "Call present" },
1354         { 0x07, "Call received" },
1355         { 0x08, "Connect request" },
1356         { 0x09, "Incoming call proceeding" },
1357         { 0x0A, "Active" },
1358         { 0x0B, "Disconnect request" },
1359         { 0x0C, "Disconnect indication" },
1360         { 0x0F, "Suspend request" },
1361         { 0x12, "Resume request" },
1362         { 0x13, "Release request" },
1363         { 0x16, "Call abort"},
1364         { 0x19, "Overlap receiving" },
1365         { 0x3D, "Restart request" },
1366         { 0x3E, "Restart" },
1367         { 0,    NULL }
1368 };
1369
1370 static void
1371 dissect_q931_call_state_ie(tvbuff_t *tvb, int offset, int len,
1372     proto_tree *tree)
1373 {
1374         guint8 octet;
1375         guint8 coding_standard;
1376
1377         if (len == 0)
1378                 return;
1379         octet = tvb_get_guint8(tvb, offset);
1380         coding_standard = octet & 0x60;
1381         proto_tree_add_uint(tree, hf_q931_coding_standard, tvb, offset, 1, octet);
1382         if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
1383                 /*
1384                  * We don't know how the call state is encoded,
1385                  * so just dump it as data and be done with it.
1386                  */
1387                 proto_tree_add_text(tree, tvb, offset,
1388                     len, "Data: %s",
1389                     tvb_bytes_to_str(tvb, offset, len));
1390                 return;
1391         }
1392         proto_tree_add_text(tree, tvb, offset, 1,
1393             "Call state: %s",
1394             val_to_str(octet & 0x3F, q931_call_state_vals,
1395               "Unknown (0x%02X)"));
1396 }
1397
1398 /*
1399  * Dissect a Channel identification information element.
1400  */
1401 #define Q931_INTERFACE_IDENTIFIED       0x40
1402 #define Q931_NOT_BASIC_CHANNEL          0x20
1403
1404 static const value_string q931_basic_channel_selection_vals[] = {
1405         { 0x00, "No channel" },
1406         { 0x01, "B1 channel" },
1407         { 0x02, "B2 channel" },
1408         { 0x03, "Any channel" },
1409         { 0,    NULL }
1410 };
1411
1412 static const value_string q931_not_basic_channel_selection_vals[] = {
1413         { 0x00, "No channel" },
1414         { 0x01, "Channel indicated in following octets" },
1415         { 0x03, "Any channel" },
1416         { 0,    NULL }
1417 };
1418
1419 #define Q931_IS_SLOT_MAP                0x10
1420
1421 static const value_string q931_element_type_vals[] = {
1422         { 0x03, "B-channel units" },
1423         { 0x06, "H0-channel units" },
1424         { 0x08, "H11-channel units" },
1425         { 0x09, "H12-channel units" },
1426         { 0,    NULL }
1427 };
1428
1429 static void
1430 dissect_q931_channel_identification_ie(tvbuff_t *tvb, int offset, int len,
1431     proto_tree *tree)
1432 {
1433         guint8 octet;
1434         guint8 coding_standard;
1435
1436         if (len == 0)
1437                 return;
1438         octet = tvb_get_guint8(tvb, offset);
1439
1440         proto_tree_add_item(tree, hf_q931_extension_ind, tvb, offset, 1, FALSE);
1441         proto_tree_add_item(tree, hf_q931_channel_interface_explicit, tvb, offset, 1, FALSE);
1442         proto_tree_add_item(tree, hf_q931_channel_interface_type, tvb, offset, 1, FALSE);
1443         proto_tree_add_item(tree, hf_q931_channel_exclusive, tvb, offset, 1, FALSE);
1444         proto_tree_add_item(tree, hf_q931_channel_dchan, tvb, offset, 1, FALSE);
1445         
1446         if (octet & Q931_NOT_BASIC_CHANNEL) {
1447                 proto_tree_add_item(tree, hf_q931_channel_selection_pri, tvb, offset, 1, FALSE);
1448         } else {
1449                 proto_tree_add_item(tree, hf_q931_channel_selection_bri, tvb, offset, 1, FALSE);
1450         }
1451         offset += 1;
1452         len -= 1;
1453
1454         if (octet & Q931_INTERFACE_IDENTIFIED) {
1455                 guint8 octet;
1456                 int identifier_offset = offset;
1457                 int identifier_len = 0;
1458                 do {
1459                         if (len == 0)
1460                                 break;
1461                         octet = tvb_get_guint8(tvb, offset);
1462                         offset += 1;
1463                         len -= 1;
1464                         identifier_len++;
1465                 } while (!(octet & Q931_IE_VL_EXTENSION));
1466
1467                 /*
1468                  * XXX - do we want to strip off the 8th bit on the
1469                  * last octet of the interface identifier?
1470                  */
1471                 if (identifier_len != 0) {
1472                         proto_tree_add_text(tree, tvb, identifier_offset,
1473                             identifier_len, "Interface identifier: %s",
1474                             bytes_to_str(
1475                               tvb_get_ptr(tvb, identifier_offset, identifier_len),
1476                               identifier_len));
1477                 }
1478         }
1479
1480         if (octet & Q931_NOT_BASIC_CHANNEL) {
1481                 if (len == 0)
1482                         return;
1483                 octet = tvb_get_guint8(tvb, offset);
1484                 coding_standard = octet & 0x60;
1485                 proto_tree_add_item(tree, hf_q931_extension_ind, tvb, offset, 1, FALSE);
1486                 proto_tree_add_uint(tree, hf_q931_coding_standard, tvb, offset, 1, octet);
1487                 if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
1488                         /*
1489                          * We don't know how the channel identifier is
1490                          * encoded, so just dump it as data and be done
1491                          * with it.
1492                          */
1493                         proto_tree_add_text(tree, tvb, offset,
1494                             len, "Data: %s",
1495                             tvb_bytes_to_str(tvb, offset, len));
1496                         return;
1497                 }
1498                 proto_tree_add_item(tree, hf_q931_channel_map, tvb, offset, 1, FALSE);
1499                 proto_tree_add_item(tree, hf_q931_channel_element_type, tvb, offset, 1, FALSE);
1500                 
1501                 offset += 1;
1502                 len -= 1;
1503
1504                 if (octet & Q931_IS_SLOT_MAP) {
1505                         guint8 octet;
1506                         while (len) {
1507                                 octet = tvb_get_guint8(tvb, offset);
1508                                 proto_tree_add_text(tree, tvb, offset, 1,
1509                                         "Slot map: 0x%02x", octet);
1510                                 offset += 1;
1511                                 len -= 1;
1512                         } 
1513                 } else {
1514                         guint8 octet;
1515                         do {
1516                                 if (len == 0)
1517                                         break;
1518                                 octet = tvb_get_guint8(tvb, offset);
1519
1520                                 proto_tree_add_item(tree, hf_q931_extension_ind, tvb, offset, 1, FALSE);
1521                                 proto_tree_add_item(tree,hf_q931_channel_number,tvb,offset,1,FALSE);
1522
1523                                 offset += 1;
1524                                 len -= 1;
1525                         } while (!(octet & Q931_IE_VL_EXTENSION));
1526                 }
1527         }
1528 }
1529
1530 /*
1531  * Dissect a Progress indicator information element.
1532  */
1533 static const value_string q931_progress_description_vals[] = {
1534         { 0x01, "Call is not end-to-end ISDN - progress information available in-band" },
1535         { 0x02, "Destination address is non-ISDN" },
1536         { 0x03, "Origination address is non-ISDN" },
1537         { 0x04, "Call has returned to the ISDN" },
1538         { 0x05, "Interworking has occurred and has resulted in a telecommunications service change" },
1539         { 0x08, "In-band information or an appropriate pattern is now available" },
1540         { 0,    NULL }
1541 };
1542
1543 void
1544 dissect_q931_progress_indicator_ie(tvbuff_t *tvb, int offset, int len,
1545     proto_tree *tree)
1546 {
1547         guint8 octet;
1548         guint8 coding_standard;
1549
1550         if (len == 0)
1551                 return;
1552         octet = tvb_get_guint8(tvb, offset);
1553         coding_standard = octet & 0x60;
1554         proto_tree_add_uint(tree, hf_q931_coding_standard, tvb, offset, 1, octet);
1555         if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
1556                 /*
1557                  * We don't know how the progress indicator is encoded,
1558                  * so just dump it as data and be done with it.
1559                  */
1560                 proto_tree_add_text(tree, tvb, offset,
1561                     len, "Data: %s",
1562                     tvb_bytes_to_str(tvb, offset, len));
1563                 return;
1564         }
1565         proto_tree_add_text(tree, tvb, offset, 1,
1566             "Location: %s",
1567             val_to_str(octet & 0x0F, q931_cause_location_vals,
1568               "Unknown (0x%X)"));
1569         offset += 1;
1570         len -= 1;
1571
1572         if (len == 0)
1573                 return;
1574         octet = tvb_get_guint8(tvb, offset);
1575         proto_tree_add_text(tree, tvb, offset, 1,
1576             "Progress description: %s",
1577             val_to_str(octet & 0x7F, q931_progress_description_vals,
1578               "Unknown (0x%02X)"));
1579 }
1580
1581 /*
1582  * Dissect a Network-specific facilities or Transit network selection
1583  * information element.
1584  */
1585 static const value_string q931_netid_type_vals[] = {
1586         { 0x00, "User specified" },
1587         { 0x20, "National network identification" },
1588         { 0x30, "International network identification" },
1589         { 0,    NULL }
1590 };
1591
1592 static const value_string q931_netid_plan_vals[] = {
1593         { 0x00, "Unknown" },
1594         { 0x01, "Carrier Identification Code" },
1595         { 0x03, "X.121 data network identification code" },
1596         { 0,    NULL }
1597 };
1598
1599 static void
1600 dissect_q931_ns_facilities_ie(tvbuff_t *tvb, int offset, int len,
1601     proto_tree *tree)
1602 {
1603         guint8 octet;
1604         int netid_len;
1605
1606         if (len == 0)
1607                 return;
1608         octet = tvb_get_guint8(tvb, offset);
1609         netid_len = octet & 0x7F;
1610         proto_tree_add_text(tree, tvb, offset, 1,
1611             "Network identification length: %u",
1612             netid_len);
1613         offset += 1;
1614         len -= 1;
1615         if (netid_len != 0) {
1616                 if (len == 0)
1617                         return;
1618                 octet = tvb_get_guint8(tvb, offset);
1619                 proto_tree_add_text(tree, tvb, offset, 1,
1620                     "Type of network identification: %s",
1621                     val_to_str(octet & 0x70, q931_netid_type_vals,
1622                       "Unknown (0x%02X)"));
1623                 proto_tree_add_text(tree, tvb, offset, 1,
1624                     "Network identification plan: %s",
1625                     val_to_str(octet & 0x0F, q931_netid_plan_vals,
1626                       "Unknown (0x%02X)"));
1627                 offset += 1;
1628                 len -= 1;
1629                 netid_len--;
1630
1631                 if (len == 0)
1632                         return;
1633                 if (netid_len > len)
1634                         netid_len = len;
1635                 if (netid_len != 0) {
1636                         proto_tree_add_text(tree, tvb, offset, netid_len,
1637                             "Network identification: %s",
1638                             tvb_format_text(tvb, offset, netid_len));
1639                         offset += netid_len;
1640                         len -= netid_len;
1641                 }
1642         }
1643
1644         /*
1645          * Whatever is left is the network-specific facility
1646          * specification.
1647          */
1648          if (len == 0)
1649                 return;
1650         proto_tree_add_text(tree, tvb, offset,
1651             len, "Network-specific facility specification: %s",
1652             tvb_bytes_to_str(tvb, offset, len));
1653 }
1654
1655 /*
1656  * Dissect a Notification indicator information element.
1657  */
1658 static const value_string q931_notification_description_vals[] = {
1659         { 0x00, "User suspended" },
1660         { 0x01, "User resumed" },
1661         { 0x02, "Bearer service change" },
1662         { 0,    NULL }
1663 };
1664
1665 static void
1666 dissect_q931_notification_indicator_ie(tvbuff_t *tvb, int offset, int len,
1667     proto_tree *tree)
1668 {
1669         guint8 octet;
1670
1671         if (len == 0)
1672                 return;
1673         octet = tvb_get_guint8(tvb, offset);
1674         proto_tree_add_text(tree, tvb, offset, 1,
1675             "Notification description: %s",
1676             val_to_str(octet & 0x7F, q931_notification_description_vals,
1677               "Unknown (0x%02X)"));
1678 }
1679
1680 /*
1681  * Dissect a Date/time information element.
1682  */
1683 static void
1684 dissect_q931_date_time_ie(tvbuff_t *tvb, int offset, int len,
1685     proto_tree *tree)
1686 {
1687         if (len == 6) {
1688                 /*
1689                  * XXX - what is "year" relative to?  Is "month" 0-origin or
1690                  * 1-origin?  Q.931 doesn't say....
1691                  */
1692                 proto_tree_add_text(tree, tvb, offset, 6,
1693                     "Date/time: %02u-%02u-%02u %02u:%02u:%02u",
1694                     tvb_get_guint8(tvb, offset + 0), tvb_get_guint8(tvb, offset + 1), tvb_get_guint8(tvb, offset + 2),
1695                     tvb_get_guint8(tvb, offset + 3), tvb_get_guint8(tvb, offset + 4), tvb_get_guint8(tvb, offset + 5));
1696         } else if (len == 5) {
1697                 proto_tree_add_text(tree, tvb, offset, 5,
1698                     "Date/time: %02u-%02u-%02u %02u:%02u:00",
1699                     tvb_get_guint8(tvb, offset + 0), tvb_get_guint8(tvb, offset + 1), tvb_get_guint8(tvb, offset + 2),
1700                     tvb_get_guint8(tvb, offset + 3), tvb_get_guint8(tvb, offset + 4));
1701         } else {
1702                 proto_tree_add_text(tree, tvb, offset, len,
1703                     "Date/time: length is %d, should be 5 or 6", len);
1704         }
1705 }
1706
1707 /*
1708  * Dissect a Signal information element.
1709  */
1710 static const value_string q931_signal_vals[] = {
1711         { 0x00, "Dial tone on" },
1712         { 0x01, "Ring tone on" },
1713         { 0x02, "Intercept tone on" },
1714         { 0x03, "Network congestion tone on" }, /* "fast busy" */
1715         { 0x04, "Busy tone on" },
1716         { 0x05, "Confirm tone on" },
1717         { 0x06, "Answer tone on" },
1718         { 0x07, "Call waiting tone on" },
1719         { 0x08, "Off-hook warning tone on" },
1720         { 0x09, "Preemption tone on" },
1721         { 0x3F, "Tones off" },
1722         { 0x40, "Alerting on - pattern 0" },
1723         { 0x41, "Alerting on - pattern 1" },
1724         { 0x42, "Alerting on - pattern 2" },
1725         { 0x43, "Alerting on - pattern 3" },
1726         { 0x44, "Alerting on - pattern 4" },
1727         { 0x45, "Alerting on - pattern 5" },
1728         { 0x46, "Alerting on - pattern 6" },
1729         { 0x47, "Alerting on - pattern 7" },
1730         { 0x4F, "Alerting off" },
1731         { 0,    NULL }
1732 };
1733
1734 static void
1735 dissect_q931_signal_ie(tvbuff_t *tvb, int offset, int len,
1736     proto_tree *tree)
1737 {
1738         if (len != 1) {
1739                 proto_tree_add_text(tree, tvb, offset, len,
1740                     "Signal: length is %d, should be 1", len);
1741                 return;
1742         }
1743         proto_tree_add_text(tree, tvb, offset, 1,
1744             "Signal: %s",
1745             val_to_str(tvb_get_guint8(tvb, offset), q931_signal_vals,
1746                 "Unknown (0x%02X)"));
1747 }
1748
1749 /*
1750  * Dissect an Information rate information element.
1751  */
1752 static const value_string q931_throughput_class_vals[] = {
1753         { 0x03, "75 bit/s" },
1754         { 0x04, "150 bit/s" },
1755         { 0x05, "300 bit/s" },
1756         { 0x06, "600 bit/s" },
1757         { 0x07, "1200 bit/s" },
1758         { 0x08, "2400 bit/s" },
1759         { 0x09, "4800 bit/s" },
1760         { 0x0A, "9600 bit/s" },
1761         { 0x0B, "19200 bit/s" },
1762         { 0x0C, "48000 bit/s" },
1763         { 0x0D, "64000 bit/s" },
1764         { 0,    NULL }
1765 };
1766
1767 static void
1768 dissect_q931_information_rate_ie(tvbuff_t *tvb, int offset, int len,
1769     proto_tree *tree)
1770 {
1771         if (len != 4) {
1772                 proto_tree_add_text(tree, tvb, offset, len,
1773                     "Information rate: length is %d, should be 4", len);
1774                 return;
1775         }
1776         proto_tree_add_text(tree, tvb, offset + 0, 1,
1777             "Incoming information rate: %s",
1778             val_to_str(tvb_get_guint8(tvb, offset + 0) & 0x1F,
1779               q931_throughput_class_vals, "Unknown (0x%02X)"));
1780         proto_tree_add_text(tree, tvb, offset + 1, 1,
1781             "Outgoing information rate: %s",
1782             val_to_str(tvb_get_guint8(tvb, offset + 1) & 0x1F,
1783               q931_throughput_class_vals, "Unknown (0x%02X)"));
1784         proto_tree_add_text(tree, tvb, offset + 2, 1,
1785             "Minimum incoming information rate: %s",
1786             val_to_str(tvb_get_guint8(tvb, offset + 2) & 0x1F,
1787               q931_throughput_class_vals, "Unknown (0x%02X)"));
1788         proto_tree_add_text(tree, tvb, offset + 3, 1,
1789             "Minimum outgoing information rate: %s",
1790             val_to_str(tvb_get_guint8(tvb, offset + 3) & 0x1F,
1791               q931_throughput_class_vals, "Unknown (0x%02X)"));
1792 }
1793
1794 static int
1795 dissect_q931_guint16_value(tvbuff_t *tvb, int offset, int len,
1796     proto_tree *tree, const char *label)
1797 {
1798         guint8 octet;
1799         guint16 value;
1800         int value_len;
1801
1802         value_len = 0;
1803
1804         octet = tvb_get_guint8(tvb, offset);
1805         if (octet & Q931_IE_VL_EXTENSION) {
1806                 /*
1807                  * Only one octet long - error.
1808                  */
1809                 goto bad_length;
1810         }
1811         value = (octet & 0x3) << 14;
1812         offset += 1;
1813         len -= 1;
1814         value_len++;
1815
1816         if (len == 0) {
1817                 /*
1818                  * We've reached the end of the information element - error.
1819                  */
1820                 goto past_end;
1821         }
1822         octet = tvb_get_guint8(tvb, offset);
1823         if (octet & Q931_IE_VL_EXTENSION) {
1824                 /*
1825                  * Only two octets long - error.
1826                  */
1827                 goto bad_length;
1828         }
1829         value |= (octet & 0x7F) << 7;
1830         offset += 1;
1831         len -= 1;
1832         value_len++;
1833
1834         if (len == 0) {
1835                 /*
1836                  * We've reached the end of the information element - error.
1837                  */
1838                 goto past_end;
1839         }
1840         octet = tvb_get_guint8(tvb, offset);
1841         if (!(octet & Q931_IE_VL_EXTENSION)) {
1842                 /*
1843                  * More than three octets long - error.
1844                  */
1845                 goto bad_length;
1846         }
1847         value |= (octet & 0x7F);
1848         offset += 1;
1849         len -= 1;
1850         value_len++;
1851
1852         proto_tree_add_text(tree, tvb, offset, value_len, "%s: %u ms", label,
1853             value);
1854         return value_len;
1855
1856 past_end:
1857         proto_tree_add_text(tree, tvb, offset, len,
1858             "%s goes past end of information element", label);
1859         return -1;
1860
1861 bad_length:
1862         proto_tree_add_text(tree, tvb, offset, len, "%s isn't 3 octets long",
1863             label);
1864         return -1;
1865 }
1866
1867 /*
1868  * Dissect an End-to-end transit delay information element.
1869  */
1870 static void
1871 dissect_q931_e2e_transit_delay_ie(tvbuff_t *tvb, int offset, int len,
1872     proto_tree *tree)
1873 {
1874         int value_len;
1875
1876         if (len == 0)
1877                 return;
1878         value_len = dissect_q931_guint16_value(tvb, offset, len, tree,
1879             "Cumulative transit delay");
1880         if (value_len < 0)
1881                 return; /* error */
1882         offset += value_len;
1883         len -= value_len;
1884
1885         if (len == 0)
1886                 return;
1887         value_len = dissect_q931_guint16_value(tvb, offset, len, tree,
1888             "Requested end-to-end transit delay");
1889         if (value_len < 0)
1890                 return; /* error */
1891         offset += value_len;
1892         len -= value_len;
1893
1894         if (len == 0)
1895                 return;
1896         value_len = dissect_q931_guint16_value(tvb, offset, len, tree,
1897             "Maximum end-to-end transit delay");
1898 }
1899
1900 /*
1901  * Dissect a Transit delay selection and indication information element.
1902  */
1903 static void
1904 dissect_q931_td_selection_and_int_ie(tvbuff_t *tvb, int offset, int len,
1905     proto_tree *tree)
1906 {
1907         if (len == 0)
1908                 return;
1909         dissect_q931_guint16_value(tvb, offset, len, tree,
1910             "Transit delay");
1911 }
1912
1913 /*
1914  * Dissect a Packet layer binary parameters information element.
1915  */
1916 static const value_string q931_fast_selected_vals[] = {
1917         { 0x00, "Fast select not requested" },
1918         { 0x08, "Fast select not requested" },
1919         { 0x10, "Fast select requested with no restriction of response" },
1920         { 0x18, "Fast select requested with restrictions of response" },
1921         { 0x00, NULL }
1922 };
1923
1924 static void
1925 dissect_q931_pl_binary_parameters_ie(tvbuff_t *tvb, int offset, int len,
1926     proto_tree *tree)
1927 {
1928         guint8 octet;
1929
1930         if (len == 0)
1931                 return;
1932         octet = tvb_get_guint8(tvb, offset);
1933         proto_tree_add_text(tree, tvb, offset, 1,
1934             "Fast select: %s",
1935             val_to_str(octet & 0x18, q931_fast_selected_vals, "Unknown (0x%02X)"));
1936         proto_tree_add_text(tree, tvb, offset, 1,
1937             "%s",
1938             (octet & 0x04) ? "No request/request denied" :
1939                              "Request indicated/request accepted");
1940         proto_tree_add_text(tree, tvb, offset, 1,
1941             "%s confirmation",
1942             (octet & 0x02) ? "Link-by-link" : "End-to-end");
1943         proto_tree_add_text(tree, tvb, offset, 1,
1944             "Modulus %u sequencing",
1945             (octet & 0x01) ? 8 : 128);
1946 }
1947
1948 /*
1949  * Dissect a Packet layer window size information element.
1950  */
1951 static void
1952 dissect_q931_pl_window_size_ie(tvbuff_t *tvb, int offset, int len,
1953     proto_tree *tree)
1954 {
1955         if (len == 0)
1956                 return;
1957         proto_tree_add_text(tree, tvb, offset, 1,
1958             "Forward value: %u", tvb_get_guint8(tvb, offset) & 0x7F);
1959         offset += 1;
1960         len -= 1;
1961
1962         if (len == 0)
1963                 return;
1964         proto_tree_add_text(tree, tvb, offset, 1,
1965             "Backward value: %u", tvb_get_guint8(tvb, offset) & 0x7F);
1966 }
1967
1968 /*
1969  * Dissect a Packet size information element.
1970  */
1971 static void
1972 dissect_q931_packet_size_ie(tvbuff_t *tvb, int offset, int len,
1973     proto_tree *tree)
1974 {
1975         if (len == 0)
1976                 return;
1977         proto_tree_add_text(tree, tvb, offset, 1,
1978             "Forward value: %u", tvb_get_guint8(tvb, offset) & 0x7F);
1979         offset += 1;
1980         len -= 1;
1981
1982         if (len == 0)
1983                 return;
1984         proto_tree_add_text(tree, tvb, offset, 1,
1985             "Backward value: %u", tvb_get_guint8(tvb, offset) & 0x7F);
1986 }
1987
1988 /*
1989  * Dissect a Closed user group information element.
1990  */
1991 static const value_string q931_cug_indication_vals[] = {
1992         { 0x01, "Closed user group selection" },
1993         { 0x02, "Closed user group with outgoing access selection and indication" },
1994         { 0,    NULL }
1995 };
1996
1997 static void
1998 dissect_q931_cug_ie(tvbuff_t *tvb, int offset, int len, proto_tree *tree)
1999 {
2000         if (len == 0)
2001                 return;
2002         proto_tree_add_text(tree, tvb, offset, 1,
2003             "CUG indication: %s",
2004             val_to_str(tvb_get_guint8(tvb, offset) & 0x07,
2005               q931_cug_indication_vals, "Unknown (0x%02X)"));
2006         offset += 1;
2007         len -= 1;
2008
2009         if (len == 0)
2010                 return;
2011         proto_tree_add_text(tree, tvb, offset, len, "CUG index code: %s",
2012             tvb_format_text(tvb, offset, len));
2013 }
2014
2015 /*
2016  * Dissect a Reverse charging indication information element.
2017  */
2018 static const value_string q931_reverse_charging_indication_vals[] = {
2019         { 0x01, "Reverse charging requested" },
2020         { 0,    NULL }
2021 };
2022
2023 static void
2024 dissect_q931_reverse_charge_ind_ie(tvbuff_t *tvb, int offset, int len,
2025     proto_tree *tree)
2026 {
2027         if (len == 0)
2028                 return;
2029         proto_tree_add_text(tree, tvb, offset, 1,
2030             "Reverse charging indication: %s",
2031             val_to_str(tvb_get_guint8(tvb, offset) & 0x07,
2032               q931_reverse_charging_indication_vals, "Unknown (0x%02X)"));
2033 }
2034
2035 /*
2036  * Dissect a (phone) number information element.
2037  */
2038 static const value_string q931_number_type_vals[] = {
2039         { 0x0, "Unknown" },
2040         { 0x1, "International number" },
2041         { 0x2, "National number" },
2042         { 0x3, "Network specific number" },
2043         { 0x4, "Subscriber number" },
2044         { 0x6, "Abbreviated number" },
2045         { 0,    NULL }
2046 };
2047
2048 static const value_string q931_numbering_plan_vals[] = {
2049         { 0x00, "Unknown" },
2050         { 0x01, "E.164 ISDN/telephony numbering" },
2051         { 0x03, "X.121 data numbering" },
2052         { 0x04, "F.69 Telex numbering" },
2053         { 0x08, "National standard numbering" },
2054         { 0x09, "Private numbering" },
2055         { 0,    NULL }
2056 };
2057
2058 static const value_string q931_presentation_indicator_vals[] = {
2059         { 0x00, "Presentation allowed" },
2060         { 0x01, "Presentation restricted" },
2061         { 0x02, "Number not available due to interworking" },
2062         { 0,    NULL }
2063 };
2064
2065 static const value_string q931_screening_indicator_vals[] = {
2066         { 0x00, "User-provided, not screened" },
2067         { 0x01, "User-provided, verified and passed" },
2068         { 0x02, "User-provided, verified and failed" },
2069         { 0x03, "Network-provided" },
2070         { 0,    NULL }
2071 };
2072
2073 static const value_string q931_redirection_reason_vals[] = {
2074         { 0x00, "Unknown" },
2075         { 0x01, "Call forwarding busy or called DTE busy" },
2076         { 0x02, "Call forwarding no reply" },
2077         { 0x04, "Call deflection" },
2078         { 0x09, "Called DTE out of order" },
2079         { 0x0A, "Call forwarding by the called DTE" },
2080         { 0x0F, "Call forwarding unconditional or systematic call redirection" },
2081         { 0,    NULL }
2082 };
2083
2084 static void
2085 dissect_q931_number_ie(tvbuff_t *tvb, int offset, int len,
2086     proto_tree *tree, int hfindex, e164_info_t e164_info)
2087 {
2088         guint8 octet;
2089         gint number_plan;
2090
2091         if (len == 0)
2092                 return;
2093         octet = tvb_get_guint8(tvb, offset);
2094         number_plan = octet & 0x0f;
2095         e164_info.nature_of_address = ( octet & 0x70 ) >> 4;
2096         proto_tree_add_uint(tree, hf_q931_numbering_plan, tvb, offset, 1, octet);
2097         proto_tree_add_uint(tree, hf_q931_number_type, tvb, offset, 1, octet);
2098         proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
2099         
2100         offset += 1;
2101         len -= 1;
2102
2103         if (!(octet & Q931_IE_VL_EXTENSION)) {
2104                 if (len == 0)
2105                         return;
2106                 octet = tvb_get_guint8(tvb, offset);
2107                 proto_tree_add_uint(tree, hf_q931_screening_ind, tvb, offset, 1, octet);
2108                 proto_tree_add_uint(tree, hf_q931_presentation_ind, tvb, offset, 1, octet);
2109                 proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
2110                 offset += 1;
2111                 len -= 1;
2112         }
2113
2114         /*
2115          * XXX - only in a Redirecting number information element.
2116          */
2117         if (!(octet & Q931_IE_VL_EXTENSION)) {
2118                 if (len == 0)
2119                         return;
2120                 octet = tvb_get_guint8(tvb, offset);
2121                 proto_tree_add_text(tree, tvb, offset, 1,
2122                     "Reason for redirection: %s",
2123                     val_to_str(octet & 0x0F, q931_redirection_reason_vals,
2124                       "Unknown (0x%X)"));
2125                 offset += 1;
2126                 len -= 1;
2127         }
2128
2129         if (len == 0)
2130                 return;
2131         proto_tree_add_item(tree, hfindex, tvb, offset, len, FALSE);
2132         proto_item_append_text(proto_tree_get_parent(tree), ": '%s'", tvb_format_text(tvb, offset, len));
2133
2134         if ( number_plan == 1 ) {
2135                 if ( e164_info.e164_number_type != NONE ){
2136
2137                         e164_info.E164_number_str = tvb_get_ephemeral_string(tvb, offset, len);
2138                         e164_info.E164_number_length = len;
2139                         dissect_e164_number(tvb, tree, offset, len, e164_info);
2140                 }
2141         }
2142
2143     /* Collect q931_packet_info */
2144     if ( e164_info.e164_number_type == CALLING_PARTY_NUMBER && have_valid_q931_pi)
2145           q931_pi->calling_number = tvb_get_ephemeral_string(tvb, offset, len);
2146     if ( e164_info.e164_number_type == CALLED_PARTY_NUMBER && have_valid_q931_pi)
2147           q931_pi->called_number = tvb_get_ephemeral_string(tvb, offset, len);
2148 }
2149
2150 /*
2151  * Dissect a party subaddress information element.
2152  */
2153 static const value_string q931_subaddress_type_vals[] = {
2154         { 0x00, "X.213/ISO 8348 Add.2 NSAP" },
2155         { 0x20, "User-specified" },
2156         { 0,    NULL }
2157 };
2158
2159 static const value_string q931_odd_even_indicator_vals[] = {
2160         { 0x00, "Even number of address signals" },
2161         { 0x08, "Odd number of address signals" },
2162         { 0,    NULL }
2163 };
2164
2165 static void
2166 dissect_q931_party_subaddr_ie(tvbuff_t *tvb, int offset, int len,
2167     proto_tree *tree)
2168 {
2169         guint8 octet;
2170
2171         if (len == 0)
2172                 return;
2173         octet = tvb_get_guint8(tvb, offset);
2174         proto_tree_add_text(tree, tvb, offset, 1,
2175             "Type of subaddress: %s",
2176             val_to_str(octet & 0x70, q931_subaddress_type_vals,
2177               "Unknown (0x%02X)"));
2178         proto_tree_add_text(tree, tvb, offset, 1,
2179             "Odd/even indicator: %s",
2180             val_to_str(octet & 0x08, q931_odd_even_indicator_vals,
2181               "Unknown (0x%02X)"));
2182         offset += 1;
2183         len -= 1;
2184
2185         if (len == 0)
2186                 return;
2187         proto_tree_add_text(tree, tvb, offset, len, "Subaddress: %s",
2188             tvb_bytes_to_str(tvb, offset, len));
2189 }
2190
2191 /*
2192  * Dissect a Restart indicator information element.
2193  */
2194 static const value_string q931_restart_indicator_class_vals[] = {
2195         { 0x00, "Indicated channels" },
2196         { 0x06, "Single interface" },
2197         { 0x07, "All interfaces" },
2198         { 0,    NULL }
2199 };
2200
2201 static void
2202 dissect_q931_restart_indicator_ie(tvbuff_t *tvb, int offset, int len,
2203     proto_tree *tree)
2204 {
2205         if (len != 1) {
2206                 proto_tree_add_text(tree, tvb, offset, len,
2207                     "Restart indicator: length is %d, should be 1", len);
2208                 return;
2209         }
2210         proto_tree_add_text(tree, tvb, offset, 1,
2211             "Restart indicator: %s",
2212             val_to_str(tvb_get_guint8(tvb, offset) & 0x07,
2213               q931_restart_indicator_class_vals, "Unknown (0x%02X)"));
2214 }
2215
2216 /*
2217  * Dissect a High-layer compatibility information element.
2218  */
2219 #define Q931_AUDIOVISUAL        0x60
2220 static const value_string q931_high_layer_characteristics_vals[] = {
2221         { 0x01,             "Telephony" },
2222         { 0x04,             "F.182 Facsimile Group 2/3" },
2223         { 0x21,             "F.184 Facsimile Group 4 Class I" },
2224         { 0x24,             "F.230 Teletex, basic and mixed mode, and F.184 Facsimile Group 4, Classes II and III" },
2225         { 0x28,             "F.220 Teletex, basic and processable mode" },
2226         { 0x31,             "F.200 Teletex, basic mode" },
2227         { 0x32,             "F.300 and T.102 syntax-based Videotex" },
2228         { 0x33,             "F.300 and T.101 international Videotex interworking" },
2229         { 0x35,             "F.60 Telex" },
2230         { 0x38,             "X.400 Message Handling Systems" },
2231         { 0x41,             "X.200 OSI application" },
2232         { 0x42,             "FTAM application" },
2233         { 0x5E,             "Reserved for maintenance" },
2234         { 0x5F,             "Reserved for management" },
2235         { Q931_AUDIOVISUAL, "F.720/F.821 and F.731 Profile 1a videotelephony" },
2236         { 0x61,             "F.702 and F.731 Profile 1b videoconferencing" },
2237         { 0x62,             "F.702 and F.731 audiographic conferencing" },
2238         { 0,                NULL }
2239 };
2240
2241 static const value_string q931_audiovisual_characteristics_vals[] = {
2242         { 0x01, "Capability set of initial channel of H.221" },
2243         { 0x02, "Capability set of subsequent channel of H.221" },
2244         { 0x21, "Capability set of initial channel of an active 3.1kHz audio or speech call" },
2245         { 0x00, NULL }
2246 };
2247
2248 void
2249 dissect_q931_high_layer_compat_ie(tvbuff_t *tvb, int offset, int len,
2250     proto_tree *tree)
2251 {
2252         guint8 octet;
2253         guint8 coding_standard;
2254         guint8 characteristics;
2255
2256         if (len == 0)
2257                 return;
2258         octet = tvb_get_guint8(tvb, offset);
2259         coding_standard = octet & 0x60;
2260         proto_tree_add_uint(tree, hf_q931_coding_standard, tvb, offset, 1, octet);
2261         offset += 1;
2262         len -= 1;
2263         if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
2264                 /*
2265                  * We don't know how the call state is encoded,
2266                  * so just dump it as data and be done with it.
2267                  */
2268                 proto_tree_add_text(tree, tvb, offset,
2269                     len, "Data: %s",
2270                     tvb_bytes_to_str(tvb, offset, len));
2271                 return;
2272         }
2273
2274         if (len == 0)
2275                 return;
2276         octet = tvb_get_guint8(tvb, offset);
2277         characteristics = octet & 0x7F;
2278         proto_tree_add_text(tree, tvb, offset, 1,
2279             "High layer characteristics identification: %s",
2280             val_to_str(characteristics, q931_high_layer_characteristics_vals,
2281              "Unknown (0x%02X)"));
2282         offset += 1;
2283         len -= 1;
2284
2285         if (!(octet & Q931_IE_VL_EXTENSION)) {
2286                 if (len == 0)
2287                         return;
2288                 octet = tvb_get_guint8(tvb, offset);
2289                 if (characteristics == Q931_AUDIOVISUAL) {
2290                         proto_tree_add_text(tree, tvb, offset, 1,
2291                             "Extended audiovisual characteristics identification: %s",
2292                             val_to_str(octet & 0x7F,
2293                               q931_audiovisual_characteristics_vals,
2294                               "Unknown (0x%02X)"));
2295                 } else {
2296                         proto_tree_add_text(tree, tvb, offset, 1,
2297                             "Extended high layer characteristics identification: %s",
2298                             val_to_str(octet & 0x7F,
2299                               q931_high_layer_characteristics_vals,
2300                               "Unknown (0x%02X)"));
2301                 }
2302         }
2303 }
2304
2305
2306 /*
2307  * Dissect a User-user information element.
2308  */
2309 #define Q931_PROTOCOL_DISCRIMINATOR_IA5         0x04
2310 #define Q931_PROTOCOL_DISCRIMINATOR_ASN1        0x05
2311
2312 const value_string q931_protocol_discriminator_vals[] = {
2313         { 0x00,                                 "User-specific protocol" },
2314         { 0x01,                                 "OSI high layer protocols" },
2315         { 0x02,                                 "X.244" },
2316         { Q931_PROTOCOL_DISCRIMINATOR_IA5,      "IA5 characters" },
2317         { Q931_PROTOCOL_DISCRIMINATOR_ASN1,     "X.208 and X.209 coded user information" },
2318         { 0x07,                                 "V.120 rate adaption" },
2319         { 0x08,                                 "Q.931/I.451 user-network call control messages" },
2320         { 0,                                    NULL }
2321 };
2322
2323 void
2324 dissect_q931_user_user_ie(tvbuff_t *tvb, int offset, int len,
2325     proto_tree *tree)
2326 {
2327         guint8 octet;
2328
2329         if (len == 0)
2330                 return;
2331         octet = tvb_get_guint8(tvb, offset);
2332         proto_tree_add_text(tree, tvb, offset, 1,
2333             "Protocol discriminator: %s",
2334             val_to_str(octet, q931_protocol_discriminator_vals,
2335             "Unknown (0x%02x)"));
2336         offset += 1;
2337         len -= 1;
2338
2339         if (len == 0)
2340                 return;
2341         switch (octet) {
2342
2343         case Q931_PROTOCOL_DISCRIMINATOR_IA5:
2344                 proto_tree_add_text(tree, tvb, offset, len, "User information: %s",
2345                     tvb_format_text(tvb, offset, len));
2346                 break;
2347
2348         default:
2349                 proto_tree_add_text(tree, tvb, offset, len, "User information: %s",
2350                     tvb_bytes_to_str(tvb, offset, len));
2351                 break;
2352         }
2353 }
2354
2355 /*
2356  * Dissect information elements consisting of ASCII^H^H^H^H^HIA5 text.
2357  */
2358 static void
2359 dissect_q931_ia5_ie(tvbuff_t *tvb, int offset, int len, proto_tree *tree,
2360     const char *label)
2361 {
2362         if (len != 0) {
2363                 proto_tree_add_text(tree, tvb, offset, len, "%s: %s", label,
2364                     tvb_format_text(tvb, offset, len));
2365                 proto_item_append_text(proto_tree_get_parent(tree), "  '%s'", tvb_format_text(tvb, offset, len));
2366         }
2367 }
2368
2369 static void
2370 dissect_q931_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2371     gboolean is_tpkt)
2372 {
2373         int             offset = 0;
2374         proto_tree      *q931_tree = NULL;
2375         proto_tree      *ie_tree = NULL;
2376         proto_item      *ti, *ti_ie;
2377         guint8          call_ref_len;
2378         guint8          call_ref[15];
2379         guint32         call_ref_val;
2380         guint8          message_type, segmented_message_type;
2381         guint8          info_element;
2382         guint16         info_element_len;
2383         gboolean        more_frags; 
2384         guint32         frag_len;
2385         fragment_data *fd_head;
2386         tvbuff_t *next_tvb = NULL;
2387
2388         q931_pi=ep_alloc(sizeof(q931_packet_info));
2389
2390         /* Init struct for collecting q931_packet_info */
2391         reset_q931_packet_info(q931_pi);
2392         have_valid_q931_pi=TRUE;
2393
2394         if (check_col(pinfo->cinfo, COL_PROTOCOL))
2395                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Q.931");
2396
2397         if (tree) {
2398                 ti = proto_tree_add_item(tree, proto_q931, tvb, offset, -1,
2399                     FALSE);
2400                 q931_tree = proto_item_add_subtree(ti, ett_q931);
2401
2402                 dissect_q931_protocol_discriminator(tvb, offset, q931_tree);
2403         }
2404         offset += 1;
2405         call_ref_len = tvb_get_guint8(tvb, offset) & 0xF;       /* XXX - do as a bit field? */
2406         if (q931_tree != NULL)
2407                 proto_tree_add_uint(q931_tree, hf_q931_call_ref_len, tvb, offset, 1, call_ref_len);
2408         offset += 1;
2409         switch (call_ref_len) {
2410                 case 0: call_ref_val = 0; break;
2411                 case 1: call_ref_val = tvb_get_guint8(tvb, offset);     break;
2412                 case 2: call_ref_val = tvb_get_ntohs(tvb, offset); break;
2413                 case 3: call_ref_val = tvb_get_ntoh24(tvb, offset); break;
2414                 default: call_ref_val = tvb_get_ntohl(tvb, offset);
2415         } 
2416         if (call_ref_len != 0) {
2417                 tvb_memcpy(tvb, call_ref, offset, call_ref_len);
2418                 if (q931_tree != NULL) {
2419                         proto_tree_add_boolean(q931_tree, hf_q931_call_ref_flag,
2420                             tvb, offset, 1, (call_ref[0] & 0x80) != 0);
2421                         call_ref[0] &= 0x7F;
2422                         proto_tree_add_bytes(q931_tree, hf_q931_call_ref,
2423                             tvb, offset, call_ref_len, call_ref);
2424                 } else
2425                 {       /* info for the tap */
2426                         call_ref[0] &= 0x7F;
2427                 }
2428                 /* XXX - Should crv be something besides a guint32? */
2429                 memcpy(&(q931_pi->crv), call_ref, call_ref_len > sizeof(q931_pi->crv) ? sizeof(q931_pi->crv) : call_ref_len );
2430                 offset += call_ref_len;
2431         }
2432         message_type = tvb_get_guint8(tvb, offset);
2433         if(have_valid_q931_pi) {
2434                 q931_pi->message_type = message_type;
2435         }
2436         if (check_col(pinfo->cinfo, COL_INFO)) {
2437                 col_add_str(pinfo->cinfo, COL_INFO,
2438                     val_to_str(message_type, q931_message_type_vals,
2439                       "Unknown message type (0x%02X)"));
2440         }
2441         if (q931_tree != NULL)
2442                 proto_tree_add_uint(q931_tree, hf_q931_message_type, tvb, offset, 1, message_type);
2443         offset += 1;
2444
2445         /*
2446          * And now for the information elements....
2447          */
2448         if ((message_type != Q931_SEGMENT) || !q931_reassembly || 
2449                         (tvb_reported_length_remaining(tvb, offset) <= 4)) {
2450                 dissect_q931_IEs(tvb, pinfo, tree, q931_tree, is_tpkt, offset, 0);
2451                 return;
2452         }
2453         info_element = tvb_get_guint8(tvb, offset);
2454         info_element_len = tvb_get_guint8(tvb, offset + 1);
2455         if ((info_element != Q931_IE_SEGMENTED_MESSAGE) || (info_element_len < 2)) {
2456                 dissect_q931_IEs(tvb, pinfo, tree, q931_tree, is_tpkt, offset, 0);
2457                 return;
2458         }
2459         /* Segmented message IE */
2460         ti_ie = proto_tree_add_text(q931_tree, tvb, offset, 1+1+info_element_len, "%s",
2461                                     val_to_str(info_element, q931_info_element_vals[0], "Unknown information element (0x%02X)"));
2462         ie_tree = proto_item_add_subtree(ti_ie, ett_q931_ie);
2463         proto_tree_add_text(ie_tree, tvb, offset, 1, "Information element: %s",
2464                                     val_to_str(info_element, q931_info_element_vals[0], "Unknown (0x%02X)"));
2465         proto_tree_add_text(ie_tree, tvb, offset + 1, 1, "Length: %u", info_element_len);
2466         dissect_q931_segmented_message_ie(tvb, offset + 2, info_element_len, ie_tree);
2467         more_frags = (tvb_get_guint8(tvb, offset + 2) & 0x7F) != 0;
2468         segmented_message_type = tvb_get_guint8(tvb, offset + 3);
2469         if (check_col(pinfo->cinfo, COL_INFO)) {
2470                 col_append_fstr(pinfo->cinfo, COL_INFO, " of %s",
2471                     val_to_str(segmented_message_type, q931_message_type_vals, "Unknown message type (0x%02X)"));
2472         }
2473         offset += 1 + 1 + info_element_len;
2474         /* Reassembly */
2475         frag_len = tvb_length_remaining(tvb, offset);
2476         fd_head = fragment_add_seq_next(tvb, offset, pinfo, call_ref_val,
2477                                                                         q931_fragment_table, q931_reassembled_table,
2478                                                                         frag_len, more_frags);
2479         if (fd_head) {
2480                 if (pinfo->fd->num == fd_head->reassembled_in) {  /* last fragment */
2481                         if (fd_head->next != NULL) {  /* 2 or more segments */
2482                                 next_tvb = tvb_new_real_data(fd_head->data, fd_head->len, fd_head->len);
2483                                 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
2484                                 add_new_data_source(pinfo, next_tvb, "Reassembled Q.931 IEs");
2485                                 /* Show all fragments. */
2486                 if (tree) {
2487                     proto_item *frag_tree_item;
2488                     show_fragment_seq_tree(fd_head, &q931_frag_items, q931_tree, pinfo, next_tvb, &frag_tree_item);
2489                 }
2490                         } else {  /* only 1 segment */
2491                                 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
2492                         }
2493                         if (check_col(pinfo->cinfo, COL_INFO)) {
2494                                 col_add_fstr(pinfo->cinfo, COL_INFO, "%s [reassembled]",
2495                                     val_to_str(segmented_message_type, q931_message_type_vals, "Unknown message type (0x%02X)"));
2496                         }
2497                 } else {
2498                         if (tree) proto_tree_add_uint(q931_tree, hf_q931_reassembled_in, tvb, offset, frag_len, fd_head->reassembled_in);
2499                 }
2500         }
2501         if (next_tvb)
2502                 dissect_q931_IEs(next_tvb, pinfo, tree, q931_tree, is_tpkt, 0, 0);
2503 }
2504
2505 static const value_string q931_codeset_vals[] = {
2506         { 0x00, "Q.931 information elements" },
2507         { 0x04, "Information elements for ISO/IEC use" },
2508         { 0x05, "Information elements for national use" },
2509         { 0x06, "Information elements specific to the local network" },
2510         { 0x07, "User-specific information elements" },
2511         { 0x00, NULL },
2512 };
2513
2514 static void
2515 dissect_q931_IEs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *root_tree,
2516     proto_tree *q931_tree, gboolean is_tpkt, int offset, int initial_codeset)
2517 {
2518         proto_item      *ti;
2519         proto_tree      *ie_tree = NULL;
2520         guint8          info_element;
2521         guint8          dummy;
2522         guint16         info_element_len;
2523         int             codeset, locked_codeset;
2524         gboolean        non_locking_shift, first_segment;
2525         tvbuff_t        *h225_tvb, *next_tvb;
2526         e164_info_t e164_info;
2527         e164_info.e164_number_type = NONE;
2528
2529         codeset = locked_codeset = initial_codeset;
2530         non_locking_shift = TRUE;
2531         first_segment = FALSE;
2532         while (tvb_reported_length_remaining(tvb, offset) > 0) {
2533                 info_element = tvb_get_guint8(tvb, offset);
2534
2535                 /* Check for the codeset shift */
2536                 if ((info_element & Q931_IE_SO_MASK) &&
2537                     ((info_element & Q931_IE_SO_IDENTIFIER_MASK) == Q931_IE_SHIFT)) {
2538                         non_locking_shift = info_element & Q931_IE_SHIFT_NON_LOCKING;
2539                         codeset = info_element & Q931_IE_SHIFT_CODESET;
2540                         if (!non_locking_shift)
2541                                 locked_codeset = codeset;
2542                         if (q931_tree != NULL) {
2543                                 proto_tree_add_text(q931_tree, tvb, offset, 1,
2544                                     "%s shift to codeset %u: %s",
2545                                     (non_locking_shift ? "Non-locking" : "Locking"),
2546                                     codeset,
2547                                     val_to_str(codeset, q931_codeset_vals,
2548                                       "Unknown (0x%02X)"));
2549                         }
2550                         offset += 1;
2551                         continue;
2552                 }
2553
2554                 /*
2555                  * Check for the single-octet IEs.
2556                  */
2557                 if (info_element & Q931_IE_SO_MASK) {
2558                         /*
2559                          * Check for subdissectors for this IE or
2560                          * for all IEs in this codeset.
2561                          */
2562                         if (dissector_get_port_handle(codeset_dissector_table, codeset) ||
2563                             dissector_get_port_handle(ie_dissector_table, (codeset << 8) | (info_element & Q931_IE_SO_IDENTIFIER_MASK))) {
2564                                 next_tvb = tvb_new_subset (tvb, offset, 1, 1);
2565                                 if (dissector_try_port(ie_dissector_table, (codeset << 8) | (info_element & Q931_IE_SO_IDENTIFIER_MASK), next_tvb, pinfo, q931_tree) ||
2566                                     dissector_try_port(codeset_dissector_table, codeset, next_tvb, pinfo, q931_tree)) {
2567                                         offset += 1;
2568                                         codeset = locked_codeset;
2569                                         continue;
2570                                 }
2571                         }
2572
2573                         switch ((codeset << 8) | (info_element & Q931_IE_SO_IDENTIFIER_MASK)) {
2574
2575                         case CS0 | Q931_IE_MORE_DATA_OR_SEND_COMP:
2576                                 switch (info_element) { 
2577
2578                                 case Q931_IE_MORE_DATA:
2579                                         if (q931_tree != NULL) {
2580                                                 proto_tree_add_text(q931_tree, tvb, offset, 1,
2581                                                     "More data");
2582                                         }
2583                                         break;
2584
2585                                 case Q931_IE_SENDING_COMPLETE:
2586                                         if (q931_tree != NULL) {
2587                                                 proto_tree_add_text(q931_tree, tvb, offset, 1,
2588                                                     "Sending complete");
2589                                         }
2590                                         break;
2591
2592                                 default:
2593                                         if (q931_tree != NULL) {
2594                                                 proto_tree_add_text(q931_tree, tvb, offset, 1,
2595                                                     "Unknown information element (0x%02X)",
2596                                                     info_element);
2597                                         }
2598                                         break;
2599                                 }
2600                                 break;
2601
2602                         case CS0 | Q931_IE_CONGESTION_LEVEL:
2603                                 if (q931_tree != NULL) {
2604                                         proto_tree_add_text(q931_tree, tvb, offset, 1,
2605                                             "Congestion level: %s",
2606                                             val_to_str(info_element & Q931_IE_SO_IE_MASK,
2607                                               q931_congestion_level_vals,
2608                                               "Unknown (0x%X)"));
2609                                 }
2610                                 break;
2611
2612                         case CS0 | Q931_IE_REPEAT_INDICATOR:
2613                                 if (q931_tree != NULL) {
2614                                         proto_tree_add_text(q931_tree, tvb, offset, 1,
2615                                             "Repeat indicator: %s",
2616                                             val_to_str(info_element & Q931_IE_SO_IE_MASK,
2617                                           q931_repeat_indication_vals,
2618                                               "Unknown (0x%X)"));
2619                                 }
2620                                 break;
2621
2622                         default:
2623                                 if (q931_tree != NULL) {
2624                                         proto_tree_add_text(q931_tree, tvb, offset, 1,
2625                                             "Unknown information element (0x%02X)",
2626                                             info_element);
2627                                 }
2628                                 break;
2629                         }
2630                         offset += 1;
2631                         codeset = locked_codeset;
2632                         continue;
2633                 }
2634
2635                 /*
2636                  * Variable-length IE.
2637                  *
2638                  * According to page 18 from Recommendation H.225.0 :
2639                  * " Length of user-user contents contents
2640                  * - Shall be 2 octets instead of 1 (as in Figure 4-36/Q.931)"
2641                  *
2642                  * We assume that if this is Q.931-over-TPKT, it might
2643                  * be H.225 traffic, and check for the IE being a user-user
2644                  * IE with ASN.1 encoding of the user information.
2645                  */
2646                 if (is_tpkt && tvb_bytes_exist(tvb, offset, 4) &&
2647                     codeset == 0 && tvb_get_guint8(tvb, offset) == Q931_IE_USER_USER &&
2648                     tvb_get_guint8(tvb, offset + 3) == Q931_PROTOCOL_DISCRIMINATOR_ASN1)  {
2649                         info_element_len = tvb_get_ntohs(tvb, offset + 1);
2650                         if (q931_tree != NULL) {
2651                                 ti = proto_tree_add_text(q931_tree, tvb, offset,
2652                                     1+2+info_element_len, "%s",
2653                                     val_to_str(info_element,
2654                                       q931_info_element_vals[codeset],
2655                                       "Unknown information element (0x%02X)"));
2656                                 ie_tree = proto_item_add_subtree(ti,
2657                                     ett_q931_ie);
2658                                 proto_tree_add_text(ie_tree, tvb, offset, 1,
2659                                     "Information element: %s",
2660                                     val_to_str(info_element,
2661                                       q931_info_element_vals[codeset], "Unknown (0x%02X)"));
2662                                 proto_tree_add_text(ie_tree, tvb, offset + 1,
2663                                     2, "Length: %u", info_element_len);
2664                                 proto_tree_add_text(ie_tree, tvb, offset + 3,
2665                                     1, "Protocol discriminator: %s",
2666                                     val_to_str(tvb_get_guint8(tvb, offset + 3),
2667                                       q931_protocol_discriminator_vals,
2668                                       "Unknown (0x%02x)"));
2669                         }
2670
2671                         if (info_element_len > 1) {
2672                                 /*
2673                                  * If we don't desegment limit the length 
2674                                  * to the actual size in the frame
2675                                  */
2676                                 if (!pinfo->can_desegment) {
2677                                         info_element_len = min(info_element_len, tvb_length_remaining(tvb, offset + 3));
2678                                 }
2679                                 /*
2680                                  * Do we have a handle for the H.225
2681                                  * dissector?
2682                                  */
2683                                 if (h225_handle != NULL) {
2684                                         /*
2685                                          * Yes - call it, regardless of
2686                                          * whether we're building a
2687                                          * protocol tree or not.
2688                                          */
2689                                         h225_tvb = tvb_new_subset(tvb,
2690                                             offset + 4, info_element_len - 1,
2691                                             info_element_len - 1);
2692                                         call_dissector(h225_handle, h225_tvb,
2693                                             pinfo, root_tree);
2694                                 } else {
2695                                         /*
2696                                          * No - just show it as "User
2697                                          * information" (if "ie_tree" is
2698                                          * null, this won't add anything).
2699                                          */
2700                                         proto_tree_add_text(ie_tree, tvb,
2701                                             offset + 4, info_element_len - 1,
2702                                             "User information: %s",
2703                                             tvb_bytes_to_str(tvb, offset + 4,
2704                                               info_element_len - 1));
2705                                 }
2706                         }
2707                         offset += 1 + 2 + info_element_len;
2708                 } else {
2709                         info_element_len = tvb_get_guint8(tvb, offset + 1);
2710
2711                         if (first_segment && (tvb_reported_length_remaining(tvb, offset + 2) < info_element_len)) {  /* incomplete IE at the end of the 1st segment */
2712                                 proto_tree_add_text(q931_tree, tvb, offset, tvb_reported_length_remaining(tvb, offset), "Incomplete IE in the 1st segment");
2713                                 break;
2714                         }
2715
2716                         /*
2717                          * Check for subdissectors for this IE or
2718                          * for all IEs in this codeset.
2719                          */
2720                         if (dissector_get_port_handle(codeset_dissector_table, codeset) ||
2721                             dissector_get_port_handle(ie_dissector_table, (codeset << 8) | info_element)) {
2722                                 next_tvb = tvb_new_subset (tvb, offset, info_element_len + 2, info_element_len + 2);
2723                                 if (dissector_try_port(ie_dissector_table, (codeset << 8) | info_element, next_tvb, pinfo, q931_tree) ||
2724                                     dissector_try_port(codeset_dissector_table, codeset, next_tvb, pinfo, q931_tree)) {
2725                                         offset += 2 + info_element_len;
2726                                         codeset = locked_codeset;
2727                                         continue;
2728                                 }
2729                         }
2730
2731                         ti = proto_tree_add_text(q931_tree, tvb, offset, 1+1+info_element_len, "%s",
2732                                     val_to_str(info_element, q931_info_element_vals[codeset], "Unknown information element (0x%02X)"));
2733                         ie_tree = proto_item_add_subtree(ti, ett_q931_ie);
2734                         proto_tree_add_text(ie_tree, tvb, offset, 1, "Information element: %s",
2735                                     val_to_str(info_element, q931_info_element_vals[codeset], "Unknown (0x%02X)"));
2736                         proto_tree_add_text(ie_tree, tvb, offset + 1, 1, "Length: %u", info_element_len);
2737
2738                         if (((codeset << 8) | info_element) == (CS0 | Q931_IE_SEGMENTED_MESSAGE)) {
2739                                 dissect_q931_segmented_message_ie(tvb, offset + 2, info_element_len, ie_tree);
2740                                 if (check_col(pinfo->cinfo, COL_INFO)) {
2741                                         col_append_fstr(pinfo->cinfo, COL_INFO, " of %s",
2742                                             val_to_str(tvb_get_guint8(tvb, offset + 3), q931_message_type_vals, "Unknown message type (0x%02X)"));
2743                                 }
2744                                 if (tvb_get_guint8(tvb, offset + 2) & 0x80) {  /* the 1st segment */
2745                                         first_segment = TRUE;
2746                                 } else {  /* not the 1st segment */
2747                                         proto_tree_add_text(q931_tree, tvb, offset + 4, tvb_reported_length_remaining(tvb, offset + 4), "Message segment");
2748                                         info_element_len += tvb_reported_length_remaining(tvb, offset + 4);
2749                                 }
2750                         } else {
2751                                 /*
2752                                  * For the calling number, called number,
2753                                  * and release cause IEs, don't check
2754                                  * for the tree being null, as
2755                                  * the dissectors for those IEs also
2756                                  * supply information for the tap used
2757                                  * in VoIP calls.
2758                                  */
2759                                 switch ((codeset << 8) | info_element) {
2760
2761                                 case CS0 | Q931_IE_BEARER_CAPABILITY:
2762                                 case CS0 | Q931_IE_LOW_LAYER_COMPAT:
2763                                         if (q931_tree != NULL) {
2764                                                 dissect_q931_bearer_capability_ie(tvb,
2765                                                         offset + 2, info_element_len,
2766                                                         ie_tree);
2767                                         }
2768                                         break;
2769
2770                                 case CS0 | Q931_IE_CAUSE:
2771                                         dissect_q931_cause_ie(tvb,
2772                                                 offset + 2, info_element_len,
2773                                                 ie_tree,
2774                                                 hf_q931_cause_value, &dummy);
2775                                         break;
2776
2777                                 case CS0 | Q931_IE_CALL_STATE:
2778                                         if (q931_tree != NULL) {
2779                                                 dissect_q931_call_state_ie(tvb,
2780                                                         offset + 2, info_element_len,
2781                                                         ie_tree);
2782                                         }
2783                                         break;
2784
2785                                 case CS0 | Q931_IE_CHANNEL_IDENTIFICATION:
2786                                         if (q931_tree != NULL) {
2787                                                 dissect_q931_channel_identification_ie(
2788                                                         tvb, offset + 2, info_element_len,
2789                                                         ie_tree);
2790                                         }
2791                                         break;
2792
2793                                 case CS0 | Q931_IE_PROGRESS_INDICATOR:
2794                                         if (q931_tree != NULL) {
2795                                                 dissect_q931_progress_indicator_ie(tvb,
2796                                                         offset + 2, info_element_len,
2797                                                         ie_tree);
2798                                         }
2799                                         break;
2800
2801                                 case CS0 | Q931_IE_NETWORK_SPECIFIC_FACIL:
2802                                 case CS0 | Q931_IE_TRANSIT_NETWORK_SEL:
2803                                         if (q931_tree != NULL) {
2804                                                 dissect_q931_ns_facilities_ie(tvb,
2805                                                         offset + 2, info_element_len,
2806                                                         ie_tree);
2807                                         }
2808                                         break;
2809
2810                                 case CS0 | Q931_IE_NOTIFICATION_INDICATOR:
2811                                         if (q931_tree != NULL) {
2812                                                 dissect_q931_notification_indicator_ie(
2813                                                         tvb, offset + 2, info_element_len,
2814                                                         ie_tree);
2815                                         }
2816                                         break;
2817
2818                                 case CS0 | Q931_IE_DISPLAY:
2819                                         if (q931_tree != NULL) {
2820                                                 dissect_q931_ia5_ie(tvb, offset + 2,
2821                                                         info_element_len, ie_tree,
2822                                                         "Display information");
2823                                         }
2824                                         break;
2825
2826                                 case CS0 | Q931_IE_DATE_TIME:
2827                                         if (q931_tree != NULL) {
2828                                                 dissect_q931_date_time_ie(tvb,
2829                                                         offset + 2, info_element_len,
2830                                                         ie_tree);
2831                                         }
2832                                         break;
2833
2834                                 case CS0 | Q931_IE_KEYPAD_FACILITY:
2835                                         if (q931_tree != NULL) {
2836                                                 dissect_q931_ia5_ie(tvb, offset + 2,
2837                                                         info_element_len, ie_tree,
2838                                                         "Keypad facility");
2839                                         }
2840                                         break;
2841
2842                                 case CS0 | Q931_IE_SIGNAL:
2843                                         if (q931_tree != NULL) {
2844                                                 dissect_q931_signal_ie(tvb,
2845                                                         offset + 2, info_element_len,
2846                                                         ie_tree);
2847                                         }
2848                                         break;
2849
2850                                 case CS0 | Q931_IE_INFORMATION_RATE:
2851                                         if (q931_tree != NULL) {
2852                                                 dissect_q931_information_rate_ie(tvb,
2853                                                         offset + 2, info_element_len,
2854                                                         ie_tree);
2855                                         }
2856                                         break;
2857
2858                                 case CS0 | Q931_IE_E2E_TRANSIT_DELAY:
2859                                         if (q931_tree != NULL) {
2860                                                 dissect_q931_e2e_transit_delay_ie(tvb,
2861                                                         offset + 2, info_element_len,
2862                                                         ie_tree);
2863                                         }
2864                                         break;
2865
2866                                 case CS0 | Q931_IE_TD_SELECTION_AND_INT:
2867                                         if (q931_tree != NULL) {
2868                                                 dissect_q931_td_selection_and_int_ie(
2869                                                         tvb, offset + 2, info_element_len,
2870                                                         ie_tree);
2871                                         }
2872                                         break;
2873
2874                                 case CS0 | Q931_IE_PL_BINARY_PARAMETERS:
2875                                         if (q931_tree != NULL) {
2876                                                 dissect_q931_pl_binary_parameters_ie(
2877                                                         tvb, offset + 2, info_element_len,
2878                                                         ie_tree);
2879                                         }
2880                                         break;
2881
2882                                 case CS0 | Q931_IE_PL_WINDOW_SIZE:
2883                                         if (q931_tree != NULL) {
2884                                                 dissect_q931_pl_window_size_ie(tvb,
2885                                                         offset + 2, info_element_len,
2886                                                         ie_tree);
2887                                         }
2888                                         break;
2889
2890                                 case CS0 | Q931_IE_PACKET_SIZE:
2891                                         if (q931_tree != NULL) {
2892                                                 dissect_q931_packet_size_ie(tvb,
2893                                                         offset + 2, info_element_len,
2894                                                         ie_tree);
2895                                         }
2896                                         break;
2897
2898                                 case CS0 | Q931_IE_CUG:
2899                                         if (q931_tree != NULL) {
2900                                                 dissect_q931_cug_ie(tvb,
2901                                                         offset + 2, info_element_len,
2902                                                         ie_tree);
2903                                         }
2904                                         break;
2905
2906                                 case CS0 | Q931_IE_REVERSE_CHARGE_IND:
2907                                         if (q931_tree != NULL) {
2908                                                 dissect_q931_reverse_charge_ind_ie(tvb,
2909                                                         offset + 2, info_element_len,
2910                                                         ie_tree);
2911                                         }
2912                                         break;
2913
2914                                 case CS0 | Q931_IE_CONNECTED_NUMBER_DEFAULT:
2915                                         if (q931_tree != NULL) {
2916                                                 dissect_q931_number_ie(tvb,
2917                                                         offset + 2, info_element_len,
2918                                                         ie_tree,
2919                                                         hf_q931_connected_number, e164_info);
2920                                         }
2921                                         break;
2922
2923
2924                                 case CS0 | Q931_IE_CALLING_PARTY_NUMBER:
2925                                         e164_info.e164_number_type = CALLING_PARTY_NUMBER;
2926                                         dissect_q931_number_ie(tvb,
2927                                                 offset + 2, info_element_len,
2928                                                 ie_tree,
2929                                                 hf_q931_calling_party_number, e164_info);
2930                                         break;
2931
2932                                 case CS0 | Q931_IE_CALLED_PARTY_NUMBER:
2933                                         e164_info.e164_number_type = CALLED_PARTY_NUMBER;
2934                                         dissect_q931_number_ie(tvb,
2935                                                 offset + 2, info_element_len,
2936                                                 ie_tree,
2937                                                 hf_q931_called_party_number, e164_info);
2938                                         break;
2939
2940                                 case CS0 | Q931_IE_CALLING_PARTY_SUBADDR:
2941                                 case CS0 | Q931_IE_CALLED_PARTY_SUBADDR:
2942                                         if (q931_tree != NULL) {
2943                                                 dissect_q931_party_subaddr_ie(tvb,
2944                                                         offset + 2, info_element_len,
2945                                                         ie_tree);
2946                                         }
2947                                         break;
2948
2949                                 case CS0 | Q931_IE_REDIRECTING_NUMBER:
2950                                         if (q931_tree != NULL) {
2951                                                 dissect_q931_number_ie(tvb,
2952                                                         offset + 2, info_element_len,
2953                                                         ie_tree,
2954                                                         hf_q931_redirecting_number, e164_info);
2955                                         }
2956                                         break;
2957
2958                                 case CS0 | Q931_IE_RESTART_INDICATOR:
2959                                         if (q931_tree != NULL) {
2960                                                 dissect_q931_restart_indicator_ie(tvb,
2961                                                         offset + 2, info_element_len,
2962                                                         ie_tree);
2963                                         }
2964                                         break;
2965
2966                                 case CS0 | Q931_IE_HIGH_LAYER_COMPAT:
2967                                         if (q931_tree != NULL) {
2968                                                 dissect_q931_high_layer_compat_ie(tvb,
2969                                                         offset + 2, info_element_len,
2970                                                         ie_tree);
2971                                         }
2972                                         break;
2973
2974                                 case CS0 | Q931_IE_USER_USER:
2975                                         if (q931_tree != NULL) {
2976                                                 dissect_q931_user_user_ie(tvb,
2977                                                         offset + 2, info_element_len,
2978                                                         ie_tree);
2979                                         }
2980                                         break;
2981
2982                                 case CS6 | Q931_IE_DISPLAY:
2983                                         if (q931_tree != NULL) {
2984                                                 dissect_q931_ia5_ie(tvb, offset + 2,
2985                                                         info_element_len, ie_tree,
2986                                                         "Avaya Display");
2987                                         }
2988                                         break;
2989
2990                                 default:
2991                                         if (q931_tree != NULL) {
2992                                                 proto_tree_add_text(ie_tree, tvb,
2993                                                         offset + 2, info_element_len,
2994                                                         "Data: %s",
2995                                                         bytes_to_str(
2996                                                           tvb_get_ptr(tvb, offset + 2,
2997                                                                   info_element_len),
2998                                                           info_element_len));
2999                                         }
3000                                         break;
3001                                 }
3002                         }
3003                         offset += 1 + 1 + info_element_len;
3004                 }
3005                 codeset = locked_codeset;
3006         }
3007         if(have_valid_q931_pi) {
3008                 tap_queue_packet(q931_tap, pinfo, q931_pi);
3009         }
3010         have_valid_q931_pi=FALSE;
3011 }
3012
3013 /*
3014  * Q.931-over-TPKT-over-TCP.
3015  */
3016 static gboolean
3017 dissect_q931_tpkt_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3018 {
3019         int lv_tpkt_len;
3020
3021         /*
3022          * Check whether this looks like a TPKT-encapsulated
3023          * Q.931 packet.
3024          *
3025          * The minimum length of a Q.931 message is 3:
3026          * 1 byte for the protocol discriminator,
3027          * 1 for the call_reference length,
3028          * and one for the message type.
3029          */
3030         lv_tpkt_len = is_tpkt(tvb, 3);
3031         if (lv_tpkt_len == -1) {
3032                 /*
3033                  * It's not a TPKT packet; reject it.
3034                  */
3035                 return FALSE;
3036         }
3037
3038         /*
3039          * If this segment is *exactly* the length of a TPKT header,
3040          * we assume that, as it looks like a TPKT header, it
3041          * is one, and that the code put a TPKT header in one
3042          * segment and the rest of the PDU in another.
3043          */
3044         if (tvb_length(tvb) == 4) {
3045                 /*
3046                  * It is - call the "dissect TPKT over a TCP stream"
3047                  * routine.
3048                  */
3049                 dissect_tpkt_encap(tvb, pinfo, tree, q931_desegment,
3050                     q931_tpkt_pdu_handle);
3051                 return TRUE;
3052         }
3053
3054         /*
3055          * Well, we have more data than just the TPKT header;
3056          * check whether it looks like the beginning of a
3057          * Q.931 message.
3058          *
3059          * The minimum length of a Q.931 message is 3, as per the
3060          * above.
3061          *
3062          * Check that we have that many bytes past the TPKT header in
3063          * the tvbuff; we already know that the TPKT header says we
3064          * have that many bytes (as we passed 3 as the "min_len" argument
3065          * to "is_tpkt()").
3066          */
3067         if (!tvb_bytes_exist(tvb, 4, 3))
3068                 return FALSE;
3069
3070         /* Check the protocol discriminator */
3071         if (tvb_get_guint8(tvb, 4) != NLPID_Q_931) {
3072                 /* Doesn't look like Q.931 inside TPKT */
3073                 return FALSE;
3074         }
3075
3076         /*
3077          * OK, it looks like Q.931-over-TPKT.
3078          * Call the "dissect TPKT over a TCP stream" routine.
3079          */
3080         dissect_tpkt_encap(tvb, pinfo, tree, q931_desegment,
3081             q931_tpkt_pdu_handle);
3082
3083         return TRUE;
3084 }
3085
3086 static void
3087 dissect_q931_tpkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3088 {
3089         dissect_q931_tpkt_heur(tvb, pinfo, tree);
3090 }
3091
3092 static void
3093 dissect_q931_tpkt_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3094 {
3095         dissect_q931_pdu(tvb, pinfo, tree, TRUE);
3096 }
3097
3098 static void
3099 dissect_q931(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3100 {
3101         dissect_q931_pdu(tvb, pinfo, tree, FALSE);
3102 }
3103
3104 static void
3105 dissect_q931_ie_cs0(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3106 {
3107         dissect_q931_IEs(tvb, pinfo, NULL, tree, FALSE, 0, 0);
3108 }
3109
3110 static void
3111 dissect_q931_ie_cs7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3112 {
3113         dissect_q931_IEs(tvb, pinfo, NULL, tree, FALSE, 0, 7);
3114 }
3115
3116 static void 
3117 q931_init(void) {
3118         /* Initialize the fragment and reassembly tables */
3119         fragment_table_init(&q931_fragment_table);
3120         reassembled_table_init(&q931_reassembled_table);
3121 }
3122
3123 void
3124 proto_register_q931(void)
3125 {
3126         static hf_register_info hf[] = {
3127                 { &hf_q931_discriminator,
3128                   { "Protocol discriminator", "q931.disc", FT_UINT8, BASE_HEX, NULL, 0x0,
3129                         "", HFILL }},
3130
3131                 { &hf_q931_call_ref_len,
3132                   { "Call reference value length", "q931.call_ref_len", FT_UINT8, BASE_DEC, NULL, 0x0,
3133                         "", HFILL }},
3134
3135                 { &hf_q931_call_ref_flag,
3136                   { "Call reference flag", "q931.call_ref_flag", FT_BOOLEAN, BASE_NONE, TFS(&tfs_call_ref_flag), 0x0,
3137                         "", HFILL }},
3138
3139                 { &hf_q931_call_ref,
3140                   { "Call reference value", "q931.call_ref", FT_BYTES, BASE_HEX, NULL, 0x0,
3141                         "", HFILL }},
3142
3143                 { &hf_q931_message_type,
3144                   { "Message type", "q931.message_type", FT_UINT8, BASE_HEX, VALS(q931_message_type_vals), 0x0,
3145                         "", HFILL }},
3146
3147                 { &hf_q931_segment_type,
3148                   { "Segmented message type", "q931.segment_type", FT_UINT8, BASE_HEX, VALS(q931_message_type_vals), 0x0,
3149                         "", HFILL }},
3150
3151                 { &hf_q931_coding_standard,
3152                   { "Coding standard", "q931.coding_standard", FT_UINT8, BASE_HEX,
3153                          VALS(q931_coding_standard_vals), 0x60,"", HFILL }},
3154
3155                 { &hf_q931_information_transfer_capability,
3156                   { "Information transfer capability", "q931.information_transfer_capability", FT_UINT8, BASE_HEX,
3157                          VALS(q931_information_transfer_capability_vals), 0x1f,"", HFILL }},
3158
3159                 { &hf_q931_transfer_mode,
3160                   { "Transfer mode", "q931.transfer_mode", FT_UINT8, BASE_HEX,
3161                          VALS(q931_transfer_mode_vals), 0x60,"", HFILL }},
3162
3163                 { &hf_q931_information_transfer_rate,
3164                   { "Information transfer rate", "q931.information_transfer_rate", FT_UINT8, BASE_HEX,
3165                          VALS(q931_information_transfer_rate_vals), 0x1f,"", HFILL }},
3166
3167                 { &hf_q931_uil1,
3168                   { "User information layer 1 protocol", "q931.uil1", FT_UINT8, BASE_HEX,
3169                          VALS(q931_uil1_vals), 0x1f,"", HFILL }},
3170
3171                 { &hf_q931_cause_location,
3172                   { "Cause location", "q931.cause_location", FT_UINT8, BASE_DEC, VALS(q931_cause_location_vals), 0x0f,
3173                         "", HFILL }},
3174
3175                 { &hf_q931_cause_value,
3176                   { "Cause value", "q931.cause_value", FT_UINT8, BASE_DEC, VALS(q931_cause_code_vals), 0x7f,
3177                         "", HFILL }},
3178
3179                 { &hf_q931_number_type,
3180                   { "Number type", "q931.number_type", FT_UINT8, BASE_HEX, VALS(q931_number_type_vals), 0x70,
3181                         "", HFILL }},
3182
3183                 { &hf_q931_numbering_plan,
3184                   { "Numbering plan", "q931.numbering_plan", FT_UINT8, BASE_HEX, VALS(q931_numbering_plan_vals), 0x0f,
3185                         "", HFILL }},
3186
3187                 { &hf_q931_screening_ind,
3188                   { "Screening indicator", "q931.screening_ind", FT_UINT8, BASE_HEX, VALS(q931_screening_indicator_vals), 0x03,
3189                         "", HFILL }},
3190
3191                 { &hf_q931_presentation_ind,
3192                   { "Presentation indicator", "q931.presentation_ind", FT_UINT8, BASE_HEX, VALS(q931_presentation_indicator_vals), 0x60,
3193                         "", HFILL }},
3194
3195                 { &hf_q931_extension_ind,
3196                   { "Extension indicator",  "q931.extension_ind",
3197                         FT_BOOLEAN, 8, TFS(&q931_extension_ind_value), 0x80,
3198                         "", HFILL }},
3199
3200                 { &hf_q931_calling_party_number,
3201                   { "Calling party number digits", "q931.calling_party_number.digits", FT_STRING, BASE_NONE, NULL, 0x0,
3202                         "", HFILL }},
3203
3204                 { &hf_q931_called_party_number,
3205                   { "Called party number digits", "q931.called_party_number.digits", FT_STRING, BASE_NONE, NULL, 0x0,
3206                         "", HFILL }},
3207
3208                 { &hf_q931_connected_number,
3209                   { "Connected party number digits", "q931.connected_number.digits", FT_STRING, BASE_NONE, NULL, 0x0,
3210                         "", HFILL }},
3211
3212                 { &hf_q931_redirecting_number,
3213                   { "Redirecting party number digits", "q931.redirecting_number.digits", FT_STRING, BASE_NONE, NULL, 0x0,
3214                         "", HFILL }},
3215
3216     /* fields for channel identification IE */
3217                 /* 0x80 is the extension bit */
3218
3219                 { &hf_q931_channel_interface_explicit,
3220                   { "Interface identifier present", "q931.channel.interface_id_present", FT_BOOLEAN, 8, NULL, 0x40,
3221                     "True if the interface identifier is explicit in the following octets", HFILL }},
3222
3223                 { &hf_q931_channel_interface_type,
3224                   { "Interface type", "q931.channel.interface_type", FT_BOOLEAN, 8, &tfs_interface_type, 0x20,
3225                     "Identifies the ISDN interface type", HFILL }},
3226
3227                 /* 0x10 is spare */
3228                 
3229                 { &hf_q931_channel_exclusive,
3230                   { "Indicated channel is exclusive", "q931.channel.exclusive", FT_BOOLEAN, 8, &tfs_channel_exclusive, 0x08,
3231                     "True if only the indicated channel is acceptable", HFILL }},
3232
3233                 { &hf_q931_channel_dchan,
3234                   { "D-channel indicator", "q931.channel.dchan", FT_BOOLEAN, 8, NULL, 0x04,
3235                     "True if the identified channel is the D-Channel", HFILL }},
3236
3237                 { &hf_q931_channel_selection_bri,
3238                   { "Information channel selection", "q931.channel.selection", FT_UINT8, BASE_HEX, q931_basic_channel_selection_vals, 0x03,
3239                     "Identifies the information channel to be used", HFILL }},
3240
3241                 { &hf_q931_channel_selection_pri,
3242                   { "Information channel selection", "q931.channel.selection", FT_UINT8, BASE_HEX, q931_not_basic_channel_selection_vals, 0x03,
3243                     "Identifies the information channel to be used", HFILL }},
3244
3245                 { &hf_q931_channel_map,
3246                   { "Number/map", "q931.channel.map", FT_BOOLEAN, 8, &tfs_channel_map, 0x10,
3247                     "True if channel is indicates by channel map rather than number", HFILL }},
3248                 
3249                 { &hf_q931_channel_element_type,
3250                   { "Element type", "q931.channel.element_type", FT_UINT8, BASE_HEX, q931_element_type_vals, 0xF,
3251                     "Type of element in the channel number/slot map octets", HFILL }},
3252
3253                 { &hf_q931_channel_number,
3254                   { "Channel number", "q931.channel.number", FT_UINT8, BASE_DEC, NULL, 0x7F,
3255                     "Channel number", HFILL }},
3256                
3257     /* desegmentation fields */
3258                 { &hf_q931_segment_overlap,
3259                   { "Segment overlap", "q931.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3260                         "Fragment overlaps with other fragments", HFILL }},
3261
3262                 { &hf_q931_segment_overlap_conflict,
3263                   { "Conflicting data in fragment overlap", "q931.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3264                         "Overlapping fragments contained conflicting data", HFILL }},
3265
3266                 { &hf_q931_segment_multiple_tails,
3267                   { "Multiple tail fragments found", "q931.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3268                         "Several tails were found when defragmenting the packet", HFILL }},
3269
3270                 { &hf_q931_segment_too_long_segment,
3271                   { "Segment too long", "q931.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3272                         "Segment contained data past end of packet", HFILL }},
3273
3274                 { &hf_q931_segment_error,
3275                   { "Defragmentation error", "q931.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3276                         "Defragmentation error due to illegal fragments", HFILL }},
3277
3278                 { &hf_q931_segment,
3279                   { "Q.931 Segment", "q931.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3280                         "Q.931 Segment", HFILL }},
3281
3282                 { &hf_q931_segments,
3283                   { "Q.931 Segments", "q931.segments", FT_NONE, BASE_NONE, NULL, 0x0,
3284                         "Q.931 Segments", HFILL }},
3285
3286                 { &hf_q931_reassembled_in,
3287                   { "Reassembled Q.931 in frame", "q931.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3288                         "This Q.931 message is reassembled in this frame", HFILL}}, 
3289         };
3290         static gint *ett[] = {
3291                 &ett_q931,
3292                 &ett_q931_ie,
3293                 &ett_q931_segments,
3294                 &ett_q931_segment,
3295         };
3296         module_t *q931_module;
3297
3298         proto_q931 = proto_register_protocol("Q.931", "Q.931", "q931");
3299         proto_register_field_array (proto_q931, hf, array_length(hf));
3300         proto_register_subtree_array(ett, array_length(ett));
3301         register_init_routine(q931_init);
3302
3303         register_dissector("q931", dissect_q931, proto_q931);
3304         register_dissector("q931.tpkt", dissect_q931_tpkt, proto_q931);
3305         q931_tpkt_handle = find_dissector("q931.tpkt");
3306         q931_tpkt_pdu_handle = create_dissector_handle(dissect_q931_tpkt_pdu,
3307             proto_q931);
3308         register_dissector("q931.ie", dissect_q931_ie_cs0, proto_q931);
3309         register_dissector("q931.ie.cs7", dissect_q931_ie_cs7, proto_q931);
3310
3311         /* subdissector code */ 
3312         codeset_dissector_table = register_dissector_table("q931.codeset", "Q.931 Codeset", FT_UINT8, BASE_HEX);
3313         ie_dissector_table = register_dissector_table("q931.ie", "Q.931 IE", FT_UINT16, BASE_HEX);
3314
3315         q931_module = prefs_register_protocol(proto_q931, NULL);
3316         prefs_register_bool_preference(q931_module, "desegment_h323_messages",
3317             "Reassemble Q.931 messages spanning multiple TCP segments",
3318             "Whether the Q.931 dissector should reassemble messages spanning multiple TCP segments."
3319             " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3320             &q931_desegment);
3321         prefs_register_bool_preference(q931_module, "reassembly",
3322             "Reassemble segmented Q.931 messages",
3323             "Reassemble segmented Q.931 messages (Q.931 - Annex H)",
3324             &q931_reassembly);
3325        /* Register for tapping */
3326        q931_tap = register_tap("q931");
3327 }
3328
3329 void
3330 proto_reg_handoff_q931(void)
3331 {
3332         dissector_handle_t q931_handle;
3333
3334         q931_handle = find_dissector("q931");
3335         dissector_add("lapd.sapi", LAPD_SAPI_Q931, q931_handle);
3336
3337         /*
3338          * Attempt to get a handle for the H.225 dissector.
3339          * If we can't, the handle we get is null, and we'll just
3340          * dissect putatively-H.255 Call Signaling stuff as User
3341          * Information.
3342          */
3343         h225_handle = find_dissector("h225");
3344
3345         /*
3346          * For H.323.
3347          */
3348         heur_dissector_add("tcp", dissect_q931_tpkt_heur, proto_q931);
3349 }
3350
3351 static void reset_q931_packet_info(q931_packet_info *pi)
3352 {
3353     if(pi == NULL) {
3354         return;
3355     }
3356
3357     pi->calling_number = NULL;
3358     pi->called_number = NULL;
3359     pi->cause_value = 0xFF;
3360     pi->crv = -1;
3361 }