Add the NLPID value for PPP.
[obnox/wireshark/wip.git] / packet-q931.c
1 /* packet-q931.c
2  * Routines for Q.931 frame disassembly
3  * Guy Harris <guy@alum.mit.edu>
4  *
5  * $Id: packet-q931.c,v 1.13 2000/01/13 05:41:21 guy Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@zing.org>
9  * Copyright 1998
10  *
11  * 
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  * 
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
33 #endif
34
35 #include <stdio.h>
36 #include <glib.h>
37 #include <string.h>
38 #include "packet.h"
39 #include "nlpid.h"
40 #include "packet-q931.h"
41
42 /* Q.931 references:
43  *
44  * http://www.acacia-net.com/Clarinet/Protocol/q9313svn.htm
45  * http://www.acacia-net.com/Clarinet/Protocol/q9311sc3.htm
46  * http://www.acacia-net.com/Clarinet/Protocol/q9317oz7.htm
47  * http://www.protocols.com/pbook/isdn.htm
48  * http://freesoft.org/CIE/Topics/126.htm
49  * http://noc.comstar.ru/miscdocs/ascend-faq-cause-codes.html
50  * http://www.andrews-arnold.co.uk/isdn/q931cause.html
51  * http://www.tulatelecom.ru/staff/german/DSSHelp/MessList/InfEl/InfElList.html
52  */
53
54 static int proto_q931 = -1;
55 static int hf_q931_discriminator = -1;
56 static int hf_q931_call_ref_len = -1;
57 static int hf_q931_call_ref = -1;
58 static int hf_q931_message_type = -1;
59
60 static gint ett_q931 = -1;
61 static gint ett_q931_ie = -1;
62
63 /*
64  * Q.931 message types.
65  */
66 #define Q931_ALERTING           0x01
67 #define Q931_CALL_PROCEEDING    0x02
68 #define Q931_CONNECT            0x07
69 #define Q931_CONNECT_ACK        0x0F
70 #define Q931_PROGRESS           0x03
71 #define Q931_SETUP              0x05
72 #define Q931_SETUP_ACK          0x0B
73 #define Q931_HOLD               0x24
74 #define Q931_HOLD_ACK           0x28
75 #define Q931_HOLD_REJECT        0x30
76 #define Q931_RESUME             0x26
77 #define Q931_RESUME_ACK         0x2E
78 #define Q931_RESUME_REJECT      0x22
79 #define Q931_RETRIEVE           0x31
80 #define Q931_RETRIEVE_ACK       0x33
81 #define Q931_RETRIEVE_REJECT    0x37
82 #define Q931_SUSPEND            0x25
83 #define Q931_SUSPEND_ACK        0x2D
84 #define Q931_SUSPEND_REJECT     0x21
85 #define Q931_USER_INFORMATION   0x20
86 #define Q931_DISCONNECT         0x45
87 #define Q931_RELEASE            0x4D
88 #define Q931_RELEASE_COMPLETE   0x5A
89 #define Q931_RESTART            0x46
90 #define Q931_RESTART_ACK        0x4E
91 #define Q931_CONGESTION_CONTROL 0x79
92 #define Q931_FACILITY           0x62
93 #define Q931_INFORMATION        0x7B
94 #define Q931_NOTIFY             0x6E
95 #define Q931_REGISTER           0x64
96 #define Q931_SEGMENT            0x60
97 #define Q931_STATUS             0x7D
98 #define Q931_STATUS_ENQUIRY     0x75
99
100 static const value_string q931_message_type_vals[] = {
101         { Q931_ALERTING,                "ALERTING" },
102         { Q931_CALL_PROCEEDING,         "CALL PROCEEDING" },
103         { Q931_CONNECT,                 "CONNECT" },
104         { Q931_CONNECT_ACK,             "CONNECT ACKNOWLEDGE" },
105         { Q931_PROGRESS,                "PROGRESS" },
106         { Q931_SETUP,                   "SETUP" },
107         { Q931_SETUP_ACK,               "SETUP ACKNOWLEDGE" },
108         { Q931_HOLD,                    "HOLD" },
109         { Q931_HOLD_ACK,                "HOLD_ACKNOWLEDGE" },
110         { Q931_HOLD_REJECT,             "HOLD_REJECT" },
111         { Q931_RESUME,                  "RESUME" },
112         { Q931_RESUME_ACK,              "RESUME ACKNOWLEDGE" },
113         { Q931_RESUME_REJECT,           "RESUME REJECT" },
114         { Q931_RETRIEVE,                "RETRIEVE" },
115         { Q931_RETRIEVE_ACK,            "RETRIEVE ACKNOWLEDGE" },
116         { Q931_RETRIEVE_REJECT,         "RETRIEVE REJECT" },
117         { Q931_SUSPEND,                 "SUSPEND" },
118         { Q931_SUSPEND_ACK,             "SUSPEND ACKNOWLEDGE" },
119         { Q931_SUSPEND_REJECT,          "SUSPEND REJECT" },
120         { Q931_USER_INFORMATION,        "USER INFORMATION" },
121         { Q931_DISCONNECT,              "DISCONNECT" },
122         { Q931_RELEASE,                 "RELEASE" },
123         { Q931_RELEASE_COMPLETE,        "RELEASE COMPLETE" },
124         { Q931_RESTART,                 "RESTART" },
125         { Q931_RESTART_ACK,             "RESTART ACKNOWLEDGE" },
126         { Q931_CONGESTION_CONTROL,      "CONGESTION CONTROL" },
127         { Q931_FACILITY,                "FACILITY" },
128         { Q931_INFORMATION,             "INFORMATION" },
129         { Q931_NOTIFY,                  "NOTIFY" },
130         { Q931_REGISTER,                "REGISTER" },
131         { Q931_SEGMENT,                 "SEGMENT" },
132         { Q931_STATUS,                  "STATUS" },
133         { Q931_STATUS_ENQUIRY,          "STATUS ENQUIRY" },
134         { 0,                            NULL }
135 };
136
137 /*
138  * Information elements.
139  */
140
141 /*
142  * Single-octet IEs.
143  */
144 #define Q931_IE_SO_IDENTIFIER_MASK      0xf0    /* IE identifier mask */
145 #define Q931_IE_SO_IDENTIFIER_SHIFT     4       /* IE identifier shift */
146 #define Q931_IE_SO_IE_MASK              0x0F    /* IE mask */
147
148 #define Q931_IE_SHIFT                   0x90
149 #define Q931_IE_SHIFT_LOCKING           0x08    /* locking shift */
150 #define Q931_IE_SHIFT_CODESET           0x0F    /* codeset */
151
152 #define Q931_IE_MORE_DATA_OR_SEND_COMP  0xA0    /* More Data or Sending Complete */
153 #define Q931_IE_MORE_DATA               0xA0
154 #define Q931_IE_SENDING_COMPLETE        0xA1
155
156 #define Q931_IE_CONGESTION_LEVEL        0xB0
157 #define Q931_IE_REPEAT_INDICATOR        0xD0
158
159 /*
160  * Variable-length IEs.
161  */
162 #define Q931_IE_VL_EXTENSION            0x80    /* Extension flag */
163
164 /*
165  * Codeset 0 (default).
166  */
167 #define Q931_IE_SEGMENTED_MESSAGE       0x00
168 #define Q931_IE_BEARER_CAPABILITY       0x04
169 #define Q931_IE_CAUSE                   0x08
170 #define Q931_IE_CALL_IDENTITY           0x10
171 #define Q931_IE_CALL_STATE              0x14
172 #define Q931_IE_CHANNEL_IDENTIFICATION  0x18
173 #define Q931_IE_FACILITY                0x1C
174 #define Q931_IE_PROGRESS_INDICATOR      0x1E
175 #define Q931_IE_NETWORK_SPECIFIC_FACIL  0x20    /* Network Specific Facilities */
176 #define Q931_IE_NOTIFICATION_INDICATOR  0x27
177 #define Q931_IE_DISPLAY                 0x28
178 #define Q931_IE_DATE_TIME               0x29
179 #define Q931_IE_KEYPAD_FACILITY         0x2C
180 #define Q931_IE_INFORMATION_REQUEST     0x32
181 #define Q931_IE_SIGNAL                  0x34
182 #define Q931_IE_SWITCHHOOK              0x36
183 #define Q931_IE_FEATURE_ACTIVATION      0x38
184 #define Q931_IE_FEATURE_INDICATION      0x39
185 #define Q931_IE_ENDPOINT_IDENTIFIER     0x3B
186 #define Q931_IE_SERVICE_PROFILE_ID      0x3A
187 #define Q931_IE_INFORMATION_RATE        0x40
188 #define Q931_IE_E2E_TRANSIT_DELAY       0x42    /* End-to-end Transit Delay */
189 #define Q931_IE_TD_SELECTION_AND_INT    0x43    /* Transit Delay Selection and Indication */
190 #define Q931_IE_PL_BINARY_PARAMETERS    0x44    /* Packet layer binary parameters */
191 #define Q931_IE_PL_WINDOW_SIZE          0x45    /* Packet layer window size */
192 #define Q931_IE_PACKET_SIZE             0x46    /* Packet size */
193 #define Q931_IE_CUG                     0x47    /* Closed user group */
194 #define Q931_IE_REVERSE_CHARGE_IND      0x4A    /* Reverse charging indication */
195 #define Q931_IE_CALLING_PARTY_NUMBER    0x6C    /* Calling Party Number */
196 #define Q931_IE_CALLING_PARTY_SUBADDR   0x6D    /* Calling Party Subaddress */
197 #define Q931_IE_CALLED_PARTY_NUMBER     0x70    /* Called Party Number */
198 #define Q931_IE_CALLED_PARTY_SUBADDR    0x71    /* Called Party Subaddress */
199 #define Q931_IE_REDIRECTING_NUMBER      0x74
200 #define Q931_IE_REDIRECTION_NUMBER      0x76
201 #define Q931_IE_TRANSIT_NETWORK_SEL     0x78    /* Transit Network Selection */
202 #define Q931_IE_RESTART_INDICATOR       0x79
203 #define Q931_IE_LOW_LAYER_COMPAT        0x7C    /* Low-Layer Compatibility */
204 #define Q931_IE_HIGH_LAYER_COMPAT       0x7D    /* High-Layer Compatibility */
205 #define Q931_IE_USER_USER               0x7E    /* User-User */
206 #define Q931_IE_ESCAPE                  0x7F    /* Escape for extension */
207
208 /*
209  * Codeset 0 ETSI.
210  */
211 #define Q931_IE_CONNECTED_NUMBER        0x8C
212 #define Q931_IE_CONNECTED_SUBADDR       0x8D
213
214 /*
215  * Codeset 5 (National-specific) Belgium.
216  */
217 #define Q931_IE_CHARGING_ADVICE         0x1A
218
219 /*
220  * Codeset 5 (National-specific) Bellcore National ISDN.
221  */
222 #define Q931_IE_OPERATOR_SYSTEM_ACCESS  0x1D
223
224 /*
225  * Codeset 6 (Network-specific) Belgium.
226  */
227 /* 0x1A is Charging Advice, as with Codeset 5 */
228 #define Q931_IE_REDIRECTING_NUMBER      0x74
229
230 /*
231  * Codeset 6 (Network-specific) FT-Numeris.
232  */
233 /* 0x1D is User Capability */
234
235 /*
236  * Codeset 6 (Network-specific) Bellcore National ISDN.
237  */
238 #define Q931_IE_REDIRECTING_SUBADDR     0x75    /* Redirecting Subaddress */
239 /* 0x76 is Redirection Number, but that's also Codeset 0 */
240 #define Q931_IE_CALL_APPEARANCE         0x7B
241
242 static const value_string q931_info_element_vals[] = {
243         { Q931_IE_SEGMENTED_MESSAGE,            "Segmented message" },
244         { Q931_IE_BEARER_CAPABILITY,            "Bearer capability" },
245         { Q931_IE_CAUSE,                        "Cause" },
246         { Q931_IE_CALL_IDENTITY,                "Call identity" },
247         { Q931_IE_CALL_STATE,                   "Call state" },
248         { Q931_IE_CHANNEL_IDENTIFICATION,       "Channel identification" },
249         { Q931_IE_FACILITY,                     "Facility" },
250         { Q931_IE_PROGRESS_INDICATOR,           "Progress indicator" },
251         { Q931_IE_NETWORK_SPECIFIC_FACIL,       "Network specific facilities" },
252         { Q931_IE_NOTIFICATION_INDICATOR,       "Notification indicator" },
253         { Q931_IE_DISPLAY,                      "Display" },
254         { Q931_IE_DATE_TIME,                    "Date/Time" },
255         { Q931_IE_KEYPAD_FACILITY,              "Keypad facility" },
256         { Q931_IE_INFORMATION_REQUEST,          "Information request" },
257         { Q931_IE_SIGNAL,                       "Signal" },
258         { Q931_IE_SWITCHHOOK,                   "Switchhook" },
259         { Q931_IE_FEATURE_ACTIVATION,           "Feature activation" },
260         { Q931_IE_FEATURE_INDICATION,           "Feature Indication" },
261         { Q931_IE_ENDPOINT_IDENTIFIER,          "Endpoint identifier" },
262         { Q931_IE_SERVICE_PROFILE_ID,           "Service profile ID" },
263         { Q931_IE_INFORMATION_RATE,             "Information rate" },
264         { Q931_IE_E2E_TRANSIT_DELAY,            "End-to-end transit delay" },
265         { Q931_IE_TD_SELECTION_AND_INT,         "Transit delay selection and indication" },
266         { Q931_IE_PL_BINARY_PARAMETERS,         "Packet layer binary parameters" },
267         { Q931_IE_PL_WINDOW_SIZE,               "Packet layer window size" },
268         { Q931_IE_PACKET_SIZE,                  "Packet size" },
269         { Q931_IE_CUG,                          "Closed user group" },
270         { Q931_IE_REVERSE_CHARGE_IND,           "Reverse charging indication" },
271         { Q931_IE_CALLING_PARTY_NUMBER,         "Calling party number" },
272         { Q931_IE_CALLING_PARTY_SUBADDR,        "Calling party subaddress" },
273         { Q931_IE_CALLED_PARTY_NUMBER,          "Called party number" },
274         { Q931_IE_CALLED_PARTY_SUBADDR,         "Called party subaddress" },
275         { Q931_IE_REDIRECTING_NUMBER,           "Redirecting number" },
276         { Q931_IE_REDIRECTION_NUMBER,           "Redirection number" },
277         { Q931_IE_TRANSIT_NETWORK_SEL,          "Transit network selection" },
278         { Q931_IE_RESTART_INDICATOR,            "Restart indicator" },
279         { Q931_IE_LOW_LAYER_COMPAT,             "Low-layer compatibility" },
280         { Q931_IE_HIGH_LAYER_COMPAT,            "High-layer compatibility" },
281         { Q931_IE_USER_USER,                    "User-user" },
282         { Q931_IE_ESCAPE,                       "Escape" },
283         { Q931_IE_CONNECTED_NUMBER,             "Connected number" },
284         { Q931_IE_CONNECTED_SUBADDR,            "Connected subaddress" },
285         { Q931_IE_CHARGING_ADVICE,              "Charging advice" },
286         { Q931_IE_OPERATOR_SYSTEM_ACCESS,       "Operator system access" },
287         { Q931_IE_REDIRECTING_NUMBER,           "Redirecting number" },
288         { Q931_IE_REDIRECTING_SUBADDR,          "Redirecting subaddress" },
289         { Q931_IE_CALL_APPEARANCE,              "Call appearance" },
290         { 0,                                    NULL }
291 };
292
293 static const value_string q931_congestion_level_vals[] = {
294         { 0x0, "Receiver ready" },
295         { 0xF, "Receiver not ready" },
296         { 0,   NULL }
297 };
298
299 static const value_string q931_repeat_indication_vals[] = {
300         { 0x2, "Prioritized list" },
301         { 0,   NULL }
302 };
303
304 /*
305  * ITU-standardized coding.
306  */
307 #define Q931_ITU_STANDARDIZED_CODING    0x00
308
309 /*
310  * Dissect a Segmented message information element.
311  */
312 static void
313 dissect_q931_segmented_message_ie(const u_char *pd, int offset, int len,
314     proto_tree *tree)
315 {
316         if (len != 2) {
317                 proto_tree_add_text(tree, offset, len,
318                     "Segmented message: length is %d, should be 2\n", len);
319                 return;
320         }
321         if (pd[offset] & 0x80) {
322                 proto_tree_add_text(tree, offset, 1,
323                     "First segment: %u segments remaining",
324                     pd[offset] & 0x7F);
325         } else {
326                 proto_tree_add_text(tree, offset, 1,
327                     "Not first segment: %u segments remaining",
328                     pd[offset] & 0x7F);
329         }
330         proto_tree_add_text(tree, offset + 1, 1,
331             "Segmented message type: %u\n", pd[offset + 1]);
332 }
333
334 /*
335  * Dissect a Bearer capability or Low-layer compatibility information element.
336  */
337 static const value_string q931_bc_coding_standard_vals[] = {
338         { 0x00, "ITU-T standardized coding" },
339         { 0x20, "ISO/IEC standard" },
340         { 0x40, "National standard" },
341         { 0x60, "Standard defined for this particular network" },
342         { 0,    NULL }
343 };
344
345 static const value_string q931_information_transfer_capability_vals[] = {
346         { 0x00, "Speech" },
347         { 0x08, "Unrestricted digital information" },
348         { 0x09, "Restricted digital information" },
349         { 0x10, "3.1 kHz audio" },
350         { 0x11, "Unrestricted digital information with tones/announcements" },
351         { 0x18, "Video" },
352         { 0,    NULL }
353 };
354         
355 static const value_string q931_transfer_mode_vals[] = {
356         { 0x00, "Circuit mode" },
357         { 0x40, "Packet mode" },
358         { 0,    NULL }
359 };
360
361 #define Q931_IT_RATE_MULTIRATE  0x18
362
363 static const value_string q931_information_transfer_rate_vals[] = {
364         { 0x00,                         "Packet mode" },
365         { 0x10,                         "64 kbit/s" },
366         { 0x11,                         "2 x 64 kbit/s" },
367         { 0x13,                         "384 kbit/s" },
368         { 0x15,                         "1536 kbit/s" },
369         { 0x17,                         "1920 kbit/s" },
370         { Q931_IT_RATE_MULTIRATE,       "Multirate (64 kbit/s base rate)" },
371         { 0,                            NULL }
372 };
373         
374 static const value_string q931_uil1_vals[] = {
375         { 0x01, "V.110/I.460/X.30 rate adaption" },
376         { 0x02, "Recommendation G.711 u-law" },
377         { 0x03, "Recommendation G.711 A-law" },
378         { 0x04, "Recommendation G.721 32 kbit/s ADPCM and Recommendation I.460" },
379         { 0x05, "Recommendation H.221 and H.242" },
380         { 0x06, "Recommendation H.223 and H.245" },
381         { 0x07, "Non-ITU-T-standardized rate adaption" },
382         { 0x08, "V.120 rate adaption" },
383         { 0x09, "X.31 HDLC flag stuffing" },
384         { 0,    NULL },
385 };
386
387 static const value_string q931_l1_user_rate_vals[] = {
388         { 0x00, "Rate indicated by E-bits" },
389         { 0x01, "0.6 kbit/s" },
390         { 0x02, "1.2 kbit/s" },
391         { 0x03, "2.4 kbit/s" },
392         { 0x04, "3.6 kbit/s" },
393         { 0x05, "4.8 kbit/s" },
394         { 0x06, "7.2 kbit/s" },
395         { 0x07, "8 kbit/s" },
396         { 0x08, "9.6 kbit/s" },
397         { 0x09, "14.4 kbit/s" },
398         { 0x0A, "16 kbit/s" },
399         { 0x0B, "19.2 kbit/s" },
400         { 0x0C, "32 kbit/s" },
401         { 0x0E, "48 kbit/s" },
402         { 0x0F, "56 kbit/s" },
403         { 0x10, "64 kbit/s "},
404         { 0x15, "0.1345 kbit/s" },
405         { 0x16, "0.100 kbit/s" },
406         { 0x17, "0.075/1.2 kbit/s" },
407         { 0x18, "1.2/0.075 kbit/s" },
408         { 0x19, "0.050 kbit/s" },
409         { 0x1A, "0.075 kbit/s" },
410         { 0x1B, "0.110 kbit/s" },
411         { 0x1C, "0.150 kbit/s" },
412         { 0x1D, "0.200 kbit/s" },
413         { 0x1E, "0.300 kbit/s" },
414         { 0x1F, "12 kbit/s" },
415         { 0,    NULL }
416 };
417
418 static const value_string q931_l1_intermediate_rate_vals[] = {
419         { 0x20, "8 kbit/s" },
420         { 0x40, "16 kbit/s" },
421         { 0x60, "32 kbit/s" },
422         { 0,    NULL }
423 };
424
425 static const value_string q931_l1_stop_bits_vals[] = {
426         { 0x20, "1" },
427         { 0x40, "1.5" },
428         { 0x60, "2" },
429         { 0,    NULL }
430 };
431
432 static const value_string q931_l1_data_bits_vals[] = {
433         { 0x08, "5" },
434         { 0x10, "7" },
435         { 0x18, "8" },
436         { 0,    NULL }
437 };
438
439 static const value_string q931_l1_parity_vals[] = {
440         { 0x00, "Odd" },
441         { 0x02, "Even" },
442         { 0x03, "None" },
443         { 0x04, "Forced to 0" },
444         { 0x05, "Forced to 1" },
445         { 0,    NULL }
446 };
447
448 static const value_string q931_l1_modem_type_vals[] = {
449         { 0x11, "V.21" },
450         { 0x12, "V.22" },
451         { 0x13, "V.22 bis" },
452         { 0x14, "V.23" },
453         { 0x15, "V.26" },
454         { 0x16, "V.26 bis" },
455         { 0x17, "V.26 ter" },
456         { 0x18, "V.27" },
457         { 0x19, "V.27 bis" },
458         { 0x1A, "V.27 ter" },
459         { 0x1B, "V.29" },
460         { 0x1C, "V.32" },
461         { 0x1E, "V.34" },
462         { 0,    NULL }
463 };
464
465 #define Q931_UIL2_USER_SPEC     0x10
466
467 static const value_string q931_uil2_vals[] = {
468         { 0x01,                 "Basic mode ISO 1745" },
469         { 0x02,                 "Q.921/I.441" },        /* LAPD */
470         { 0x06,                 "X.25, link layer" },   /* LAPB */
471         { 0x07,                 "X.25 multilink" },     /* or 0x0F? */
472         { 0x08,                 "T.71 Extended LAPB" },
473         { 0x09,                 "HDLC ARM" },
474         { 0x0A,                 "HDLC NRM" },
475         { 0x0B,                 "HDLC ABM" },
476         { 0x0C,                 "ISO 8802/2 LLC" },
477         { 0x0D,                 "X.75 Single Link Procedure" },
478         { 0x0E,                 "Q.922" },
479         { 0x0F,                 "Core aspects of Q.922" },
480         { Q931_UIL2_USER_SPEC,  "User-specified" },
481         { 0x11,                 "ISO 7776 DTE-DTE operation" },
482         { 0,                    NULL }
483 };
484
485 static const value_string q931_mode_vals[] = {
486         { 0x20, "Normal mode" },
487         { 0x40, "Extended mode" },
488         { 0,    NULL }
489 };
490
491 #define Q931_UIL3_X25_PL        0x06
492 #define Q931_UIL3_ISO_8208      0x07    /* X.25-based */
493 #define Q931_UIL3_X223          0x08    /* X.25-based */
494 #define Q931_UIL3_TR_9577       0x0B
495 #define Q931_UIL3_USER_SPEC     0x10
496
497 static const value_string q931_uil3_vals[] = {
498         { 0x02,                 "Q.931/I.451" },
499         { Q931_UIL3_X25_PL,     "X.25, packet layer" },
500         { Q931_UIL3_ISO_8208,   "ISO/IEC 8208" },
501         { Q931_UIL3_X223,       "X.223/ISO 8878" },
502         { 0x09,                 "ISO/IEC 8473" },
503         { 0x0A,                 "T.70" },
504         { Q931_UIL3_TR_9577,    "ISO/IEC TR 9577" },
505         { Q931_UIL3_USER_SPEC,  "User-specified" },
506         { 0,                    NULL }
507 };
508
509 void
510 dissect_q931_bearer_capability_ie(const u_char *pd, int offset, int len,
511     proto_tree *tree)
512 {
513         guint8 octet;
514         guint8 coding_standard;
515         guint8 it_rate;
516         guint8 modem_type;
517         guint8 uil2_protocol;
518         guint8 uil3_protocol;
519         guint8 add_l3_info;
520
521         if (len == 0)
522                 return;
523         octet = pd[offset];
524         coding_standard = octet & 0x60;
525         proto_tree_add_text(tree, offset, 1,
526             "Coding standard: %s",
527             val_to_str(coding_standard, q931_bc_coding_standard_vals, NULL));
528         if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
529                 /*
530                  * We don't know how the bearer capability is encoded,
531                  * so just dump it as data and be done with it.
532                  */
533                 proto_tree_add_text(tree, offset,
534                     len, "Data: %s", bytes_to_str(&pd[offset], len));
535                 return;
536         }
537         proto_tree_add_text(tree, offset, 1,
538             "Information transfer capability: %s",
539             val_to_str(octet & 0x1F, q931_information_transfer_capability_vals,
540               "Unknown (0x%02X)"));
541         offset += 1;
542         len -= 1;
543
544         /*
545          * XXX - only in Low-layer compatibility information element.
546          */
547         if (!(octet & Q931_IE_VL_EXTENSION)) {
548                 if (len == 0)
549                         return;
550                 octet = pd[offset];
551                 proto_tree_add_text(tree, offset, 1,
552                     "Out-band negotiation %spossible",
553                     (octet & 0x40) ? "" : "not ");
554                 offset += 1;
555                 len -= 1;
556         }
557
558         if (len == 0)
559                 return;
560         octet = pd[offset];
561         proto_tree_add_text(tree, offset, 1,
562             "Transfer mode: %s",
563             val_to_str(octet & 0x60, q931_transfer_mode_vals,
564               "Unknown (0x%02X)"));
565         it_rate = octet & 0x1F;
566         proto_tree_add_text(tree, offset, 1,
567             "Information transfer rate: %s",
568             val_to_str(it_rate, q931_information_transfer_rate_vals,
569               "Unknown (0x%02X)"));
570         offset += 1;
571         len -= 1;
572
573         if (it_rate == Q931_IT_RATE_MULTIRATE) {
574                 if (len == 0)
575                         return;
576                 proto_tree_add_text(tree, offset, 1, "Rate multiplier: %u", pd[offset]);
577                 offset += 1;
578                 len -= 1;
579         }
580
581         if (len == 0)
582                 return;
583         octet = pd[offset];
584         if ((octet & 0x60) == 0x20) {
585                 /*
586                  * Layer 1 information.
587                  */
588                 proto_tree_add_text(tree, offset, 1,
589                     "User information layer 1 protocol: %s",
590                     val_to_str(octet & 0x1F, q931_uil1_vals,
591                       "Unknown (0x%02X)"));
592                 offset += 1;
593                 len -= 1;
594                 
595                 if (octet & Q931_IE_VL_EXTENSION)
596                         goto l1_done;
597                 if (len == 0)
598                         return;
599                 octet = pd[offset];
600                 proto_tree_add_text(tree, offset, 1,
601                     "Layer 1 is %s",
602                     (octet & 0x40) ? "Asynchronous" : "Synchronous");
603                 proto_tree_add_text(tree, offset, 1,
604                     "Layer 1 in-band negotiation is %spossible",
605                     (octet & 0x20) ? "" : "not ");
606                 proto_tree_add_text(tree, offset, 1,
607                     "User rate: %s",
608                     val_to_str(octet & 0x1F, q931_l1_user_rate_vals,
609                       "Unknown (0x%02X)"));
610                 offset += 1;
611                 len -= 1;
612
613                 if (octet & Q931_IE_VL_EXTENSION)
614                         goto l1_done;
615                 if (len == 0)
616                         return;
617                 octet = pd[offset];
618                 proto_tree_add_text(tree, offset, 1,
619                     "Intermediate rate: %s",
620                       val_to_str(octet & 0x60, q931_l1_intermediate_rate_vals,
621                        "Unknown (0x%X)"));
622                 proto_tree_add_text(tree, offset, 1,
623                     "%s to send data with network independent clock",
624                     (octet & 0x10) ? "Required" : "Not required");
625                 proto_tree_add_text(tree, offset, 1,
626                     "%s accept data with network independent clock",
627                     (octet & 0x08) ? "Can" : "Cannot");
628                 proto_tree_add_text(tree, offset, 1,
629                     "%s to send data with flow control mechanism",
630                     (octet & 0x04) ? "Required" : "Not required");
631                 proto_tree_add_text(tree, offset, 1,
632                     "%s accept data with flow control mechanism",
633                     (octet & 0x02) ? "Can" : "Cannot");
634                 offset += 1;
635                 len -= 1;
636
637                 if (octet & Q931_IE_VL_EXTENSION)
638                         goto l1_done;
639                 if (len == 0)
640                         return;
641                 octet = pd[offset];
642                 proto_tree_add_text(tree, offset, 1,
643                     "Rate adaption header %sincluded",
644                     (octet & 0x40) ? "" : "not ");
645                 proto_tree_add_text(tree, offset, 1,
646                     "Multiple frame establishment %ssupported",
647                     (octet & 0x20) ? "" : "not ");
648                 proto_tree_add_text(tree, offset, 1,
649                     "%s mode of operation",
650                     (octet & 0x10) ? "Protocol sensitive" : "Bit transparent");
651                 proto_tree_add_text(tree, offset, 1,
652                     (octet & 0x08) ?
653                       "Full protocol negotiation" : "LLI = 256 only");
654                 proto_tree_add_text(tree, offset, 1,
655                     "Message originator is %s",
656                     (octet & 0x04) ? "Assignor only" : "Default assignee");
657                 proto_tree_add_text(tree, offset, 1,
658                     "Negotiation is done %s",
659                     (octet & 0x02) ? "in-band" : "out-of-band");
660                 offset += 1;
661                 len -= 1;
662
663                 if (octet & Q931_IE_VL_EXTENSION)
664                         goto l1_done;
665                 if (len == 0)
666                         return;
667                 octet = pd[offset];
668                 proto_tree_add_text(tree, offset, 1,
669                     "Stop bits: %s",
670                       val_to_str(octet & 0x60, q931_l1_stop_bits_vals,
671                        "Unknown (0x%X)"));
672                 proto_tree_add_text(tree, offset, 1,
673                     "Data bits: %s",
674                       val_to_str(octet & 0x18, q931_l1_data_bits_vals,
675                        "Unknown (0x%X)"));
676                 proto_tree_add_text(tree, offset, 1,
677                     "Parity: %s",
678                       val_to_str(octet & 0x08, q931_l1_parity_vals,
679                        "Unknown (0x%X)"));
680
681                 if (octet & Q931_IE_VL_EXTENSION)
682                         goto l1_done;
683                 if (len == 0)
684                         return;
685                 octet = pd[offset];
686                 proto_tree_add_text(tree, offset, 1,
687                     "%s duplex",
688                     (octet & 0x40) ? "Full" : "Half");
689                 modem_type = octet & 0x3F;
690                 if (modem_type <= 0x5 ||
691                     (modem_type >= 0x20 && modem_type <= 0x2F)) {
692                         proto_tree_add_text(tree, offset, 1,
693                             "Modem type: National use 0x%02X", modem_type);
694                 } else if (modem_type >= 0x30) {
695                         proto_tree_add_text(tree, offset, 1,
696                             "Modem type: User specified 0x%02X", modem_type);
697                 } else {
698                         proto_tree_add_text(tree, offset, 1,
699                             "Modem type: %s",
700                               val_to_str(modem_type, q931_l1_modem_type_vals,
701                               NULL));
702                 }
703                 offset += 1;
704                 len -= 1;
705         }
706 l1_done:
707         ;
708
709         if (len == 0)
710                 return;
711         octet = pd[offset];
712         if ((octet & 0x60) == 0x40) {
713                 /*
714                  * Layer 2 information.
715                  */
716                 uil2_protocol = octet & 0x1F;
717                 proto_tree_add_text(tree, offset, 1,
718                     "User information layer 2 protocol: %s",
719                     val_to_str(uil2_protocol, q931_uil2_vals,
720                       "Unknown (0x%02X)"));
721                 offset += 1;
722                 len -= 1;
723
724                 /*
725                  * XXX - only in Low-layer compatibility information element.
726                  */
727                 if (octet & Q931_IE_VL_EXTENSION)
728                         goto l2_done;
729                 if (len == 0)
730                         return;
731                 octet = pd[offset];
732                 if (uil2_protocol == Q931_UIL2_USER_SPEC) {
733                         proto_tree_add_text(tree, offset, 1,
734                             "User-specified layer 2 protocol information: 0x%02X",
735                             octet & 0x7F);
736                 } else {
737                         proto_tree_add_text(tree, offset, 1,
738                             "Mode: %s",
739                             val_to_str(octet & 0x60, q931_mode_vals,
740                               "Unknown (0x%02X)"));
741                 }
742                 offset += 1;
743                 len -= 1;
744
745                 if (octet & Q931_IE_VL_EXTENSION)
746                         goto l2_done;
747                 if (len == 0)
748                         return;
749                 octet = pd[offset];
750                 proto_tree_add_text(tree, offset, 1,
751                     "Window size: %u k", octet & 0x7F);
752                 offset += 1;
753                 len -= 1;
754         }
755 l2_done:
756         ;
757
758         if (len == 0)
759                 return;
760         octet = pd[offset];
761         if ((octet & 0x60) == 0x60) {
762                 /*
763                  * Layer 3 information.
764                  */
765                 uil3_protocol = octet & 0x1F;
766                 proto_tree_add_text(tree, offset, 1,
767                     "User information layer 3 protocol: %s",
768                     val_to_str(uil3_protocol, q931_uil3_vals,
769                       "Unknown (0x%02X)"));
770                 offset += 1;
771                 len -= 1;
772
773
774                 /*
775                  * XXX - only in Low-layer compatibility information element.
776                  */
777                 if (octet & Q931_IE_VL_EXTENSION)
778                         goto l3_done;
779                 if (len == 0)
780                         return;
781                 octet = pd[offset];
782                 switch (uil3_protocol) {
783
784                 case Q931_UIL3_X25_PL:
785                 case Q931_UIL3_ISO_8208:
786                 case Q931_UIL3_X223:
787                         proto_tree_add_text(tree, offset, 1,
788                             "Mode: %s",
789                             val_to_str(octet & 0x60, q931_mode_vals,
790                               "Unknown (0x%02X)"));
791                         offset += 1;
792                         len -= 1;
793
794                         if (octet & Q931_IE_VL_EXTENSION)
795                                 goto l3_done;
796                         if (len == 0)
797                                 return;
798                         octet = pd[offset];
799                         proto_tree_add_text(tree, offset, 1,
800                             "Default packet size: %u", octet & 0x0F);
801                         offset += 1;
802                         len -= 1;
803
804                         if (octet & Q931_IE_VL_EXTENSION)
805                                 goto l3_done;
806                         if (len == 0)
807                                 return;
808                         octet = pd[offset];
809                         proto_tree_add_text(tree, offset, 1,
810                             "Packet window size: %u", octet & 0x7F);
811                         offset += 1;
812                         len -= 1;
813                         break;
814
815                 case Q931_UIL3_USER_SPEC:
816                         proto_tree_add_text(tree, offset, 1,
817                             "Default packet size: %u octets",
818                             1 << (octet & 0x0F));
819                         offset += 1;
820                         len -= 1;
821                         break;
822
823                 case Q931_UIL3_TR_9577:
824                         add_l3_info = (octet & 0x0F) << 4;
825                         if (octet & Q931_IE_VL_EXTENSION)
826                                 goto l3_done;
827                         if (len == 0)
828                                 return;
829                         octet = pd[offset + 1];
830                         add_l3_info |= (octet & 0x0F);
831                         proto_tree_add_text(tree, offset, 2,
832                             "Additional layer 3 protocol information: %s",
833                             val_to_str(add_l3_info, nlpid_vals,
834                               "Unknown (0x%02X)"));
835                         offset += 2;
836                         len -= 2;
837                         break;
838                 }
839         }
840 l3_done:
841         ;
842 }
843
844 /*
845  * Dissect a Cause information element.
846  */
847 static const value_string q931_cause_coding_standard_vals[] = {
848         { 0x00, "ITU-T standardized coding" },
849         { 0x20, "ISO/IEC standard" },
850         { 0x40, "National standard" },
851         { 0x60, "Standard specific to identified location" },
852         { 0,    NULL }
853 };
854         
855 static const value_string q931_cause_location_vals[] = {
856         { 0x00, "User (U)" },
857         { 0x01, "Private network serving the local user (LPN)" },
858         { 0x02, "Public network serving the local user (LN)" },
859         { 0x03, "Transit network (TN)" },
860         { 0x04, "Public network serving the remote user (RLN)" },
861         { 0x05, "Private network serving the remote user (RPN)" },
862         { 0x07, "International network (INTL)" },
863         { 0x0A, "Network beyond interworking point (BI)" },
864         { 0,    NULL }
865 };
866
867 static const value_string q931_cause_recommendation_vals[] = {
868         { 0x00, "Q.931" },
869         { 0x03, "X.21" },
870         { 0x04, "X.25" },
871         { 0x05, "Q.1031/Q.1051" },
872         { 0,    NULL }
873 };
874
875 /*
876  * Cause codes for Cause.
877  */
878 static const value_string q931_cause_code_vals[] = {
879         { 0x00, "Valid cause code not yet received" },
880         { 0x01, "Unallocated (unassigned) number" },
881         { 0x02, "No route to specified transit network" },
882         { 0x03, "No route to destination" },
883         { 0x04, "Send special information tone" },
884         { 0x05, "Misdialled trunk prefix" },
885         { 0x06, "Channel unacceptable" },
886         { 0x07, "Call awarded and being delivered in an established channel" },
887         { 0x08, "Prefix 0 dialed but not allowed" },
888         { 0x09, "Prefix 1 dialed but not allowed" },
889         { 0x0A, "Prefix 1 dialed but not required" },
890         { 0x0B, "More digits received than allowed, call is proceeding" },
891         { 0x10, "Normal call clearing" },
892         { 0x11, "User busy" },
893         { 0x12, "No user responding" },
894         { 0x13, "No answer from user (user alerted)" },
895         { 0x14, "Subscriber absent" },
896         { 0x15, "Call rejected" },
897         { 0x16, "Number changed" },
898         { 0x17, "Reverse charging rejected" },
899         { 0x18, "Call suspended" },
900         { 0x19, "Call resumed" },
901         { 0x1A, "Non-selected user clearing" },
902         { 0x1B, "Destination out of order" },
903         { 0x1C, "Invalid number format (incomplete number)" },
904         { 0x1D, "Facility rejected" },
905         { 0x1E, "Response to STATUS ENQUIRY" },
906         { 0x1F, "Normal unspecified" },
907         { 0x21, "Circuit out of order" },
908         { 0x22, "No circuit/channel available" },
909         { 0x23, "Destination unattainable" },
910         { 0x25, "Degraded service" },
911         { 0x26, "Network out of order" },
912         { 0x27, "Transit delay range cannot be achieved" },
913         { 0x28, "Throughput range cannot be achieved" },
914         { 0x29, "Temporary failure" },
915         { 0x2A, "Switching equipment congestion" },
916         { 0x2B, "Access information discarded" },
917         { 0x2C, "Requested circuit/channel not available" },
918         { 0x2D, "Pre-empted" },
919         { 0x2E, "Precedence call blocked" },
920         { 0x2F, "Resources unavailable, unspecified" },
921         { 0x31, "Quality of service unavailable" },
922         { 0x32, "Requested facility not subscribed" },
923         { 0x33, "Reverse charging not allowed" },
924         { 0x34, "Outgoing calls barred" },
925         { 0x35, "Outgoing calls barred within CUG" },
926         { 0x36, "Incoming calls barred" },
927         { 0x37, "Incoming calls barred within CUG" },
928         { 0x38, "Call waiting not subscribed" },
929         { 0x39, "Bearer capability not authorized" },
930         { 0x3A, "Bearer capability not presently available" },
931         { 0x3E, "Inconsistency in designated outgoing access information and subscriber class" },
932         { 0x3F, "Service or option not available, unspecified" },
933         { 0x41, "Bearer capability not implemented" },
934         { 0x42, "Channel type not implemented" },
935         { 0x43, "Transit network selection not implemented" },
936         { 0x44, "Message not implemented" },
937         { 0x45, "Requested facility not implemented" },
938         { 0x46, "Only restricted digital information bearer capability is available" },
939         { 0x4F, "Service or option not implemented, unspecified" },
940         { 0x51, "Invalid call reference value" },
941         { 0x52, "Identified channel does not exist" },
942         { 0x53, "Call identity does not exist for suspended call" },
943         { 0x54, "Call identity in use" },
944         { 0x55, "No call suspended" },
945         { 0x56, "Call having the requested call identity has been cleared" },
946         { 0x57, "Called user not member of CUG" },
947         { 0x58, "Incompatible destination" },
948         { 0x59, "Non-existent abbreviated address entry" },
949         { 0x5A, "Destination address missing, and direct call not subscribed" },
950         { 0x5B, "Invalid transit network selection (national use)" },
951         { 0x5C, "Invalid facility parameter" },
952         { 0x5D, "Mandatory information element is missing" },
953         { 0x5F, "Invalid message, unspecified" },
954         { 0x60, "Mandatory information element is missing" },
955         { 0x61, "Message type non-existent or not implemented" },
956         { 0x62, "Message not compatible with call state or message type non-existent or not implemented" },
957         { 0x63, "Information element nonexistant or not implemented" },
958         { 0x64, "Invalid information element contents" },
959         { 0x65, "Message not compatible with call state" },
960         { 0x66, "Recovery on timer expiry" },
961         { 0x67, "Parameter non-existent or not implemented - passed on" },
962         { 0x6E, "Message with unrecognized parameter discarded" },
963         { 0x6F, "Protocol error, unspecified" },
964         { 0x7F, "Internetworking, unspecified" },
965         { 0,    NULL }
966 };
967
968 static void
969 dissect_q931_cause_ie(const u_char *pd, int offset, int len,
970     proto_tree *tree)
971 {
972         guint8 octet;
973         guint8 coding_standard;
974
975         if (len == 0)
976                 return;
977         octet = pd[offset];
978         coding_standard = octet & 0x60;
979         proto_tree_add_text(tree, offset, 1,
980             "Coding standard: %s",
981             val_to_str(coding_standard, q931_cause_coding_standard_vals, NULL));
982         if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
983                 /*
984                  * We don't know how the cause is encoded,
985                  * so just dump it as data and be done with it.
986                  */
987                 proto_tree_add_text(tree, offset,
988                     len, "Data: %s", bytes_to_str(&pd[offset], len));
989                 return;
990         }
991         proto_tree_add_text(tree, offset, 1,
992             "Location: %s",
993             val_to_str(octet & 0x0F, q931_cause_location_vals,
994               "Unknown (0x%X)"));
995         offset += 1;
996         len -= 1;
997
998         if (!(octet & Q931_IE_VL_EXTENSION)) {
999                 if (len == 0)
1000                         return;
1001                 octet = pd[offset];
1002                 proto_tree_add_text(tree, offset, 1,
1003                     "Recommendation: %s",
1004                     val_to_str(octet & 0x7F, q931_cause_recommendation_vals,
1005                       "Unknown (0x%X)"));
1006                 offset += 1;
1007                 len -= 1;
1008         }
1009
1010         if (len == 0)
1011                 return;
1012         octet = pd[offset];
1013         proto_tree_add_text(tree, offset, 1,
1014             "Cause value: %s",
1015             val_to_str(octet & 0x7F, q931_cause_code_vals,
1016               "Unknown (0x%X)"));
1017         offset += 1;
1018         len -= 1;
1019
1020         if (len == 0)
1021                 return;
1022         proto_tree_add_text(tree, offset, len,
1023             "Diagnostics: %s",
1024             bytes_to_str(&pd[offset], len));
1025 }
1026
1027 /*
1028  * Dissect a Call state information element.
1029  */
1030 static const value_string q931_coding_standard_vals[] = {
1031         { 0x00, "ITU-T standardized coding" },
1032         { 0x20, "ISO/IEC standard" },
1033         { 0x40, "National standard" },
1034         { 0x60, "Standard defined for the network" },
1035         { 0,    NULL }
1036 };
1037         
1038 static const value_string q931_call_state_vals[] = {
1039         { 0x00, "Null" },
1040         { 0x01, "Call initiated" },
1041         { 0x02, "Overlap sending" },
1042         { 0x03, "Outgoing call proceeding" },
1043         { 0x04, "Call delivered" },
1044         { 0x06, "Call present" },
1045         { 0x07, "Call received" },
1046         { 0x09, "Connect request" },
1047         { 0x0A, "Incoming call proceeding" },
1048         { 0x0B, "Active" },
1049         { 0x0C, "Disconnect request" },
1050         { 0x0F, "Disconnect indication" },
1051         { 0x11, "Suspend request" },
1052         { 0x13, "Resume request" },
1053         { 0x16, "Release request" },
1054         { 0x19, "Overlap receiving" },
1055         { 0x3D, "Restart request" },
1056         { 0x3E, "Restart" },
1057         { 0,    NULL }
1058 };
1059
1060 static void
1061 dissect_q931_call_state_ie(const u_char *pd, int offset, int len,
1062     proto_tree *tree)
1063 {
1064         guint8 octet;
1065         guint8 coding_standard;
1066
1067         if (len == 0)
1068                 return;
1069         octet = pd[offset];
1070         coding_standard = octet & 0x60;
1071         proto_tree_add_text(tree, offset, 1,
1072             "Coding standard: %s",
1073             val_to_str(coding_standard, q931_coding_standard_vals, NULL));
1074         if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
1075                 /*
1076                  * We don't know how the call state is encoded,
1077                  * so just dump it as data and be done with it.
1078                  */
1079                 proto_tree_add_text(tree, offset,
1080                     len, "Data: %s", bytes_to_str(&pd[offset], len));
1081                 return;
1082         }
1083         proto_tree_add_text(tree, offset, 1,
1084             "Call state: %s",
1085             val_to_str(octet & 0x3F, q931_call_state_vals,
1086               "Unknown (0x%02X)"));
1087 }
1088
1089 /*
1090  * Dissect a Channel identification information element.
1091  */
1092 #define Q931_INTERFACE_IDENTIFIED       0x40
1093 #define Q931_NOT_BASIC_CHANNEL          0x20
1094
1095 static const value_string q931_basic_channel_selection_vals[] = {
1096         { 0x00, "No channel" },
1097         { 0x01, "B1 channel" },
1098         { 0x02, "B2 channel" },
1099         { 0x03, "Any channel" },
1100         { 0,    NULL }
1101 };
1102
1103 static const value_string q931_not_basic_channel_selection_vals[] = {
1104         { 0x00, "No channel" },
1105         { 0x01, "Channel indicated in following octets" },
1106         { 0x03, "Any channel" },
1107         { 0,    NULL }
1108 };
1109
1110 #define Q931_IS_SLOT_MAP                0x10
1111         
1112 static const value_string q931_element_type_vals[] = {
1113         { 0x03, "B-channel units" },
1114         { 0x06, "H0-channel units" },
1115         { 0x08, "H11-channel units" },
1116         { 0x09, "H12-channel units" },
1117         { 0,    NULL }
1118 };
1119
1120 static void
1121 dissect_q931_channel_identification_ie(const u_char *pd, int offset, int len,
1122     proto_tree *tree)
1123 {
1124         guint8 octet;
1125         int identifier_offset;
1126         int identifier_len;
1127         guint8 coding_standard;
1128
1129         if (len == 0)
1130                 return;
1131         octet = pd[offset];
1132         proto_tree_add_text(tree, offset, 1,
1133             "Interface %s identified",
1134             (octet & Q931_INTERFACE_IDENTIFIED) ? "explicitly" : "implicitly");
1135         proto_tree_add_text(tree, offset, 1,
1136             "%s interface",
1137             (octet & Q931_NOT_BASIC_CHANNEL) ? "Not basic" : "Basic");
1138         proto_tree_add_text(tree, offset, 1,
1139             "Indicated channel is %s",
1140             (octet & 0x08) ? "required" : "preferred");
1141         proto_tree_add_text(tree, offset, 1,
1142             "Indicated channel is %sthe D-channel",
1143             (octet & 0x04) ? "" : "not ");
1144         if (octet & Q931_NOT_BASIC_CHANNEL) {
1145                 proto_tree_add_text(tree, offset, 1,
1146                     "Channel selection: %s",
1147                     val_to_str(octet & 0x03, q931_not_basic_channel_selection_vals,
1148                       NULL));
1149         } else {
1150                 proto_tree_add_text(tree, offset, 1,
1151                     "Channel selection: %s",
1152                     val_to_str(octet & 0x03, q931_basic_channel_selection_vals,
1153                       NULL));
1154         }
1155         offset += 1;
1156         len -= 1;
1157
1158         if (octet & Q931_INTERFACE_IDENTIFIED) {
1159                 identifier_offset = offset;
1160                 identifier_len = 0;
1161                 do {
1162                         if (len == 0)
1163                                 break;
1164                         octet = pd[offset];
1165                         offset += 1;
1166                         len -= 1;
1167                         identifier_len++;
1168                 } while (!(octet & Q931_IE_VL_EXTENSION));
1169
1170                 /*
1171                  * XXX - do we want to strip off the 8th bit on the
1172                  * last octet of the interface identifier?
1173                  */
1174                 if (identifier_len != 0) {
1175                         proto_tree_add_text(tree, identifier_offset,
1176                             identifier_len, "Interface identifier: %s",
1177                             bytes_to_str(&pd[identifier_offset],
1178                               identifier_len));
1179                 }
1180         }
1181
1182         if (octet & Q931_NOT_BASIC_CHANNEL) {
1183                 if (len == 0)
1184                         return;
1185                 octet = pd[offset];
1186                 coding_standard = octet & 0x60;
1187                 proto_tree_add_text(tree, offset, 1,
1188                     "Coding standard: %s",
1189                     val_to_str(coding_standard, q931_coding_standard_vals,
1190                       NULL));
1191                 if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
1192                         /*
1193                          * We don't know how the channel identifier is
1194                          * encoded, so just dump it as data and be done
1195                          * with it.
1196                          */
1197                         proto_tree_add_text(tree, offset,
1198                             len, "Data: %s", bytes_to_str(&pd[offset], len));
1199                         return;
1200                 }
1201                 proto_tree_add_text(tree, offset, 1,
1202                     "Channel is indicated by %s",
1203                     (octet & Q931_IS_SLOT_MAP) ? "slot map" : "number");
1204                 proto_tree_add_text(tree, offset, 1,
1205                     "%s type: %s",
1206                     (octet & Q931_IS_SLOT_MAP) ? "Map element" : "Channel",
1207                     val_to_str(octet & 0x0F, q931_element_type_vals,
1208                     "Unknown (0x%02X)"));
1209
1210                 /*
1211                  * XXX - dump the channel number or slot map.
1212                  */
1213         }
1214 }
1215
1216 /*
1217  * Dissect a Progress indicator information element.
1218  */
1219 static const value_string q931_progress_description_vals[] = {
1220         { 0x01, "Call is not end-to-end ISDN - progress information available in-band" },
1221         { 0x02, "Destination address is non-ISDN" },
1222         { 0x03, "Origination address is non-ISDN" },
1223         { 0x04, "Call has returned to the ISDN" },
1224         { 0x05, "Interworking has occurred and has resulted in a telecommunications service change" },
1225         { 0x08, "In-band information or an appropriate pattern is now available" },
1226         { 0,    NULL }
1227 };
1228
1229 void
1230 dissect_q931_progress_indicator_ie(const u_char *pd, int offset, int len,
1231     proto_tree *tree)
1232 {
1233         guint8 octet;
1234         guint8 coding_standard;
1235
1236         if (len == 0)
1237                 return;
1238         octet = pd[offset];
1239         coding_standard = octet & 0x60;
1240         proto_tree_add_text(tree, offset, 1,
1241             "Coding standard: %s",
1242             val_to_str(coding_standard, q931_cause_coding_standard_vals, NULL));
1243         if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
1244                 /*
1245                  * We don't know how the progress indicator is encoded,
1246                  * so just dump it as data and be done with it.
1247                  */
1248                 proto_tree_add_text(tree, offset,
1249                     len, "Data: %s", bytes_to_str(&pd[offset], len));
1250                 return;
1251         }
1252         proto_tree_add_text(tree, offset, 1,
1253             "Location: %s",
1254             val_to_str(octet & 0x0F, q931_cause_location_vals,
1255               "Unknown (0x%X)"));
1256         offset += 1;
1257         len -= 1;
1258
1259         if (len == 0)
1260                 return;
1261         octet = pd[offset];
1262         proto_tree_add_text(tree, offset, 1,
1263             "Progress description: %s",
1264             val_to_str(octet & 0x7F, q931_progress_description_vals,
1265               "Unknown (0x%02X)"));
1266 }
1267
1268 /*
1269  * Dissect a Network-specific facilities or Transit network selection
1270  * information element.
1271  */
1272 static const value_string q931_netid_type_vals[] = {
1273         { 0x00, "User specified" },
1274         { 0x20, "National network identification" },
1275         { 0x30, "International network identification" },
1276         { 0,    NULL }
1277 };
1278
1279 static const value_string q931_netid_plan_vals[] = {
1280         { 0x00, "Unknown" },
1281         { 0x01, "Carrier Identification Code" },
1282         { 0x03, "X.121 data network identification code" },
1283         { 0,    NULL }
1284 };
1285
1286 static void
1287 dissect_q931_ns_facilities_ie(const u_char *pd, int offset, int len,
1288     proto_tree *tree)
1289 {
1290         guint8 octet;
1291         int netid_len;
1292
1293         if (len == 0)
1294                 return;
1295         octet = pd[offset];
1296         netid_len = octet & 0x7F;
1297         proto_tree_add_text(tree, offset, 1,
1298             "Network identification length: %u",
1299             netid_len);
1300         offset += 1;
1301         len -= 1;
1302         if (netid_len != 0) {
1303                 if (len == 0)
1304                         return;
1305                 octet = pd[offset];
1306                 proto_tree_add_text(tree, offset, 1,
1307                     "Type of network identification: %s",
1308                     val_to_str(octet & 0x70, q931_netid_type_vals,
1309                       "Unknown (0x%02X)"));
1310                 proto_tree_add_text(tree, offset, 1,
1311                     "Network identification plan: %s",
1312                     val_to_str(octet & 0x0F, q931_netid_plan_vals,
1313                       "Unknown (0x%02X)"));
1314                 offset += 1;
1315                 len -= 1;
1316                 netid_len--;
1317
1318                 if (len == 0)
1319                         return;
1320                 if (netid_len > len)
1321                         netid_len = len;
1322                 if (netid_len != 0) {
1323                         proto_tree_add_text(tree, offset, netid_len,
1324                             "Network identification: %.*s",
1325                             netid_len, &pd[offset]);
1326                         offset += netid_len;
1327                         len -= netid_len;
1328                 }
1329         }
1330
1331         /*
1332          * Whatever is left is the network-specific facility
1333          * specification.
1334          */
1335          if (len == 0)
1336                 return;
1337         proto_tree_add_text(tree, offset,
1338             len, "Network-specific facility specification: %s",
1339             bytes_to_str(&pd[offset], len));
1340 }
1341
1342 /*
1343  * Dissect a Notification indicator information element.
1344  */
1345 static const value_string q931_notification_description_vals[] = {
1346         { 0x00, "User suspended" },
1347         { 0x01, "User resumed" },
1348         { 0x02, "Bearer service change" },
1349         { 0,    NULL }
1350 };
1351
1352 static void
1353 dissect_q931_notification_indicator_ie(const u_char *pd, int offset, int len,
1354     proto_tree *tree)
1355 {
1356         guint8 octet;
1357
1358         if (len == 0)
1359                 return;
1360         octet = pd[offset];
1361         proto_tree_add_text(tree, offset, 1,
1362             "Notification description: %s",
1363             val_to_str(octet & 0x7F, q931_notification_description_vals,
1364               "Unknown (0x%02X)"));
1365 }
1366
1367 /*
1368  * Dissect a Date/time information element.
1369  */
1370 static void
1371 dissect_q931_date_time_ie(const u_char *pd, int offset, int len,
1372     proto_tree *tree)
1373 {
1374         if (len != 6) {
1375                 proto_tree_add_text(tree, offset, len,
1376                     "Date/time: length is %d, should be 6\n", len);
1377                 return;
1378         }
1379         /*
1380          * XXX - what is "year" relative to?  Is "month" 0-origin or
1381          * 1-origin?  Q.931 doesn't say....
1382          */
1383         proto_tree_add_text(tree, offset, 6,
1384             "Date/time: %02u-%02u-%02u %02u:%02u:%02u",
1385             pd[offset + 0], pd[offset + 1], pd[offset + 2],
1386             pd[offset + 3], pd[offset + 4], pd[offset + 5]);
1387 }
1388
1389 /*
1390  * Dissect a Signal information element.
1391  */
1392 static const value_string q931_signal_vals[] = {
1393         { 0x00, "Dial tone on" },
1394         { 0x01, "Ring tone on" },
1395         { 0x02, "Intercept tone on" },
1396         { 0x03, "Network congestion tone on" }, /* "fast busy" */
1397         { 0x04, "Busy tone on" },
1398         { 0x05, "Confirm tone on" },
1399         { 0x06, "Answer tone on" },
1400         { 0x07, "Call waiting tone on" },
1401         { 0x08, "Off-hoke warning tone on" },
1402         { 0x09, "Preemption tone on" },
1403         { 0x3F, "Tones off" },
1404         { 0x40, "Alerting on - pattern 0" },
1405         { 0x41, "Alerting on - pattern 1" },
1406         { 0x42, "Alerting on - pattern 2" },
1407         { 0x43, "Alerting on - pattern 3" },
1408         { 0x44, "Alerting on - pattern 4" },
1409         { 0x45, "Alerting on - pattern 5" },
1410         { 0x46, "Alerting on - pattern 6" },
1411         { 0x47, "Alerting on - pattern 7" },
1412         { 0x4F, "Alerting off" },
1413         { 0,    NULL }
1414 };
1415
1416 static void
1417 dissect_q931_signal_ie(const u_char *pd, int offset, int len,
1418     proto_tree *tree)
1419 {
1420         if (len != 1) {
1421                 proto_tree_add_text(tree, offset, len,
1422                     "Signal: length is %d, should be 1\n", len);
1423                 return;
1424         }
1425         proto_tree_add_text(tree, offset, 1,
1426             "Signal: %s",
1427             val_to_str(pd[offset], q931_signal_vals, "Unknown (0x%02X)"));
1428 }
1429
1430 /*
1431  * Dissect an Information rate information element.
1432  */
1433 static const value_string q931_throughput_class_vals[] = {
1434         { 0x03, "75 bit/s" },
1435         { 0x04, "150 bit/s" },
1436         { 0x05, "300 bit/s" },
1437         { 0x06, "600 bit/s" },
1438         { 0x07, "1200 bit/s" },
1439         { 0x08, "2400 bit/s" },
1440         { 0x09, "4800 bit/s" },
1441         { 0x0A, "9600 bit/s" },
1442         { 0x0B, "19200 bit/s" },
1443         { 0x0C, "48000 bit/s" },
1444         { 0x0D, "64000 bit/s" },
1445         { 0,    NULL }
1446 };
1447
1448 static void
1449 dissect_q931_information_rate_ie(const u_char *pd, int offset, int len,
1450     proto_tree *tree)
1451 {
1452         if (len != 4) {
1453                 proto_tree_add_text(tree, offset, len,
1454                     "Information rate: length is %d, should be 4\n", len);
1455                 return;
1456         }
1457         proto_tree_add_text(tree, offset + 0, 1,
1458             "Incoming information rate: %s",
1459             val_to_str(pd[offset + 0] & 0x1F, q931_throughput_class_vals,
1460               "Unknown (0x%02X)"));
1461         proto_tree_add_text(tree, offset + 1, 1,
1462             "Outgoing information rate: %s",
1463             val_to_str(pd[offset + 1] & 0x1F, q931_throughput_class_vals,
1464               "Unknown (0x%02X)"));
1465         proto_tree_add_text(tree, offset + 2, 1,
1466             "Minimum incoming information rate: %s",
1467             val_to_str(pd[offset + 2] & 0x1F, q931_throughput_class_vals,
1468               "Unknown (0x%02X)"));
1469         proto_tree_add_text(tree, offset + 3, 1,
1470             "Minimum outgoing information rate: %s",
1471             val_to_str(pd[offset + 3] & 0x1F, q931_throughput_class_vals,
1472               "Unknown (0x%02X)"));
1473 }
1474
1475 static int
1476 dissect_q931_guint16_value(const u_char *pd, int offset, int len,
1477     proto_tree *tree, char *label)
1478 {
1479         guint8 octet;
1480         guint16 value;
1481         int value_len;
1482
1483         value_len = 0;
1484
1485         octet = pd[offset];
1486         if (octet & Q931_IE_VL_EXTENSION) {
1487                 /*
1488                  * Only one octet long - error.
1489                  */
1490                 goto bad_length;
1491         }
1492         value = (octet & 0x3) << 14;
1493         offset += 1;
1494         len -= 1;
1495         value_len++;
1496
1497         if (len == 0) {
1498                 /*
1499                  * We've reached the end of the information element - error.
1500                  */
1501                 goto past_end;
1502         }
1503         octet = pd[offset];
1504         if (octet & Q931_IE_VL_EXTENSION) {
1505                 /*
1506                  * Only two octets long - error.
1507                  */
1508                 goto bad_length;
1509         }
1510         value |= (octet & 0x7F) << 7;
1511         offset += 1;
1512         len -= 1;
1513         value_len++;
1514
1515         if (len == 0) {
1516                 /*
1517                  * We've reached the end of the information element - error.
1518                  */
1519                 goto past_end;
1520         }
1521         octet = pd[offset];
1522         if (!(octet & Q931_IE_VL_EXTENSION)) {
1523                 /*
1524                  * More than three octets long - error.
1525                  */
1526                 goto bad_length;
1527         }
1528         value |= (octet & 0x7F);
1529         offset += 1;
1530         len -= 1;
1531         value_len++;
1532
1533         proto_tree_add_text(tree, offset, value_len, "%s: %u ms", label,
1534             value);
1535         return value_len;
1536
1537 past_end:
1538         proto_tree_add_text(tree, offset, len,
1539             "%s goes past end of information element", label);
1540         return -1;
1541
1542 bad_length:
1543         proto_tree_add_text(tree, offset, len, "%s isn't 3 octets long",
1544             label);
1545         return -1;
1546 }
1547
1548 /*
1549  * Dissect an End-to-end transit delay information element.
1550  */
1551 static void
1552 dissect_q931_e2e_transit_delay_ie(const u_char *pd, int offset, int len,
1553     proto_tree *tree)
1554 {
1555         int value_len;
1556
1557         if (len == 0)
1558                 return;
1559         value_len = dissect_q931_guint16_value(pd, offset, len, tree,
1560             "Cumulative transit delay");
1561         if (value_len < 0)
1562                 return; /* error */
1563         offset += value_len;
1564         len -= value_len;
1565
1566         if (len == 0)
1567                 return;
1568         value_len = dissect_q931_guint16_value(pd, offset, len, tree,
1569             "Requested end-to-end transit delay");
1570         if (value_len < 0)
1571                 return; /* error */
1572         offset += value_len;
1573         len -= value_len;
1574
1575         if (len == 0)
1576                 return;
1577         value_len = dissect_q931_guint16_value(pd, offset, len, tree,
1578             "Maximum end-to-end transit delay");
1579 }
1580
1581 /*
1582  * Dissect a Transit delay selection and indication information element.
1583  */
1584 static void
1585 dissect_q931_td_selection_and_int_ie(const u_char *pd, int offset, int len,
1586     proto_tree *tree)
1587 {
1588         if (len == 0)
1589                 return;
1590         dissect_q931_guint16_value(pd, offset, len, tree,
1591             "Transit delay");
1592 }
1593
1594 /*
1595  * Dissect a Packet layer binary parameters information element.
1596  */
1597 static const value_string q931_fast_selected_vals[] = {
1598         { 0x00, "Fast select not requested" },
1599         { 0x08, "Fast select not requested" },
1600         { 0x10, "Fast select requested with no restriction of response" },
1601         { 0x18, "Fast select requested with restrictions of response" },
1602         { 0x00, NULL }
1603 };
1604
1605 static void
1606 dissect_q931_pl_binary_parameters_ie(const u_char *pd, int offset, int len,
1607     proto_tree *tree)
1608 {
1609         guint8 octet;
1610
1611         if (len == 0)
1612                 return;
1613         octet = pd[offset];
1614         proto_tree_add_text(tree, offset, 1,
1615             "Fast select: %s",
1616             val_to_str(octet & 0x18, q931_fast_selected_vals,
1617               NULL));
1618         proto_tree_add_text(tree, offset, 1,
1619             "%s",
1620             (octet & 0x04) ? "No request/request denied" :
1621                              "Request indicated/request accepted");
1622         proto_tree_add_text(tree, offset, 1,
1623             "%s confirmation",
1624             (octet & 0x02) ? "Link-by-link" : "End-to-end");
1625         proto_tree_add_text(tree, offset, 1,
1626             "Modulus %u sequencing",
1627             (octet & 0x01) ? 8 : 128);
1628 }
1629
1630 /*
1631  * Dissect a Packet layer window size information element.
1632  */
1633 static void
1634 dissect_q931_pl_window_size_ie(const u_char *pd, int offset, int len,
1635     proto_tree *tree)
1636 {
1637         if (len == 0)
1638                 return;
1639         proto_tree_add_text(tree, offset, 1,
1640             "Forward value: %u", pd[offset] & 0x7F);
1641         offset += 1;
1642         len -= 1;
1643
1644         if (len == 0)
1645                 return;
1646         proto_tree_add_text(tree, offset, 1,
1647             "Backward value: %u", pd[offset] & 0x7F);
1648 }
1649
1650 /*
1651  * Dissect a Packet size information element.
1652  */
1653 static void
1654 dissect_q931_packet_size_ie(const u_char *pd, int offset, int len,
1655     proto_tree *tree)
1656 {
1657         if (len == 0)
1658                 return;
1659         proto_tree_add_text(tree, offset, 1,
1660             "Forward value: %u", pd[offset] & 0x7F);
1661         offset += 1;
1662         len -= 1;
1663
1664         if (len == 0)
1665                 return;
1666         proto_tree_add_text(tree, offset, 1,
1667             "Backward value: %u", pd[offset] & 0x7F);
1668 }
1669
1670 /*
1671  * Dissect a Closed user group information element.
1672  */
1673 static const value_string q931_cug_indication_vals[] = {
1674         { 0x01, "Closed user group selection" },
1675         { 0x02, "Closed user group with outgoing access selection and indication" },
1676         { 0,    NULL }
1677 };
1678
1679 static void
1680 dissect_q931_cug_ie(const u_char *pd, int offset, int len, proto_tree *tree)
1681 {
1682         if (len == 0)
1683                 return;
1684         proto_tree_add_text(tree, offset, 1,
1685             "CUG indication: %s",
1686             val_to_str(pd[offset] & 0x07, q931_cug_indication_vals,
1687               "Unknown (0x%02X)"));
1688         offset += 1;
1689         len -= 1;
1690
1691         if (len == 0)
1692                 return;
1693         proto_tree_add_text(tree, offset, len, "CUG index code: %.*s", len,
1694             &pd[offset]);
1695 }
1696
1697 /*
1698  * Dissect a Reverse charging indication information element.
1699  */
1700 static const value_string q931_reverse_charging_indication_vals[] = {
1701         { 0x01, "Reverse charging requested" },
1702         { 0,    NULL }
1703 };
1704
1705 static void
1706 dissect_q931_reverse_charge_ind_ie(const u_char *pd, int offset, int len,
1707     proto_tree *tree)
1708 {
1709         if (len == 0)
1710                 return;
1711         proto_tree_add_text(tree, offset, 1,
1712             "Reverse charging indication: %s",
1713             val_to_str(pd[offset] & 0x07, q931_reverse_charging_indication_vals,
1714               "Unknown (0x%02X)"));
1715 }
1716
1717 /*
1718  * Dissect a (phone) number information element.
1719  */
1720 static const value_string q931_number_type_vals[] = {
1721         { 0x00, "Unknown" },
1722         { 0x10, "International number" },
1723         { 0x20, "National number" },
1724         { 0x30, "Network specific number" },
1725         { 0x40, "Subscriber number" },
1726         { 0x60, "Abbreviated number" },
1727         { 0,    NULL }
1728 };
1729
1730 static const value_string q931_numbering_plan_vals[] = {
1731         { 0x00, "Unknown" },
1732         { 0x01, "E.164 ISDN/telephony numbering" },
1733         { 0x03, "X.121 data numbering" },
1734         { 0x04, "F.69 Telex numbering" },
1735         { 0x08, "National standard numbering" },
1736         { 0x09, "Private numbering" },
1737         { 0,    NULL }
1738 };
1739
1740 static const value_string q931_presentation_indicator_vals[] = {
1741         { 0x00, "Presentation allowed" },
1742         { 0x20, "Presentation restricted" },
1743         { 0x40, "Number not available due to interworking" },
1744         { 0,    NULL }
1745 };
1746
1747 static const value_string q931_screening_indicator_vals[] = {
1748         { 0x00, "User-provided, not screened" },
1749         { 0x01, "User-provided, verified and passed" },
1750         { 0x02, "User-provided, verified and failed" },
1751         { 0x03, "Network-provided" },
1752         { 0,    NULL }
1753 };
1754
1755 static const value_string q931_redirection_reason_vals[] = {
1756         { 0x00, "Unknown" },
1757         { 0x01, "Call forwarding busy or called DTE busy" },
1758         { 0x02, "Call forwarding no reply" },
1759         { 0x04, "Call deflection" },
1760         { 0x09, "Called DTE out of order" },
1761         { 0x0A, "Call forwarding by the called DTE" },
1762         { 0x0F, "Call forwarding unconditional or systematic call redirection" },
1763         { 0,    NULL }
1764 };
1765
1766 static void
1767 dissect_q931_number_ie(const u_char *pd, int offset, int len,
1768     proto_tree *tree)
1769 {
1770         guint8 octet;
1771
1772         if (len == 0)
1773                 return;
1774         octet = pd[offset];
1775         proto_tree_add_text(tree, offset, 1,
1776             "Type of number: %s",
1777             val_to_str(octet & 0x70, q931_number_type_vals,
1778               "Unknown (0x%02X)"));
1779         proto_tree_add_text(tree, offset, 1,
1780             "Numbering plan: %s",
1781             val_to_str(octet & 0x0F, q931_numbering_plan_vals,
1782               "Unknown (0x%02X)"));
1783         offset += 1;
1784         len -= 1;
1785
1786         if (!(octet & Q931_IE_VL_EXTENSION)) {
1787                 if (len == 0)
1788                         return;
1789                 octet = pd[offset];
1790                 proto_tree_add_text(tree, offset, 1,
1791                     "Presentation indicator: %s",
1792                     val_to_str(octet & 0x60, q931_presentation_indicator_vals,
1793                       "Unknown (0x%X)"));
1794                 proto_tree_add_text(tree, offset, 1,
1795                     "Screening indicator: %s",
1796                     val_to_str(octet & 0x03, q931_screening_indicator_vals,
1797                       "Unknown (0x%X)"));
1798                 offset += 1;
1799                 len -= 1;
1800         }
1801
1802         /*
1803          * XXX - only in a Redirecting number information element.
1804          */
1805         if (!(octet & Q931_IE_VL_EXTENSION)) {
1806                 if (len == 0)
1807                         return;
1808                 octet = pd[offset];
1809                 proto_tree_add_text(tree, offset, 1,
1810                     "Reason for redirection: %s",
1811                     val_to_str(octet & 0x0F, q931_redirection_reason_vals,
1812                       "Unknown (0x%X)"));
1813                 offset += 1;
1814                 len -= 1;
1815         }
1816
1817         if (len == 0)
1818                 return;
1819         proto_tree_add_text(tree, offset, len, "Number: %.*s",
1820             len, &pd[offset]);
1821 }
1822
1823 /*
1824  * Dissect a party subaddress information element.
1825  */
1826 static const value_string q931_subaddress_type_vals[] = {
1827         { 0x00, "X.213/ISO 8348 Add.2 NSAP" },
1828         { 0x20, "User-specified" },
1829         { 0,    NULL }
1830 };
1831
1832 static const value_string q931_odd_even_indicator_vals[] = {
1833         { 0x00, "Even number of address signals" },
1834         { 0x10, "Odd number of address signals" },
1835         { 0,    NULL }
1836 };
1837
1838 static void
1839 dissect_q931_party_subaddr_ie(const u_char *pd, int offset, int len,
1840     proto_tree *tree)
1841 {
1842         guint8 octet;
1843
1844         if (len == 0)
1845                 return;
1846         octet = pd[offset];
1847         proto_tree_add_text(tree, offset, 1,
1848             "Type of subaddress: %s",
1849             val_to_str(octet & 0x70, q931_subaddress_type_vals,
1850               "Unknown (0x%02X)"));
1851         proto_tree_add_text(tree, offset, 1,
1852             "Odd/even indicator: %s",
1853             val_to_str(octet & 0x10, q931_odd_even_indicator_vals,
1854               NULL));
1855         offset += 1;
1856         len -= 1;
1857
1858         if (len == 0)
1859                 return;
1860         proto_tree_add_text(tree, offset, len, "Subaddress: %s",
1861             bytes_to_str(&pd[offset], len));
1862 }
1863
1864 /*
1865  * Dissect a Restart indicator information element.
1866  */
1867 static const value_string q931_restart_indicator_class_vals[] = {
1868         { 0x00, "Indicated channels" },
1869         { 0x06, "Single interface" },
1870         { 0x07, "All interfaces" },
1871         { 0,    NULL }
1872 };
1873
1874 static void
1875 dissect_q931_restart_indicator_ie(const u_char *pd, int offset, int len,
1876     proto_tree *tree)
1877 {
1878         if (len != 1) {
1879                 proto_tree_add_text(tree, offset, len,
1880                     "Restart indicator: length is %d, should be 1\n", len);
1881                 return;
1882         }
1883         proto_tree_add_text(tree, offset, 1,
1884             "Restart indicator: %s",
1885             val_to_str(pd[offset] & 0x07, q931_restart_indicator_class_vals,
1886               "Unknown (0x%02X)"));
1887 }
1888
1889 /*
1890  * Dissect a High-layer compatibility information element.
1891  */
1892 #define Q931_AUDIOVISUAL        0x60
1893 static const value_string q931_high_layer_characteristics_vals[] = {
1894         { 0x01,             "Telephony" },
1895         { 0x04,             "F.182 Facsimile Group 2/3" },
1896         { 0x21,             "F.184 Facsimile Group 4 Class I" },
1897         { 0x24,             "F.230 Teletex, basic and mixed mode, and F.184 Facsimile Group 4, Classes II and III" },
1898         { 0x28,             "F.220 Teletex, basic and processable mode" },
1899         { 0x31,             "F.200 Teletex, basic mode" },
1900         { 0x32,             "F.300 and T.102 syntax-based Videotex" },
1901         { 0x33,             "F.300 and T.101 international Videotex interworking" },
1902         { 0x35,             "F.60 Telex" },
1903         { 0x38,             "X.400 Message Handling Systems" },
1904         { 0x41,             "X.200 OSI application" },
1905         { 0x42,             "FTAM application" },
1906         { 0x5E,             "Reserved for maintenance" },
1907         { 0x5F,             "Reserved for management" },
1908         { Q931_AUDIOVISUAL, "F.720/F.821 and F.731 Profile 1a videotelephony" },
1909         { 0x61,             "F.702 and F.731 Profile 1b videoconferencing" },
1910         { 0x62,             "F.702 and F.731 audiographic conferencing" },
1911         { 0,                NULL }
1912 };
1913
1914 static const value_string q931_audiovisual_characteristics_vals[] = {
1915         { 0x01, "Capability set of initial channel of H.221" },
1916         { 0x02, "Capability set of subsequent channel of H.221" },
1917         { 0x21, "Capability set of initial channel of an active 3.1kHz audio or speech call" },
1918         { 0x00, NULL }
1919 };
1920
1921 void
1922 dissect_q931_high_layer_compat_ie(const u_char *pd, int offset, int len,
1923     proto_tree *tree)
1924 {
1925         guint8 octet;
1926         guint8 coding_standard;
1927         guint8 characteristics;
1928
1929         if (len == 0)
1930                 return;
1931         octet = pd[offset];
1932         coding_standard = octet & 0x60;
1933         proto_tree_add_text(tree, offset, 1,
1934             "Coding standard: %s",
1935             val_to_str(coding_standard, q931_coding_standard_vals, NULL));
1936         if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
1937                 /*
1938                  * We don't know how the call state is encoded,
1939                  * so just dump it as data and be done with it.
1940                  */
1941                 proto_tree_add_text(tree, offset,
1942                     len, "Data: %s", bytes_to_str(&pd[offset], len));
1943                 return;
1944         }
1945
1946         if (len == 0)
1947                 return;
1948         octet = pd[offset];
1949         characteristics = octet & 0x7F;
1950         proto_tree_add_text(tree, offset, 1,
1951             "High layer characteristics identification: %s",
1952             val_to_str(characteristics, q931_high_layer_characteristics_vals,
1953               NULL));
1954         offset += 1;
1955         len -= 1;
1956
1957         if (!(octet & Q931_IE_VL_EXTENSION)) {
1958                 if (len == 0)
1959                         return;
1960                 octet = pd[offset];
1961                 if (characteristics == Q931_AUDIOVISUAL) {
1962                         proto_tree_add_text(tree, offset, 1,
1963                             "Extended audiovisual characteristics identification: %s",
1964                             val_to_str(octet & 0x7F, q931_audiovisual_characteristics_vals,
1965                               NULL));
1966                 } else {
1967                         proto_tree_add_text(tree, offset, 1,
1968                             "Extended high layer characteristics identification: %s",
1969                             val_to_str(octet & 0x7F, q931_high_layer_characteristics_vals,
1970                               NULL));
1971                 }
1972         }
1973 }
1974
1975
1976 /*
1977  * Dissect a User-user information element.
1978  */
1979 #define Q931_PROTOCOL_DISCRIMINATOR_IA5 0x04
1980
1981 static const value_string q931_protocol_discriminator_vals[] = {
1982         { 0x00,                                 "User-specific protocol" },
1983         { 0x01,                                 "OSI high layer protocols" },
1984         { 0x02,                                 "X.244" },
1985         { Q931_PROTOCOL_DISCRIMINATOR_IA5,      "IA5 characters" },
1986         { 0x05,                                 "X.208 and X.209 coded user information" },
1987         { 0x07,                                 "V.120 rate adaption" },
1988         { 0x08,                                 "Q.931/I.451 user-network call control messages" },
1989         { 0,                                    NULL }
1990 };
1991
1992 static void
1993 dissect_q931_user_user_ie(const u_char *pd, int offset, int len,
1994     proto_tree *tree)
1995 {
1996         guint8 octet;
1997
1998         if (len == 0)
1999                 return;
2000         octet = pd[offset];
2001         proto_tree_add_text(tree, offset, 1,
2002             "Protocol discriminator: %s",
2003             val_to_str(octet, q931_protocol_discriminator_vals,
2004             "Unknown (0x%02x)"));
2005         offset += 1;
2006         len -= 1;
2007
2008         if (len == 0)
2009                 return;
2010         switch (octet) {
2011
2012         case Q931_PROTOCOL_DISCRIMINATOR_IA5:
2013                 proto_tree_add_text(tree, offset, len, "User information: %.*s",
2014                     len, &pd[offset]);
2015                 break;
2016
2017         default:
2018                 proto_tree_add_text(tree, offset, len, "User information: %s",
2019                     bytes_to_str(&pd[offset], len));
2020                 break;
2021         }
2022 }
2023
2024 /*
2025  * Dissect information elements consisting of ASCII^H^H^H^H^HIA5 text.
2026  */
2027 static void
2028 dissect_q931_ia5_ie(const u_char *pd, int offset, int len, proto_tree *tree,
2029     char *label)
2030 {
2031         if (len != 0) {
2032                 proto_tree_add_text(tree, offset, len, "%s: %.*s", label, len,
2033                     &pd[offset]);
2034         }
2035 }
2036
2037 static const value_string q931_codeset_vals[] = {
2038         { 0x00, "Q.931 information elements" },
2039         { 0x04, "Information elements for ISO/IEC use" },
2040         { 0x05, "Information elements for national use" },
2041         { 0x06, "Information elements specific to the local network" },
2042         { 0x07, "User-specific information elements" },
2043         { 0x00, NULL },
2044 };
2045
2046 void
2047 dissect_q931(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
2048 {
2049         proto_tree      *q931_tree = NULL;
2050         proto_item      *ti;
2051         proto_tree      *ie_tree;
2052         guint8          call_ref_len;
2053         guint8          call_ref[15];
2054         guint8          message_type;
2055         guint8          info_element;
2056         guint8          info_element_len;
2057         int             codeset;
2058         gboolean        non_locking_shift;
2059
2060         if (check_col(fd, COL_PROTOCOL))
2061                 col_add_str(fd, COL_PROTOCOL, "Q.931");
2062
2063         if (tree) {
2064                 ti = proto_tree_add_item(tree, proto_q931, offset,
2065                     END_OF_FRAME, NULL);
2066                 q931_tree = proto_item_add_subtree(ti, ett_q931);
2067
2068                 proto_tree_add_item(q931_tree, hf_q931_discriminator, offset, 1, pd[offset]);
2069         }
2070         offset += 1;
2071         call_ref_len = pd[offset] & 0xF;        /* XXX - do as a bit field? */
2072         if (q931_tree != NULL)
2073                 proto_tree_add_item(q931_tree, hf_q931_call_ref_len, offset, 1, call_ref_len);
2074         offset += 1;
2075         if (call_ref_len != 0) {
2076                 /* XXX - split this into flag and value */
2077                 memcpy(call_ref, &pd[offset], call_ref_len);
2078                 if (q931_tree != NULL)
2079                         proto_tree_add_item(q931_tree, hf_q931_call_ref, offset, call_ref_len, call_ref);
2080                 offset += call_ref_len;
2081         }
2082         message_type = pd[offset];
2083         if (check_col(fd, COL_INFO)) {
2084                 col_add_str(fd, COL_INFO,
2085                     val_to_str(message_type, q931_message_type_vals,
2086                       "Unknown message type (0x%02X)"));
2087         }
2088         if (q931_tree != NULL)
2089                 proto_tree_add_item(q931_tree, hf_q931_message_type, offset, 1, message_type);
2090         offset += 1;
2091
2092         /*
2093          * And now for the information elements....
2094          */
2095         codeset = 0;    /* start out in codeset 0 */
2096         non_locking_shift = TRUE;
2097         while (IS_DATA_IN_FRAME(offset)) {
2098                 info_element = pd[offset];
2099
2100                 /*
2101                  * Check for the single-octet IEs.
2102                  */
2103                 switch (info_element & Q931_IE_SO_IDENTIFIER_MASK) {
2104
2105                 case Q931_IE_SHIFT:
2106                         non_locking_shift =
2107                             !(info_element & Q931_IE_SHIFT_LOCKING);
2108                         codeset = info_element & Q931_IE_SHIFT_CODESET;
2109                         if (q931_tree != NULL) {
2110                                 proto_tree_add_text(q931_tree, offset, 1,
2111                                     "%s shift to codeset %u: %s",
2112                                     (non_locking_shift ? "Non-locking" : "Locking"),
2113                                     codeset,
2114                                     val_to_str(codeset, q931_codeset_vals,
2115                                       "Unknown (0x%02X)"));
2116                         }
2117                         offset += 1;
2118                         continue;
2119
2120                 case Q931_IE_MORE_DATA_OR_SEND_COMP:
2121                         switch (info_element) {
2122
2123                         case Q931_IE_MORE_DATA:
2124                                 if (q931_tree != NULL) {
2125                                         proto_tree_add_text(q931_tree, offset, 1,
2126                                             "More data");
2127                                 }
2128                                 break;
2129
2130                         case Q931_IE_SENDING_COMPLETE:
2131                                 if (q931_tree != NULL) {
2132                                         proto_tree_add_text(q931_tree, offset, 1,
2133                                             "Sending complete");
2134                                 }
2135                                 break;
2136
2137                         default:
2138                                 if (q931_tree != NULL) {
2139                                         proto_tree_add_text(q931_tree, offset, 1,
2140                                             "Unknown information element (0x%02X",
2141                                             info_element);
2142                                 }
2143                                 break;
2144                         }
2145                         offset += 1;
2146                         if (non_locking_shift)
2147                                 codeset = 0;
2148                         continue;
2149
2150                 case Q931_IE_CONGESTION_LEVEL:
2151                         if (q931_tree != NULL) {
2152                                 proto_tree_add_text(q931_tree, offset, 1,
2153                                     "Congestion level: %s",
2154                                     val_to_str(info_element & Q931_IE_SO_IE_MASK,
2155                                       q931_congestion_level_vals,
2156                                       "Unknown (0x%X)"));
2157                         }               
2158                         offset += 1;
2159                         if (non_locking_shift)
2160                                 codeset = 0;
2161                         continue;
2162
2163                 case Q931_IE_REPEAT_INDICATOR:
2164                         if (q931_tree != NULL) {
2165                                 proto_tree_add_text(q931_tree, offset, 1,
2166                                     "Repeat indicator: %s",
2167                                     val_to_str(info_element & Q931_IE_SO_IE_MASK,
2168                                       q931_repeat_indication_vals,
2169                                       "Unknown (0x%X)"));
2170                         }               
2171                         offset += 1;
2172                         if (non_locking_shift)
2173                                 codeset = 0;
2174                         continue;
2175
2176                 default:
2177                         break;
2178                 }
2179
2180                 /*
2181                  * Variable-length IE.
2182                  */
2183                 if (!BYTES_ARE_IN_FRAME(offset + 1, 1))
2184                         break;  /* ran past end of frame */
2185                 info_element_len = pd[offset + 1];
2186                 if (!BYTES_ARE_IN_FRAME(offset + 2, info_element_len))
2187                         break;  /* ran past end of frame */
2188                 if (q931_tree != NULL) {
2189                         ti = proto_tree_add_text(q931_tree, offset,
2190                             1+1+info_element_len, "%s",
2191                             val_to_str(info_element, q931_info_element_vals,
2192                               "Unknown information element (0x%02X)"));
2193                         ie_tree = proto_item_add_subtree(ti, ett_q931_ie);
2194                         proto_tree_add_text(ie_tree, offset, 1,
2195                             "Information element: %s",
2196                             val_to_str(info_element, q931_info_element_vals,
2197                               "Unknown (0x%02X)"));
2198                         proto_tree_add_text(ie_tree, offset + 1, 1,
2199                             "Length: %u", info_element_len);
2200
2201                         switch (info_element) {
2202
2203                         case Q931_IE_SEGMENTED_MESSAGE:
2204                                 dissect_q931_segmented_message_ie(pd,
2205                                     offset + 2, info_element_len, ie_tree);
2206                                 break;
2207
2208                         case Q931_IE_BEARER_CAPABILITY:
2209                         case Q931_IE_LOW_LAYER_COMPAT:
2210                                 dissect_q931_bearer_capability_ie(pd,
2211                                     offset + 2, info_element_len, ie_tree);
2212                                 break;
2213
2214                         case Q931_IE_CAUSE:
2215                                 dissect_q931_cause_ie(pd,
2216                                     offset + 2, info_element_len, ie_tree);
2217                                 break;
2218
2219                         case Q931_IE_CALL_STATE:
2220                                 dissect_q931_call_state_ie(pd,
2221                                     offset + 2, info_element_len, ie_tree);
2222                                 break;
2223
2224                         case Q931_IE_CHANNEL_IDENTIFICATION:
2225                                 dissect_q931_channel_identification_ie(pd,
2226                                     offset + 2, info_element_len, ie_tree);
2227                                 break;
2228
2229                         case Q931_IE_PROGRESS_INDICATOR:
2230                                 dissect_q931_progress_indicator_ie(pd,
2231                                     offset + 2, info_element_len, ie_tree);
2232                                 break;
2233
2234                         case Q931_IE_NETWORK_SPECIFIC_FACIL:
2235                         case Q931_IE_TRANSIT_NETWORK_SEL:
2236                                 dissect_q931_ns_facilities_ie(pd,
2237                                     offset + 2, info_element_len, ie_tree);
2238                                 break;
2239
2240                         case Q931_IE_NOTIFICATION_INDICATOR:
2241                                 dissect_q931_notification_indicator_ie(pd,
2242                                     offset + 2, info_element_len, ie_tree);
2243                                 break;
2244
2245                         case Q931_IE_DISPLAY:
2246                                 dissect_q931_ia5_ie(pd, offset + 2,
2247                                     info_element_len, ie_tree,
2248                                     "Display information");
2249                                 break;
2250
2251                         case Q931_IE_DATE_TIME:
2252                                 dissect_q931_date_time_ie(pd,
2253                                     offset + 2, info_element_len, ie_tree);
2254                                 break;
2255
2256                         case Q931_IE_KEYPAD_FACILITY:
2257                                 dissect_q931_ia5_ie(pd, offset + 2,
2258                                     info_element_len, ie_tree,
2259                                     "Keypad facility");
2260                                 break;
2261
2262                         case Q931_IE_SIGNAL:
2263                                 dissect_q931_signal_ie(pd,
2264                                     offset + 2, info_element_len, ie_tree);
2265                                 break;
2266
2267                         case Q931_IE_INFORMATION_RATE:
2268                                 dissect_q931_information_rate_ie(pd,
2269                                     offset + 2, info_element_len, ie_tree);
2270                                 break;
2271
2272                         case Q931_IE_E2E_TRANSIT_DELAY:
2273                                 dissect_q931_e2e_transit_delay_ie(pd,
2274                                     offset + 2, info_element_len, ie_tree);
2275                                 break;
2276
2277                         case Q931_IE_TD_SELECTION_AND_INT:
2278                                 dissect_q931_td_selection_and_int_ie(pd,
2279                                     offset + 2, info_element_len, ie_tree);
2280                                 break;
2281
2282                         case Q931_IE_PL_BINARY_PARAMETERS:
2283                                 dissect_q931_pl_binary_parameters_ie(pd,
2284                                     offset + 2, info_element_len, ie_tree);
2285                                 break;
2286
2287                         case Q931_IE_PL_WINDOW_SIZE:
2288                                 dissect_q931_pl_window_size_ie(pd,
2289                                     offset + 2, info_element_len, ie_tree);
2290                                 break;
2291
2292                         case Q931_IE_PACKET_SIZE:
2293                                 dissect_q931_packet_size_ie(pd,
2294                                     offset + 2, info_element_len, ie_tree);
2295                                 break;
2296
2297                         case Q931_IE_CUG:
2298                                 dissect_q931_cug_ie(pd,
2299                                     offset + 2, info_element_len, ie_tree);
2300                                 break;
2301
2302                         case Q931_IE_REVERSE_CHARGE_IND:
2303                                 dissect_q931_reverse_charge_ind_ie(pd,
2304                                     offset + 2, info_element_len, ie_tree);
2305                                 break;
2306
2307                         case Q931_IE_CALLING_PARTY_NUMBER:
2308                         case Q931_IE_CALLED_PARTY_NUMBER:
2309                         case Q931_IE_REDIRECTING_NUMBER:
2310                                 dissect_q931_number_ie(pd,
2311                                     offset + 2, info_element_len, ie_tree);
2312                                 break;
2313
2314                         case Q931_IE_CALLING_PARTY_SUBADDR:
2315                         case Q931_IE_CALLED_PARTY_SUBADDR:
2316                                 dissect_q931_party_subaddr_ie(pd,
2317                                     offset + 2, info_element_len, ie_tree);
2318                                 break;
2319
2320                         case Q931_IE_RESTART_INDICATOR:
2321                                 dissect_q931_restart_indicator_ie(pd,
2322                                     offset + 2, info_element_len, ie_tree);
2323                                 break;
2324
2325                         case Q931_IE_HIGH_LAYER_COMPAT:
2326                                 dissect_q931_high_layer_compat_ie(pd,
2327                                     offset + 2, info_element_len, ie_tree);
2328                                 break;
2329
2330                         case Q931_IE_USER_USER:
2331                                 dissect_q931_user_user_ie(pd,
2332                                     offset + 2, info_element_len, ie_tree);
2333                                 break;
2334
2335                         default:
2336                                 proto_tree_add_text(ie_tree, offset + 2,
2337                                     info_element_len, "Data: %s",
2338                                     bytes_to_str(&pd[offset + 2],
2339                                       info_element_len));
2340                                 break;
2341                         }
2342                 }
2343                 offset += 1 + 1 + info_element_len;
2344                 if (non_locking_shift)
2345                         codeset = 0;
2346         }
2347 }
2348
2349 void
2350 proto_register_q931(void)
2351 {
2352     static hf_register_info hf[] = {
2353         { &hf_q931_discriminator,
2354           { "Protocol discriminator", "q931.disc", FT_UINT8, BASE_HEX, NULL, 0x0, 
2355                 "" }},
2356
2357         { &hf_q931_call_ref_len,
2358           { "Call reference value length", "q931.call_ref_len", FT_UINT8, BASE_DEC, NULL, 0x0,
2359                 "" }},
2360
2361         { &hf_q931_call_ref,
2362           { "Call reference value", "q931.call_ref", FT_BYTES, BASE_HEX, NULL, 0x0,
2363                 "" }},
2364
2365         { &hf_q931_message_type,
2366           { "Message type", "q931.message_type", FT_UINT8, BASE_HEX, VALS(q931_message_type_vals), 0x0,
2367                 "" }},
2368
2369     };
2370     static gint *ett[] = {
2371         &ett_q931,
2372         &ett_q931_ie,
2373     };
2374
2375     proto_q931 = proto_register_protocol ("Q.931", "q931");
2376     proto_register_field_array (proto_q931, hf, array_length(hf));
2377     proto_register_subtree_array(ett, array_length(ett));
2378 }