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