Fix some "format not a string literal and no format arguments" warnings.
[obnox/wireshark/wip.git] / plugins / v5ua / packet-v5ua.c
1 /* packet-v5ua.c
2  * Routines for V5.2-User Adaptation Layer dissection
3  *
4  * $Id$
5  *
6  * Extension of ISDN Q.921-User Adaptation Layer dissection
7  * Copyright 2002, Michael Tuexen <Michael.Tuexen[AT]siemens.com>
8  *
9  * Christoph Neusch <christoph.neusch@nortelnetworks.com>
10  *
11  * Wireshark - Network traffic analyzer
12  * By Gerald Combs <gerald@wireshark.org>
13  * Copyright 1998 Gerald Combs
14  * 
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  * 
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  * 
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28  */
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <ctype.h>
38
39 #include <glib.h>
40
41 #include <epan/packet.h>
42 #include <epan/addr_resolv.h>
43 #include <epan/strutil.h>
44 #include <epan/sctpppids.h>      /* include V5UA payload protocol ID */
45
46
47 /* Initialize the protocol and registered fields */
48
49 static int proto_v5ua                    = -1;
50
51
52 static dissector_handle_t q931_handle;
53
54         /* round up parameter length to multiple of four */
55 #define ADD_PADDING(x) ((((x) + 3) >> 2) << 2)
56
57    /* common msg-header */
58 static int hf_version               = -1;
59 static int hf_reserved              = -1;
60 static int hf_msg_class             = -1;
61 static int hf_msg_type              = -1;
62 static int hf_msg_type_id           = -1;
63 static int hf_msg_length            = -1;
64    /* V5UA message header */
65 static int hf_link_id               = -1;
66 static int hf_chnl_id               = -1;
67 static int hf_adaptation_layer_id   = -1;
68 static int hf_text_if_id            = -1;
69 static int hf_scn_protocol_id       = -1;
70 static int hf_info_string           = -1;
71 static int hf_dlci_zero_bit         = -1;
72 static int hf_dlci_spare_bit        = -1;
73 static int hf_dlci_sapi             = -1;
74 static int hf_dlci_one_bit          = -1;
75 static int hf_dlci_tei              = -1;
76 static int hf_efa                   = -1;
77 static int hf_spare_efa             = -1;
78
79    /* variable length parameter (msg) */
80 static int hf_parameter_tag         = -1;
81 static int hf_parameter_tag_draft   = -1;
82 static int hf_parameter_length      = -1;
83 static int hf_parameter_value       = -1;
84 static int hf_parameter_padding     = -1;
85
86
87         /* parameter fields */
88 static int hf_link_status           = -1;
89 static int hf_sa_bit_id             = -1;
90 static int hf_sa_bit_value          = -1;
91 static int hf_diagnostic_info       = -1;
92 static int hf_if_range_start        = -1;
93 static int hf_if_range_end          = -1;
94 static int hf_heartbeat_data        = -1;
95 static int hf_traffic_mode_type     = -1;
96 static int hf_error_code            = -1;
97 static int hf_draft_error_code      = -1;
98 static int hf_status_type           = -1;
99 static int hf_status_id             = -1;
100 static int hf_error_reason          = -1;
101 static int hf_asp_reason            = -1;
102 static int hf_tei_status            = -1;
103 static int hf_tei_draft_status      = -1;
104 static int hf_release_reason        = -1;
105
106         /* Layer 3 message fields */
107 static int hf_l3_protocol_discriminator  = -1;
108 static int hf_l3_adress                  = -1;
109 static int hf_l3_low_adress              = -1;
110 static int hf_l3_msg_type                = -1;
111 static int hf_l3_info_element            = -1;
112
113 static int hf_l3_sequence_number         = -1;
114 static int hf_l3_v5_link_id              = -1;
115 static int hf_l3_v5_time_slot            = -1;
116
117                 /*PSTN Message*/
118 static int hf_l3_line_info               = -1;
119 static int hf_l3_cad_ringing             = -1;
120 static int hf_l3_pulse_type              = -1;
121 static int hf_l3_suppression_indicator   = -1;
122 static int hf_l3_pulse_duration          = -1;
123 static int hf_l3_ack_request_indicator   = -1;
124 static int hf_l3_number_of_pulses        = -1;
125 static int hf_l3_steady_signal           = -1;
126 static int hf_l3_auto_signalling_sequence= -1;
127 static int hf_l3_pulse_notify            = -1;
128 static int hf_l3_sequence_response       = -1;
129 static int hf_l3_digit_ack               = -1;
130 static int hf_l3_digit_info              = -1;
131 static int hf_l3_res_unavailable         = -1;
132 static int hf_l3_state                   = -1;
133 static int hf_l3_cause_type              = -1;
134 static int hf_l3_pstn_sequence_number    = -1;
135 static int hf_l3_duration_type           = -1;
136                 /*link control*/
137 static int hf_l3_link_control_function   = -1;
138                 /*Protection protocol*/
139 static int hf_l3_rejection_cause_type    = -1;
140                 /*BCC protocol*/
141 static int hf_l3_pstn_user_port_id            = -1;
142 static int hf_l3_pstn_user_port_id_lower      = -1;
143 static int hf_l3_isdn_user_port_id            = -1;
144 static int hf_l3_isdn_user_port_id_lower      = -1;
145 static int hf_l3_isdn_user_port_ts_num        = -1;
146 static int hf_l3_override                     = -1;
147 static int hf_l3_reject_cause_type            = -1;
148 static int hf_l3_bcc_protocol_error_cause     = -1;
149 static int hf_l3_connection_incomplete_reason = -1;
150                 /*Control protocol*/
151 static int hf_l3_control_function_element = -1;
152 static int hf_l3_control_function_id      = -1;
153 static int hf_l3_variant                  = -1;
154 static int hf_l3_if_id                    = -1;
155 static int hf_l3_performance_grading      = -1;
156 static int hf_l3_cp_rejection_cause       = -1;
157
158
159 /* Initialize the subtree pointers */
160 static gint ett_v5ua              = -1;
161 static gint ett_v5ua_common_header= -1;
162 static gint ett_v5ua_parameter    = -1;
163 static gint ett_v5ua_layer3       = -1;
164
165 #define RFC             0x1
166 #define DRAFT           0x2
167         /* Version of IUA */
168 static int iua_version = RFC;
169     /* Variables neccessary for dissection of draft messages */
170 static int msg_class   = -1;
171 static int msg_type    = -1;
172 static int msg_length  = -1;
173
174
175
176 /* Code to actually dissect the packets */
177
178
179         /* define the parameters for the Tags: Tag-Type,Tag-Length,Tag-Value (Payload) */
180 #define PARAMETER_TAG_OFFSET    0
181 #define PARAMETER_TAG_LENGTH    2
182 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TAG_OFFSET + PARAMETER_TAG_LENGTH)
183 #define PARAMETER_LENGTH_LENGTH 2
184 #define PARAMETER_VALUE_OFFSET  (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
185 #define PARAMETER_HEADER_OFFSET PARAMETER_TAG_OFFSET
186 #define PARAMETER_HEADER_LENGTH (PARAMETER_TAG_LENGTH + PARAMETER_LENGTH_LENGTH)
187
188
189 /*----------------------V5UA Interface Identifier (int) (Draft,RFC)------------*/ 
190
191         /* define parameter for the format of the integer formatted Interface Identifier */
192 #define INT_IF_ID_LINK_OFFSET PARAMETER_VALUE_OFFSET
193 #define INT_IF_ID_LINK_LENGTH 4
194 #define INT_IF_ID_CHNL_OFFSET INT_IF_ID_LINK_OFFSET
195 #define INT_IF_ID_CHNL_LENGTH 1
196
197 static void
198 dissect_int_interface_identifier_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
199 {
200   guint32 identifier;
201
202   proto_tree_add_item(parameter_tree, hf_link_id, parameter_tvb, INT_IF_ID_LINK_OFFSET, INT_IF_ID_LINK_LENGTH, FALSE);
203   identifier = tvb_get_ntohl(parameter_tvb,INT_IF_ID_LINK_OFFSET)>>5;
204   proto_item_append_text(parameter_item, "  Link: %d ",identifier);
205
206   proto_tree_add_item(parameter_tree, hf_chnl_id, parameter_tvb, INT_IF_ID_CHNL_OFFSET+3, INT_IF_ID_CHNL_LENGTH, FALSE);
207   identifier = tvb_get_guint8(parameter_tvb,INT_IF_ID_CHNL_OFFSET+3)&0x1f;
208   proto_item_append_text(parameter_item, " Chnl: %d ", identifier);
209
210
211 }
212 /*----------------------V5UA Interface Identifier (int) (Draft,RFC)------------*/
213
214 /*----------------------Text Interface Identifier (RFC)------------------------*/
215
216 #define TEXT_IF_ID_LENGTH_OFFSET PARAMETER_LENGTH_OFFSET
217 #define TEXT_IF_ID_VALUE_OFFSET  PARAMETER_VALUE_OFFSET
218 #define TEXT_IF_ID_HEADER_LENGTH PARAMETER_HEADER_LENGTH
219
220 static void
221 dissect_text_interface_identifier_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
222 {
223   guint16 if_id_length;
224
225   if_id_length = tvb_get_ntohs(parameter_tvb, TEXT_IF_ID_LENGTH_OFFSET) - TEXT_IF_ID_HEADER_LENGTH;
226
227   proto_tree_add_item(parameter_tree, hf_text_if_id, parameter_tvb, TEXT_IF_ID_VALUE_OFFSET, if_id_length, FALSE);
228   proto_item_append_text(parameter_item, " (0x%.*s)", if_id_length,
229                          (const char *)tvb_get_ptr(parameter_tvb, TEXT_IF_ID_VALUE_OFFSET, if_id_length));
230 }
231 /*----------------------Text Interface Identifier (RFC)------------------------*/
232
233 /*----------------------DLCI & Envelope Function Address------------------------*/
234
235
236 /* interpretation of EFA-values */
237 static const value_string efa_values[] = {
238         { 8175, "ISDN Protocol" },
239         { 8176, "PSTN Protocol" },
240         { 8177, "CC Protocol" },
241         { 8178, "BCC Protocol" },
242         { 8179, "PROT Protocol" },
243         { 8180, "Link Contol Protocol" },
244         { 8191, "VALUE RESERVED" },
245         { 0,    NULL } };
246
247 #define DLCI_LENGTH_OFFSET PARAMETER_LENGTH_OFFSET
248 #define DLCI_SAPI_OFFSET   PARAMETER_VALUE_OFFSET
249 #define DLCI_HEADER_LENGTH PARAMETER_HEADER_LENGTH
250
251 #define DLCI_SAPI_LENGTH   1
252 #define DLCI_TEI_LENGTH    1
253 #define EFA_LENGTH         2
254
255 static void
256 dissect_dlci_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
257 {
258   guint16 efa = 0, offset=0;
259
260   if     (iua_version == RFC)   offset = DLCI_SAPI_OFFSET;
261   else if(iua_version == DRAFT) offset = DLCI_HEADER_LENGTH + tvb_get_ntohs(parameter_tvb, DLCI_LENGTH_OFFSET);
262
263   proto_tree_add_item(parameter_tree, hf_dlci_zero_bit,  parameter_tvb, offset,  DLCI_SAPI_LENGTH,  FALSE);
264   proto_tree_add_item(parameter_tree, hf_dlci_spare_bit, parameter_tvb, offset,  DLCI_SAPI_LENGTH,  FALSE);
265   proto_tree_add_item(parameter_tree, hf_dlci_sapi,      parameter_tvb, offset,  DLCI_SAPI_LENGTH,  FALSE);
266
267   offset += DLCI_SAPI_LENGTH;
268   proto_tree_add_item(parameter_tree, hf_dlci_one_bit,   parameter_tvb, offset,  DLCI_TEI_LENGTH,   FALSE);
269   proto_tree_add_item(parameter_tree, hf_dlci_tei,       parameter_tvb, offset,  DLCI_TEI_LENGTH,   FALSE);
270
271   /* if SAPI & TEI not set to ZERO, value of EFA must be decode (EFA = 0 -> ISDN protocol)*/
272   if(tvb_get_ntohs(parameter_tvb,offset-DLCI_TEI_LENGTH) != 0x01){
273
274           offset += DLCI_TEI_LENGTH;
275           efa = tvb_get_ntohs(parameter_tvb, offset);
276           /* EFA-Values for ISDN-Protocal. For the "value_string"-function value must set to 8175 */
277           if(efa < 8175) efa = 8175;
278           /* Reserved values. For the "value_string"-function value must set to 8191 */
279           else if ((efa >= 8181) && (efa < 8191)) efa = 8191;
280           proto_tree_add_uint_format(parameter_tree, hf_efa,  parameter_tvb, offset, EFA_LENGTH, efa,
281                 "Envelope function address: %s (%u)", val_to_str(efa, efa_values, "unknown EFA"),tvb_get_ntohs(parameter_tvb, offset));
282           proto_item_append_text(parameter_item, " (EFA: %s )",val_to_str(efa, efa_values, "unknown EFA-value"));
283   }
284   /* if SAPI & TEI set to ZERO, EFA also shall be set to ZERO and didn't comply with value for ISDN protocol */
285   else{
286           proto_tree_add_uint_format(parameter_tree, hf_efa,  parameter_tvb, offset, EFA_LENGTH, efa,
287                 "Envelope function address: 0");
288           proto_item_append_text(parameter_item, " (EFA: 0 )");
289   }
290
291 }
292 /*----------------------DLCI & Envelope Function Address------------------------*/
293
294 /*----------------------Error Indication (Draft)-------------------------------*/
295
296         /* define Error Code Parameter for Layer Management (MGMT) Messages */
297 #define MGMT_ERROR_INVALID_TEI_DRAFT                       0x00
298 #define MGMT_ERROR_INVALID_IFID_DRAFT                      0x01
299 #define MGMT_ERROR_UNDEFINIED_MSG_DRAFT                    0x02
300 #define MGMT_ERROR_VERSION_ERR_DRAFT                       0x03
301 #define MGMT_ERROR_INVALID_STID_DRAFT                      0x04
302 #define MGMT_ERROR_INVALID_SCNV_DRAFT                      0x05
303 #define MGMT_ERROR_INVALID_ALI_DRAFT                       0x06
304
305 static const value_string draft_error_code_values[] = {
306   { MGMT_ERROR_INVALID_TEI_DRAFT,     "Invalid TEI" },
307   { MGMT_ERROR_INVALID_IFID_DRAFT,    "Invalid interface ID" },
308   { MGMT_ERROR_UNDEFINIED_MSG_DRAFT,  "An unexpected message was received" },
309   { MGMT_ERROR_VERSION_ERR_DRAFT,     "The IUA layers are of different version" },
310   { MGMT_ERROR_INVALID_STID_DRAFT,    "Invalid SCTP stream identifier" },
311   { MGMT_ERROR_INVALID_SCNV_DRAFT,    "Invalid SCN version" },
312   { MGMT_ERROR_INVALID_ALI_DRAFT,     "Invalid Adaptation Layer Identifier" },
313   { 0,                                NULL } };
314
315 #define MGMT_ERROR_MSG_LENGTH_OFFSET PARAMETER_LENGTH_OFFSET
316 #define MGMT_ERROR_MSG_HEADER_LENGTH PARAMETER_HEADER_LENGTH
317
318 #define MGMT_ERROR_CODE_LENGTH 4
319
320 static void
321 dissect_draft_error_code_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree)
322 {
323   guint16 offset = MGMT_ERROR_MSG_HEADER_LENGTH + tvb_get_ntohs(parameter_tvb, MGMT_ERROR_MSG_LENGTH_OFFSET) + 4;
324   proto_tree_add_item(parameter_tree, hf_draft_error_code, parameter_tvb, offset, MGMT_ERROR_CODE_LENGTH, FALSE);
325   offset += MGMT_ERROR_CODE_LENGTH ;
326   if( tvb_length_remaining(parameter_tvb,offset) > 0 )
327           proto_tree_add_item(parameter_tree, hf_info_string, parameter_tvb, offset, msg_length - offset,FALSE);
328 }
329 /*----------------------Error Indication (Draft)-------------------------------*/
330
331 /*----------------------Error Indication (RFC)---------------------------------*/
332
333         /* define Error Code Parameter for Layer Management (MGMT) Messages */
334 #define MGMT_ERROR_INVALID_VERSION                     0x01
335 #define MGMT_ERROR_INVALID_IF_ID                       0x02
336 #define MGMT_ERROR_UNSUPPORTED_MSG_CLASS               0x03
337 #define MGMT_ERROR_UNSUPPORTED_MSG_TYPE                0x04
338 #define MGMT_ERROR_UNSUPPORTED_TRAFFIC_HANDLING_MODE   0x05
339 #define MGMT_ERROR_UNEXPECTED_MSG                      0x06
340 #define MGMT_ERROR_PROTOCOL_ERROR                      0x07
341 #define MGMT_ERROR_UNSUPPORTED_IF_ID_TYPE              0x08
342 #define MGMT_ERROR_INVALID_STREAM_ID                   0x09
343 #define MGMT_ERROR_UNASSIGNED_TEI                      0x0a
344 #define MGMT_ERROR_UNRECOGNIZED_SAPI                   0x0b
345 #define MGMT_ERROR_INVALID_TEI_SAPI_COMBINATION        0x0c
346
347 static const value_string error_code_values[] = {
348   { MGMT_ERROR_INVALID_VERSION,                       "Invalid version" },
349   { MGMT_ERROR_INVALID_IF_ID,                         "Invalid interface identifier" },
350   { MGMT_ERROR_UNSUPPORTED_MSG_CLASS,                 "Unsuported message class" },
351   { MGMT_ERROR_UNSUPPORTED_MSG_TYPE,                  "Unsupported message type" },
352   { MGMT_ERROR_UNSUPPORTED_TRAFFIC_HANDLING_MODE,     "Unsupported traffic handling mode" },
353   { MGMT_ERROR_UNEXPECTED_MSG,                        "Unexpected message" },
354   { MGMT_ERROR_PROTOCOL_ERROR,                        "Protocol error" },
355   { MGMT_ERROR_UNSUPPORTED_IF_ID_TYPE,                "Unsupported interface identifier type" },
356   { MGMT_ERROR_INVALID_STREAM_ID,                     "Invalid stream identifier" },
357   { MGMT_ERROR_UNASSIGNED_TEI,                        "Unassigned TEI" },
358   { MGMT_ERROR_UNRECOGNIZED_SAPI,                     "Unrecognized SAPI" },
359   { MGMT_ERROR_INVALID_TEI_SAPI_COMBINATION,          "Invalid TEI/SAPI combination" },
360   { 0,                                                NULL } };
361
362 #define MGMT_ERROR_CODE_OFFSET PARAMETER_VALUE_OFFSET
363
364 static void
365 dissect_error_code_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
366 {
367   proto_tree_add_item(parameter_tree, hf_error_code, parameter_tvb, MGMT_ERROR_CODE_OFFSET, MGMT_ERROR_CODE_LENGTH, FALSE);
368   proto_item_append_text(parameter_item, " (%s)",
369                          val_to_str(tvb_get_ntohl(parameter_tvb, MGMT_ERROR_CODE_OFFSET), error_code_values, "Unknown error code"));
370 }
371
372 static void
373 dissect_diagnostic_information_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
374 {
375   guint16 diag_info_length;
376
377   diag_info_length = tvb_get_ntohs(parameter_tvb, MGMT_ERROR_MSG_LENGTH_OFFSET) - MGMT_ERROR_MSG_HEADER_LENGTH;
378   proto_tree_add_item(parameter_tree, hf_diagnostic_info, parameter_tvb, PARAMETER_VALUE_OFFSET, diag_info_length, FALSE);
379   proto_item_append_text(parameter_item, " (%u byte%s)", diag_info_length, plurality(diag_info_length, "", "s"));
380 }
381 /*----------------------Error Indication (RFC)---------------------------------*/
382
383 /*----------------------Notify (RFC)-------------------------------------------*/
384
385         /* define Status Type parameters for Notify (NTFY) Messages */
386 #define NTFY_STATUS_TYPE_AS_STATE_CHANGE  0x01
387 #define NTFY_STATUS_TYPE_OTHER            0x02
388
389 static const value_string status_type_values[] = {
390   { NTFY_STATUS_TYPE_AS_STATE_CHANGE,        "Application server state change" },
391   { NTFY_STATUS_TYPE_OTHER,                  "Other" },
392   { 0,                                       NULL } };
393
394         /* define Status Identification parameters for NTFY Messages (AS state change)*/
395 #define NTFY_STATUS_IDENT_AS_DOWN          0x01
396 #define NTFY_STATUS_IDENT_AS_INACTIVE      0x02
397 #define NTFY_STATUS_IDENT_AS_ACTIVE        0x03
398 #define NTFY_STATUS_IDENT_AS_PENDING       0x04
399         /* define Status Identification parameters for NTFY Messages (Other)*/
400 #define NTFY_STATUS_INSUFFICIENT_ASP_RES_ACTIVE 0x01
401 #define NTFY_STATUS_ALTERNATE_ASP_ACTIVE        0x02
402
403 static const value_string status_type_id_values[] = {
404   { NTFY_STATUS_TYPE_AS_STATE_CHANGE * 256 * 256 + NTFY_STATUS_IDENT_AS_DOWN,         "Application server down" },
405   { NTFY_STATUS_TYPE_AS_STATE_CHANGE * 256 * 256 + NTFY_STATUS_IDENT_AS_INACTIVE,     "Application server inactive" },
406   { NTFY_STATUS_TYPE_AS_STATE_CHANGE * 256 * 256 + NTFY_STATUS_IDENT_AS_ACTIVE,       "Application server active" },
407   { NTFY_STATUS_TYPE_AS_STATE_CHANGE * 256 * 256 + NTFY_STATUS_IDENT_AS_PENDING,      "Application server pending" },
408   { NTFY_STATUS_TYPE_OTHER * 256 * 256 + NTFY_STATUS_INSUFFICIENT_ASP_RES_ACTIVE,     "Insufficient ASP resources active in AS" },
409   { NTFY_STATUS_TYPE_OTHER * 256 * 256 + NTFY_STATUS_ALTERNATE_ASP_ACTIVE,            "Alternate ASP active" },
410   { 0,                                           NULL } };
411
412 #define NTFY_STATUS_TYPE_OFFSET  PARAMETER_VALUE_OFFSET
413 #define NTFY_STATUS_TYPE_LENGTH  2
414 #define NTFY_STATUS_IDENT_OFFSET (NTFY_STATUS_TYPE_OFFSET + NTFY_STATUS_TYPE_LENGTH)
415 #define NTFY_STATUS_IDENT_LENGTH 2
416
417 static void
418 dissect_status_type_identification_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
419 {
420   guint16 status_type, status_id;
421
422   status_type = tvb_get_ntohs(parameter_tvb, NTFY_STATUS_TYPE_OFFSET);
423   status_id   = tvb_get_ntohs(parameter_tvb, NTFY_STATUS_IDENT_OFFSET);
424
425   proto_tree_add_item(parameter_tree, hf_status_type, parameter_tvb, NTFY_STATUS_TYPE_OFFSET, NTFY_STATUS_TYPE_LENGTH, FALSE);
426   proto_tree_add_uint_format(parameter_tree, hf_status_id,  parameter_tvb, NTFY_STATUS_IDENT_OFFSET, NTFY_STATUS_IDENT_LENGTH,
427                              status_id, "Status identification: %u (%s)", status_id,
428                              val_to_str(status_type * 256 * 256 + status_id, status_type_id_values, "unknown"));
429
430   proto_item_append_text(parameter_item, " (%s)",
431                          val_to_str(status_type * 256 * 256 + status_id, status_type_id_values, "Unknown status information"));
432 }
433 /*----------------------Notify (RFC)-------------------------------------------*/
434
435 /*----------------------TEI Status Indication,Confirm (RFC)--------------------*/
436
437         /* define parameters for TEI Status (Indication,Confirm) Messages */
438 #define TEI_STATUS_ASSIGNED       0x0
439 #define TEI_STATUS_UNASSIGNED     0x1
440
441 static const value_string tei_status_values[] = {
442   { TEI_STATUS_ASSIGNED,   "TEI is considered assigned by Q.921" },
443   { TEI_STATUS_UNASSIGNED, "TEI is considered unassigned by Q.921" },
444   { 0,                     NULL } };
445
446 #define TEI_STATUS_OFFSET PARAMETER_VALUE_OFFSET
447 #define TEI_STATUS_LENGTH 4
448
449 static void
450 dissect_tei_status_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
451 {
452   proto_tree_add_item(parameter_tree, hf_tei_status, parameter_tvb, TEI_STATUS_OFFSET, TEI_STATUS_LENGTH, FALSE);
453   proto_item_append_text(parameter_item, " (%s)",
454                       val_to_str(tvb_get_ntohl(parameter_tvb, TEI_STATUS_OFFSET), tei_status_values, "Unknown TEI status"));
455 }
456 /*----------------------TEI Status (RFC)---------------------------------------*/
457
458 /*----------------------TEI Status Indication,Confirm (Draft)------------------*/
459 #define TEI_DRAFT_IN_SERVICE     0x0
460 #define TEI_DRAFT_OUT_OF_SERVICE 0x1
461
462 static const value_string tei_draft_status_values[] = {
463         { TEI_DRAFT_IN_SERVICE,    "TEI is in service" },
464         { TEI_DRAFT_OUT_OF_SERVICE,"TEI is out of service" },
465         { 0,                       NULL } };
466
467 #define TEI_STATUS_LENGTH_OFFSET PARAMETER_LENGTH_OFFSET
468
469 static void
470 dissect_draft_tei_status_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
471 {
472   gint length, offset;
473   offset = tvb_get_ntohs(parameter_tvb, TEI_STATUS_LENGTH_OFFSET) + 8;
474   length = msg_length - offset;
475   if(tvb_length_remaining(parameter_tvb, offset) > 0 ){
476           proto_tree_add_item(parameter_tree, hf_tei_draft_status, parameter_tvb, offset, TEI_STATUS_LENGTH, FALSE);
477           proto_item_append_text(parameter_item, " (%s)",
478                 val_to_str(tvb_get_ntohl(parameter_tvb, offset), tei_draft_status_values, "Unknown TEI Status"));
479   }
480 }
481 /*----------------------TEI Status (Draft)-------------------------------------*/
482
483 /*----------------------ASP Up,Down,Active,Inactive (Draft)--------------------*/
484
485 static void
486 dissect_asp_msg_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
487 {
488   guint16 adaptation_layer_id_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
489
490   proto_tree_add_item(parameter_tree, hf_adaptation_layer_id, parameter_tvb, PARAMETER_VALUE_OFFSET, adaptation_layer_id_length, FALSE);
491   proto_item_append_text(parameter_item, " (%.*s)", adaptation_layer_id_length,
492                          (const char *)tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, adaptation_layer_id_length));
493 }
494
495 static void
496 dissect_scn_protocol_id_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
497 {
498   guint16 id_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
499   proto_tree_add_item(parameter_tree, hf_scn_protocol_id, parameter_tvb, PARAMETER_VALUE_OFFSET, id_length, FALSE);
500   proto_item_append_text(parameter_item, " (%.*s)", id_length,
501                          (const char *)tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, id_length));
502 }
503
504 /*----------------------ASP (Draft)--------------------------------------------*/
505
506 /*----------------------ASP Down + Ack (RFC)--------------------------------*/
507         /* define reason parameter for Application Server Process Maintenance (ASPM) Messages */
508 #define ASP_REASON_MGMT   1
509
510 static const value_string asp_reason_values[] = {
511   { ASP_REASON_MGMT,      "Management inhibit" },
512   { 0,                    NULL } };
513
514 #define ASP_REASON_OFFSET PARAMETER_VALUE_OFFSET
515 #define ASP_REASON_LENGTH 4
516
517 static void
518 dissect_asp_reason_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
519 {
520   proto_tree_add_item(parameter_tree, hf_asp_reason, parameter_tvb, ASP_REASON_OFFSET, ASP_REASON_LENGTH, FALSE);
521   proto_item_append_text(parameter_item, " (%s)", val_to_str(tvb_get_ntohl(parameter_tvb, ASP_REASON_OFFSET), asp_reason_values, "Unknown ASP down reason"));
522 }
523
524
525 /*----------------------ASP (RFC)----------------------------------------------*/
526
527 /*----------------------Heartbeat Data + Ack (RFC)-----------------------------*/
528
529 #define HEARTBEAT_MSG_LENGTH_OFFSET PARAMETER_LENGTH_OFFSET
530 #define HEARTBEAT_DATA_OFFSET       PARAMETER_VALUE_OFFSET
531 #define HEARTBEAT_MSG_HEADER_LENGTH PARAMETER_HEADER_LENGTH
532
533 static void
534 dissect_heartbeat_data_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
535 {
536   guint16 heartbeat_data_length;
537
538   heartbeat_data_length = tvb_get_ntohs(parameter_tvb, HEARTBEAT_MSG_LENGTH_OFFSET) - HEARTBEAT_MSG_HEADER_LENGTH;
539   proto_tree_add_item(parameter_tree, hf_heartbeat_data, parameter_tvb, HEARTBEAT_DATA_OFFSET, heartbeat_data_length, FALSE);
540   proto_item_append_text(parameter_item, " (%u byte%s)", heartbeat_data_length, plurality(heartbeat_data_length, "", "s"));
541 }
542 /*----------------------Heartbeat Data (RFC)-----------------------------------*/
543
544
545 /*----------------------ASP Active,Inactive + Ack (RFC)------------------------*/
546 #define OVER_RIDE_TRAFFIC_MODE_TYPE  1
547 #define LOAD_SHARE_TRAFFIC_MODE_TYPE 2
548
549 static const value_string traffic_mode_type_values[] = {
550   { OVER_RIDE_TRAFFIC_MODE_TYPE,      "Over-ride" },
551   { LOAD_SHARE_TRAFFIC_MODE_TYPE,     "Load-share" },
552   { 0,                    NULL } };
553
554 #define TRAFFIC_MODE_TYPE_LENGTH 4
555 #define TRAFFIC_MODE_TYPE_OFFSET PARAMETER_VALUE_OFFSET
556
557 static void
558 dissect_traffic_mode_type_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
559 {
560   proto_tree_add_item(parameter_tree, hf_traffic_mode_type, parameter_tvb, TRAFFIC_MODE_TYPE_OFFSET, TRAFFIC_MODE_TYPE_LENGTH, FALSE);
561   proto_item_append_text(parameter_item, " (%s)",
562                          val_to_str(tvb_get_ntohl(parameter_tvb, TRAFFIC_MODE_TYPE_OFFSET), traffic_mode_type_values, "Unknown traffic mode type"));
563 }
564
565 #define INT_RANGE_START_OFFSET  PARAMETER_VALUE_OFFSET
566 #define INT_RANGE_LENGTH_OFFSET PARAMETER_LENGTH_OFFSET
567 #define INT_RANGE_HEADER_LENGTH PARAMETER_HEADER_LENGTH
568
569 #define IF_ID_START_OFFSET      0
570 #define IF_ID_START_LENGTH      4
571 #define IF_ID_END_OFFSET        (IF_ID_START_OFFSET + IF_ID_START_LENGTH)
572 #define IF_ID_END_LENGTH        4
573 #define IF_ID_INTERVAL_LENGTH   (IF_ID_START_LENGTH + IF_ID_END_LENGTH)
574
575
576 static void
577 dissect_integer_range_interface_identifier_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
578 {
579   guint16 number_of_ranges, range_number, offset;
580
581   number_of_ranges = (tvb_get_ntohs(parameter_tvb, INT_RANGE_LENGTH_OFFSET) - INT_RANGE_HEADER_LENGTH) / IF_ID_INTERVAL_LENGTH;
582   offset = INT_RANGE_START_OFFSET;
583   for(range_number = 1; range_number <= number_of_ranges; range_number++) {
584     proto_tree_add_item(parameter_tree, hf_if_range_start, parameter_tvb, offset + IF_ID_START_OFFSET, IF_ID_START_LENGTH, FALSE);
585     proto_tree_add_item(parameter_tree, hf_if_range_end,   parameter_tvb, offset + IF_ID_END_OFFSET,   IF_ID_END_LENGTH,   FALSE);
586     offset += IF_ID_INTERVAL_LENGTH;
587   };
588
589   proto_item_append_text(parameter_item, " (%u range%s)", number_of_ranges, plurality(number_of_ranges, "", "s"));
590 }
591 /*----------------------ASP Active,Inactive (RFC)------------------------------*/
592
593 /*----------------------Data Request,Indication (Draft,RFC)--------------------*/
594 /* message types of PSTN */
595 #define ESTABLISH           0x00
596 #define ESTABLISH_ACK       0x01
597 #define SIGNAL              0x02
598 #define SIGNAL_ACK          0x03
599 #define DISCONNECT          0x08
600 #define DISCONNECT_COMPLETE 0x09
601 #define STATUS_ENQUIRY      0x0c
602 #define STATUS              0x0d
603 #define PROTOCOL_PARAMETER  0x0e
604 /* message types of Control protocol */
605 #define PORT_CONTROL        0x10
606 #define PORT_CONTROL_ACK    0x11
607 #define COMMON_CONTROL      0x12
608 #define COMMON_CONTROL_ACK  0x13
609 /* message types of PROT protocol */
610 #define SWITCH_OVER_REQ     0x18
611 #define SWITCH_OVER_COM     0x19
612 #define OS_SWITCH_OVER_COM  0x1a
613 #define SWITCH_OVER_ACK     0x1b
614 #define SWITCH_OVER_REJECT  0x1c
615 #define PROT_PROTOCOL_ERROR 0x1d
616 #define RESET_SN_COM        0x1e
617 #define RESET_SN_ACK        0x1f
618 /* message types of BCC */
619 #define ALLOCATION             0x20
620 #define ALLOCATION_COMPLETE    0x21
621 #define ALLOCATION_REJECT      0x22
622 #define DE_ALLOCATION          0x23
623 #define DE_ALLOCATION_COMPLETE 0x24
624 #define DE_ALLOCATION_REJECT   0x25
625 #define AUDIT                  0x26
626 #define AUDIT_COMPLETE         0x27
627 #define AN_FAULT               0x28
628 #define AN_FAULT_ACKNOWLEDGE   0x29
629 #define BCC_PROTOCOL_ERROR     0x2a
630 /* message types of Link Control protocol */
631 #define LINK_CONTROL        0x30
632 #define LINK_CONTROL_ACK    0x31
633
634 static const value_string l3_msg_type_values [] = {
635         { ESTABLISH,             "Establish" },
636         { ESTABLISH_ACK,         "Establish Ack" },
637         { SIGNAL,                "Signal" },
638         { SIGNAL_ACK,            "Signal Ack" },
639         { DISCONNECT,            "Disconnect" },
640         { DISCONNECT_COMPLETE,   "Disconnect Complete" },
641         { STATUS_ENQUIRY,        "Status Enqueiry" },
642         { STATUS,                "Status" },
643         { PROTOCOL_PARAMETER,    "Protocol Parameter" },
644         { PORT_CONTROL,          "Port Control" },
645         { PORT_CONTROL_ACK,      "Port Control Ack" },
646         { COMMON_CONTROL,        "Common Control" },
647         { COMMON_CONTROL_ACK,    "Common Control Ack" },
648         { SWITCH_OVER_REQ,       "Switch-Over Request" },
649         { SWITCH_OVER_COM,       "Switch-Over Com" },
650         { OS_SWITCH_OVER_COM,    "OS-Switch-Over Com" },
651         { SWITCH_OVER_ACK,       "Switch-Over Ack" },
652         { SWITCH_OVER_REJECT,    "Switch-Over Reject" },
653         { PROT_PROTOCOL_ERROR,   "Protection Protocol Error" },
654         { RESET_SN_COM,          "Reset SN Com" },
655         { RESET_SN_ACK,          "Reset SN Ack" },
656         { ALLOCATION,            "Allocation" },
657         { ALLOCATION_COMPLETE,   "Allocation Complete" },
658         { ALLOCATION_REJECT,     "Allocation Reject" },
659         { DE_ALLOCATION,         "DE Allocation" },
660         { DE_ALLOCATION_COMPLETE,"DE Allocation Complete" },
661         { DE_ALLOCATION_REJECT,  "DE Allocation Reject" },
662         { AUDIT,                 "Audit" },
663         { AUDIT_COMPLETE,        "Audit Complete" },
664         { AN_FAULT,              "AN Fault" },
665         { AN_FAULT_ACKNOWLEDGE,  "AN Fault Ack" },
666         { BCC_PROTOCOL_ERROR,    "BCC Protocol Error" },
667         { LINK_CONTROL,          "Link Control" },
668         { LINK_CONTROL_ACK,      "Link Control Ack" },
669         { 0,                     NULL } };
670
671 /* PSTN protocol message info elements */
672 #define PULSE_NOTIFICATION   0xc0
673 #define LINE_INFORMATION     0x80
674 #define STATE                0x90
675 #define AUTO_SIG_SEQUENCE    0xa0
676 #define SEQUENCE_RESPONSE    0xb0
677 #define PSTN_SEQUENCE_NUMBER 0x00
678 #define CADENCED_RINGING     0x01
679 #define PULSED_SIGNAL        0x02
680 #define STEADY_SIGNAL        0x03
681 #define DIGIT_SIGNAL         0x04
682 #define RECOGNITION_TIME     0x10
683 #define ENABLE_AUTO_ACK      0x11
684 #define DISABLE_AUTO_ACK     0x12
685 #define CAUSE                0x13
686 #define RESOURCE_UNAVAILABLE 0x14
687
688 static const value_string l3_line_info_values [] = {
689         { 0x00, "Impedance marker reset" },
690         { 0x01, "Impedance marker set" },
691         { 0x02, "Low loop impedance" },
692         { 0x03, "Anomalous loop impedance" },
693         { 0x04, "Anomalous line condition received"},
694         { 0,    NULL } };
695
696 static const value_string l3_pulse_type_values [] = {
697         { 0xff, "Pulsed normal polarity" },
698         { 0xfe, "Pulsed reversed polarity" },
699         { 0xfd, "Pulsed battery on c-wire" },
700         { 0xfc, "Pulsed on hook" },
701         { 0xfb, "Pulsed reduced battery" },
702         { 0xfa, "Pulsed no battery" },
703         { 0xf9, "Initial ring" },
704         { 0xf8, "Meter pulse" },
705         { 0xf7, "50 Hz pulse" },
706         { 0xf6, "Register recall (timed loop open)" },
707         { 0xf5, "Pulsed off hook (pulsed loop closed)" },
708         { 0xf4, "Pulsed b-wire connected to earth" },
709         { 0xf3, "Earth loop pulse" },
710         { 0xf2, "Pulsed b-wire connected to battery" },
711         { 0xf1, "Pulsed a-wire connected to earth" },
712         { 0xf0, "Pulsed a-wire connected to battery" },
713         { 0xef, "Pulsed c-wire connected to earth" },
714         { 0xee, "Pulsed c-wire disconnected" },
715         { 0xed, "Pulsed normal battery" },
716         { 0xec, "Pulsed a-wire disconnected" },
717         { 0xeb, "Pulsed b-wire disconnected" },
718         { 0,    NULL } };
719
720 static const value_string l3_suppression_indication_values [] = {
721         { 0x0, "No suppression" },
722         { 0x1, "Suppression allowed by pre-defined V5.1 SIGNAL msg from LE" },
723         { 0x2, "Suppression allowed by pre-defined line signal from TE" },
724         { 0x3, "Suppression allowed by pre-defined V5.1 SIGNAL msg from LE or line signal from TE" },
725         { 0,   NULL } };
726
727 static const value_string l3_ack_request_indication_values [] = {
728         { 0x0, "No acknowledgement requested" },
729         { 0x1, "Ending acknowledgement requested when finished each pulses" },
730         { 0x2, "Ending acknowledgement requested when finished all pulses" },
731         { 0x3, "Start of pulse acknowledgement requested" },
732         { 0,   NULL } };
733
734 static const value_string l3_digit_ack_values [] = {
735         { 0x0, "No ending acknowledgement requested" },
736         { 0x1, "Ending acknowledgement requested when digit transmission is finished" },
737         { 0,   NULL } };
738
739 static const value_string l3_state_values [] = {
740         { 0x00, "AN0" },
741         { 0x01, "AN1" },
742         { 0x02, "AN2" },
743         { 0x03, "AN3" },
744         { 0x04, "AN4" },
745         { 0x05, "AN5" },
746         { 0x06, "AN6" },
747         { 0x07, "AN7" },
748         { 0,    NULL } };
749
750 static const value_string l3_steady_signal_values [] = {
751         { 0x80, "Normal polarity" },
752         { 0x81, "Reversed polarity" },
753         { 0x82, "Battery on c-wire" },
754         { 0x83, "No battery on c-wire" },
755         { 0x84, "Off hook (loop closed)" },
756         { 0x85, "On hook (loop open)" },
757         { 0x86, "Battery on a-wire" },
758         { 0x87, "A-wire on earth" },
759         { 0x88, "No battery on a-wire" },
760         { 0x89, "No batery on b-wire" },
761         { 0x8a, "Reduced battery" },
762         { 0x8b, "No battery" },
763         { 0x8c, "Alternate reduced power / no power" },
764         { 0x8d, "Normal battery" },
765         { 0x8e, "Stop ringing" },
766         { 0x8f, "Start pilot frequency" },
767         { 0x90, "Stop pilot frequency" },
768         { 0x91, "Low impedance on b-wire" },
769         { 0x92, "B-wire connected to earth" },
770         { 0x93, "B-wire disconnected from earth" },
771         { 0x94, "Battery on b-wire" },
772         { 0x95, "Low loop impedance" },
773         { 0x96, "High loop impedance" },
774         { 0x97, "Anomalous loop impedance" },
775         { 0x98, "A-wire disconnected from earth" },
776         { 0x99, "C-wire on earth" },
777         { 0x9a, "C-wire disconnected from earth" },
778         { 0,    NULL } };
779
780 static const value_string l3_cause_type_values [] = {
781         { 0x00, "Response to STATUS ENQUIRY" },
782         { 0x01, "Protocol discriminator error" },
783         { 0x03, "L3 address error" },
784         { 0x04, "Message type unrecognized" },
785         { 0x05, "Out of sequence information element" },
786         { 0x06, "Repeated optional information element" },
787         { 0x07, "Mandatory information element missing" },
788         { 0x08, "Unrecognized information element" },
789         { 0x09, "Mandatory information element content error" },
790         { 0x0a, "Optional information element content error" },
791         { 0x0b, "Message not compatible with path state" },
792         { 0x0c, "Repeated mandatory information element" },
793         { 0x0d, "Too many information elements" },
794         { 0,    NULL } };
795
796 /* BCC protocol message info elements */
797 #define USER_PORT_ID             0x40
798 #define ISDN_PORT_CHNL_ID        0x41
799 #define V5_TIME_SLOT_ID          0x42
800 #define MULTI_SLOT_MAP           0x43
801 #define BCC_REJECT_CAUSE         0x44
802 #define BCC_PROTOCOL_ERROR_CAUSE 0x45
803 #define CONNECTION_INCOMPLETE    0x46
804
805 static const value_string l3_reject_cause_type_values [] = {
806         { 0x00, "Unspecified" },
807         { 0x01, "Access network fault" },
808         { 0x02, "Access network blocked (internally)" },
809         { 0x03, "Connection already present at the PSTN user port to a different V5 time slot" },
810         { 0x04, "Connection already present at the V5 time slot(s) to a different port or ISDN user port time slot(s)" },
811         { 0x05, "Connection already present at the ISDN user port time slot(s) to a different V5 time slot(s)" },
812         { 0x06, "User port unavailable (blocked)" },
813         { 0x07, "De-allocation cannot completeddue to incompatible data content" },
814         { 0x08, "De-allocation cannot completeddue to V5 time slot(s) data incompatibility" },
815         { 0x09, "De-allocation cannot completeddue to port data incompatibility" },
816         { 0x0a, "De-allocation cannot completeddue to user port time slot(s) data incompatibility" },
817         { 0x0b, "User port not provisioned" },
818         { 0x0c, "Invalid V5 time slot(s) indication(s)" },
819         { 0x0d, "Invalid V5 2048 kbit/s link indication" },
820         { 0x0e, "Invalid user time slot(s) indication(s)" },
821         { 0x0f, "V5 time slot(s) being used as physikal C-channel(s)" },
822         { 0x10, "V5 link unavailable (blocked)" },
823         { 0,    NULL } };
824
825 static const value_string l3_bcc_protocol_error_cause_type_values [] = {
826         { 0x01, "Protocol discriminator error" },
827         { 0x04, "Message type unrecognized" },
828         { 0x05, "Out of sequence information element" },
829         { 0x06, "Repeated optional information element" },
830         { 0x07, "Mandatory information element missing" },
831         { 0x08, "Unrecognized information element" },
832         { 0x09, "Mandatory information element content error" },
833         { 0x0a, "Optional infromation element content error" },
834         { 0x0b, "Message not compatible with the BCC protocol state" },
835         { 0x0c, "Repeated mandatory information element" },
836         { 0x0d, "Too many information element" },
837         { 0x0f, "BCC Reference Number coding error" },
838         { 0,    NULL } };
839
840 static const value_string l3_connection_incomplete_reason_values [] = {
841         { 0x00, "Incomplete normal" },
842         { 0x01, "Access network fault" },
843         { 0x02, "User port not provisioned" },
844         { 0x03, "Invalid V5 time slot identification" },
845         { 0x04, "Invalid V5 2048 kbit/s link identification" },
846         { 0x05, "Time slot being used as physikal C-channel" },
847         { 0,    NULL } };
848
849
850 /* Link control protocol message info elements */
851 #define LINK_CONTROL_FUNCTION 0x30
852
853 static const value_string l3_link_control_function_values [] = {
854         { 0x00, "FE-IDReq" },
855         { 0x01, "FE-IDAck" },
856         { 0x02, "FE-IDRel" },
857         { 0x03, "FE-IDRej" },
858         { 0x04, "FE301/302 (link unblock)" },
859         { 0x05, "FE303/304 (link block)" },
860         { 0x06, "FE305 (deferred link block request" },
861         { 0x07, "FE306 (non-deferred link block request)" },
862         { 0,    NULL } };
863
864 /* Protection protocol message info elements */
865 #define SEQUENCE_NUMBER    0x50
866 #define C_CHANNEL_ID       0x51
867 #define PP_REJECTION_CAUSE 0x52
868 #define PROTOCOL_ERROR     0x53
869
870 /* Control protocolmessage info elements  */
871 #define PERFORMANCE_GRADING      0xe0
872 #define CP_REJECTION_CAUSE       0xf0
873 #define CONTROL_FUNCTION_ELEMENT 0x20
874 #define CONTROL_FUNCTION_ID      0x21
875 #define VARIANT                  0x22
876 #define INTERFACE_ID             0x23
877
878 static const value_string l3_performance_grading_values [] = {
879         { 0x00, "normal grade" },
880         { 0x01, "degraded" },
881         { 0,    NULL } };
882
883 static const value_string l3_cp_rejection_cause_values [] = {
884         { 0x00, "variant unknown" },
885         { 0x01, "variant known, not ready" },
886         { 0x02, "re-provisioning in progress (re-pro)" },
887         { 0,    NULL } };
888
889 static const value_string l3_control_function_element_values [] = {
890         { 0x01, "FE101 (activate access)" },
891         { 0x02, "FE102 (activation initiated by user)" },
892         { 0x03, "FE103 (DS activated)" },
893         { 0x04, "FE104 (access activated)" },
894         { 0x05, "FE105 (deactivate access)" },
895         { 0x06, "FE106 (access deactivated)" },
896         { 0x11, "FE201/202 (unblock)" },
897         { 0x13, "FE203/204 (block)" },
898         { 0x15, "FE205 (block request)" },
899         { 0x16, "FE206 (performance grading)" },
900         { 0x17, "FE207 (D-channel block)" },
901         { 0x18, "FE208 (D-channel unblock)" },
902         { 0,    NULL } };
903
904 static const value_string l3_control_function_id_values [] = {
905         { 0x00, "Verify re-provisioning" },
906         { 0x01, "Ready for re-provisioning" },
907         { 0x02, "Not ready for re-provisioning" },
908         { 0x03, "Switch-over to new variant" },
909         { 0x04, "Re-provisioning started" },
910         { 0x05, "Cannot re-provision" },
911         { 0x06, "Request variant and interface ID" },
912         { 0x07, "Variant and interface ID" },
913         { 0x08, "Blocking started" },
914         { 0x10, "Restart request" },
915         { 0x11, "Restart complete" },
916         { 0,    NULL } };
917
918 static const value_string l3_info_element_values [] = {
919         { PULSE_NOTIFICATION,      "Pulse notification" },
920         { LINE_INFORMATION,        "Line information" },
921         { STATE,                   "State" },
922         { AUTO_SIG_SEQUENCE,       "Autonomous signal sequence" },
923         { SEQUENCE_RESPONSE,       "Sequence response" },
924         { PSTN_SEQUENCE_NUMBER,    "Sequence number" },
925         { CADENCED_RINGING,        "Cadenced ringing" },
926         { PULSED_SIGNAL,           "Pulsed signal" },
927         { STEADY_SIGNAL,           "Steady signal" },
928         { DIGIT_SIGNAL,            "Digit signal" },
929         { RECOGNITION_TIME,        "Recognition time" },
930         { ENABLE_AUTO_ACK,         "Enable autonomous acknowledge" },
931         { DISABLE_AUTO_ACK,        "Disable autonomous acknowledge" },
932         { CAUSE,                   "Cause" },
933         { RESOURCE_UNAVAILABLE,    "Resource unavailable" },
934         { PERFORMANCE_GRADING,     "Performance grading" },
935         { CP_REJECTION_CAUSE,      "Rejection cause" },
936         { CONTROL_FUNCTION_ELEMENT,"Control function element" },
937         { CONTROL_FUNCTION_ID,     "Control function ID" },
938         { VARIANT,                 "Variant" },
939         { INTERFACE_ID,            "Interface ID" },
940         { LINK_CONTROL_FUNCTION,   "Link control funktion" },
941         { USER_PORT_ID,            "User port ID" },
942         { ISDN_PORT_CHNL_ID,       "ISDN port channel ID" },
943         { V5_TIME_SLOT_ID,         "V5 time slot ID" },
944         { MULTI_SLOT_MAP,          "Multi slot map" },
945         { BCC_REJECT_CAUSE,        "Reject cause" },
946         { BCC_PROTOCOL_ERROR_CAUSE,"Protocol error cause" },
947         { CONNECTION_INCOMPLETE,   "Connection incomplete" },
948         { SEQUENCE_NUMBER,         "Sequence number" },
949         { C_CHANNEL_ID,            "C-Channel ID" },
950         { PP_REJECTION_CAUSE,      "Rejection cause" },
951         { PROTOCOL_ERROR,          "Protocol error" },
952         { 0,                       NULL } };
953
954
955 #define DISCRIMINATOR_OFFSET 0
956 #define DISCRIMINATOR_LENGTH 1
957 #define ADDRESS_OFFSET       1
958 #define ADDRESS_LENGTH       1
959 #define LOW_ADDRESS_OFFSET   2
960 #define LOW_ADDRESS_LENGTH   1
961 #define MSG_TYPE_OFFSET      3
962 #define MSG_TYPE_LENGTH      1
963 #define MSG_HEADER_LENGTH    4
964 #define INFO_ELEMENT_OFFSET  4
965 #define INFO_ELEMENT_LENGTH  1
966
967 static void
968 dissect_layer3_message(tvbuff_t *layer3_data_tvb, proto_tree *v5ua_tree,proto_item *parameter_item, packet_info *pinfo)
969 {
970   proto_item *layer3_header_item,*layer3_item, *hidden_item;
971   proto_tree *layer3_header_tree,*layer3_tree;
972   guint16 discriminator_offset, address_offset, low_address_offset, msg_type_offset,  info_element_offset;
973   guint8  info_element, info_element_length, buffer;
974
975   if(iua_version == DRAFT){
976           discriminator_offset = DISCRIMINATOR_OFFSET;
977           address_offset       = ADDRESS_OFFSET;
978           low_address_offset   = LOW_ADDRESS_OFFSET;
979           msg_type_offset      = MSG_TYPE_OFFSET;
980           info_element_offset  = INFO_ELEMENT_OFFSET;
981   }
982   else{
983           discriminator_offset = DISCRIMINATOR_OFFSET + PARAMETER_HEADER_LENGTH;
984           address_offset       = ADDRESS_OFFSET + PARAMETER_HEADER_LENGTH;
985           low_address_offset   = LOW_ADDRESS_OFFSET + PARAMETER_HEADER_LENGTH;
986           msg_type_offset      = MSG_TYPE_OFFSET + PARAMETER_HEADER_LENGTH;
987           info_element_offset  = INFO_ELEMENT_OFFSET + PARAMETER_HEADER_LENGTH;
988   }
989
990
991   if(tvb_get_guint8(layer3_data_tvb, discriminator_offset) == 0x48){
992           layer3_header_item   = proto_tree_add_text(v5ua_tree, layer3_data_tvb, discriminator_offset, MSG_HEADER_LENGTH,"Layer3 header");
993           layer3_header_tree   = proto_item_add_subtree(layer3_header_item, ett_v5ua_layer3);
994
995           proto_tree_add_item(layer3_header_tree, hf_l3_protocol_discriminator, layer3_data_tvb, discriminator_offset, DISCRIMINATOR_LENGTH, FALSE);
996           proto_tree_add_item(layer3_header_tree, hf_l3_adress, layer3_data_tvb, address_offset, ADDRESS_LENGTH, FALSE);
997           proto_tree_add_item(layer3_header_tree, hf_l3_low_adress, layer3_data_tvb, low_address_offset, LOW_ADDRESS_LENGTH, FALSE);
998           proto_tree_add_item(layer3_header_tree, hf_l3_msg_type, layer3_data_tvb, msg_type_offset, MSG_TYPE_LENGTH, FALSE);
999           proto_item_append_text(layer3_header_item, "  Msg Type: %s",
1000                   val_to_str(tvb_get_guint8(layer3_data_tvb, msg_type_offset), l3_msg_type_values, "Unknown layer3 msg type"));
1001
1002           if(tvb_length_remaining(layer3_data_tvb,info_element_offset)){
1003                   layer3_item   = proto_tree_add_text(v5ua_tree, layer3_data_tvb, info_element_offset, tvb_length(layer3_data_tvb)-MSG_HEADER_LENGTH,"Layer3 message");
1004                   layer3_tree   = proto_item_add_subtree(layer3_item, ett_v5ua_layer3);
1005
1006                   info_element_offset  = INFO_ELEMENT_OFFSET;
1007
1008                   while(tvb_length_remaining(layer3_data_tvb,info_element_offset)){
1009                           info_element = tvb_get_guint8(layer3_data_tvb, info_element_offset);
1010                           hidden_item = proto_tree_add_item(layer3_tree, hf_l3_info_element, layer3_data_tvb,info_element_offset,INFO_ELEMENT_LENGTH,FALSE);
1011                           PROTO_ITEM_SET_HIDDEN(hidden_item);
1012                           switch(tvb_get_guint8(layer3_data_tvb, msg_type_offset) & 0xf0){
1013                           case 0x00:
1014                                   /* Variable Length */
1015                                   if(info_element < 0x80){
1016                                   switch(info_element){
1017                                   case PSTN_SEQUENCE_NUMBER:
1018                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1019                                           proto_tree_add_item(layer3_tree,hf_l3_pstn_sequence_number,layer3_data_tvb,info_element_offset+2,info_element_length,FALSE);
1020                                           info_element_offset +=info_element_length+2;
1021                                           break;
1022                                   case CADENCED_RINGING:
1023                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1024                                           proto_tree_add_item(layer3_tree,hf_l3_cad_ringing,layer3_data_tvb,info_element_offset+2,info_element_length,FALSE);
1025                                           info_element_offset +=info_element_length+2;
1026                                           break;
1027                                   case PULSED_SIGNAL:
1028                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1029                                           proto_tree_add_item(layer3_tree,hf_l3_pulse_type,layer3_data_tvb,info_element_offset+2,1,FALSE);/*info_element_length,FALSE); */
1030                                           proto_tree_add_item(layer3_tree,hf_l3_suppression_indicator,layer3_data_tvb,info_element_offset+3,1,FALSE);
1031                                           proto_tree_add_item(layer3_tree,hf_l3_pulse_duration,layer3_data_tvb,info_element_offset+3,1,FALSE);
1032                                           proto_tree_add_item(layer3_tree,hf_l3_ack_request_indicator,layer3_data_tvb,info_element_offset+4,1,FALSE);
1033                                           proto_tree_add_item(layer3_tree,hf_l3_number_of_pulses,layer3_data_tvb,info_element_offset+4,1,FALSE);
1034                                           info_element_offset +=info_element_length+2;
1035                                           break;
1036                                   case STEADY_SIGNAL:
1037                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1038                                           proto_tree_add_item(layer3_tree,hf_l3_steady_signal,layer3_data_tvb,info_element_offset+2,info_element_length,FALSE);
1039                                           proto_item_append_text(layer3_item, "  Steady Signal: %s",
1040                                                 val_to_str(tvb_get_guint8(layer3_data_tvb, info_element_offset+2), l3_steady_signal_values, "Unknown Signal"));
1041                                           info_element_offset +=info_element_length+2;
1042                                           break;
1043                                   case DIGIT_SIGNAL:
1044                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1045                                           buffer = tvb_get_guint8(layer3_data_tvb, info_element_offset+2)>>6;
1046                                           buffer = buffer&0x01;
1047                                           proto_tree_add_uint_format(layer3_tree, hf_l3_digit_ack,layer3_data_tvb,info_element_offset+2,1,buffer,
1048                                                 "Digit ack request indication: %s",val_to_str(buffer,l3_digit_ack_values,"unknown"));
1049                                           proto_tree_add_item(layer3_tree,hf_l3_digit_info,layer3_data_tvb,info_element_offset+2,info_element_length,FALSE);
1050                                           info_element_offset +=info_element_length+2;
1051                                           break;
1052                                   case RECOGNITION_TIME:
1053                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1054                                           buffer = tvb_get_guint8(layer3_data_tvb,info_element_offset+2)&0x7f;
1055                                           /*Signal = Coding of pulse type*/
1056                                           if(buffer>=0x6b)
1057                                                 proto_tree_add_item(layer3_tree,hf_l3_pulse_type,layer3_data_tvb,info_element_offset+2,1,FALSE);
1058                                           /*Signal = Coding of steady signal type*/
1059                                           else if(buffer<=0x1a)
1060                                                 proto_tree_add_item(layer3_tree,hf_l3_steady_signal,layer3_data_tvb,info_element_offset+2,1,FALSE);
1061                                           proto_tree_add_item(layer3_tree,hf_l3_duration_type,layer3_data_tvb,info_element_offset+3,1,FALSE);
1062                                           info_element_offset +=info_element_length+2;
1063                                           break;
1064                                   case ENABLE_AUTO_ACK:
1065                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1066                                           buffer = tvb_get_guint8(layer3_data_tvb,info_element_offset+2)&0x7f;
1067                                           /*Signal*/
1068                                           if(buffer>=0x6b)
1069                                                 proto_tree_add_item(layer3_tree,hf_l3_pulse_type,layer3_data_tvb,info_element_offset+2,1,FALSE);
1070                                           else if(buffer<=0x1a)
1071                                                 proto_tree_add_item(layer3_tree,hf_l3_steady_signal,layer3_data_tvb,info_element_offset+2,1,FALSE);
1072
1073                                           buffer = tvb_get_guint8(layer3_data_tvb,info_element_offset+3)&0x7f;
1074                                           /*Response*/
1075                                           if(buffer>=0x6b)
1076                                                 proto_tree_add_item(layer3_tree,hf_l3_pulse_type,layer3_data_tvb,info_element_offset+3,1,FALSE);
1077                                           else if(buffer<=0x1a)
1078                                                 proto_tree_add_item(layer3_tree,hf_l3_steady_signal,layer3_data_tvb,info_element_offset+3,1,FALSE);
1079                                                 
1080                                           if(tvb_length_remaining(layer3_data_tvb, info_element_offset+4)){
1081                                                 proto_tree_add_item(layer3_tree,hf_l3_suppression_indicator,layer3_data_tvb,info_element_offset+4,1,FALSE);
1082                                                 proto_tree_add_item(layer3_tree,hf_l3_pulse_duration,layer3_data_tvb,info_element_offset+4,1,FALSE);
1083                                           }
1084                                           if(tvb_length_remaining(layer3_data_tvb, info_element_offset+5)){
1085                                                 proto_tree_add_item(layer3_tree,hf_l3_ack_request_indicator,layer3_data_tvb,info_element_offset+5,1,FALSE);
1086                                                 proto_tree_add_item(layer3_tree,hf_l3_number_of_pulses,layer3_data_tvb,info_element_offset+5,1,FALSE);
1087                                           }
1088                                           info_element_offset +=info_element_length+2;
1089                                           break;
1090                                   case DISABLE_AUTO_ACK:
1091                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1092                                           buffer = tvb_get_guint8(layer3_data_tvb,info_element_offset+2)&0x7f;
1093                                           if(buffer>=0x6b)
1094                                                 proto_tree_add_item(layer3_tree,hf_l3_pulse_type,layer3_data_tvb,info_element_offset+2,1,FALSE);
1095                                           else if(buffer<=0x1a)
1096                                                 proto_tree_add_item(layer3_tree,hf_l3_steady_signal,layer3_data_tvb,info_element_offset+2,1,FALSE);
1097                                           info_element_offset +=info_element_length+2;
1098                                           break;
1099                                   case CAUSE:
1100                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1101                                           proto_tree_add_item(layer3_tree,hf_l3_cause_type,layer3_data_tvb,info_element_offset+2,1,FALSE);
1102                                           if(tvb_length_remaining(layer3_data_tvb, info_element_offset+3))
1103                                           proto_tree_add_uint_format(layer3_tree, hf_l3_msg_type,layer3_data_tvb, info_element_offset+3,1,tvb_get_guint8(layer3_data_tvb,info_element_offset+3),
1104                                                 "Diagnostic: %s",val_to_str(tvb_get_guint8(layer3_data_tvb,info_element_offset+3),l3_msg_type_values,"unknown"));
1105                                           info_element_offset +=info_element_length+2;
1106                                           break;
1107                                   case RESOURCE_UNAVAILABLE:
1108                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1109                                           proto_tree_add_item(layer3_tree,hf_l3_res_unavailable,layer3_data_tvb,info_element_offset+2,info_element_length,FALSE);
1110                                           info_element_offset +=info_element_length+2;
1111                                           break;
1112                                   default:
1113                                           info_element_offset += 1;
1114                                           break;
1115                                   }
1116                                   }
1117                                   /* Single Octet */
1118                                   else if(info_element >= 0x80){
1119                                           switch(info_element & 0xf0){
1120                                           case PULSE_NOTIFICATION:
1121                                                   proto_tree_add_item(layer3_tree,hf_l3_pulse_notify,layer3_data_tvb,info_element_offset,1,FALSE);
1122                                                   break;
1123                                           case LINE_INFORMATION:
1124                                                   proto_tree_add_item(layer3_tree,hf_l3_line_info,layer3_data_tvb,info_element_offset,1,FALSE);
1125                                                   break;
1126                                           case STATE:
1127                                                   proto_tree_add_item(layer3_tree,hf_l3_state,layer3_data_tvb,info_element_offset,1,FALSE);
1128                                                   break;
1129                                           case AUTO_SIG_SEQUENCE:
1130                                                   proto_tree_add_item(layer3_tree,hf_l3_auto_signalling_sequence,layer3_data_tvb,info_element_offset,1,FALSE);
1131                                                   break;
1132                                           case SEQUENCE_RESPONSE:
1133                                                   proto_tree_add_item(layer3_tree,hf_l3_sequence_response,layer3_data_tvb,info_element_offset,1,FALSE);
1134                                                   break;
1135                                           default:
1136                                                   break;
1137                                           }
1138                                           info_element_offset += 1;
1139                                   }
1140                                   break;
1141
1142                           case 0x10:
1143                                   /* Variable Length */
1144                                   if(info_element < 0x80){
1145                                   switch(info_element){
1146                                   case CONTROL_FUNCTION_ELEMENT:
1147                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1148                                           proto_tree_add_item(layer3_tree,hf_l3_control_function_element,layer3_data_tvb,info_element_offset+2,info_element_length,FALSE);
1149                                           info_element_offset +=info_element_length+2;
1150                                           break;
1151                                   case CONTROL_FUNCTION_ID:
1152                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1153                                           proto_tree_add_item(layer3_tree,hf_l3_control_function_id,layer3_data_tvb,info_element_offset+2,info_element_length,FALSE);
1154                                           info_element_offset +=info_element_length+2;
1155                                           break;
1156                                   case VARIANT:
1157                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1158                                           proto_tree_add_item(layer3_tree,hf_l3_variant,layer3_data_tvb,info_element_offset+2,info_element_length,FALSE);
1159                                           info_element_offset +=info_element_length+2;
1160                                           break;
1161                                   case INTERFACE_ID:
1162                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1163                                           proto_tree_add_item(layer3_tree,hf_l3_if_id,layer3_data_tvb,info_element_offset+2,info_element_length,FALSE);
1164                                           info_element_offset +=info_element_length+2;
1165                                           break;
1166                                   case SEQUENCE_NUMBER:
1167                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1168                                           proto_tree_add_item(layer3_tree,hf_l3_sequence_number,layer3_data_tvb,info_element_offset+2,info_element_length,FALSE);
1169                                           info_element_offset +=info_element_length+2;
1170                                           break;
1171                                   case C_CHANNEL_ID:
1172                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1173                                           proto_tree_add_item(layer3_tree,hf_l3_v5_link_id,layer3_data_tvb,info_element_offset+2,1,FALSE);
1174                                           proto_tree_add_item(layer3_tree,hf_l3_v5_time_slot,layer3_data_tvb,info_element_offset+3,1,FALSE);
1175                                           info_element_offset +=info_element_length+2;
1176                                           break;
1177                                   case PP_REJECTION_CAUSE:
1178                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1179                                           proto_tree_add_item(layer3_tree,hf_l3_rejection_cause_type,layer3_data_tvb,info_element_offset+2,info_element_length,FALSE);
1180                                           info_element_offset +=info_element_length+2;
1181                                           break;
1182                                   case PROTOCOL_ERROR:
1183                                           break;
1184                                   default:
1185                                           info_element_offset += 1;
1186                                           break;
1187                                   }
1188                                   }
1189                                   /* Single Octet */
1190                                   else if(info_element >= 0x80){
1191                                           switch(info_element & 0xf0){
1192                                           case PERFORMANCE_GRADING:
1193                                                   proto_tree_add_item(layer3_tree,hf_l3_performance_grading,layer3_data_tvb,info_element_offset,1,FALSE);
1194                                                   break;
1195                                           case CP_REJECTION_CAUSE:
1196                                                   proto_tree_add_item(layer3_tree,hf_l3_cp_rejection_cause,layer3_data_tvb,info_element_offset,1,FALSE);
1197                                                   break;
1198                                           default:
1199                                                   break;
1200                                           }
1201                                           info_element_offset += 1;
1202                                   }
1203                                   break;
1204
1205                           case 0x20:
1206                                   /* Variable Length */
1207                                   switch(info_element){
1208                                   case USER_PORT_ID:
1209                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1210                                           buffer = tvb_get_guint8(layer3_data_tvb,info_element_offset+2)&0x01;
1211                                           if(buffer==0x01){
1212                                                   proto_tree_add_item(layer3_tree,hf_l3_pstn_user_port_id,layer3_data_tvb,info_element_offset+2,1,FALSE);
1213                                                   proto_tree_add_item(layer3_tree,hf_l3_pstn_user_port_id_lower,layer3_data_tvb,info_element_offset+3,1,FALSE);
1214                                           }
1215                                           else if(buffer == 0x00){
1216                                                   proto_tree_add_item(layer3_tree,hf_l3_isdn_user_port_id,layer3_data_tvb,info_element_offset+2,1,FALSE);
1217                                                   proto_tree_add_item(layer3_tree,hf_l3_isdn_user_port_id_lower,layer3_data_tvb,info_element_offset+3,1,FALSE);
1218                                           }
1219                                           info_element_offset +=info_element_length+2;                    
1220                                           break;
1221                                   case ISDN_PORT_CHNL_ID:
1222                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1223                                           proto_tree_add_item(layer3_tree,hf_l3_isdn_user_port_ts_num,layer3_data_tvb,info_element_offset+2,1,FALSE);
1224                                           info_element_offset +=info_element_length+2;
1225                                           break;
1226                                   case V5_TIME_SLOT_ID:
1227                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1228                                           proto_tree_add_item(layer3_tree,hf_l3_v5_link_id,layer3_data_tvb,info_element_offset+2,1,FALSE);
1229                                           proto_tree_add_item(layer3_tree,hf_l3_override,layer3_data_tvb,info_element_offset+3,1,FALSE);
1230                                           proto_tree_add_item(layer3_tree,hf_l3_v5_time_slot,layer3_data_tvb,info_element_offset+3,1,FALSE);
1231                                           info_element_offset +=info_element_length+2;
1232                                           break;
1233                                   case MULTI_SLOT_MAP:
1234                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1235                                           proto_tree_add_item(layer3_tree,hf_l3_v5_link_id,layer3_data_tvb,info_element_offset+2,1,FALSE);
1236                                           /* add ts upts here */
1237                                           info_element_offset +=info_element_length+2;
1238                                           break;
1239                                   case BCC_REJECT_CAUSE:
1240                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1241                                           proto_tree_add_item(layer3_tree,hf_l3_reject_cause_type,layer3_data_tvb,info_element_offset+2,1,FALSE);
1242                                           /* add diagnostic */
1243                                           info_element_offset +=info_element_length+2;
1244                                           break;
1245                                   case BCC_PROTOCOL_ERROR_CAUSE:
1246                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1247                                           proto_tree_add_item(layer3_tree,hf_l3_bcc_protocol_error_cause,layer3_data_tvb,info_element_offset+2,1,FALSE);
1248                                           /* add diagnostic */
1249                                           info_element_offset +=info_element_length+2;
1250                                           break;
1251                                   case CONNECTION_INCOMPLETE:
1252                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1253                                           proto_tree_add_item(layer3_tree,hf_l3_connection_incomplete_reason,layer3_data_tvb,info_element_offset+2,1,FALSE);
1254                                           info_element_offset +=info_element_length+2;
1255                                           break;
1256                                   default:
1257                                           info_element_offset += 1;
1258                                           break;
1259                                   }
1260                                   break;
1261
1262                           case 0x30:
1263                                   /* Variable Length */
1264                                   switch(info_element){
1265                                   case LINK_CONTROL_FUNCTION:
1266                                           info_element_length = tvb_get_guint8(layer3_data_tvb,info_element_offset+1);
1267                                           proto_tree_add_item(layer3_tree,hf_l3_link_control_function,layer3_data_tvb,info_element_offset+2,info_element_length,FALSE);
1268                                           info_element_offset += info_element_length+2;
1269                                           break;
1270                                   default:
1271                                           info_element_offset += 1;
1272                                           break;
1273                                   }
1274                                   break;
1275
1276                           default:
1277                                   info_element_offset += 1;
1278                                   break;
1279                           }
1280                   }
1281           }
1282   }
1283   else{
1284           guint16 protocol_data_length;
1285           tvbuff_t *protocol_data_tvb;
1286
1287           protocol_data_length = tvb_get_ntohs(layer3_data_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;
1288           protocol_data_tvb    = tvb_new_subset(layer3_data_tvb, PARAMETER_VALUE_OFFSET, protocol_data_length, protocol_data_length);
1289           call_dissector(q931_handle, protocol_data_tvb, pinfo, v5ua_tree);
1290
1291           proto_item_append_text(parameter_item, " (%u byte%s)", protocol_data_length, plurality(protocol_data_length, "", "s"));
1292   }
1293 }
1294
1295 /*----------------------Data Request,Indication (Draft,RFC)------------------------*/
1296
1297 /*----------------------Establish Request,Confirm,Indication (Draft,RFC)-------*/
1298 /*
1299  * no additional parameter
1300  */
1301 /*----------------------Establish Request,Confirm,Indication (Draft,RFC)-------*/
1302
1303 /*----------------------Release Indication, Request (Draft,RFC)----------------*/
1304
1305         /* define parameters for Release Request and Indication Messages */
1306 #define RELEASE_MGMT   0x0
1307 #define RELEASE_PHYS   0x1
1308 #define RELEASE_DM     0x2
1309 #define RELEASE_OTHER  0x3
1310
1311 static const value_string release_reason_values[] = {
1312         { RELEASE_MGMT,    "Management layer generated release" },
1313         { RELEASE_PHYS,    "Physical layer alarm generated release" },
1314         { RELEASE_DM,      "Specific to a request" },
1315         { RELEASE_OTHER,   "Other reason" },
1316         { 0,               NULL } };
1317
1318 #define RELEASE_REASON_LENGTH_OFFSET PARAMETER_LENGTH_OFFSET
1319 #define RELEASE_REASON_OFFSET        PARAMETER_VALUE_OFFSET
1320 #define RELEASE_REASON_LENGTH        4
1321
1322 static void
1323 dissect_release_reason_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1324 {
1325   gint offset = RELEASE_REASON_OFFSET;
1326   if(iua_version == DRAFT) offset = tvb_get_ntohs(parameter_tvb, RELEASE_REASON_LENGTH_OFFSET)+8;
1327   proto_tree_add_item(parameter_tree, hf_release_reason, parameter_tvb, offset, RELEASE_REASON_LENGTH, FALSE);
1328   if(iua_version != DRAFT)
1329           proto_item_append_text(parameter_item, " (%s)",
1330                 val_to_str(tvb_get_ntohl(parameter_tvb, offset), release_reason_values, "Unknown release reason"));
1331 }
1332 /*----------------------Release Indication,Request (Draft,RFC)-----------------*/
1333
1334 /*----------------------Link Status Start,Stop Report (Draft,RFC)--------------*/
1335 /*
1336  * No additional Parameter
1337  */
1338 /*----------------------Link Status Start,Stop Report (Draft,RFC)--------------*/
1339
1340 /*----------------------Link Status Indication (Draft,RFC)---------------------*/
1341
1342         /* define parameters for Link Status Indication */
1343 #define LINK_STATUS_OPERTIONAL      0x0
1344 #define LINK_STATUS_NON_OPERTIONAL  0x1
1345
1346 static const value_string link_status_values[] = {
1347   { LINK_STATUS_OPERTIONAL,      "Link is in operation" },
1348   { LINK_STATUS_NON_OPERTIONAL,  "Link is not in operation" },
1349   { 0,                           NULL } };
1350
1351 #define LINK_STATUS_OFFSET   PARAMETER_VALUE_OFFSET
1352 #define LINK_STATUS_LENGTH   4
1353
1354 static void
1355 dissect_link_status_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1356 {
1357   proto_tree_add_item(parameter_tree, hf_link_status, parameter_tvb, LINK_STATUS_OFFSET, LINK_STATUS_LENGTH, FALSE);
1358   proto_item_append_text(parameter_item, " (%s)",
1359           val_to_str(tvb_get_ntohl(parameter_tvb, LINK_STATUS_OFFSET),link_status_values, "Unknown Link status"));
1360 }
1361 /*----------------------Link Status Indication (Draft,RFC)---------------------*/
1362
1363 /*----------------------Sa-Bit (Draft,RFC)-------------------------------------*/
1364
1365         /* define parameter for sa-bit message */
1366 #define SA_BIT_ID_ZERO     0x0
1367 #define SA_BIT_ID_ONE      0x1
1368 #define SA_BIT_VALUE_SA7   0x7
1369
1370 static const value_string sa_bit_values[] = {
1371         { SA_BIT_ID_ZERO,    "set to ZERO" },
1372         { SA_BIT_ID_ONE,     "set to ONE" },
1373         { SA_BIT_VALUE_SA7,  "Sa7 Bit" },
1374         { 0,                 NULL } };
1375
1376 #define SA_BIT_ID_OFFSET     PARAMETER_VALUE_OFFSET
1377 #define SA_BIT_ID_LENGTH     2
1378 #define SA_BIT_VALUE_OFFSET  (SA_BIT_ID_OFFSET + SA_BIT_ID_LENGTH)
1379 #define SA_BIT_VALUE_LENGTH  2
1380
1381 static void
1382 dissect_sa_bit_status_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1383 {
1384   proto_tree_add_item(parameter_tree, hf_sa_bit_id, parameter_tvb, SA_BIT_ID_OFFSET, SA_BIT_ID_LENGTH, FALSE);
1385   proto_tree_add_item(parameter_tree, hf_sa_bit_value, parameter_tvb, SA_BIT_VALUE_OFFSET, SA_BIT_VALUE_LENGTH, FALSE);
1386   proto_item_append_text(parameter_item, " (%s %s)",
1387           val_to_str(tvb_get_ntohs(parameter_tvb, SA_BIT_ID_OFFSET), sa_bit_values, "unknown"),
1388           val_to_str(tvb_get_ntohs(parameter_tvb, SA_BIT_VALUE_OFFSET), sa_bit_values, "unknown Bit"));
1389
1390 }
1391 /*----------------------Sa-Bit (Draft,RFC)-------------------------------------*/
1392
1393 /*----------------------Error Indication (RFC)---------------------------------*/
1394
1395 #define ERROR_REASON_OVERLOAD 0x1
1396
1397 static const value_string error_reason_values[] = {
1398         { ERROR_REASON_OVERLOAD, "C-Channel is in overload state" },
1399         { 0,                     NULL } };
1400
1401 #define ERROR_REASON_LENGTH 4
1402 #define ERROR_REASON_OFFSET PARAMETER_VALUE_OFFSET
1403
1404 static void
1405 dissect_error_indication_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1406 {
1407   proto_tree_add_item(parameter_tree, hf_error_reason, parameter_tvb, ERROR_REASON_OFFSET, ERROR_REASON_LENGTH, FALSE);
1408   proto_item_append_text(parameter_item, " (%s)",
1409           val_to_str(tvb_get_ntohl(parameter_tvb, ERROR_REASON_OFFSET), error_reason_values, "unknown"));
1410 }
1411 /*----------------------Error Indication (RFC)---------------------------------*/
1412
1413 #define INFO_STRING_OFFSET PARAMETER_VALUE_OFFSET
1414
1415 static void
1416 dissect_info_string_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1417 {
1418   guint16 info_string_length;
1419
1420   info_string_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
1421   if(iua_version == DRAFT) info_string_length += 4;
1422   if(info_string_length > 4){
1423         info_string_length -= PARAMETER_HEADER_LENGTH;
1424         proto_tree_add_item(parameter_tree, hf_info_string, parameter_tvb, INFO_STRING_OFFSET, info_string_length, FALSE);
1425         proto_item_append_text(parameter_item, " (%.*s)", info_string_length,
1426                 (const char *)tvb_get_ptr(parameter_tvb, INFO_STRING_OFFSET, info_string_length));
1427   }
1428 }
1429
1430 static void
1431 dissect_unknown_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1432 {
1433   guint16 parameter_value_length;
1434
1435   parameter_value_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;
1436   if (parameter_value_length > 0)
1437     proto_tree_add_item(parameter_tree, hf_parameter_value, parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, FALSE);
1438   proto_item_append_text(parameter_item, " with tag %u and %u byte%s value",
1439           tvb_get_ntohs(parameter_tvb, PARAMETER_TAG_OFFSET), parameter_value_length, plurality(parameter_value_length, "", "s"));
1440 }
1441
1442
1443 #define INT_INTERFACE_IDENTIFIER_PARAMETER_TAG           0x01
1444 #define ASP_MSG_PARAMETER_TAG                            0x02
1445 #define TEXT_INTERFACE_IDENTIFIER_PARAMETER_TAG          0x03
1446 #define INFO_PARAMETER_TAG                               0x04
1447 #define DLCI_PARAMETER_TAG                               0x05
1448 #define DIAGNOSTIC_INFORMATION_PARAMETER_TAG             0x07
1449 #define INTEGER_RANGE_INTERFACE_IDENTIFIER_PARAMETER_TAG 0x08
1450 #define HEARTBEAT_DATA_PARAMETER_TAG                     0x09
1451 #define ASP_DOWN_REASON_PARAMETER_TAG                    0x0a
1452 #define TRAFFIC_MODE_TYPE_PARAMETER_TAG                  0x0b
1453 #define ERROR_CODE_PARAMETER_TAG                         0x0c
1454 #define STATUS_TYPE_INDENTIFICATION_PARAMETER_TAG        0x0d
1455 #define PROTOCOL_DATA_PARAMETER_TAG                      0x0e
1456 #define RELEASE_REASON_PARAMETER_TAG                     0x0f
1457 #define TEI_STATUS_PARAMETER_TAG                         0x10
1458 #define LINK_STATUS_PARAMETER_TAG                        0x11
1459 #define SA_BIT_STATUS_PARAMETER_TAG                      0x12
1460 #define ERROR_INDICATION_PARAMETER_TAG                   0x13
1461
1462 static const value_string parameter_tag_values[] = {
1463   { INT_INTERFACE_IDENTIFIER_PARAMETER_TAG,              "V5UA Interface Identifier (int)" },
1464   { TEXT_INTERFACE_IDENTIFIER_PARAMETER_TAG,             "Text Interface Identifier" },
1465   { INFO_PARAMETER_TAG,                                  "Info" },
1466   { DLCI_PARAMETER_TAG,                                  "DLCI" },
1467   { DIAGNOSTIC_INFORMATION_PARAMETER_TAG,                "Diagnostic information" },
1468   { INTEGER_RANGE_INTERFACE_IDENTIFIER_PARAMETER_TAG,    "Integer range interface identifier" },
1469   { HEARTBEAT_DATA_PARAMETER_TAG,                        "Hearbeat data" },
1470   { ASP_DOWN_REASON_PARAMETER_TAG,                       "ASP DOWN Reason" },
1471   { TRAFFIC_MODE_TYPE_PARAMETER_TAG,                     "Traffic mode type" },
1472   { ERROR_CODE_PARAMETER_TAG,                            "Error code" },
1473   { STATUS_TYPE_INDENTIFICATION_PARAMETER_TAG,           "Status type/identification" },
1474   { PROTOCOL_DATA_PARAMETER_TAG,                         "Protocol Data" },
1475   { RELEASE_REASON_PARAMETER_TAG,                        "Reason" },
1476   { TEI_STATUS_PARAMETER_TAG,                            "TEI status" },
1477   { LINK_STATUS_PARAMETER_TAG,                           "Link status" },
1478   { SA_BIT_STATUS_PARAMETER_TAG,                         "SA-Bit status" },
1479   { ERROR_INDICATION_PARAMETER_TAG,                      "Error reason" },
1480   { 0,                                                   NULL } };
1481
1482 static const value_string parameter_tag_draft_values[] = {
1483   { INT_INTERFACE_IDENTIFIER_PARAMETER_TAG,              "V5UA Interface Identifier (int)" },
1484   { ASP_MSG_PARAMETER_TAG,                               "ASP Adaption Layer ID" },
1485   { TEXT_INTERFACE_IDENTIFIER_PARAMETER_TAG,             "SCN Protocol Identifier" },
1486   { INFO_PARAMETER_TAG,                                  "Info" },
1487   { LINK_STATUS_PARAMETER_TAG,                           "Link status" },
1488   { SA_BIT_STATUS_PARAMETER_TAG,                         "SA-Bit status" },
1489   { ERROR_INDICATION_PARAMETER_TAG,                      "Error reason" },
1490   { 0,                                                   NULL } };
1491
1492
1493
1494 static void
1495 dissect_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *v5ua_tree)
1496 {
1497   guint16 tag, length, padding_length;
1498   proto_item *parameter_item;
1499   proto_tree *parameter_tree;
1500
1501   /* extract tag and length from the parameter */
1502   tag      = tvb_get_ntohs(parameter_tvb, PARAMETER_TAG_OFFSET);
1503   length   = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
1504   /* on IUA-Draft messages the message length not including the message header */
1505   if((iua_version==DRAFT)&&(tag<=0x4)){
1506           /* at V5UA Header, length of header and length of DLCI+EFA must be added */
1507           if(tag==0x1)       length += 8;
1508           /* at ASP message tags only length of header must be added */
1509           else if(tag<=0x4)  length += PARAMETER_HEADER_LENGTH;
1510           /* for following message-tags are no length information available. Only in common msg header */
1511       if((msg_class==0 || msg_class==1 || msg_class==9) && msg_type<=10)
1512         length = msg_length;
1513   }
1514   padding_length = tvb_length(parameter_tvb) - length;
1515
1516   /* create proto_tree stuff */
1517
1518   switch(iua_version){
1519   case RFC:
1520           parameter_item   = proto_tree_add_text(v5ua_tree, parameter_tvb, PARAMETER_HEADER_OFFSET, tvb_length(parameter_tvb), "%s",
1521                 val_to_str(tag, parameter_tag_values, "Unknown parameter"));
1522           parameter_tree   = proto_item_add_subtree(parameter_item, ett_v5ua_parameter);
1523
1524           /* add tag to the v5ua tree */
1525           proto_tree_add_item(parameter_tree, hf_parameter_tag, parameter_tvb, PARAMETER_TAG_OFFSET, PARAMETER_TAG_LENGTH, FALSE);
1526           break;
1527
1528   case DRAFT:
1529   default:
1530           parameter_item   = proto_tree_add_text(v5ua_tree, parameter_tvb, PARAMETER_HEADER_OFFSET, tvb_length(parameter_tvb), "%s",
1531                 val_to_str(tag, parameter_tag_draft_values, "Unknown parameter"));
1532           parameter_tree   = proto_item_add_subtree(parameter_item, ett_v5ua_parameter);
1533
1534           /* add tag to the v5ua tree */
1535           proto_tree_add_item(parameter_tree, hf_parameter_tag_draft, parameter_tvb, PARAMETER_TAG_OFFSET, PARAMETER_TAG_LENGTH, FALSE);
1536           break;
1537
1538   };
1539
1540   /* add length to the v5ua tree */
1541   proto_tree_add_item(parameter_tree, hf_parameter_length, parameter_tvb, PARAMETER_LENGTH_OFFSET, PARAMETER_LENGTH_LENGTH, FALSE);
1542
1543   switch(tag) {
1544   case INT_INTERFACE_IDENTIFIER_PARAMETER_TAG:
1545         if(iua_version == RFC) dissect_int_interface_identifier_parameter(parameter_tvb, parameter_tree, parameter_item);
1546         if(iua_version == DRAFT){
1547                 dissect_int_interface_identifier_parameter(parameter_tvb, parameter_tree, parameter_item);
1548                 dissect_dlci_parameter(parameter_tvb, parameter_tree, parameter_item);
1549
1550                 /* for the following parameters no tag- and length-informations available. Parameters must be dissect with info from common msg header */
1551                 if(msg_class==0 && msg_type==0)    dissect_draft_error_code_parameter(parameter_tvb, parameter_tree);
1552                 if(msg_class==1)                   dissect_draft_tei_status_parameter(parameter_tvb, parameter_tree, parameter_item);
1553                 if(msg_class==9){
1554                         if(msg_type==1||msg_type==2||msg_type==3||msg_type==4){
1555                                 guint16 length, offset;
1556                                 tvbuff_t *layer3_data_tvb;
1557                                 offset = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) + 8;
1558                                 length = msg_length - offset;
1559                                 if(length > 0){
1560                                         if(tvb_get_guint8(parameter_tvb, offset) == 0x48){
1561                                                 layer3_data_tvb = tvb_new_subset(parameter_tvb, offset, length, length);
1562                                                 dissect_layer3_message(layer3_data_tvb, v5ua_tree, parameter_item, pinfo);
1563                                         }
1564                                 }
1565                         }
1566                         else if(msg_type==8||msg_type==10) dissect_release_reason_parameter(parameter_tvb, parameter_tree, parameter_item);
1567                 }
1568         }
1569     break;
1570   case ASP_MSG_PARAMETER_TAG:
1571     dissect_asp_msg_parameter(parameter_tvb, parameter_tree, parameter_item);
1572     break;
1573   case TEXT_INTERFACE_IDENTIFIER_PARAMETER_TAG:
1574     if(iua_version == RFC)
1575       dissect_text_interface_identifier_parameter(parameter_tvb, parameter_tree, parameter_item);
1576     if(iua_version == DRAFT)
1577       dissect_scn_protocol_id_parameter(parameter_tvb, parameter_tree, parameter_item);
1578     break;
1579   case INFO_PARAMETER_TAG:
1580     dissect_info_string_parameter(parameter_tvb, parameter_tree, parameter_item);
1581     break;
1582   case DLCI_PARAMETER_TAG:
1583     dissect_dlci_parameter(parameter_tvb, parameter_tree, parameter_item);
1584     break;
1585   case DIAGNOSTIC_INFORMATION_PARAMETER_TAG:
1586     dissect_diagnostic_information_parameter(parameter_tvb, parameter_tree, parameter_item);
1587     break;
1588   case INTEGER_RANGE_INTERFACE_IDENTIFIER_PARAMETER_TAG:
1589     dissect_integer_range_interface_identifier_parameter(parameter_tvb, parameter_tree, parameter_item);
1590     break;
1591   case HEARTBEAT_DATA_PARAMETER_TAG:
1592     dissect_heartbeat_data_parameter(parameter_tvb, parameter_tree, parameter_item);
1593     break;
1594   case ASP_DOWN_REASON_PARAMETER_TAG:
1595     dissect_asp_reason_parameter(parameter_tvb, parameter_tree, parameter_item);
1596     break;
1597   case TRAFFIC_MODE_TYPE_PARAMETER_TAG:
1598     dissect_traffic_mode_type_parameter(parameter_tvb, parameter_tree, parameter_item);
1599     break;
1600   case ERROR_CODE_PARAMETER_TAG:
1601     dissect_error_code_parameter(parameter_tvb, parameter_tree, parameter_item);
1602     break;
1603   case STATUS_TYPE_INDENTIFICATION_PARAMETER_TAG:
1604     dissect_status_type_identification_parameter(parameter_tvb, parameter_tree, parameter_item);
1605     break;
1606   case PROTOCOL_DATA_PARAMETER_TAG:
1607     dissect_layer3_message(parameter_tvb, v5ua_tree, parameter_item, pinfo);
1608     break;
1609   case RELEASE_REASON_PARAMETER_TAG:
1610     dissect_release_reason_parameter(parameter_tvb, parameter_tree, parameter_item);
1611     break;
1612   case TEI_STATUS_PARAMETER_TAG:
1613     dissect_tei_status_parameter(parameter_tvb, parameter_tree, parameter_item);
1614     break;
1615   case LINK_STATUS_PARAMETER_TAG:
1616     dissect_link_status_parameter(parameter_tvb, parameter_tree, parameter_item);
1617     break;
1618   case SA_BIT_STATUS_PARAMETER_TAG:
1619     dissect_sa_bit_status_parameter(parameter_tvb, parameter_tree, parameter_item);
1620     break;
1621   case ERROR_INDICATION_PARAMETER_TAG:
1622     dissect_error_indication_parameter( parameter_tvb, parameter_tree, parameter_item);
1623     break;
1624   default:
1625     dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
1626     break;
1627   };
1628
1629   if (padding_length > 0){
1630     proto_tree_add_item(parameter_tree, hf_parameter_padding, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length, FALSE);
1631   }
1632 }
1633
1634 /* dissect the V5UA-Parameters into subsets which are separated by Tag-Length-Header and call up the dissector for the subsets */
1635 static void
1636 dissect_parameters(tvbuff_t *parameters_tvb, packet_info *pinfo, proto_tree *tree _U_, proto_tree *v5ua_tree)
1637 {
1638   gint tag, offset, length, total_length, remaining_length;
1639   tvbuff_t *parameter_tvb;
1640
1641   
1642   offset = 0;
1643   while((remaining_length = tvb_length_remaining(parameters_tvb, offset))) {
1644         tag = tvb_get_ntohs(parameters_tvb, offset + PARAMETER_TAG_OFFSET);
1645         length = tvb_get_ntohs(parameters_tvb, offset + PARAMETER_LENGTH_OFFSET);
1646         if(iua_version==DRAFT){
1647                 if(tag==0x1) length += 8;               /* V5UA Header */
1648                 else if(tag<=0x4) length += PARAMETER_HEADER_LENGTH;    /* ASP MSGs */
1649
1650                 /* add the parameters which are not separated by tag-length-header to the V5UA header */
1651                 if((msg_class==0 || msg_class==1 || msg_class==9)&&msg_type<=10)
1652                         length = msg_length;
1653         }        
1654         total_length = ADD_PADDING(length);
1655         if (remaining_length >= length)
1656           total_length = MIN(total_length, remaining_length);
1657         /* create a tvb for the parameter including the padding bytes */
1658         parameter_tvb  = tvb_new_subset(parameters_tvb, offset, total_length, total_length);
1659         dissect_parameter(parameter_tvb, pinfo, v5ua_tree);
1660         /* get rid of the handled parameter */
1661         offset += total_length;
1662         }
1663 }
1664
1665
1666
1667         /* define the common header fields of V5UA MSG */
1668 #define COMMON_HEADER_VERSION_LENGTH        1
1669 #define COMMON_HEADER_RESERVED_LENGTH       1
1670 #define COMMON_HEADER_MSG_CLASS_LENGTH      1
1671 #define COMMON_HEADER_MSG_TYPE_LENGTH       1
1672 #define COMMON_HEADER_MSG_LENGTH_LENGTH     4
1673 #define COMMON_HEADER_LENGTH                (COMMON_HEADER_VERSION_LENGTH + COMMON_HEADER_RESERVED_LENGTH +\
1674                                              COMMON_HEADER_MSG_CLASS_LENGTH + COMMON_HEADER_MSG_TYPE_LENGTH +\
1675                                              COMMON_HEADER_MSG_LENGTH_LENGTH)
1676
1677         /* define the offsets of common header */
1678 #define COMMON_HEADER_OFFSET            0
1679 #define COMMON_HEADER_VERSION_OFFSET    COMMON_HEADER_OFFSET
1680 #define COMMON_HEADER_RESERVED_OFFSET   (COMMON_HEADER_VERSION_OFFSET       + COMMON_HEADER_VERSION_LENGTH)
1681 #define COMMON_HEADER_MSG_CLASS_OFFSET  (COMMON_HEADER_RESERVED_OFFSET      + COMMON_HEADER_RESERVED_LENGTH)
1682 #define COMMON_HEADER_MSG_TYPE_OFFSET   (COMMON_HEADER_MSG_CLASS_OFFSET     + COMMON_HEADER_MSG_CLASS_LENGTH)
1683 #define COMMON_HEADER_MSG_LENGTH_OFFSET (COMMON_HEADER_MSG_TYPE_OFFSET      + COMMON_HEADER_MSG_TYPE_LENGTH)
1684 #define COMMON_HEADER_PARAMETERS_OFFSET (COMMON_HEADER_OFFSET               + COMMON_HEADER_LENGTH)
1685
1686         /* version of V5UA protocol */
1687 #define V5UA_PROTOCOL_VERSION_RELEASE_1     1
1688
1689 static const value_string v5ua_protocol_version_values[] = {
1690   { V5UA_PROTOCOL_VERSION_RELEASE_1,  "Release 1" },
1691   { 0,                                NULL } };
1692
1693         /* define V5UA MSGs */
1694 #define MSG_CLASS_MGMT_MSG        0
1695 #define MSG_CLASS_MGMT_MSG_DRAFT  1
1696 #define MSG_CLASS_ASPSM_MSG       3
1697 #define MSG_CLASS_ASPTM_MSG       4
1698 #define MSG_CLASS_V5PTM_MSG_DRAFT 9
1699 #define MSG_CLASS_V5PTM_MSG      14
1700
1701 static const value_string msg_class_values[] = {
1702         { MSG_CLASS_MGMT_MSG,  "Management Messages" },
1703         { MSG_CLASS_MGMT_MSG_DRAFT,"Management Messages"},
1704         { MSG_CLASS_ASPSM_MSG, "ASP state maintenance message" },
1705         { MSG_CLASS_ASPTM_MSG, "ASP traffic maintenance message" },
1706         { MSG_CLASS_V5PTM_MSG_DRAFT, "V5 Boundary Primitives Transport Message" },
1707         { MSG_CLASS_V5PTM_MSG, "V5 Boundary Primitives Transport Message" },
1708         { 0,                           NULL } }; 
1709
1710         /* message types for MGMT messages */
1711 #define MGMT_MSG_TYPE_ERR                  0
1712 #define MGMT_MSG_TYPE_NTFY                 1
1713 #define MGMT_MSG_TYPE_TEI_STATUS_REQ       2
1714 #define MGMT_MSG_TYPE_TEI_STATUS_CON       3
1715 #define MGMT_MSG_TYPE_TEI_STATUS_IND       4
1716         /* MGMT messages for Nortel draft version*/
1717 #define MGMT_MSG_DRAFT_TYPE_TEI_STATUS_REQ       1
1718 #define MGMT_MSG_DRAFT_TYPE_TEI_STATUS_CON       2
1719 #define MGMT_MSG_DRAFT_TYPE_TEI_STATUS_IND       3
1720
1721
1722         /* message types for ASPSM messages */
1723 #define ASPSM_MSG_TYPE_UP                   1
1724 #define ASPSM_MSG_TYPE_DOWN                 2
1725 #define ASPSM_MSG_TYPE_BEAT                 3
1726 #define ASPSM_MSG_TYPE_UP_ACK               4
1727 #define ASPSM_MSG_TYPE_DOWN_ACK             5
1728 #define ASPSM_MSG_TYPE_BEAT_ACK             6
1729
1730         /* message types for ASPTM messages */
1731 #define ASPTM_MSG_TYPE_ACTIVE               1
1732 #define ASPTM_MSG_TYPE_INACTIVE             2
1733 #define ASPTM_MSG_TYPE_ACTIVE_ACK           3
1734 #define ASPTM_MSG_TYPE_INACTIVE_ACK         4
1735
1736         /* message types for V5PTM messages */
1737 #define V5PTM_MSG_TYPE_DATA_REQUEST                 1
1738 #define V5PTM_MSG_TYPE_DATA_INDICATION              2
1739 #define V5PTM_MSG_TYPE_UNIT_DATA_REQUEST            3
1740 #define V5PTM_MSG_TYPE_UNIT_DATA_INDICATION         4
1741 #define V5PTM_MSG_TYPE_ESTABLISH_REQUEST            5
1742 #define V5PTM_MSG_TYPE_ESTABLISH_CONFIRM            6
1743 #define V5PTM_MSG_TYPE_ESTABLISH_INDICATION         7
1744 #define V5PTM_MSG_TYPE_RELEASE_REQUEST              8
1745 #define V5PTM_MSG_TYPE_RELEASE_CONFIRM              9
1746 #define V5PTM_MSG_TYPE_RELEASE_INDICATION          10
1747 #define V5PTM_MSG_TYPE_LINK_STATUS_START_REPORTING 11
1748 #define V5PTM_MSG_TYPE_LINK_STATUS_STOP_REPORTING  12
1749 #define V5PTM_MSG_TYPE_LINK_STATUS_INDICATION      13
1750 #define V5PTM_MSG_TYPE_SA_BIT_SET_REQUEST          14
1751 #define V5PTM_MSG_TYPE_SA_BIT_SET_CONFIRM          15
1752 #define V5PTM_MSG_TYPE_SA_BIT_STATUS_REQUEST       16
1753 #define V5PTM_MSG_TYPE_SA_BIT_STATUS_INDICATION    17
1754 #define V5PTM_MSG_TYPE_ERROR_INDICATION            18
1755
1756 static const value_string msg_class_type_values[] = {
1757   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_ERR,                         "Error" },
1758   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_NTFY,                        "Notify" },
1759   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_TEI_STATUS_REQ,              "TEI status request" },
1760   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_TEI_STATUS_CON,              "TEI status confirmation" },
1761   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_TEI_STATUS_IND,              "TEI status indication" },
1762
1763   { MSG_CLASS_MGMT_MSG_DRAFT * 256 + MGMT_MSG_DRAFT_TYPE_TEI_STATUS_REQ,   "TEI status request" },
1764   { MSG_CLASS_MGMT_MSG_DRAFT * 256 + MGMT_MSG_DRAFT_TYPE_TEI_STATUS_CON,   "TEI status confimation" },
1765   { MSG_CLASS_MGMT_MSG_DRAFT * 256 + MGMT_MSG_DRAFT_TYPE_TEI_STATUS_IND,   "TEI status indication" },
1766
1767   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_UP,                         "ASP up" },
1768   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_DOWN,                       "ASP down" },
1769   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_BEAT,                       "Heartbeat" },
1770   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_UP_ACK,                     "ASP up ack" },
1771   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_DOWN_ACK,                   "ASP down ack" },
1772   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_BEAT_ACK,                   "Heartbeat ack" },
1773
1774   { MSG_CLASS_ASPTM_MSG * 256 + ASPTM_MSG_TYPE_ACTIVE ,                    "ASP active" },
1775   { MSG_CLASS_ASPTM_MSG * 256 + ASPTM_MSG_TYPE_INACTIVE ,                  "ASP inactive" },
1776   { MSG_CLASS_ASPTM_MSG * 256 + ASPTM_MSG_TYPE_ACTIVE_ACK ,                "ASP active ack" },
1777   { MSG_CLASS_ASPTM_MSG * 256 + ASPTM_MSG_TYPE_INACTIVE_ACK ,              "ASP inactive ack" },
1778
1779   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_DATA_REQUEST,               "Data request" },
1780   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_DATA_INDICATION,            "Data indication" },
1781   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_UNIT_DATA_REQUEST,          "Unit data request" },
1782   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_UNIT_DATA_INDICATION,       "Unit data indication" },
1783   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_ESTABLISH_REQUEST,          "Establish request" },
1784   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_ESTABLISH_CONFIRM,          "Establish confirmation" },
1785   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_ESTABLISH_INDICATION,       "Establish indication" },
1786   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_RELEASE_REQUEST,            "Release request" },
1787   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_RELEASE_CONFIRM,            "Release confirmation" },
1788   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_RELEASE_INDICATION,         "Release indication" },
1789   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_LINK_STATUS_START_REPORTING,"Link status start reporting" },
1790   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_LINK_STATUS_STOP_REPORTING, "Link status stop reporting" },
1791   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_LINK_STATUS_INDICATION,     "Link status indication" },
1792   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_SA_BIT_SET_REQUEST,         "Sa-Bit set request" },
1793   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_SA_BIT_SET_CONFIRM,         "Sa-Bit set confirm" },
1794   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_SA_BIT_STATUS_REQUEST,      "Sa-Bit status request" },
1795   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_SA_BIT_STATUS_INDICATION,   "Sa-Bit status indication" },
1796   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_ERROR_INDICATION,           "Error indication" },
1797
1798   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_DATA_REQUEST,               "Data request" },
1799   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_DATA_INDICATION,            "Data indication" },
1800   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_UNIT_DATA_REQUEST,          "Unit data request" },
1801   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_UNIT_DATA_INDICATION,       "Unit data indication" },
1802   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_ESTABLISH_REQUEST,          "Establish request" },
1803   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_ESTABLISH_CONFIRM,          "Establish confirmation" },
1804   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_ESTABLISH_INDICATION,       "Establish indication" },
1805   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_RELEASE_REQUEST,            "Release request" },
1806   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_RELEASE_CONFIRM,            "Release confirmation" },
1807   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_RELEASE_INDICATION,         "Release indication" },
1808   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_LINK_STATUS_START_REPORTING,"Link status start reporting" },
1809   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_LINK_STATUS_STOP_REPORTING, "Link status stop reporting" },
1810   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_LINK_STATUS_INDICATION,     "Link status indication" },
1811   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_SA_BIT_SET_REQUEST,         "Sa-Bit set request" },
1812   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_SA_BIT_SET_CONFIRM,         "Sa-Bit set confirm" },
1813   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_SA_BIT_STATUS_REQUEST,      "Sa-Bit status request" },
1814   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_SA_BIT_STATUS_INDICATION,   "Sa-Bit status indication" },
1815   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_ERROR_INDICATION,           "Error indication" },
1816
1817   { 0,                                                                                  NULL } };
1818
1819
1820 static void
1821 dissect_common_header(tvbuff_t *common_header_tvb, packet_info *pinfo, proto_tree *v5ua_tree)
1822 {
1823   proto_item *common_header_item;
1824   proto_tree *common_header_tree;
1825
1826   guint8 message_class, message_type;
1827
1828   message_class  = tvb_get_guint8(common_header_tvb, COMMON_HEADER_MSG_CLASS_OFFSET);
1829   message_type   = tvb_get_guint8(common_header_tvb, COMMON_HEADER_MSG_TYPE_OFFSET);
1830
1831   /* Add message type into info column */
1832   if (check_col(pinfo->cinfo, COL_INFO)) {
1833     col_add_str(pinfo->cinfo, COL_INFO, val_to_str(message_class * 256 + message_type, msg_class_type_values, "UNKNOWN"));
1834     col_append_str(pinfo->cinfo, COL_INFO, " ");
1835   }
1836
1837   if (v5ua_tree) {
1838
1839           /* create proto_tree stuff */
1840     common_header_item   = proto_tree_add_text(v5ua_tree, common_header_tvb, COMMON_HEADER_OFFSET, tvb_length(common_header_tvb),"Common Msg-Header");
1841     common_header_tree   = proto_item_add_subtree(common_header_item, ett_v5ua_common_header);
1842
1843           /* add the components of the common header to the protocol tree */
1844     proto_tree_add_item(common_header_tree, hf_version, common_header_tvb, COMMON_HEADER_VERSION_OFFSET, COMMON_HEADER_VERSION_LENGTH, FALSE);
1845     proto_tree_add_item(common_header_tree, hf_reserved, common_header_tvb, COMMON_HEADER_RESERVED_OFFSET, COMMON_HEADER_RESERVED_LENGTH, FALSE);
1846     proto_tree_add_item(common_header_tree, hf_msg_class, common_header_tvb, COMMON_HEADER_MSG_CLASS_OFFSET, COMMON_HEADER_MSG_CLASS_LENGTH, FALSE);
1847     proto_tree_add_uint_format(common_header_tree, hf_msg_type,
1848                               common_header_tvb, COMMON_HEADER_MSG_TYPE_OFFSET, COMMON_HEADER_MSG_TYPE_LENGTH,
1849                               message_type, "Message type: %s ( %u )",
1850                               val_to_str(message_class * 256 + message_type, msg_class_type_values, "reserved"), message_type);
1851     proto_tree_add_uint(common_header_tree, hf_msg_type_id, common_header_tvb, COMMON_HEADER_MSG_TYPE_OFFSET, COMMON_HEADER_MSG_TYPE_LENGTH,
1852                               message_class * 256 + message_type);
1853     proto_tree_add_item(common_header_tree, hf_msg_length, common_header_tvb, COMMON_HEADER_MSG_LENGTH_OFFSET, COMMON_HEADER_MSG_LENGTH_LENGTH, FALSE);
1854
1855         /* Add message type to the Common Msg-Header line */
1856     proto_item_append_text(common_header_item, " (%s)",val_to_str(message_class * 256 + message_type, msg_class_type_values, "Unknown Msg-Type"));
1857   }
1858
1859         /* the following info are required to dissect IUA-Draft messages.
1860         In the DRAFT-Specification V5UA-Parameters are not separated by Tag-Length-Header (as defined in RFC-Spec) */
1861   if (iua_version == DRAFT){
1862           msg_class = message_class;
1863           msg_type  = message_type;
1864           msg_length = tvb_get_ntohl (common_header_tvb, COMMON_HEADER_MSG_LENGTH_OFFSET);
1865   }
1866 }
1867
1868 /* dissect the V5UA-packet in two subsets: Common Msg-Header (used by all msgs) and V5UA-parameter */
1869 static void
1870 dissect_v5ua_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *v5ua_tree)
1871 {
1872   tvbuff_t *common_header_tvb, *parameters_tvb;
1873
1874   common_header_tvb = tvb_new_subset(tvb, COMMON_HEADER_OFFSET, COMMON_HEADER_LENGTH, COMMON_HEADER_LENGTH);
1875   dissect_common_header(common_header_tvb, pinfo, v5ua_tree);
1876
1877   parameters_tvb    = tvb_new_subset(tvb, COMMON_HEADER_LENGTH, -1, -1);
1878   dissect_parameters(parameters_tvb, pinfo, tree, v5ua_tree);
1879 }
1880         
1881         
1882 static void
1883 dissect_v5ua(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1884 {
1885
1886    gint    offset, remaining_length, length, tag, one_bit;
1887
1888
1889 /* Set up structures needed to add the protocol subtree and manage it */
1890         proto_tree *v5ua_tree;
1891         proto_item *ti;
1892
1893 /* Make entries in Protocol column and Info column on summary display */
1894         if (check_col(pinfo->cinfo, COL_PROTOCOL)) 
1895                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "V5UA");
1896
1897         if (check_col(pinfo->cinfo, COL_INFO)) 
1898                 col_clear(pinfo->cinfo, COL_INFO);
1899
1900         if (tree) {
1901 /* create display subtree for the protocol */
1902                 ti = proto_tree_add_item(tree, proto_v5ua, tvb, 0, -1, FALSE);
1903                 v5ua_tree = proto_item_add_subtree(ti, ett_v5ua);
1904         }
1905         else {
1906                 v5ua_tree=NULL;
1907         };
1908
1909         /* detect version of IUA */
1910    iua_version = RFC;
1911    offset = COMMON_HEADER_LENGTH;
1912
1913    remaining_length = tvb_length_remaining(tvb, offset);
1914
1915    while(remaining_length) {
1916            tag = tvb_get_ntohs(tvb, offset);
1917            /*0x01,0x03: Inerface Id (draft&RFC)*/
1918                 if(tag==0x1){
1919                         length = tvb_get_ntohs(tvb, offset+2);
1920                         tag = tvb_get_ntohs(tvb, offset+length);
1921                         /* tag 0x5 indicates the DLCI in the V5UA-Header accoriding to RFC spec */
1922                         if(tag==0x5){
1923                                 remaining_length = FALSE;
1924                         }
1925                         else{
1926                                 one_bit = tvb_get_guint8(tvb, offset+4+length+1);
1927                                 /* no indication from DLCI by tag (in the V5UA-Header according DRAFT).
1928                                         Thus the ONE-Bit within DLCI have to compare */
1929                                 if((one_bit & 0x01) == 0x01){
1930                                         iua_version = DRAFT;
1931                                         remaining_length = FALSE;
1932                                 }
1933                                 /* an indication to incorrect bit in DLCI.
1934                                         Must be include to decode an incorrect implemented message on Nortels PVG*/
1935                                 else{
1936                                         proto_item_append_text(v5ua_tree, "   !! DLCI INCORRECT !!");
1937
1938                                         iua_version = DRAFT;
1939                                         remaining_length = FALSE;
1940                                 }
1941                         }
1942                 }
1943                 /*0x02: AL Id (draft) following after common msg header without V5UA header*/
1944                 else if(tag==0x02){
1945                         iua_version = DRAFT;
1946                         remaining_length = FALSE;
1947                 }
1948                 /*0x03: Text formatted IId SHALL not be supported by draft*/
1949                 else if(tag==0x03){
1950                         iua_version = RFC;
1951                         remaining_length = FALSE;
1952                 }
1953                 /*ASP, Notify and Error messages (RFC) only contain common msg header followed by parameter*/
1954                 else if(tag==0x04 || tag == 0x0a || tag == 0x0b || tag == 0x0c || tag == 0x0d){
1955                         remaining_length = FALSE;
1956                 }
1957                 else{
1958                         offset+=2;
1959                         remaining_length = tvb_length_remaining(tvb, offset);
1960                 }
1961                 /* add a notice for the draft version */
1962                 if(iua_version == DRAFT){
1963                         if (check_col(pinfo->cinfo, COL_PROTOCOL)) 
1964                                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "V5UA (draft)");
1965                 }
1966    }
1967  
1968
1969    /* dissect the message */
1970   dissect_v5ua_message(tvb, pinfo, tree, v5ua_tree);
1971 }
1972
1973
1974
1975 /* Register the protocol with Wireshark */
1976
1977 /* this format is require because a script is used to build the C function
1978    that calls all the protocol registration. */
1979
1980
1981 void
1982 proto_register_v5ua(void)
1983 {
1984
1985 /* Setup list of header fields  */
1986         static hf_register_info hf[] = {
1987                 { &hf_version,
1988                         { "Version",                "v5ua.version",
1989                            FT_UINT8,    BASE_DEC, VALS(v5ua_protocol_version_values),0x0,
1990                            "", HFILL } },
1991                 { &hf_reserved,
1992                         { "Reserved",               "v5ua.reserved",
1993                            FT_UINT8,    BASE_HEX, NULL,                             0x0,
1994                            NULL, HFILL } },
1995                 { &hf_msg_class,
1996                         { "Message class",          "v5ua.msg_class",
1997                            FT_UINT8,    BASE_DEC, VALS(msg_class_values),           0x0,
1998                            NULL, HFILL } },
1999                 { &hf_msg_type,
2000                         { "Message Type",           "v5ua.msg_type",
2001                            FT_UINT8,    BASE_DEC, NULL,                             0x0,
2002                            NULL, HFILL } },
2003                 { &hf_msg_type_id,
2004                         { "Message Type ID",        "v5ua.msg_type_id",
2005                            FT_UINT8,    BASE_DEC, VALS(msg_class_type_values),      0x0,
2006                            NULL, HFILL } },
2007                 { &hf_msg_length,
2008                         { "Message length",         "v5ua.msg_length",
2009                            FT_UINT32,   BASE_DEC, NULL,                             0x0,
2010                            NULL, HFILL } },
2011                 { &hf_link_id,
2012                         { "Link Identifier",        "v5ua.link_id",
2013                            FT_UINT32,   BASE_DEC, NULL,                           ~0x1f,
2014                            NULL, HFILL } },
2015                 { &hf_chnl_id,
2016                         { "Channel Identifier",     "v5ua.channel_id",
2017                            FT_UINT8,    BASE_DEC, NULL,                            0x1f,
2018                            NULL, HFILL } },
2019                 { &hf_adaptation_layer_id,
2020                         { "Adaptation Layer ID",    "v5ua.adaptation_layer_id",
2021                            FT_STRING,   BASE_NONE,NULL,                             0x0,
2022                            NULL, HFILL } },
2023                 { &hf_text_if_id,
2024                         { "Text interface identifier","v5ua.text_interface_id",
2025                            FT_STRING,   BASE_NONE,NULL,                             0x0,
2026                            NULL, HFILL } },
2027                 { &hf_scn_protocol_id,
2028                         { "SCN Protocol Identifier","v5ua.scn_protocol_id",
2029                            FT_STRING,   BASE_NONE,NULL,                             0x0,
2030                            NULL, HFILL } },
2031                 { &hf_info_string,
2032                         { "Info String",            "v5ua.info_string",
2033                            FT_STRING,   BASE_NONE,NULL,                             0x0,
2034                            NULL, HFILL } },
2035                 { &hf_dlci_zero_bit,
2036                         { "Zero bit",               "v5ua.dlci_zero_bit",
2037                            FT_BOOLEAN,  8,        NULL,                             0x01,
2038                            NULL, HFILL } },
2039                 { &hf_dlci_spare_bit,
2040                         { "Spare bit",              "v5ua.dlci_spare_bit",
2041                            FT_BOOLEAN,  8,        NULL,                             0x02,
2042                            NULL, HFILL } },
2043                 { &hf_dlci_sapi,
2044                         { "SAPI",                   "v5ua.dlci_sapi",
2045                            FT_UINT8,    BASE_HEX, NULL,                             0xfc,
2046                            NULL, HFILL } },
2047                 { &hf_dlci_one_bit,
2048                         { "One bit",                "v5ua.dlci_one_bit",
2049                            FT_BOOLEAN,  8,        NULL,                             0x01,
2050                            NULL, HFILL } },
2051                 { &hf_dlci_tei,
2052                         { "TEI",                    "v5ua.dlci_tei",
2053                            FT_UINT8,    BASE_HEX, NULL,                             0xfe,
2054                            NULL, HFILL } },
2055                 { &hf_efa,
2056                         { "Envelope Function Address","v5ua.efa",
2057                            FT_UINT16,   BASE_DEC, VALS(efa_values),                 0x0,
2058                            NULL, HFILL } },
2059                 { &hf_spare_efa,
2060                         { "Envelope Function Address (spare)","v5ua.efa",
2061                            FT_UINT16,   BASE_DEC, NULL,                              ~7,
2062                            NULL, HFILL } },
2063                 { &hf_asp_reason,
2064                         { "Reason",                 "v5ua.asp_reason",
2065                            FT_UINT32,   BASE_HEX, VALS(asp_reason_values),          0x0,
2066                            NULL, HFILL } },
2067                 { &hf_release_reason,
2068                         { "Release Reason",         "v5ua.release_reason",
2069                            FT_UINT32,   BASE_HEX, VALS(release_reason_values),      0x0,
2070                            NULL, HFILL } },
2071                 { &hf_tei_status,
2072                         { "TEI status",             "v5ua.tei_status",
2073                            FT_UINT32,   BASE_HEX, VALS(tei_status_values),          0x0,
2074                            NULL, HFILL } },
2075                 { &hf_tei_draft_status,
2076                         { "TEI status",             "v5ua.tei_draft_status",
2077                            FT_UINT32,   BASE_HEX, VALS(tei_draft_status_values),    0x0,
2078                            NULL, HFILL } },
2079                 { &hf_link_status,
2080                         { "Link Status",            "v5ua.link_status",
2081                            FT_UINT32,   BASE_HEX, NULL,                             0x0,
2082                            NULL, HFILL } },
2083                 { &hf_sa_bit_id,
2084                         { "BIT ID",                 "v5ua.sa_bit_id",
2085                            FT_UINT16,   BASE_HEX, VALS(sa_bit_values),              0x0,
2086                            NULL, HFILL } },
2087                 { &hf_sa_bit_value,
2088                         { "Bit Value",              "v5ua.sa_bit_value",
2089                            FT_UINT16,   BASE_HEX, VALS(sa_bit_values),              0x0,
2090                            NULL, HFILL } },
2091                 { &hf_parameter_tag,
2092                         { "Parameter Tag",          "v5ua.parameter_tag",
2093                            FT_UINT16,   BASE_HEX, VALS(parameter_tag_values),       0x0,
2094                            NULL, HFILL } },
2095                 { &hf_parameter_tag_draft,
2096                         { "Parameter Tag",          "v5ua.parameter_tag",
2097                            FT_UINT16,   BASE_HEX, VALS(parameter_tag_draft_values), 0x0,
2098                            NULL, HFILL } },
2099                 { &hf_parameter_length, 
2100                         { "Parameter length",       "v5ua.parameter_length",
2101                            FT_UINT16,   BASE_DEC, NULL,                             0x0,
2102                            NULL, HFILL } },
2103                 { &hf_parameter_value,
2104                         { "Parameter value",        "v5ua.parameter_value",
2105                            FT_BYTES,    BASE_NONE,NULL,                             0x0,
2106                            NULL, HFILL } },
2107                 { &hf_parameter_padding,
2108                         { "Parameter padding",      "v5ua.parameter_padding",
2109                            FT_BYTES,    BASE_NONE,NULL,                             0x0,
2110                            NULL, HFILL } },
2111                 { &hf_diagnostic_info,
2112                         { "Diagnostic Information", "v5ua.diagnostic_info",
2113                            FT_BYTES,    BASE_NONE,NULL,                             0x0,
2114                            NULL, HFILL } },
2115                 { &hf_if_range_start,
2116                         { "Interface range Start",  "v5ua.interface_range_start",
2117                            FT_UINT32,   BASE_HEX, NULL,                             0x0,
2118                            NULL, HFILL } },
2119                 { &hf_if_range_end,
2120                         { "Interface range End",    "v5ua.interface_range_end",
2121                            FT_UINT32,   BASE_HEX, NULL,                             0x0,
2122                            NULL, HFILL } },
2123                 { &hf_heartbeat_data,
2124                         { "Heartbeat data",         "v5ua.heartbeat_data",
2125                            FT_BYTES,    BASE_NONE,NULL,                             0x0,
2126                            NULL, HFILL } },
2127                 { &hf_traffic_mode_type,
2128                         { "Traffic mode type",      "v5ua.traffic_mode_type",
2129                            FT_UINT32,   BASE_HEX, VALS(traffic_mode_type_values),   0x0,
2130                            NULL, HFILL } },
2131                 { &hf_error_code,
2132                         { "Error code",             "v5ua.error_code",
2133                            FT_UINT32,   BASE_HEX, VALS(error_code_values),          0x0,
2134                            NULL, HFILL } },
2135                 { &hf_draft_error_code,
2136                         { "Error code (draft)",     "v5ua.draft_error_code",
2137                            FT_UINT32,   BASE_HEX, VALS(draft_error_code_values),    0x0,
2138                            NULL, HFILL } },
2139                 { &hf_status_type,
2140                         { "Status type",            "v5ua.status_type",
2141                            FT_UINT16,   BASE_DEC, VALS(status_type_values),         0x0,
2142                            NULL, HFILL } },
2143                 { &hf_status_id,
2144                         { "Status identification",  "v5ua.status_id",
2145                            FT_UINT16,   BASE_DEC, NULL,                             0x0,
2146                            NULL, HFILL } },
2147                 { &hf_error_reason,
2148                         { "Error Reason",           "v5ua.error_reason",
2149                            FT_UINT32,   BASE_HEX, VALS(error_reason_values),        0x0,
2150                            NULL, HFILL } },
2151
2152                 /* header fields for layer 3 content*/
2153                 { &hf_l3_protocol_discriminator,
2154                         { "Protocol Discriminator", "v5ua.l3_protocol_disc",
2155                            FT_UINT8,    BASE_HEX, NULL,                             0x0,
2156                            NULL, HFILL } },
2157                 { &hf_l3_adress,
2158                         { "Layer3 address",        "v5ua.l3_address",
2159                            FT_UINT8,    BASE_HEX, NULL,                             0xfe,
2160                            NULL, HFILL } },
2161                 { &hf_l3_low_adress,
2162                         { "Layer3 low address",    "v5ua.l3_low_address",
2163                            FT_UINT8,    BASE_HEX, NULL,                             0x0,
2164                            NULL, HFILL } },
2165                 {&hf_l3_msg_type,
2166                         { "Layer3 message type",   "v5ua.l3_msg_type",
2167                            FT_UINT8,    BASE_HEX, VALS(l3_msg_type_values),         0x0,
2168                            NULL, HFILL } },
2169                 {&hf_l3_info_element,
2170                         { "Layer3 information element",   "v5ua.l3_info_element",
2171                            FT_UINT8,    BASE_HEX, VALS(l3_info_element_values),     0x0,
2172                            NULL, HFILL } },
2173                 {&hf_l3_line_info,
2174                         { "Line_Information",      "v5ua.l3_line_info",
2175                            FT_UINT8,    BASE_HEX, VALS(l3_line_info_values),        0x0f,
2176                            NULL, HFILL } },
2177                 {&hf_l3_cad_ringing,
2178                         {"Cadenced ringing type",  "v5ua.l3_cad_ringing",
2179                            FT_UINT8,    BASE_HEX, NULL,                             0x7f,
2180                            NULL, HFILL } },
2181                 {&hf_l3_pulse_type,
2182                         { "Pulse Type",            "v5ua.l3_pulse_type",
2183                            FT_UINT8,    BASE_HEX, VALS(l3_pulse_type_values),       0x0,
2184                            NULL, HFILL } },
2185                 {&hf_l3_suppression_indicator,
2186                         { "Suppression indicator",  "v5ua.l3_suppression_indicator",
2187                            FT_UINT8,    BASE_HEX, VALS(l3_suppression_indication_values),0x60,
2188                            NULL, HFILL } },
2189                 {&hf_l3_pulse_duration,
2190                         { "Pulse duration type",   "v5ua.l3_pulse_duration",
2191                            FT_UINT8,    BASE_HEX, NULL,                             0x1f,
2192                            NULL, HFILL } },
2193                 {&hf_l3_ack_request_indicator,
2194                         { "Ack request indicator",    "v5ua.l3_ack_request_indicator",
2195                            FT_UINT8,    BASE_HEX, VALS(l3_ack_request_indication_values),0x60,
2196                            NULL, HFILL } },
2197                 {&hf_l3_number_of_pulses,
2198                         { "Number of pulses",      "v5ua.l3_number_of_pulses",
2199                            FT_UINT8,    BASE_DEC, NULL,                             0x1f,
2200                            NULL, HFILL } },
2201                 {&hf_l3_steady_signal,
2202                         { "Steady Signal",         "v5ua.l3_steady_signal",
2203                            FT_UINT8,    BASE_HEX, VALS(l3_steady_signal_values),    0x0,
2204                            NULL, HFILL } },
2205                 {&hf_l3_auto_signalling_sequence,
2206                         { "Autonomous signalling sequence","v5ua.l3_auto_signalling_sequence",
2207                            FT_UINT8,    BASE_HEX, NULL,                             0x0f,
2208                            NULL, HFILL } },
2209                 {&hf_l3_sequence_number,
2210                         { "Sequence number",    "v5ua.l3_sequence_number",
2211                            FT_UINT8,    BASE_HEX, NULL,                             0x7f,
2212                            NULL, HFILL } },
2213                 {&hf_l3_pulse_notify,
2214                         { "Pulse notification",    "v5ua.l3_pulse_notification",
2215                            FT_UINT8,    BASE_HEX, NULL,                             0x0,
2216                            NULL, HFILL } },
2217                 {&hf_l3_sequence_response,
2218                         { "Sequence response",    "v5ua.l3_sequence_response",
2219                            FT_UINT8,    BASE_HEX, NULL,                             0x0f,
2220                            NULL, HFILL } },
2221                 {&hf_l3_digit_ack,
2222                         { "Digit ack request indication","v5ua.l3_digit_ack",
2223                            FT_UINT8,    BASE_HEX, VALS(l3_digit_ack_values),        0x40,
2224                            NULL, HFILL } },
2225                 {&hf_l3_digit_info,
2226                         { "Digit information",    "v5ua.l3_digit_info",
2227                            FT_UINT8,    BASE_HEX, NULL,                             0x0f,
2228                            NULL, HFILL } },
2229                 {&hf_l3_res_unavailable,
2230                         { "Resource unavailable", "v5ua.l3_res_unavailable",
2231                            FT_STRING,   BASE_NONE,NULL,                             0x0,
2232                            NULL, HFILL } },
2233                 {&hf_l3_state,
2234                         { "PSTN FSM state",       "v5ua.l3_state",
2235                            FT_UINT8,    BASE_HEX, VALS(l3_state_values),            0x0f,
2236                            NULL, HFILL } },
2237                 {&hf_l3_cause_type,
2238                         { "Cause type",           "v5ua.l3_cause_type",
2239                            FT_UINT8,    BASE_HEX, VALS(l3_cause_type_values),       0x7f,
2240                            NULL, HFILL } },
2241                 {&hf_l3_link_control_function,
2242                         { "Link control function","v5ua.l3_link_control_function",
2243                            FT_UINT8,    BASE_HEX, VALS(l3_link_control_function_values),0x7f,
2244                            NULL, HFILL } },
2245                 {&hf_l3_pstn_user_port_id,
2246                         { "PSTN User Port identification Value","v5ua.l3_pstn_user_port_id",
2247                            FT_UINT8,    BASE_HEX, NULL,                             0xfe,
2248                            NULL, HFILL } },
2249                 {&hf_l3_pstn_user_port_id_lower,
2250                         { "PSTN User Port Identification Value (lower)","v5ua.l3_pstn_user_port_id_lower",
2251                            FT_UINT8,    BASE_HEX, NULL,                             0x0,
2252                            NULL, HFILL } },
2253                 {&hf_l3_isdn_user_port_id,
2254                         { "ISDN User Port Identification Value","v5ua.l3_isdn_user_port_id",
2255                            FT_UINT8,    BASE_HEX, NULL,                             0xfc,
2256                            NULL, HFILL } },
2257                 {&hf_l3_isdn_user_port_id_lower,
2258                         { "ISDN User Port Identification Value (lower)","v5ua.l3_user_port_id_lower",
2259                            FT_UINT8,    BASE_HEX, NULL,                             0x0fe,
2260                            NULL, HFILL } },
2261                 {&hf_l3_isdn_user_port_ts_num,
2262                         { "ISDN user port time slot number","v5ua.l3_isdn_user_port_ts_num",
2263                            FT_UINT8,    BASE_HEX, NULL,                             0x1f,
2264                            NULL, HFILL } },
2265                 {&hf_l3_override,
2266                         { "Override",    "v5ua.l3_override",
2267                            FT_BOOLEAN,  8,        NULL,                             0x20,
2268                            NULL, HFILL } },
2269                 {&hf_l3_v5_link_id,
2270                         { "V5 2048 kbit/s Link Identifier",    "v5ua.l3_link_id",
2271                            FT_UINT8,    BASE_HEX, NULL,                             0x0,
2272                            NULL, HFILL } },
2273                 {&hf_l3_v5_time_slot,
2274                         { "V5 Time Slot Number",    "v5ua.l3_v5_time_slot",
2275                            FT_UINT8,    BASE_DEC, NULL,                             0x1f,
2276                            NULL, HFILL } },
2277                 {&hf_l3_reject_cause_type,
2278                         { "Reject cause type",    "v5ua.l3_reject_cause_type",
2279                            FT_UINT8,    BASE_HEX, VALS(l3_reject_cause_type_values),0x7f,
2280                            NULL, HFILL } },
2281                 {&hf_l3_bcc_protocol_error_cause,
2282                         { "BCC Protocol error cause type",    "v5ua.l3_bcc_protocol_cause",
2283                            FT_UINT8,    BASE_HEX, VALS(l3_bcc_protocol_error_cause_type_values),0x7f,
2284                            NULL, HFILL } },
2285                 {&hf_l3_connection_incomplete_reason,
2286                         { "Reason",    "v5ua.l3_connection_incomplete_reason",
2287                            FT_UINT8,    BASE_HEX, VALS(l3_connection_incomplete_reason_values), 0x0,
2288                            NULL, HFILL } },
2289                 {&hf_l3_control_function_element,
2290                         { "Control function element",    "v5ua.l3_control_function_element",
2291                            FT_UINT8,    BASE_HEX, VALS(l3_control_function_element_values),     0x7f,
2292                            NULL, HFILL } },
2293                 {&hf_l3_control_function_id,
2294                         { "Control function ID",    "v5ua.l3_control_function",
2295                            FT_UINT8,    BASE_HEX, VALS(l3_control_function_id_values),          0x7f,
2296                            NULL, HFILL } },
2297                 {&hf_l3_variant,
2298                         { "Variant",    "v5ua.l3_variant",
2299                            FT_UINT8,    BASE_DEC, NULL,                                         0x0,
2300                            NULL, HFILL } },
2301                 {&hf_l3_if_id,
2302                         { "Interface ID",    "v5ua.l3_interface_id",
2303                            FT_UINT32,   BASE_HEX, NULL,                                         0x0,
2304                            NULL, HFILL } },
2305                 {&hf_l3_performance_grading,
2306                         { "Performance grading",    "v5ua.l3_performance_grading",
2307                            FT_UINT8,    BASE_HEX, VALS(l3_performance_grading_values),          0x0f,
2308                            NULL, HFILL } },
2309                 {&hf_l3_cp_rejection_cause,
2310                         { "Rejection cause",    "v5ua.l3_cp_rejection_cause",
2311                            FT_UINT8,    BASE_HEX, VALS(l3_cp_rejection_cause_values),           0x0f,
2312                            NULL, HFILL } },
2313                 {&hf_l3_pstn_sequence_number,
2314                         { "Sequence number",    "v5ua.l3_pstn_sequence_number",
2315                            FT_UINT8,    BASE_HEX, NULL,                                         0x7f,
2316                            NULL, HFILL } },
2317                 {&hf_l3_duration_type,
2318                         { "Duration Type",    "v5ua.l3_duration_type",
2319                            FT_UINT8,    BASE_HEX, NULL,                                         0x3f,
2320                            NULL, HFILL } }
2321                 };
2322
2323 /* Setup protocol subtree array */
2324         static gint *ett[] = {
2325                 &ett_v5ua,
2326                 &ett_v5ua_common_header,
2327                 &ett_v5ua_parameter,
2328                 &ett_v5ua_layer3
2329         };
2330
2331 /* Register the protocol name and description */
2332         proto_v5ua = proto_register_protocol("V5.2-User Adaptation Layer", "V5UA", "v5ua");
2333
2334 /* Required function calls to register the header fields and subtrees used */
2335         proto_register_field_array(proto_v5ua, hf, array_length(hf));
2336         proto_register_subtree_array(ett, array_length(ett));
2337 }
2338
2339
2340 /* In RFC specification the SCTP registered User Port Number Assignment for V5UA is 5675 */
2341 #define SCTP_PORT_V5UA_RFC         5675
2342 #define SCTP_PORT_V5UA_DRAFT      10001
2343
2344 void
2345 proto_reg_handoff_v5ua(void)
2346 {
2347         dissector_handle_t v5ua_handle;
2348
2349         v5ua_handle = create_dissector_handle(dissect_v5ua, proto_v5ua);
2350         q931_handle = find_dissector("q931");
2351
2352         dissector_add("sctp.port", SCTP_PORT_V5UA_DRAFT, v5ua_handle);
2353         dissector_add("sctp.port", SCTP_PORT_V5UA_RFC, v5ua_handle);
2354         dissector_add("sctp.ppi",  V5UA_PAYLOAD_PROTOCOL_ID, v5ua_handle);
2355 }