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