Rename the routines that handle dissector tables with unsigned integer
[obnox/wireshark/wip.git] / epan / dissectors / packet-v5ua.c
1 /* packet-v5ua.c
2  *
3  * Extension of all V5.2-User Adaptation Layer dissection elements
4  * References:
5  * RFC 3807
6  * RFC 4233
7  * RFC 5133
8  *
9  * Copyright 2009
10  *
11  * ISKRATEL d.o.o.            |       4S d.o.o.
12  * http://www.iskratel.si/    |       http://www.4es.si/
13  * <info@iskratel.si>         |       <projects@4es.si>
14  * Vladimir Smrekar <vladimir.smrekar@gmail.com>
15  *
16  * Routines for V5.2-User Adaptation Layer dissection
17  *
18  * $Id$
19  *
20  * Extension of ISDN Q.921-User Adaptation Layer dissection
21  * Copyright 2002, Michael Tuexen <Michael.Tuexen[AT]siemens.com>
22  *
23  * Christoph Neusch <christoph.neusch@nortelnetworks.com>
24  *
25  * Wireshark - Network traffic analyzer
26  * By Gerald Combs <gerald@wireshark.org>
27  * Copyright 1998 Gerald Combs
28  *
29  * This program is free software; you can redistribute it and/or
30  * modify it under the terms of the GNU General Public License
31  * as published by the Free Software Foundation; either version 2
32  * of the License, or (at your option) any later version.
33  *
34  * This program is distributed in the hope that it will be useful,
35  * but WITHOUT ANY WARRANTY; without even the implied warranty of
36  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37  * GNU General Public License for more details.
38  *
39  * You should have received a copy of the GNU General Public License
40  * along with this program; if not, write to the Free Software
41  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
42  */
43
44 #ifdef HAVE_CONFIG_H
45 # include "config.h"
46 #endif
47
48 #include <stdlib.h>
49 #include <ctype.h>
50
51 #include <glib.h>
52
53 #include <epan/packet.h>
54 #include <epan/addr_resolv.h>
55 #include <epan/strutil.h>
56 #include <epan/sctpppids.h>      /* include V5UA payload protocol ID */
57
58 static int paddingl = 0;
59 static int dlci_efa = -1;
60
61 /* Initialize the protocol and registered fields */
62 static int proto_v5ua                    = -1;
63
64 static dissector_handle_t q931_handle;
65 static dissector_handle_t v52_handle;
66
67         /* round up parameter length to multiple of four */
68 #define ADD_PADDING(x) ((((x) + 3) >> 2) << 2)
69
70    /* common msg-header */
71 static int hf_version               = -1;
72 static int hf_reserved              = -1;
73 static int hf_msg_class             = -1;
74 static int hf_msg_type              = -1;
75 static int hf_msg_type_id           = -1;
76 static int hf_msg_length            = -1;
77    /* V5UA message header */
78 static int hf_link_id               = -1;
79 static int hf_chnl_id               = -1;
80 static int hf_adaptation_layer_id   = -1;
81 static int hf_text_if_id            = -1;
82 static int hf_scn_protocol_id       = -1;
83 static int hf_info_string           = -1;
84 static int hf_asp_identifier        = -1;
85 static int hf_dlci_zero_bit         = -1;
86 static int hf_dlci_spare_bit        = -1;
87 static int hf_dlci_sapi             = -1;
88 static int hf_dlci_one_bit          = -1;
89 static int hf_dlci_tei              = -1;
90 static int hf_efa                   = -1;
91 static int hf_spare_efa             = -1;
92    /* variable length parameter (msg) */
93 static int hf_parameter_tag         = -1;
94 static int hf_parameter_tag_draft   = -1;
95 static int hf_parameter_length      = -1;
96 static int hf_parameter_value       = -1;
97 static int hf_parameter_padding     = -1;
98
99         /* parameter fields */
100 static int hf_link_status           = -1;
101 static int hf_sa_bit_id             = -1;
102 static int hf_sa_bit_value          = -1;
103 static int hf_diagnostic_info       = -1;
104 static int hf_if_range_start        = -1;
105 static int hf_if_range_end          = -1;
106 static int hf_heartbeat_data        = -1;
107 static int hf_traffic_mode_type     = -1;
108 static int hf_error_code            = -1;
109 static int hf_draft_error_code      = -1;
110 static int hf_status_type           = -1;
111 static int hf_status_id             = -1;
112 static int hf_error_reason          = -1;
113 static int hf_asp_reason            = -1;
114 static int hf_tei_status            = -1;
115 static int hf_tei_draft_status      = -1;
116 static int hf_release_reason        = -1;
117
118 /* Initialize the subtree pointers */
119 static gint ett_v5ua              = -1;
120 static gint ett_v5ua_common_header= -1;
121 static gint ett_v5ua_parameter    = -1;
122 static gint ett_v5ua_layer3       = -1;
123
124 #define RFC             0x1
125 #define DRAFT           0x2
126         /* Version of IUA */
127 static int iua_version = RFC;
128     /* Variables neccessary for dissection of draft messages */
129 static int msg_class   = -1;
130 static int msg_type    = -1;
131 static int msg_length  = -1;
132 static int messageclassCopy = -1;
133 static int sa_bit_id    = -1;
134 static int link_status_operational = -1;
135
136 /* Code to actually dissect the packets */
137
138         /* define the parameters for the Tags: Tag-Type,Tag-Length,Tag-Value (Payload) */
139 #define PARAMETER_TAG_OFFSET    0
140 #define PARAMETER_TAG_LENGTH    2
141 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TAG_OFFSET + PARAMETER_TAG_LENGTH)
142 #define PARAMETER_LENGTH_LENGTH 2
143 #define PARAMETER_VALUE_OFFSET  (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
144 #define PARAMETER_HEADER_OFFSET PARAMETER_TAG_OFFSET
145 #define PARAMETER_HEADER_LENGTH (PARAMETER_TAG_LENGTH + PARAMETER_LENGTH_LENGTH)
146
147
148 /*----------------------V5UA Interface Identifier (int) (Draft,RFC)------------*/
149
150         /* define parameter for the format of the integer formatted Interface Identifier */
151 #define INT_IF_ID_LINK_OFFSET PARAMETER_VALUE_OFFSET
152 #define INT_IF_ID_LINK_LENGTH 4
153 #define INT_IF_ID_CHNL_OFFSET INT_IF_ID_LINK_OFFSET
154 #define INT_IF_ID_CHNL_LENGTH 1
155 #define INT_INTERFACE_ID_LENGTH 4
156
157 static int linkIdentifier = -1;
158
159 static void
160 dissect_int_interface_identifier_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
161 {
162   guint32 identifier;
163   guint16 number_of_ids, id_number;
164   gint offset;
165
166   number_of_ids= (tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH) / INT_INTERFACE_ID_LENGTH;
167
168   offset = INT_IF_ID_LINK_OFFSET;
169   identifier = tvb_get_ntohl(parameter_tvb,INT_IF_ID_LINK_OFFSET)>>5;
170   proto_item_append_text(parameter_item, "(");
171   for (id_number = 1; id_number <= number_of_ids; id_number++) {
172     proto_tree_add_item(parameter_tree, hf_link_id, parameter_tvb, offset, INT_IF_ID_LINK_LENGTH, FALSE);
173     identifier = tvb_get_ntohl(parameter_tvb,offset)>>5;
174     if (id_number < 2) {
175         proto_item_append_text(parameter_item, "L:%d",identifier);
176     } else {
177         proto_item_append_text(parameter_item, " | L:%d",identifier);
178     }
179     linkIdentifier = identifier;
180
181     proto_tree_add_item(parameter_tree, hf_chnl_id, parameter_tvb, offset+3, INT_IF_ID_CHNL_LENGTH, FALSE);
182     identifier = tvb_get_guint8(parameter_tvb,offset+3)&0x1f;
183     proto_item_append_text(parameter_item, " C:%d", identifier);
184     offset += INT_INTERFACE_ID_LENGTH;
185     }
186   proto_item_append_text(parameter_item, ")");
187 }
188 /*----------------------V5UA Interface Identifier (int) (Draft,RFC)------------*/
189
190 /*----------------------Text Interface Identifier (RFC)------------------------*/
191
192 #define TEXT_IF_ID_LENGTH_OFFSET PARAMETER_LENGTH_OFFSET
193 #define TEXT_IF_ID_VALUE_OFFSET  PARAMETER_VALUE_OFFSET
194 #define TEXT_IF_ID_HEADER_LENGTH PARAMETER_HEADER_LENGTH
195
196 static void
197 dissect_text_interface_identifier_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
198 {
199   guint16 if_id_length;
200
201   if_id_length = tvb_get_ntohs(parameter_tvb, TEXT_IF_ID_LENGTH_OFFSET) - TEXT_IF_ID_HEADER_LENGTH;
202
203   proto_tree_add_item(parameter_tree, hf_text_if_id, parameter_tvb, TEXT_IF_ID_VALUE_OFFSET, if_id_length, FALSE);
204   proto_item_append_text(parameter_item, " (0x%.*s)", if_id_length,
205                          (const char *)tvb_get_ptr(parameter_tvb, TEXT_IF_ID_VALUE_OFFSET, if_id_length));
206 }
207 /*----------------------Text Interface Identifier (RFC)------------------------*/
208
209 /*----------------------DLCI & Envelope Function Address------------------------*/
210
211
212 /* interpretation of EFA-values */
213 static const value_string efa_values[] = {
214         { 8175, "ISDN Protocol" },
215         { 8176, "PSTN Protocol" },
216         { 8177, "CONTROL Protocol" },
217         { 8178, "BCC Protocol" },
218         { 8179, "PROT Protocol" },
219         { 8180, "Link Control Protocol" },
220         { 8191, "VALUE RESERVED" },
221         { 0,    NULL } };
222
223 #define DLCI_LENGTH_OFFSET PARAMETER_LENGTH_OFFSET
224 #define DLCI_SAPI_OFFSET   PARAMETER_VALUE_OFFSET
225 #define DLCI_HEADER_LENGTH PARAMETER_HEADER_LENGTH
226
227 #define DLCI_SAPI_LENGTH   1
228 #define DLCI_TEI_LENGTH    1
229 #define EFA_LENGTH         2
230
231 static void
232 dissect_dlci_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item, packet_info *pinfo)
233 {
234   guint16 efa = 0, offset = 0;
235
236 guint8 sapi = -1;
237 guint8 tei = -1;
238
239
240   if     (iua_version == RFC)   offset = DLCI_SAPI_OFFSET;
241   else if(iua_version == DRAFT) offset = DLCI_HEADER_LENGTH + tvb_get_ntohs(parameter_tvb, DLCI_LENGTH_OFFSET);
242
243   proto_tree_add_item(parameter_tree, hf_dlci_zero_bit,  parameter_tvb, offset,  DLCI_SAPI_LENGTH,  FALSE);
244   proto_tree_add_item(parameter_tree, hf_dlci_spare_bit, parameter_tvb, offset,  DLCI_SAPI_LENGTH,  FALSE);
245   proto_tree_add_item(parameter_tree, hf_dlci_sapi,      parameter_tvb, offset,  DLCI_SAPI_LENGTH,  FALSE);
246
247   offset += DLCI_SAPI_LENGTH;
248   proto_tree_add_item(parameter_tree, hf_dlci_one_bit,   parameter_tvb, offset,  DLCI_TEI_LENGTH,   FALSE);
249   proto_tree_add_item(parameter_tree, hf_dlci_tei,       parameter_tvb, offset,  DLCI_TEI_LENGTH,   FALSE);
250
251 sapi = tvb_get_ntohs(parameter_tvb, offset-DLCI_TEI_LENGTH-DLCI_SAPI_LENGTH)>>2;
252 tei = tvb_get_ntohs(parameter_tvb, offset-DLCI_TEI_LENGTH)>>1;
253
254   /* if SAPI & TEI not set to ZERO, value of EFA must be decode (EFA = 0 -> ISDN protocol)*/
255   if(tvb_get_ntohs(parameter_tvb,offset-DLCI_TEI_LENGTH) != 0x01){
256
257           offset += DLCI_TEI_LENGTH;
258           efa = tvb_get_ntohs(parameter_tvb, offset);
259           dlci_efa = tvb_get_ntohs(parameter_tvb, offset);
260
261         if (dlci_efa >= 0 && dlci_efa <= 8175) { col_append_fstr(pinfo->cinfo, COL_INFO, " | ISDN: %u", dlci_efa); }
262         else if (dlci_efa == 8176) { col_append_str(pinfo->cinfo, COL_INFO, " | PSTN"); }
263         else if (dlci_efa == 8177) { col_append_str(pinfo->cinfo, COL_INFO, " | Ctrl"); }
264         else if (dlci_efa == 8178) { col_append_str(pinfo->cinfo, COL_INFO, " | BCC"); }
265         else if (dlci_efa == 8179) { col_append_str(pinfo->cinfo, COL_INFO, " | ProtProt"); }
266         else if (dlci_efa == 8180) { col_append_str(pinfo->cinfo, COL_INFO, " | LinkCtrl"); }
267         else {};
268
269           if(efa <= 8175) {
270                 proto_tree_add_uint_format(parameter_tree, hf_efa,  parameter_tvb, offset, EFA_LENGTH, efa,
271                 "Envelope function address: ISDN (%u)", efa);
272           proto_item_append_text(parameter_item, " (SAPI:%u TEI:%u EFA:ISDN (%u))",sapi,tei,efa);
273           }
274           else if (efa > 8175 && efa <= 8180){
275                 proto_tree_add_uint_format(parameter_tree, hf_efa,  parameter_tvb, offset, EFA_LENGTH, efa,
276                 "Envelope function address: %s (%u)", val_to_str(efa, efa_values, "unknown EFA"),tvb_get_ntohs(parameter_tvb, offset));
277           proto_item_append_text(parameter_item, " (SAPI:%u TEI:%u EFA:%s (%u))",sapi,tei,val_to_str(efa, efa_values, "unknown EFA-value"),efa);
278           }
279           else if(efa >= 8181){
280                 proto_tree_add_uint_format(parameter_tree, hf_efa,  parameter_tvb, offset, EFA_LENGTH, efa,
281                 "Envelope function address: RESERVED (%u)", efa);
282           proto_item_append_text(parameter_item, " (SAPI:%u TEI:%u EFA:RESERVED (%u))",sapi,tei,efa);
283           }
284           else {
285                 proto_tree_add_uint_format(parameter_tree, hf_efa,  parameter_tvb, offset, EFA_LENGTH, efa,
286                 "Envelope function address: %u", efa);
287                 proto_item_append_text(parameter_item, " (SAPI:%u TEI:%u EFA:%u)",sapi,tei,efa);
288           }
289   }
290   /* if SAPI & TEI set to ZERO, EFA also shall be set to ZERO and didn't comply with value for ISDN protocol */
291   else{
292           offset += DLCI_TEI_LENGTH;
293           efa = tvb_get_ntohs(parameter_tvb, offset);
294           dlci_efa = tvb_get_ntohs(parameter_tvb, offset);
295
296         if (dlci_efa >= 0 && dlci_efa <= 8175) { col_append_fstr(pinfo->cinfo, COL_INFO, " | ISDN: %u", dlci_efa); }
297         else if (dlci_efa == 8176) { col_append_str(pinfo->cinfo, COL_INFO, " | PSTN"); }
298         else if (dlci_efa == 8177) { col_append_str(pinfo->cinfo, COL_INFO, " | Ctrl"); }
299         else if (dlci_efa == 8178) { col_append_str(pinfo->cinfo, COL_INFO, " | BCC"); }
300         else if (dlci_efa == 8179) { col_append_str(pinfo->cinfo, COL_INFO, " | ProtProt"); }
301         else if (dlci_efa == 8180) { col_append_str(pinfo->cinfo, COL_INFO, " | LinkCtrl"); }
302         else {};
303
304           if(efa <= 8175) {
305
306           proto_tree_add_uint_format(parameter_tree, hf_efa,  parameter_tvb, offset, EFA_LENGTH, efa,
307                 "Envelope function address: ISDN (%u)", efa);
308           proto_item_append_text(parameter_item, " (SAPI:%u TEI:%u EFA:ISDN (%u))",sapi,tei,efa);
309
310           }
311           else if (efa > 8175 && efa <= 8180){
312
313                 proto_tree_add_uint_format(parameter_tree, hf_efa,  parameter_tvb, offset, EFA_LENGTH, efa,
314                 "Envelope function address: %s (%u)", val_to_str(efa, efa_values, "unknown EFA"),tvb_get_ntohs(parameter_tvb, offset));
315           proto_item_append_text(parameter_item, " (SAPI:%u TEI:%u EFA:%s (%u))",sapi,tei,val_to_str(efa, efa_values, "unknown EFA-value"),efa);
316
317           }
318           else if(efa >= 8181){
319                 proto_tree_add_uint_format(parameter_tree, hf_efa,  parameter_tvb, offset, EFA_LENGTH, efa,
320                 "Envelope function address: RESERVED (%u)", efa);
321           proto_item_append_text(parameter_item, " (SAPI:%u TEI:%u EFA:RESERVED (%u))",sapi,tei,efa);
322           }
323           else {
324                 proto_tree_add_uint_format(parameter_tree, hf_efa,  parameter_tvb, offset, EFA_LENGTH, efa,
325                 "Envelope function address: %u", efa);
326                 proto_item_append_text(parameter_item, " (SAPI:%u TEI:%u EFA:%u)",sapi,tei,efa);
327           }
328   }
329 }
330 /*----------------------DLCI & Envelope Function Address------------------------*/
331
332 /*----------------------Error Indication (Draft)-------------------------------*/
333
334         /* define Error Code Parameter for Layer Management (MGMT) Messages */
335 #define MGMT_ERROR_INVALID_TEI_DRAFT                       0x00
336 #define MGMT_ERROR_INVALID_IFID_DRAFT                      0x01
337 #define MGMT_ERROR_UNDEFINIED_MSG_DRAFT                    0x02
338 #define MGMT_ERROR_VERSION_ERR_DRAFT                       0x03
339 #define MGMT_ERROR_INVALID_STID_DRAFT                      0x04
340 #define MGMT_ERROR_INVALID_SCNV_DRAFT                      0x05
341 #define MGMT_ERROR_INVALID_ALI_DRAFT                       0x06
342
343 static const value_string draft_error_code_values[] = {
344   { MGMT_ERROR_INVALID_TEI_DRAFT,     "Invalid TEI" },
345   { MGMT_ERROR_INVALID_IFID_DRAFT,    "Invalid interface ID" },
346   { MGMT_ERROR_UNDEFINIED_MSG_DRAFT,  "An unexpected message was received" },
347   { MGMT_ERROR_VERSION_ERR_DRAFT,     "The IUA layers are of different version" },
348   { MGMT_ERROR_INVALID_STID_DRAFT,    "Invalid SCTP stream identifier" },
349   { MGMT_ERROR_INVALID_SCNV_DRAFT,    "Invalid SCN version" },
350   { MGMT_ERROR_INVALID_ALI_DRAFT,     "Invalid Adaptation Layer Identifier" },
351   { 0,                                NULL } };
352
353 #define MGMT_ERROR_MSG_LENGTH_OFFSET PARAMETER_LENGTH_OFFSET
354 #define MGMT_ERROR_MSG_HEADER_LENGTH PARAMETER_HEADER_LENGTH
355
356 #define MGMT_ERROR_CODE_LENGTH 4
357
358 static void
359 dissect_draft_error_code_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree)
360 {
361   guint16 offset = MGMT_ERROR_MSG_HEADER_LENGTH + tvb_get_ntohs(parameter_tvb, MGMT_ERROR_MSG_LENGTH_OFFSET) + 4;
362   proto_tree_add_item(parameter_tree, hf_draft_error_code, parameter_tvb, offset, MGMT_ERROR_CODE_LENGTH, FALSE);
363   offset += MGMT_ERROR_CODE_LENGTH ;
364   if( tvb_length_remaining(parameter_tvb,offset) > 0 )
365           proto_tree_add_item(parameter_tree, hf_info_string, parameter_tvb, offset, msg_length - offset,FALSE);
366 }
367 /*----------------------Error Indication (Draft)-------------------------------*/
368
369 /*----------------------Error Indication (RFC)---------------------------------*/
370
371         /* define Error Code Parameter for Layer Management (MGMT) Messages */
372 #define MGMT_ERROR_INVALID_VERSION                     0x01
373 #define MGMT_ERROR_INVALID_IF_ID                       0x02
374 #define MGMT_ERROR_UNSUPPORTED_MSG_CLASS               0x03
375 #define MGMT_ERROR_UNSUPPORTED_MSG_TYPE                0x04
376 #define MGMT_ERROR_UNSUPPORTED_TRAFFIC_HANDLING_MODE   0x05
377 #define MGMT_ERROR_UNEXPECTED_MSG                      0x06
378 #define MGMT_ERROR_PROTOCOL_ERROR                      0x07
379 #define MGMT_ERROR_UNSUPPORTED_IF_ID_TYPE              0x08
380 #define MGMT_ERROR_INVALID_STREAM_ID                   0x09
381 #define MGMT_ERROR_UNASSIGNED_TEI                      0x0a
382 #define MGMT_ERROR_UNRECOGNIZED_SAPI                   0x0b
383 #define MGMT_ERROR_INVALID_TEI_SAPI_COMBINATION        0x0c
384
385 static const value_string error_code_values[] = {
386   { MGMT_ERROR_INVALID_VERSION,                       "Invalid version" },
387   { MGMT_ERROR_INVALID_IF_ID,                         "Invalid interface identifier" },
388   { MGMT_ERROR_UNSUPPORTED_MSG_CLASS,                 "Unsuported message class" },
389   { MGMT_ERROR_UNSUPPORTED_MSG_TYPE,                  "Unsupported message type" },
390   { MGMT_ERROR_UNSUPPORTED_TRAFFIC_HANDLING_MODE,     "Unsupported traffic handling mode" },
391   { MGMT_ERROR_UNEXPECTED_MSG,                        "Unexpected message" },
392   { MGMT_ERROR_PROTOCOL_ERROR,                        "Protocol error" },
393   { MGMT_ERROR_UNSUPPORTED_IF_ID_TYPE,                "Unsupported interface identifier type" },
394   { MGMT_ERROR_INVALID_STREAM_ID,                     "Invalid stream identifier" },
395   { MGMT_ERROR_UNASSIGNED_TEI,                        "Unassigned TEI" },
396   { MGMT_ERROR_UNRECOGNIZED_SAPI,                     "Unrecognized SAPI" },
397   { MGMT_ERROR_INVALID_TEI_SAPI_COMBINATION,          "Invalid TEI/SAPI combination" },
398   { 0,                                                NULL } };
399
400 #define MGMT_ERROR_CODE_OFFSET PARAMETER_VALUE_OFFSET
401
402 static void
403 dissect_error_code_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
404 {
405   proto_tree_add_item(parameter_tree, hf_error_code, parameter_tvb, MGMT_ERROR_CODE_OFFSET, MGMT_ERROR_CODE_LENGTH, FALSE);
406   proto_item_append_text(parameter_item, " (%s)",
407                          val_to_str(tvb_get_ntohl(parameter_tvb, MGMT_ERROR_CODE_OFFSET), error_code_values, "Unknown error code"));
408 }
409
410 static void
411 dissect_diagnostic_information_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
412 {
413   guint16 diag_info_length;
414
415   diag_info_length = tvb_get_ntohs(parameter_tvb, MGMT_ERROR_MSG_LENGTH_OFFSET) - MGMT_ERROR_MSG_HEADER_LENGTH;
416   proto_tree_add_item(parameter_tree, hf_diagnostic_info, parameter_tvb, PARAMETER_VALUE_OFFSET, diag_info_length, FALSE);
417   proto_item_append_text(parameter_item, " (%u byte%s)", diag_info_length, plurality(diag_info_length, "", "s"));
418 }
419 /*----------------------Error Indication (RFC)---------------------------------*/
420
421 /*----------------------Notify (RFC)-------------------------------------------*/
422
423         /* define Status Type parameters for Notify (NTFY) Messages */
424 #define NTFY_STATUS_TYPE_AS_STATE_CHANGE  0x01
425 #define NTFY_STATUS_TYPE_OTHER            0x02
426
427 static const value_string status_type_values[] = {
428   { NTFY_STATUS_TYPE_AS_STATE_CHANGE,        "Application server state change" },
429   { NTFY_STATUS_TYPE_OTHER,                  "Other" },
430   { 0,                                       NULL } };
431
432         /* define Status Identification parameters for NTFY Messages (AS state change)*/
433 #define NTFY_STATUS_IDENT_AS_DOWN          0x01
434 #define NTFY_STATUS_IDENT_AS_INACTIVE      0x02
435 #define NTFY_STATUS_IDENT_AS_ACTIVE        0x03
436 #define NTFY_STATUS_IDENT_AS_PENDING       0x04
437         /* define Status Identification parameters for NTFY Messages (Other)*/
438 #define NTFY_STATUS_INSUFFICIENT_ASP_RES_ACTIVE 0x01
439 #define NTFY_STATUS_ALTERNATE_ASP_ACTIVE        0x02
440
441 static const value_string status_type_id_values[] = {
442   { NTFY_STATUS_TYPE_AS_STATE_CHANGE * 256 * 256 + NTFY_STATUS_IDENT_AS_DOWN,         "Application server down" },
443   { NTFY_STATUS_TYPE_AS_STATE_CHANGE * 256 * 256 + NTFY_STATUS_IDENT_AS_INACTIVE,     "Application server inactive" },
444   { NTFY_STATUS_TYPE_AS_STATE_CHANGE * 256 * 256 + NTFY_STATUS_IDENT_AS_ACTIVE,       "Application server active" },
445   { NTFY_STATUS_TYPE_AS_STATE_CHANGE * 256 * 256 + NTFY_STATUS_IDENT_AS_PENDING,      "Application server pending" },
446   { NTFY_STATUS_TYPE_OTHER * 256 * 256 + NTFY_STATUS_INSUFFICIENT_ASP_RES_ACTIVE,     "Insufficient ASP resources active in AS" },
447   { NTFY_STATUS_TYPE_OTHER * 256 * 256 + NTFY_STATUS_ALTERNATE_ASP_ACTIVE,            "Alternate ASP active" },
448   { 0,                                           NULL } };
449
450 #define NTFY_STATUS_TYPE_OFFSET  PARAMETER_VALUE_OFFSET
451 #define NTFY_STATUS_TYPE_LENGTH  2
452 #define NTFY_STATUS_IDENT_OFFSET (NTFY_STATUS_TYPE_OFFSET + NTFY_STATUS_TYPE_LENGTH)
453 #define NTFY_STATUS_IDENT_LENGTH 2
454
455 static void
456 dissect_status_type_identification_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
457 {
458   guint16 status_type, status_id;
459
460   status_type = tvb_get_ntohs(parameter_tvb, NTFY_STATUS_TYPE_OFFSET);
461   status_id   = tvb_get_ntohs(parameter_tvb, NTFY_STATUS_IDENT_OFFSET);
462
463   proto_tree_add_item(parameter_tree, hf_status_type, parameter_tvb, NTFY_STATUS_TYPE_OFFSET, NTFY_STATUS_TYPE_LENGTH, FALSE);
464   proto_tree_add_uint_format(parameter_tree, hf_status_id,  parameter_tvb, NTFY_STATUS_IDENT_OFFSET, NTFY_STATUS_IDENT_LENGTH,
465                              status_id, "Status identification: %u (%s)", status_id,
466                              val_to_str(status_type * 256 * 256 + status_id, status_type_id_values, "unknown"));
467
468   proto_item_append_text(parameter_item, " (%s)",
469                          val_to_str(status_type * 256 * 256 + status_id, status_type_id_values, "Unknown status information"));
470 }
471 /*----------------------Notify (RFC)-------------------------------------------*/
472
473 /*----------------------TEI Status Indication,Confirm (RFC)--------------------*/
474
475         /* define parameters for TEI Status (Indication,Confirm) Messages */
476 #define TEI_STATUS_ASSIGNED       0x0
477 #define TEI_STATUS_UNASSIGNED     0x1
478
479 static const value_string tei_status_values[] = {
480   { TEI_STATUS_ASSIGNED,   "TEI is considered assigned by Q.921" },
481   { TEI_STATUS_UNASSIGNED, "TEI is considered unassigned by Q.921" },
482   { 0,                     NULL } };
483
484 #define TEI_STATUS_OFFSET PARAMETER_VALUE_OFFSET
485 #define TEI_STATUS_LENGTH 4
486
487 static void
488 dissect_tei_status_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
489 {
490   proto_tree_add_item(parameter_tree, hf_tei_status, parameter_tvb, TEI_STATUS_OFFSET, TEI_STATUS_LENGTH, FALSE);
491   proto_item_append_text(parameter_item, " (%s)",
492                       val_to_str(tvb_get_ntohl(parameter_tvb, TEI_STATUS_OFFSET), tei_status_values, "Unknown TEI status"));
493 }
494 /*----------------------TEI Status (RFC)---------------------------------------*/
495
496 /*----------------------TEI Status Indication,Confirm (Draft)------------------*/
497 #define TEI_DRAFT_IN_SERVICE     0x0
498 #define TEI_DRAFT_OUT_OF_SERVICE 0x1
499
500 static const value_string tei_draft_status_values[] = {
501         { TEI_DRAFT_IN_SERVICE,    "TEI is in service" },
502         { TEI_DRAFT_OUT_OF_SERVICE,"TEI is out of service" },
503         { 0,                       NULL } };
504
505 #define TEI_STATUS_LENGTH_OFFSET PARAMETER_LENGTH_OFFSET
506
507 static void
508 dissect_draft_tei_status_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
509 {
510   gint length, offset;
511   offset = tvb_get_ntohs(parameter_tvb, TEI_STATUS_LENGTH_OFFSET) + 8;
512   length = msg_length - offset;
513   if(tvb_length_remaining(parameter_tvb, offset) > 0 ){
514           proto_tree_add_item(parameter_tree, hf_tei_draft_status, parameter_tvb, offset, TEI_STATUS_LENGTH, FALSE);
515           proto_item_append_text(parameter_item, " (%s)",
516                 val_to_str(tvb_get_ntohl(parameter_tvb, offset), tei_draft_status_values, "Unknown TEI Status"));
517   }
518 }
519 /*----------------------TEI Status (Draft)-------------------------------------*/
520
521 /*----------------------ASP Up,Down,Active,Inactive (Draft)--------------------*/
522
523 static void
524 dissect_asp_msg_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
525 {
526   guint16 adaptation_layer_id_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
527
528   proto_tree_add_item(parameter_tree, hf_adaptation_layer_id, parameter_tvb, PARAMETER_VALUE_OFFSET, adaptation_layer_id_length, FALSE);
529   proto_item_append_text(parameter_item, " (%.*s)", adaptation_layer_id_length,
530                          (const char *)tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, adaptation_layer_id_length));
531 }
532
533 static void
534 dissect_scn_protocol_id_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
535 {
536   guint16 id_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
537   proto_tree_add_item(parameter_tree, hf_scn_protocol_id, parameter_tvb, PARAMETER_VALUE_OFFSET, id_length, FALSE);
538   proto_item_append_text(parameter_item, " (%.*s)", id_length,
539                          (const char *)tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, id_length));
540 }
541
542 /*----------------------ASP (Draft)--------------------------------------------*/
543
544 /*----------------------ASP Down + Ack (RFC)--------------------------------*/
545         /* define reason parameter for Application Server Process Maintenance (ASPM) Messages */
546 #define ASP_REASON_MGMT   1
547
548 static const value_string asp_reason_values[] = {
549   { ASP_REASON_MGMT,      "Management inhibit" },
550   { 0,                    NULL } };
551
552 #define ASP_REASON_OFFSET PARAMETER_VALUE_OFFSET
553 #define ASP_REASON_LENGTH 4
554
555 static void
556 dissect_asp_reason_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
557 {
558   proto_tree_add_item(parameter_tree, hf_asp_reason, parameter_tvb, ASP_REASON_OFFSET, ASP_REASON_LENGTH, FALSE);
559   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"));
560 }
561
562
563 /*----------------------ASP (RFC)----------------------------------------------*/
564
565 /*----------------------Heartbeat Data + Ack (RFC)-----------------------------*/
566
567 #define HEARTBEAT_MSG_LENGTH_OFFSET PARAMETER_LENGTH_OFFSET
568 #define HEARTBEAT_DATA_OFFSET       PARAMETER_VALUE_OFFSET
569 #define HEARTBEAT_MSG_HEADER_LENGTH PARAMETER_HEADER_LENGTH
570
571 static void
572 dissect_heartbeat_data_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
573 {
574   guint16 heartbeat_data_length;
575
576   heartbeat_data_length = tvb_get_ntohs(parameter_tvb, HEARTBEAT_MSG_LENGTH_OFFSET) - HEARTBEAT_MSG_HEADER_LENGTH;
577   proto_tree_add_item(parameter_tree, hf_heartbeat_data, parameter_tvb, HEARTBEAT_DATA_OFFSET, heartbeat_data_length, FALSE);
578   proto_item_append_text(parameter_item, " (%u byte%s)", heartbeat_data_length, plurality(heartbeat_data_length, "", "s"));
579 }
580 /*----------------------Heartbeat Data (RFC)-----------------------------------*/
581
582
583 /*----------------------ASP Active,Inactive + Ack (RFC)------------------------*/
584 #define OVER_RIDE_TRAFFIC_MODE_TYPE  1
585 #define LOAD_SHARE_TRAFFIC_MODE_TYPE 2
586
587 static const value_string traffic_mode_type_values[] = {
588   { OVER_RIDE_TRAFFIC_MODE_TYPE,      "Over-ride" },
589   { LOAD_SHARE_TRAFFIC_MODE_TYPE,     "Load-share" },
590   { 0,                    NULL } };
591
592 #define TRAFFIC_MODE_TYPE_LENGTH 4
593 #define TRAFFIC_MODE_TYPE_OFFSET PARAMETER_VALUE_OFFSET
594
595 static void
596 dissect_traffic_mode_type_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
597 {
598   proto_tree_add_item(parameter_tree, hf_traffic_mode_type, parameter_tvb, TRAFFIC_MODE_TYPE_OFFSET, TRAFFIC_MODE_TYPE_LENGTH, FALSE);
599   proto_item_append_text(parameter_item, " (%s)",
600                          val_to_str(tvb_get_ntohl(parameter_tvb, TRAFFIC_MODE_TYPE_OFFSET), traffic_mode_type_values, "Unknown traffic mode type"));
601 }
602
603 #define INT_RANGE_START_OFFSET  PARAMETER_VALUE_OFFSET
604 #define INT_RANGE_LENGTH_OFFSET PARAMETER_LENGTH_OFFSET
605 #define INT_RANGE_HEADER_LENGTH PARAMETER_HEADER_LENGTH
606
607 #define IF_ID_START_OFFSET      0
608 #define IF_ID_START_LENGTH      4
609 #define IF_ID_END_OFFSET        (IF_ID_START_OFFSET + IF_ID_START_LENGTH)
610 #define IF_ID_END_LENGTH        4
611 #define IF_ID_INTERVAL_LENGTH   (IF_ID_START_LENGTH + IF_ID_END_LENGTH)
612
613
614 static void
615 dissect_integer_range_interface_identifier_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
616 {
617   guint16 number_of_ranges, range_number, offset;
618
619   number_of_ranges = (tvb_get_ntohs(parameter_tvb, INT_RANGE_LENGTH_OFFSET) - INT_RANGE_HEADER_LENGTH) / IF_ID_INTERVAL_LENGTH;
620   offset = INT_RANGE_START_OFFSET;
621   for(range_number = 1; range_number <= number_of_ranges; range_number++) {
622     proto_tree_add_item(parameter_tree, hf_if_range_start, parameter_tvb, offset + IF_ID_START_OFFSET, IF_ID_START_LENGTH, FALSE);
623     proto_tree_add_item(parameter_tree, hf_if_range_end,   parameter_tvb, offset + IF_ID_END_OFFSET,   IF_ID_END_LENGTH,   FALSE);
624     offset += IF_ID_INTERVAL_LENGTH;
625   };
626
627   proto_item_append_text(parameter_item, " (%u range%s)", number_of_ranges, plurality(number_of_ranges, "", "s"));
628 }
629 /*----------------------ASP Active,Inactive (RFC)------------------------------*/
630
631 /*----------------------Data Request,Indication (Draft,RFC)--------------------*/
632
633 #define DISCRIMINATOR_OFFSET 0
634 #define DISCRIMINATOR_LENGTH 1
635 #define ADDRESS_OFFSET       1
636 #define ADDRESS_LENGTH       1
637 #define LOW_ADDRESS_OFFSET   2
638 #define LOW_ADDRESS_LENGTH   1
639
640 #define ALL_ADDRESS_OFFSET   1
641 #define ALL_ADDRESS_LENGTH   2
642
643 #define MSG_TYPE_OFFSET      3
644 #define MSG_TYPE_LENGTH      1
645 #define MSG_HEADER_LENGTH    4
646 #define INFO_ELEMENT_OFFSET  4
647 #define INFO_ELEMENT_LENGTH  1
648
649 static void
650 dissect_layer3_message(tvbuff_t *layer3_data_tvb, proto_tree *v5ua_tree,proto_item *parameter_item, packet_info *pinfo)
651 {
652   guint16 discriminator_offset, address_offset, low_address_offset, msg_type_offset,  info_element_offset;
653
654
655   guint32 all_address_offset;
656
657   if(iua_version == DRAFT){
658           discriminator_offset = DISCRIMINATOR_OFFSET;
659           address_offset       = ADDRESS_OFFSET;
660           low_address_offset   = LOW_ADDRESS_OFFSET;
661           msg_type_offset      = MSG_TYPE_OFFSET;
662           info_element_offset  = INFO_ELEMENT_OFFSET;
663   }
664   else{
665           discriminator_offset = DISCRIMINATOR_OFFSET + PARAMETER_HEADER_LENGTH;
666           address_offset       = ADDRESS_OFFSET + PARAMETER_HEADER_LENGTH;
667           low_address_offset   = LOW_ADDRESS_OFFSET + PARAMETER_HEADER_LENGTH;
668
669           all_address_offset   = address_offset;
670
671           msg_type_offset      = MSG_TYPE_OFFSET + PARAMETER_HEADER_LENGTH;
672           info_element_offset  = INFO_ELEMENT_OFFSET + PARAMETER_HEADER_LENGTH;
673   }
674
675   if (tvb_get_guint8(layer3_data_tvb, discriminator_offset) == 0x48){
676           guint16 protocol_data_length;
677           tvbuff_t *protocol_data_tvb;
678
679           protocol_data_length = tvb_get_ntohs(layer3_data_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;
680           protocol_data_tvb    = tvb_new_subset(layer3_data_tvb, PARAMETER_VALUE_OFFSET, protocol_data_length, protocol_data_length);
681
682           call_dissector(v52_handle, protocol_data_tvb, pinfo, v5ua_tree);
683
684           proto_item_append_text(parameter_item, " (%u byte%s)", protocol_data_length, plurality(protocol_data_length, "", "s"));
685
686   }
687   else{
688           guint16 protocol_data_length;
689           tvbuff_t *protocol_data_tvb;
690
691           protocol_data_length = tvb_get_ntohs(layer3_data_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;
692           protocol_data_tvb    = tvb_new_subset(layer3_data_tvb, PARAMETER_VALUE_OFFSET, protocol_data_length, protocol_data_length);
693           call_dissector(q931_handle, protocol_data_tvb, pinfo, v5ua_tree);
694
695           proto_item_append_text(parameter_item, " (%u byte%s)", protocol_data_length, plurality(protocol_data_length, "", "s"));
696   }
697 }
698
699 /*----------------------Data Request,Indication (Draft,RFC)------------------------*/
700
701 /*----------------------Establish Request,Confirm,Indication (Draft,RFC)-------*/
702 /*
703  * no additional parameter
704  */
705 /*----------------------Establish Request,Confirm,Indication (Draft,RFC)-------*/
706
707 /*----------------------Release Indication, Request (Draft,RFC)----------------*/
708
709         /* define parameters for Release Request and Indication Messages */
710 #define RELEASE_MGMT   0x0
711 #define RELEASE_PHYS   0x1
712 #define RELEASE_DM     0x2
713 #define RELEASE_OTHER  0x3
714
715 static const value_string release_reason_values[] = {
716         { RELEASE_MGMT,    "Management layer generated release" },
717         { RELEASE_PHYS,    "Physical layer alarm generated release" },
718         { RELEASE_DM,      "Specific to a request" },
719         { RELEASE_OTHER,   "Other reason" },
720         { 0,               NULL } };
721
722 #define RELEASE_REASON_LENGTH_OFFSET PARAMETER_LENGTH_OFFSET
723 #define RELEASE_REASON_OFFSET        PARAMETER_VALUE_OFFSET
724 #define RELEASE_REASON_LENGTH        4
725
726 static void
727 dissect_release_reason_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
728 {
729   gint offset = RELEASE_REASON_OFFSET;
730   if(iua_version == DRAFT) offset = tvb_get_ntohs(parameter_tvb, RELEASE_REASON_LENGTH_OFFSET)+8;
731   proto_tree_add_item(parameter_tree, hf_release_reason, parameter_tvb, offset, RELEASE_REASON_LENGTH, FALSE);
732   if(iua_version != DRAFT)
733           proto_item_append_text(parameter_item, " (%s)",
734                 val_to_str(tvb_get_ntohl(parameter_tvb, offset), release_reason_values, "Unknown release reason"));
735 }
736 /*----------------------Release Indication,Request (Draft,RFC)-----------------*/
737
738 /*----------------------Link Status Start,Stop Report (Draft,RFC)--------------*/
739 /*
740  * No additional Parameter
741  */
742 /*----------------------Link Status Start,Stop Report (Draft,RFC)--------------*/
743
744 /*----------------------Link Status Indication (Draft,RFC)---------------------*/
745
746         /* define parameters for Link Status Indication */
747 #define LINK_STATUS_OPERTIONAL      0x0
748 #define LINK_STATUS_NON_OPERTIONAL  0x1
749
750 static const value_string link_status_values[] = {
751   { LINK_STATUS_OPERTIONAL,      "Link operational" },
752   { LINK_STATUS_NON_OPERTIONAL,  "Link not operational" },
753   { 0,                           NULL } };
754
755 #define LINK_STATUS_OFFSET   PARAMETER_VALUE_OFFSET
756 #define LINK_STATUS_LENGTH   4
757
758 static void
759 dissect_link_status_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
760 {
761         proto_tree_add_item(parameter_tree, hf_link_status, parameter_tvb, LINK_STATUS_OFFSET, LINK_STATUS_LENGTH, FALSE);
762         proto_item_append_text(parameter_item, " (%s)",
763           val_to_str(tvb_get_ntohl(parameter_tvb, LINK_STATUS_OFFSET),link_status_values, "Unknown Link status"));
764
765 link_status_operational = tvb_get_ntohl(parameter_tvb, LINK_STATUS_OFFSET);
766 }
767 /*----------------------Link Status Indication (Draft,RFC)---------------------*/
768
769 /*----------------------Sa-Bit (Draft,RFC)-------------------------------------*/
770
771         /* define parameter for sa-bit message */
772 #define SA_BIT_ID_ZERO     0x0
773 #define SA_BIT_ID_ONE      0x1
774 #define SA_BIT_VALUE_SA7   0x7
775
776 static const value_string sa_bit_values[] = {
777         { SA_BIT_ID_ZERO,    "set value ZERO" },
778         { SA_BIT_ID_ONE,     "set value ONE" },
779         { SA_BIT_VALUE_SA7,  "Addresses the Sa7 Bit" },
780         { 0,                 NULL } };
781
782 #define SA_BIT_ID_OFFSET     PARAMETER_VALUE_OFFSET
783 #define SA_BIT_ID_LENGTH     2
784 #define SA_BIT_VALUE_OFFSET  (SA_BIT_ID_OFFSET + SA_BIT_ID_LENGTH)
785 #define SA_BIT_VALUE_LENGTH  2
786
787 static void
788 dissect_sa_bit_status_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
789 {
790   proto_tree_add_item(parameter_tree, hf_sa_bit_id, parameter_tvb, SA_BIT_ID_OFFSET, SA_BIT_ID_LENGTH, FALSE);
791   proto_tree_add_item(parameter_tree, hf_sa_bit_value, parameter_tvb, SA_BIT_VALUE_OFFSET, SA_BIT_VALUE_LENGTH, FALSE);
792   proto_item_append_text(parameter_item, " (%s %s)",
793           val_to_str(tvb_get_ntohs(parameter_tvb, SA_BIT_ID_OFFSET), sa_bit_values, "unknown"),
794           val_to_str(tvb_get_ntohs(parameter_tvb, SA_BIT_VALUE_OFFSET), sa_bit_values, "unknown Bit"));
795
796 sa_bit_id = tvb_get_ntohs(parameter_tvb, SA_BIT_VALUE_OFFSET);
797 }
798 /*----------------------Sa-Bit (Draft,RFC)-------------------------------------*/
799
800 /*----------------------Error Indication (RFC)---------------------------------*/
801
802 #define ERROR_REASON_OVERLOAD 0x1
803
804 static const value_string error_reason_values[] = {
805         { ERROR_REASON_OVERLOAD, "C-Channel is in overload state" },
806         { 0,                     NULL } };
807
808 #define ERROR_REASON_LENGTH 4
809 #define ERROR_REASON_OFFSET PARAMETER_VALUE_OFFSET
810
811 static void
812 dissect_error_indication_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
813 {
814   proto_tree_add_item(parameter_tree, hf_error_reason, parameter_tvb, ERROR_REASON_OFFSET, ERROR_REASON_LENGTH, FALSE);
815   proto_item_append_text(parameter_item, " (%s)",
816           val_to_str(tvb_get_ntohl(parameter_tvb, ERROR_REASON_OFFSET), error_reason_values, "unknown"));
817 }
818 /*----------------------Error Indication (RFC)---------------------------------*/
819
820 /*--------------------------ASP identifier-------------------------------------*/
821 #define ASP_IDENTIFIER_LENGTH 4
822 #define ASP_IDENTIFIER_OFFSET PARAMETER_VALUE_OFFSET
823
824 static void
825 dissect_asp_identifier_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
826 {
827   proto_tree_add_item(parameter_tree, hf_asp_identifier, parameter_tvb, ASP_IDENTIFIER_OFFSET, ASP_IDENTIFIER_LENGTH, FALSE);
828     proto_item_append_text(parameter_item, " (%d) ",tvb_get_ntohl(parameter_tvb,ASP_IDENTIFIER_OFFSET));
829 }
830 /*--------------------------ASP identifier-------------------------------------*/
831
832 #define INFO_STRING_OFFSET PARAMETER_VALUE_OFFSET
833
834 static void
835 dissect_info_string_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
836 {
837   guint16 info_string_length;
838
839   info_string_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
840   if(iua_version == DRAFT) info_string_length += 4;
841   if(info_string_length > 4){
842         info_string_length -= PARAMETER_HEADER_LENGTH;
843         proto_tree_add_item(parameter_tree, hf_info_string, parameter_tvb, INFO_STRING_OFFSET, info_string_length, FALSE);
844         proto_item_append_text(parameter_item, " (%.*s)", info_string_length,
845                 (const char *)tvb_get_ptr(parameter_tvb, INFO_STRING_OFFSET, info_string_length));
846   }
847 }
848
849
850 static void
851 dissect_unknown_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
852 {
853
854   guint16 parameter_value_length;
855
856   parameter_value_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;
857   if (parameter_value_length > 0)
858     proto_tree_add_item(parameter_tree, hf_parameter_value, parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, FALSE);
859
860   proto_item_append_text(parameter_item, " with tag %u and %u byte%s value",
861   tvb_get_ntohs(parameter_tvb, PARAMETER_TAG_OFFSET), parameter_value_length, plurality(parameter_value_length, "", "s"));
862 }
863
864 #define Reserved_TAG                                     0x00
865 #define INT_INTERFACE_IDENTIFIER_PARAMETER_TAG           0x01
866 #define ASP_MSG_PARAMETER_TAG                            0x02
867 #define TEXT_INTERFACE_IDENTIFIER_PARAMETER_TAG          0x03
868 #define INFO_PARAMETER_TAG                               0x04
869 #define DLCI_PARAMETER_TAG                               0x81
870 #define DIAGNOSTIC_INFORMATION_PARAMETER_TAG             0x07
871 #define INTEGER_RANGE_INTERFACE_IDENTIFIER_PARAMETER_TAG 0x08
872 #define HEARTBEAT_DATA_PARAMETER_TAG                     0x09
873 #define ASP_DOWN_REASON_PARAMETER_TAG                    0x0a
874 #define TRAFFIC_MODE_TYPE_PARAMETER_TAG                  0x0b
875 #define ERROR_CODE_PARAMETER_TAG                         0x0c
876 #define STATUS_TYPE_INDENTIFICATION_PARAMETER_TAG        0x0d
877 #define PROTOCOL_DATA_PARAMETER_TAG                      0x0e
878 #define RELEASE_REASON_PARAMETER_TAG                     0x0f
879 #define TEI_STATUS_PARAMETER_TAG                         0x10
880 #define ASP_IDENTIFIER_PARAMETER_TAG                     0x11
881 #define NOT_USED_IN_IUA_PARAMETER_TAG                    0x12
882 #define LINK_STATUS_PARAMETER_TAG                        0x82
883 #define SA_BIT_STATUS_PARAMETER_TAG                      0x83
884 #define ERROR_INDICATION_PARAMETER_TAG                   0x84
885
886 static const value_string parameter_tag_values[] = {
887   { Reserved_TAG,                                        "Reserved" },
888   { INT_INTERFACE_IDENTIFIER_PARAMETER_TAG,              "Interface Identifier (integer)" },
889   { TEXT_INTERFACE_IDENTIFIER_PARAMETER_TAG,             "Interface Identifier (text)" },
890   { INFO_PARAMETER_TAG,                                  "Info string" },
891   { DLCI_PARAMETER_TAG,                                  "DLCI" },
892   { DIAGNOSTIC_INFORMATION_PARAMETER_TAG,                "Diagnostic information" },
893   { INTEGER_RANGE_INTERFACE_IDENTIFIER_PARAMETER_TAG,    "Interface Identifier Range" },
894   { HEARTBEAT_DATA_PARAMETER_TAG,                        "Hearbeat data" },
895   { ASP_DOWN_REASON_PARAMETER_TAG,                       "ASP DOWN Reason" },
896   { TRAFFIC_MODE_TYPE_PARAMETER_TAG,                     "Traffic mode type" },
897   { ERROR_CODE_PARAMETER_TAG,                            "Error code" },
898   { STATUS_TYPE_INDENTIFICATION_PARAMETER_TAG,           "Status type/identification" },
899   { PROTOCOL_DATA_PARAMETER_TAG,                         "Protocol Data" },
900   { RELEASE_REASON_PARAMETER_TAG,                        "Release Reason" },
901   { TEI_STATUS_PARAMETER_TAG,                            "TEI status" },
902   { ASP_IDENTIFIER_PARAMETER_TAG,                        "ASP Identifier" },
903   { NOT_USED_IN_IUA_PARAMETER_TAG,                       "Not used in IUA" },
904   { LINK_STATUS_PARAMETER_TAG,                           "Link status" },
905   { SA_BIT_STATUS_PARAMETER_TAG,                         "SA-Bit status" },
906   { ERROR_INDICATION_PARAMETER_TAG,                      "Error reason" },
907   { 0,                                                    NULL } };
908
909 static const value_string parameter_tag_draft_values[] = {
910   { INT_INTERFACE_IDENTIFIER_PARAMETER_TAG,              "V5UA Interface Identifier (int)" },
911   { ASP_MSG_PARAMETER_TAG,                               "ASP Adaption Layer ID" },
912   { TEXT_INTERFACE_IDENTIFIER_PARAMETER_TAG,             "SCN Protocol Identifier" },
913   { INFO_PARAMETER_TAG,                                  "Info" },
914   { PROTOCOL_DATA_PARAMETER_TAG,                         "Protocol Data" },
915   { LINK_STATUS_PARAMETER_TAG,                           "Link status" },
916   { SA_BIT_STATUS_PARAMETER_TAG,                         "SA-Bit status" },
917   { ERROR_INDICATION_PARAMETER_TAG,                      "Error reason" },
918   { 0,                                                   NULL } };
919
920 static void
921 dissect_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *v5ua_tree)
922 {
923   guint16 tag, length, padding_length;
924   proto_item *parameter_item;
925   proto_tree *parameter_tree;
926
927   /* extract tag and length from the parameter */
928   tag      = tvb_get_ntohs(parameter_tvb, PARAMETER_TAG_OFFSET);
929   length   = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
930   /* on IUA-Draft messages the message length not including the message header */
931   if((iua_version==DRAFT)&&(tag<=0x4)){
932           /* at V5UA Header, length of header and length of DLCI+EFA must be added */
933           if(tag==0x1)       length += 8;
934           /* at ASP message tags only length of header must be added */
935           else if(tag<=0x4)  length += PARAMETER_HEADER_LENGTH;
936           /* for following message-tags are no length information available. Only in common msg header */
937       if((msg_class==0 || msg_class==1 || msg_class==9) && msg_type<=10)
938         length = msg_length;
939   }
940   padding_length = tvb_length(parameter_tvb) - length;
941   paddingl = padding_length;
942
943   /* create proto_tree stuff */
944   switch(iua_version){
945   case RFC:
946           parameter_item   = proto_tree_add_text(v5ua_tree, parameter_tvb, PARAMETER_HEADER_OFFSET, tvb_length(parameter_tvb), "%s",
947                 val_to_str(tag, parameter_tag_values, "Unknown parameter"));
948           parameter_tree   = proto_item_add_subtree(parameter_item, ett_v5ua_parameter);
949           /* add tag to the v5ua tree */
950           proto_tree_add_item(parameter_tree, hf_parameter_tag, parameter_tvb, PARAMETER_TAG_OFFSET, PARAMETER_TAG_LENGTH, FALSE);
951           break;
952   case DRAFT:
953   default:
954           parameter_item   = proto_tree_add_text(v5ua_tree, parameter_tvb, PARAMETER_HEADER_OFFSET, tvb_length(parameter_tvb), "%s",
955                 val_to_str(tag, parameter_tag_draft_values, "Unknown parameter"));
956           parameter_tree   = proto_item_add_subtree(parameter_item, ett_v5ua_parameter);
957
958           /* add tag to the v5ua tree */
959           proto_tree_add_item(parameter_tree, hf_parameter_tag_draft, parameter_tvb, PARAMETER_TAG_OFFSET, PARAMETER_TAG_LENGTH, FALSE);
960           break;
961   };
962
963   /* add length to the v5ua tree */
964   proto_tree_add_item(parameter_tree, hf_parameter_length, parameter_tvb, PARAMETER_LENGTH_OFFSET, PARAMETER_LENGTH_LENGTH, FALSE);
965
966   switch(tag) {
967   case INT_INTERFACE_IDENTIFIER_PARAMETER_TAG:
968         if(iua_version == RFC) dissect_int_interface_identifier_parameter(parameter_tvb, parameter_tree, parameter_item);
969         if(iua_version == DRAFT){
970                 dissect_int_interface_identifier_parameter(parameter_tvb, parameter_tree, parameter_item);
971                 dissect_dlci_parameter(parameter_tvb, parameter_tree, parameter_item, pinfo);
972
973                 /* for the following parameters no tag- and length-informations available. Parameters must be dissect with info from common msg header */
974                 if(msg_class==0 && msg_type==0)    dissect_draft_error_code_parameter(parameter_tvb, parameter_tree);
975                 if(msg_class==1)                   dissect_draft_tei_status_parameter(parameter_tvb, parameter_tree, parameter_item);
976                 if(msg_class==9){
977                         if(msg_type==1||msg_type==2||msg_type==3||msg_type==4){
978                                 guint16 length_2, offset;
979                                 tvbuff_t *layer3_data_tvb;
980                                 offset = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) + 8;
981                                 length_2 = msg_length - offset;
982                                 if(length_2 > 0){
983                                         if(tvb_get_guint8(parameter_tvb, offset) == 0x48){
984                                                 layer3_data_tvb = tvb_new_subset(parameter_tvb, offset, length_2, length_2);
985                                                 dissect_layer3_message(layer3_data_tvb, v5ua_tree, parameter_item, pinfo);
986                                         }
987                                 }
988                         }
989                         else if(msg_type==8||msg_type==10) dissect_release_reason_parameter(parameter_tvb, parameter_tree, parameter_item);
990                 }
991         }
992     break;
993   case ASP_MSG_PARAMETER_TAG:
994     dissect_asp_msg_parameter(parameter_tvb, parameter_tree, parameter_item);
995     break;
996   case TEXT_INTERFACE_IDENTIFIER_PARAMETER_TAG:
997     if(iua_version == RFC)
998       dissect_text_interface_identifier_parameter(parameter_tvb, parameter_tree, parameter_item);
999     if(iua_version == DRAFT)
1000       dissect_scn_protocol_id_parameter(parameter_tvb, parameter_tree, parameter_item);
1001     break;
1002   case INFO_PARAMETER_TAG:
1003     dissect_info_string_parameter(parameter_tvb, parameter_tree, parameter_item);
1004     break;
1005   case DLCI_PARAMETER_TAG:
1006     dissect_dlci_parameter(parameter_tvb, parameter_tree, parameter_item, pinfo);
1007     break;
1008   case DIAGNOSTIC_INFORMATION_PARAMETER_TAG:
1009     dissect_diagnostic_information_parameter(parameter_tvb, parameter_tree, parameter_item);
1010     break;
1011   case INTEGER_RANGE_INTERFACE_IDENTIFIER_PARAMETER_TAG:
1012     dissect_integer_range_interface_identifier_parameter(parameter_tvb, parameter_tree, parameter_item);
1013     break;
1014   case HEARTBEAT_DATA_PARAMETER_TAG:
1015     dissect_heartbeat_data_parameter(parameter_tvb, parameter_tree, parameter_item);
1016     break;
1017   case ASP_DOWN_REASON_PARAMETER_TAG:
1018     dissect_asp_reason_parameter(parameter_tvb, parameter_tree, parameter_item);
1019     break;
1020   case TRAFFIC_MODE_TYPE_PARAMETER_TAG:
1021     dissect_traffic_mode_type_parameter(parameter_tvb, parameter_tree, parameter_item);
1022     break;
1023   case ERROR_CODE_PARAMETER_TAG:
1024     dissect_error_code_parameter(parameter_tvb, parameter_tree, parameter_item);
1025     break;
1026   case STATUS_TYPE_INDENTIFICATION_PARAMETER_TAG:
1027     dissect_status_type_identification_parameter(parameter_tvb, parameter_tree, parameter_item);
1028     break;
1029   case PROTOCOL_DATA_PARAMETER_TAG:
1030     dissect_layer3_message(parameter_tvb, v5ua_tree, parameter_item, pinfo);
1031     break;
1032   case RELEASE_REASON_PARAMETER_TAG:
1033     dissect_release_reason_parameter(parameter_tvb, parameter_tree, parameter_item);
1034     break;
1035   case TEI_STATUS_PARAMETER_TAG:
1036     dissect_tei_status_parameter(parameter_tvb, parameter_tree, parameter_item);
1037     break;
1038   case ASP_IDENTIFIER_PARAMETER_TAG:
1039     dissect_asp_identifier_parameter(parameter_tvb, parameter_tree, parameter_item);
1040     break;
1041   case LINK_STATUS_PARAMETER_TAG:
1042     dissect_link_status_parameter(parameter_tvb, parameter_tree, parameter_item);
1043     break;
1044   case SA_BIT_STATUS_PARAMETER_TAG:
1045     dissect_sa_bit_status_parameter(parameter_tvb, parameter_tree, parameter_item);
1046     break;
1047   case ERROR_INDICATION_PARAMETER_TAG:
1048     dissect_error_indication_parameter( parameter_tvb, parameter_tree, parameter_item);
1049     break;
1050   default:
1051     dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
1052     break;
1053   };
1054
1055   if (padding_length > 0){
1056     proto_tree_add_item(parameter_tree, hf_parameter_padding, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length, FALSE);
1057   }
1058 }
1059 /* dissect the V5UA-Parameters into subsets which are separated by Tag-Length-Header and call up the dissector for the subsets */
1060 static void
1061 dissect_parameters(tvbuff_t *parameters_tvb, packet_info *pinfo, proto_tree *tree _U_, proto_tree *v5ua_tree)
1062 {
1063   gint tag, offset, length, total_length, remaining_length;
1064   tvbuff_t *parameter_tvb;
1065
1066
1067   offset = 0;
1068   while((remaining_length = tvb_length_remaining(parameters_tvb, offset))) {
1069         tag = tvb_get_ntohs(parameters_tvb, offset + PARAMETER_TAG_OFFSET);
1070         length = tvb_get_ntohs(parameters_tvb, offset + PARAMETER_LENGTH_OFFSET);
1071         if(iua_version==DRAFT){
1072                 if(tag==0x1) length += 8;               /* V5UA Header */
1073                 else if(tag<=0x4) length += PARAMETER_HEADER_LENGTH;    /* ASP MSGs */
1074
1075                 /* add the parameters which are not separated by tag-length-header to the V5UA header */
1076                 if((msg_class==0 || msg_class==1 || msg_class==9)&&msg_type<=10)
1077                         length = msg_length;
1078         }
1079         total_length = ADD_PADDING(length);
1080         if (remaining_length >= length)
1081           total_length = MIN(total_length, remaining_length);
1082         /* create a tvb for the parameter including the padding bytes */
1083         parameter_tvb  = tvb_new_subset(parameters_tvb, offset, total_length, total_length);
1084         dissect_parameter(parameter_tvb, pinfo, v5ua_tree);
1085         /* get rid of the handled parameter */
1086         offset += total_length;
1087         }
1088 }
1089
1090
1091         /* define the common header fields of V5UA MSG */
1092 #define COMMON_HEADER_VERSION_LENGTH        1
1093 #define COMMON_HEADER_RESERVED_LENGTH       1
1094 #define COMMON_HEADER_MSG_CLASS_LENGTH      1
1095 #define COMMON_HEADER_MSG_TYPE_LENGTH       1
1096 #define COMMON_HEADER_MSG_LENGTH_LENGTH     4
1097 #define COMMON_HEADER_LENGTH                (COMMON_HEADER_VERSION_LENGTH + COMMON_HEADER_RESERVED_LENGTH +\
1098                                              COMMON_HEADER_MSG_CLASS_LENGTH + COMMON_HEADER_MSG_TYPE_LENGTH +\
1099                                              COMMON_HEADER_MSG_LENGTH_LENGTH)
1100
1101         /* define the offsets of common header */
1102 #define COMMON_HEADER_OFFSET            0
1103 #define COMMON_HEADER_VERSION_OFFSET    COMMON_HEADER_OFFSET
1104 #define COMMON_HEADER_RESERVED_OFFSET   (COMMON_HEADER_VERSION_OFFSET       + COMMON_HEADER_VERSION_LENGTH)
1105 #define COMMON_HEADER_MSG_CLASS_OFFSET  (COMMON_HEADER_RESERVED_OFFSET      + COMMON_HEADER_RESERVED_LENGTH)
1106 #define COMMON_HEADER_MSG_TYPE_OFFSET   (COMMON_HEADER_MSG_CLASS_OFFSET     + COMMON_HEADER_MSG_CLASS_LENGTH)
1107 #define COMMON_HEADER_MSG_LENGTH_OFFSET (COMMON_HEADER_MSG_TYPE_OFFSET      + COMMON_HEADER_MSG_TYPE_LENGTH)
1108 #define COMMON_HEADER_PARAMETERS_OFFSET (COMMON_HEADER_OFFSET               + COMMON_HEADER_LENGTH)
1109
1110         /* version of V5UA protocol */
1111 #define V5UA_PROTOCOL_VERSION_RELEASE_1     1
1112
1113 static const value_string v5ua_protocol_version_values[] = {
1114   { V5UA_PROTOCOL_VERSION_RELEASE_1,  "Release 1.0" },
1115   { 0,                                NULL } };
1116
1117         /* define V5UA MSGs */
1118 #define MSG_CLASS_MGMT_MSG        0
1119 #define MSG_CLASS_MGMT_MSG_DRAFT  1
1120 #define MSG_CLASS_ASPSM_MSG       3
1121 #define MSG_CLASS_ASPTM_MSG       4
1122 #define MSG_CLASS_V5PTM_MSG_DRAFT 9
1123 #define MSG_CLASS_V5PTM_MSG      14
1124
1125 static const value_string msg_class_values[] = {
1126         { MSG_CLASS_MGMT_MSG,  "Management Messages" },
1127         { MSG_CLASS_MGMT_MSG_DRAFT,"Management Messages"},
1128         { MSG_CLASS_ASPSM_MSG, "ASP State Maintenance Message" },
1129         { MSG_CLASS_ASPTM_MSG, "ASP Traffic Maintenance Message" },
1130         { MSG_CLASS_V5PTM_MSG_DRAFT, "V5 Boundary Primitives Transport Message" },
1131         { MSG_CLASS_V5PTM_MSG, "V5 Boundary Primitives Transport Message" },
1132         { 0,                           NULL } };
1133
1134         /* message types for MGMT messages */
1135 #define MGMT_MSG_TYPE_ERR                  0
1136 #define MGMT_MSG_TYPE_NTFY                 1
1137 #define MGMT_MSG_TYPE_TEI_STATUS_REQ       2
1138 #define MGMT_MSG_TYPE_TEI_STATUS_CON       3
1139 #define MGMT_MSG_TYPE_TEI_STATUS_IND       4
1140 #define MGMT_MSG_TYPE_TEI_QUERY_REQUEST5  5
1141 #define MGMT_MSG_TYPE_TEI_QUERY_REQUEST   8
1142  /* end */
1143
1144         /* MGMT messages for Nortel draft version*/
1145 #define MGMT_MSG_DRAFT_TYPE_TEI_STATUS_REQ       1
1146 #define MGMT_MSG_DRAFT_TYPE_TEI_STATUS_CON       2
1147 #define MGMT_MSG_DRAFT_TYPE_TEI_STATUS_IND       3
1148 #define MGMT_MSG_DRAFT_TYPE_TEI_QUERY_REQUEST5  5
1149 #define MGMT_MSG_DRAFT_TYPE_TEI_QUERY_REQUEST   8
1150  /* end */
1151
1152         /* message types for ASPSM messages */
1153 #define ASPSM_MSG_TYPE_Reserved             0
1154 #define ASPSM_MSG_TYPE_UP                   1
1155 #define ASPSM_MSG_TYPE_DOWN                 2
1156 #define ASPSM_MSG_TYPE_BEAT                 3
1157 #define ASPSM_MSG_TYPE_UP_ACK               4
1158 #define ASPSM_MSG_TYPE_DOWN_ACK             5
1159 #define ASPSM_MSG_TYPE_BEAT_ACK             6
1160
1161         /* message types for ASPTM messages */
1162 #define ASPTM_MSG_TYPE_Reserved             0
1163 #define ASPTM_MSG_TYPE_ACTIVE               1
1164 #define ASPTM_MSG_TYPE_INACTIVE             2
1165 #define ASPTM_MSG_TYPE_ACTIVE_ACK           3
1166 #define ASPTM_MSG_TYPE_INACTIVE_ACK         4
1167
1168         /* message types for V5PTM messages */
1169 #define V5PTM_MSG_TYPE_Reserved                     0
1170 #define V5PTM_MSG_TYPE_DATA_REQUEST                 1
1171 #define V5PTM_MSG_TYPE_DATA_INDICATION              2
1172 #define V5PTM_MSG_TYPE_UNIT_DATA_REQUEST            3
1173 #define V5PTM_MSG_TYPE_UNIT_DATA_INDICATION         4
1174 #define V5PTM_MSG_TYPE_ESTABLISH_REQUEST            5
1175 #define V5PTM_MSG_TYPE_ESTABLISH_CONFIRM            6
1176 #define V5PTM_MSG_TYPE_ESTABLISH_INDICATION         7
1177 #define V5PTM_MSG_TYPE_RELEASE_REQUEST              8
1178 #define V5PTM_MSG_TYPE_RELEASE_CONFIRM              9
1179 #define V5PTM_MSG_TYPE_RELEASE_INDICATION          10
1180 #define V5PTM_MSG_TYPE_LINK_STATUS_START_REPORTING 11
1181 #define V5PTM_MSG_TYPE_LINK_STATUS_STOP_REPORTING  12
1182 #define V5PTM_MSG_TYPE_LINK_STATUS_INDICATION      13
1183 #define V5PTM_MSG_TYPE_SA_BIT_SET_REQUEST          14
1184 #define V5PTM_MSG_TYPE_SA_BIT_SET_CONFIRM          15
1185 #define V5PTM_MSG_TYPE_SA_BIT_STATUS_REQUEST       16
1186 #define V5PTM_MSG_TYPE_SA_BIT_STATUS_INDICATION    17
1187 #define V5PTM_MSG_TYPE_ERROR_INDICATION            18
1188
1189 #define MGMT_MSG_TYPE_TEI_STATUS_REQUEST5  5
1190 #define MGMT_MSG_TYPE_TEI_STATUS_REQUEST   8
1191
1192 static const value_string msg_class_type_values[] = {
1193   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_ERR,                         "Error" },
1194   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_NTFY,                        "Notify" },
1195   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_TEI_STATUS_REQ,              "TEI status request" },
1196   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_TEI_STATUS_CON,              "TEI status confirmation" },
1197   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_TEI_STATUS_IND,              "TEI status indication" },
1198   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_TEI_QUERY_REQUEST,           "TEI query request" },
1199   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_TEI_QUERY_REQUEST5,          "TEI query request" },
1200
1201   { MSG_CLASS_MGMT_MSG_DRAFT * 256 + MGMT_MSG_DRAFT_TYPE_TEI_STATUS_REQ,   "TEI status request" },
1202   { MSG_CLASS_MGMT_MSG_DRAFT * 256 + MGMT_MSG_DRAFT_TYPE_TEI_STATUS_CON,   "TEI status confimation" },
1203   { MSG_CLASS_MGMT_MSG_DRAFT * 256 + MGMT_MSG_DRAFT_TYPE_TEI_STATUS_IND,   "TEI status indication" },
1204   { MSG_CLASS_MGMT_MSG_DRAFT * 256 + MGMT_MSG_DRAFT_TYPE_TEI_QUERY_REQUEST,  "TEI query request" },
1205   { MSG_CLASS_MGMT_MSG_DRAFT * 256 + MGMT_MSG_DRAFT_TYPE_TEI_QUERY_REQUEST5, "TEI query request" },
1206
1207
1208   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_Reserved,                   "Reserved" },
1209   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_UP,                         "ASP up" },
1210   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_DOWN,                       "ASP down" },
1211   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_BEAT,                       "Heartbeat" },
1212   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_UP_ACK,                     "ASP up ack" },
1213   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_DOWN_ACK,                   "ASP down ack" },
1214   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_BEAT_ACK,                   "Heartbeat ack" },
1215
1216   { MSG_CLASS_ASPTM_MSG * 256 + ASPTM_MSG_TYPE_Reserved ,                  "Reserved" },
1217   { MSG_CLASS_ASPTM_MSG * 256 + ASPTM_MSG_TYPE_ACTIVE ,                    "ASP active" },
1218   { MSG_CLASS_ASPTM_MSG * 256 + ASPTM_MSG_TYPE_INACTIVE ,                  "ASP inactive" },
1219   { MSG_CLASS_ASPTM_MSG * 256 + ASPTM_MSG_TYPE_ACTIVE_ACK ,                "ASP active ack" },
1220   { MSG_CLASS_ASPTM_MSG * 256 + ASPTM_MSG_TYPE_INACTIVE_ACK ,              "ASP inactive ack" },
1221
1222   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_Reserved,                   "Reserved" },
1223   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_DATA_REQUEST,               "Data request" },
1224   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_DATA_INDICATION,            "Data indication" },
1225   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_UNIT_DATA_REQUEST,          "Unit data request" },
1226   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_UNIT_DATA_INDICATION,       "Unit data indication" },
1227   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_ESTABLISH_REQUEST,          "Establish request" },
1228   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_ESTABLISH_CONFIRM,          "Establish confirmation" },
1229   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_ESTABLISH_INDICATION,       "Establish indication" },
1230   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_RELEASE_REQUEST,            "Release request" },
1231   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_RELEASE_CONFIRM,            "Release confirmation" },
1232   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_RELEASE_INDICATION,         "Release indication" },
1233   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_LINK_STATUS_START_REPORTING,"Link status start reporting" },
1234   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_LINK_STATUS_STOP_REPORTING, "Link status stop reporting" },
1235   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_LINK_STATUS_INDICATION,     "Link status indication" },
1236   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_SA_BIT_SET_REQUEST,         "Sa-Bit set request" },
1237   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_SA_BIT_SET_CONFIRM,         "Sa-Bit set confirm" },
1238   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_SA_BIT_STATUS_REQUEST,      "Sa-Bit status request" },
1239   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_SA_BIT_STATUS_INDICATION,   "Sa-Bit status indication" },
1240   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_ERROR_INDICATION,           "Error indication" },
1241
1242   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_Reserved,                   "Reserved" },
1243   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_DATA_REQUEST,               "Data request" },
1244   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_DATA_INDICATION,            "Data indication" },
1245   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_UNIT_DATA_REQUEST,          "Unit data request" },
1246   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_UNIT_DATA_INDICATION,       "Unit data indication" },
1247   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_ESTABLISH_REQUEST,          "Establish request" },
1248   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_ESTABLISH_CONFIRM,          "Establish confirmation" },
1249   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_ESTABLISH_INDICATION,       "Establish indication" },
1250   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_RELEASE_REQUEST,            "Release request" },
1251   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_RELEASE_CONFIRM,            "Release confirmation" },
1252   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_RELEASE_INDICATION,         "Release indication" },
1253   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_LINK_STATUS_START_REPORTING,"Link status start reporting" },
1254   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_LINK_STATUS_STOP_REPORTING, "Link status stop reporting" },
1255   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_LINK_STATUS_INDICATION,     "Link status indication" },
1256   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_SA_BIT_SET_REQUEST,         "Sa-Bit set request" },
1257   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_SA_BIT_SET_CONFIRM,         "Sa-Bit set confirm" },
1258   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_SA_BIT_STATUS_REQUEST,      "Sa-Bit status request" },
1259   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_SA_BIT_STATUS_INDICATION,   "Sa-Bit status indication" },
1260   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_ERROR_INDICATION,           "Error indication" },
1261
1262   { 0,                                                                                  NULL } };
1263
1264 static const value_string msg_class_type_values_short[] = {
1265   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_ERR,                         "Error" },
1266   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_NTFY,                        "Notify" },
1267   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_TEI_STATUS_REQ,              "TEI status request" },
1268   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_TEI_STATUS_CON,              "TEI status confirmation" },
1269   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_TEI_STATUS_IND,              "TEI status indication" },
1270   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_TEI_QUERY_REQUEST,           "TEI query request" },
1271   { MSG_CLASS_MGMT_MSG  * 256 + MGMT_MSG_TYPE_TEI_QUERY_REQUEST5,          "TEI query request" },
1272
1273   { MSG_CLASS_MGMT_MSG_DRAFT * 256 + MGMT_MSG_DRAFT_TYPE_TEI_STATUS_REQ,   "TEI status request" },
1274   { MSG_CLASS_MGMT_MSG_DRAFT * 256 + MGMT_MSG_DRAFT_TYPE_TEI_STATUS_CON,   "TEI status confimation" },
1275   { MSG_CLASS_MGMT_MSG_DRAFT * 256 + MGMT_MSG_DRAFT_TYPE_TEI_STATUS_IND,   "TEI status indication" },
1276   { MSG_CLASS_MGMT_MSG_DRAFT * 256 + MGMT_MSG_DRAFT_TYPE_TEI_QUERY_REQUEST,  "TEI query request" },
1277   { MSG_CLASS_MGMT_MSG_DRAFT * 256 + MGMT_MSG_DRAFT_TYPE_TEI_QUERY_REQUEST5, "TEI query request" },
1278
1279
1280   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_Reserved,                   "Reserved" },
1281   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_UP,                         "ASP up" },
1282   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_DOWN,                       "ASP down" },
1283   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_BEAT,                       "Heartbeat" },
1284   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_UP_ACK,                     "ASP up ack" },
1285   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_DOWN_ACK,                   "ASP down ack" },
1286   { MSG_CLASS_ASPSM_MSG * 256 + ASPSM_MSG_TYPE_BEAT_ACK,                   "Heartbeat ack" },
1287
1288   { MSG_CLASS_ASPTM_MSG * 256 + ASPTM_MSG_TYPE_Reserved ,                  "Reserved" },
1289   { MSG_CLASS_ASPTM_MSG * 256 + ASPTM_MSG_TYPE_ACTIVE ,                    "ASP active" },
1290   { MSG_CLASS_ASPTM_MSG * 256 + ASPTM_MSG_TYPE_INACTIVE ,                  "ASP inactive" },
1291   { MSG_CLASS_ASPTM_MSG * 256 + ASPTM_MSG_TYPE_ACTIVE_ACK ,                "ASP active ack" },
1292   { MSG_CLASS_ASPTM_MSG * 256 + ASPTM_MSG_TYPE_INACTIVE_ACK ,              "ASP inactive ack" },
1293
1294   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_Reserved,                   "Reserved" },
1295   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_DATA_REQUEST,               "Data request" },
1296   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_DATA_INDICATION,            "Data indication" },
1297   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_UNIT_DATA_REQUEST,          "Unit data request" },
1298   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_UNIT_DATA_INDICATION,       "Unit data indication" },
1299   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_ESTABLISH_REQUEST,          "Establish request" },
1300   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_ESTABLISH_CONFIRM,          "Establish confirmation" },
1301   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_ESTABLISH_INDICATION,       "Establish indication" },
1302   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_RELEASE_REQUEST,            "Release request" },
1303   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_RELEASE_CONFIRM,            "Release confirmation" },
1304   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_RELEASE_INDICATION,         "Release indication" },
1305   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_LINK_STATUS_START_REPORTING,"Link status start reporting" },
1306   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_LINK_STATUS_STOP_REPORTING, "Link status stop reporting" },
1307   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_LINK_STATUS_INDICATION,     "Link status indication" },
1308   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_SA_BIT_SET_REQUEST,         "Sa-Bit set request" },
1309   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_SA_BIT_SET_CONFIRM,         "Sa-Bit set confirm" },
1310   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_SA_BIT_STATUS_REQUEST,      "Sa-Bit status request" },
1311   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_SA_BIT_STATUS_INDICATION,   "Sa-Bit status indication" },
1312   { MSG_CLASS_V5PTM_MSG_DRAFT * 256 + V5PTM_MSG_TYPE_ERROR_INDICATION,           "Error indication" },
1313
1314
1315   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_Reserved,                   "Reserved" },
1316   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_DATA_REQUEST,               "Data Req" },
1317   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_DATA_INDICATION,            "Data Ind" },
1318   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_UNIT_DATA_REQUEST,          "U Data Req" },
1319   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_UNIT_DATA_INDICATION,       "U Data Ind" },
1320   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_ESTABLISH_REQUEST,          "Est Req" },
1321   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_ESTABLISH_CONFIRM,          "Est Conf" },
1322   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_ESTABLISH_INDICATION,       "Est Ind" },
1323   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_RELEASE_REQUEST,            "Rel Req" },
1324   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_RELEASE_CONFIRM,            "Rel Con" },
1325   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_RELEASE_INDICATION,         "Rel Ind" },
1326   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_LINK_STATUS_START_REPORTING,"Link Status Start Rep" },
1327   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_LINK_STATUS_STOP_REPORTING, "Link Status Stop Rep" },
1328   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_LINK_STATUS_INDICATION,     "Link Status Ind" },
1329   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_SA_BIT_SET_REQUEST,         "Sa-Bit Set Req" },
1330   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_SA_BIT_SET_CONFIRM,         "Sa-Bit set Conf" },
1331   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_SA_BIT_STATUS_REQUEST,      "Sa-Bit Status Req" },
1332   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_SA_BIT_STATUS_INDICATION,   "Sa-Bit Status Ind" },
1333   { MSG_CLASS_V5PTM_MSG * 256 + V5PTM_MSG_TYPE_ERROR_INDICATION,           "Error Ind" },
1334   { 0,                                                                                  NULL } };
1335
1336
1337 static void
1338 dissect_common_header(tvbuff_t *common_header_tvb, packet_info *pinfo, proto_tree *v5ua_tree)
1339 {
1340   proto_item *common_header_item;
1341   proto_tree *common_header_tree;
1342
1343   guint8 message_class, message_type;
1344
1345   message_class  = tvb_get_guint8(common_header_tvb, COMMON_HEADER_MSG_CLASS_OFFSET);
1346   message_type   = tvb_get_guint8(common_header_tvb, COMMON_HEADER_MSG_TYPE_OFFSET);
1347
1348   /* Add message type into info column */
1349   col_add_str(pinfo->cinfo, COL_INFO, val_to_str(message_class * 256 + message_type, msg_class_type_values_short, "UNKNOWN"));
1350
1351
1352   if (v5ua_tree) {
1353
1354           /* create proto_tree stuff */
1355     common_header_item   = proto_tree_add_text(v5ua_tree, common_header_tvb, COMMON_HEADER_OFFSET, tvb_length(common_header_tvb),"Common Msg-Header");
1356     common_header_tree   = proto_item_add_subtree(common_header_item, ett_v5ua_common_header);
1357
1358           /* add the components of the common header to the protocol tree */
1359     proto_tree_add_item(common_header_tree, hf_version, common_header_tvb, COMMON_HEADER_VERSION_OFFSET, COMMON_HEADER_VERSION_LENGTH, FALSE);
1360     proto_tree_add_item(common_header_tree, hf_reserved, common_header_tvb, COMMON_HEADER_RESERVED_OFFSET, COMMON_HEADER_RESERVED_LENGTH, FALSE);
1361     proto_tree_add_item(common_header_tree, hf_msg_class, common_header_tvb, COMMON_HEADER_MSG_CLASS_OFFSET, COMMON_HEADER_MSG_CLASS_LENGTH, FALSE);
1362     proto_tree_add_uint_format(common_header_tree, hf_msg_type,
1363                               common_header_tvb, COMMON_HEADER_MSG_TYPE_OFFSET, COMMON_HEADER_MSG_TYPE_LENGTH,
1364                               message_type, "Message type: %s ( %u )",
1365                               val_to_str(message_class * 256 + message_type, msg_class_type_values, "reserved"), message_type);
1366     proto_tree_add_item(common_header_tree, hf_msg_length, common_header_tvb, COMMON_HEADER_MSG_LENGTH_OFFSET, COMMON_HEADER_MSG_LENGTH_LENGTH, FALSE);
1367
1368         /* Add message type to the Common Msg-Header line */
1369     proto_item_append_text(common_header_item, " (%s)",val_to_str(message_class * 256 + message_type, msg_class_type_values, "Unknown Msg-Type"));
1370     messageclassCopy = message_class;
1371   }
1372
1373         /* the following info are required to dissect IUA-Draft messages.
1374         In the DRAFT-Specification V5UA-Parameters are not separated by Tag-Length-Header (as defined in RFC-Spec) */
1375   if (iua_version == DRAFT){
1376           msg_class = message_class;
1377           msg_type  = message_type;
1378           msg_length = tvb_get_ntohl (common_header_tvb, COMMON_HEADER_MSG_LENGTH_OFFSET);
1379   }
1380 }
1381
1382 /* dissect the V5UA-packet in two subsets: Common Msg-Header (used by all msgs) and V5UA-parameter */
1383 static void
1384 dissect_v5ua_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *v5ua_tree)
1385 {
1386   tvbuff_t *common_header_tvb, *parameters_tvb;
1387
1388   common_header_tvb = tvb_new_subset(tvb, COMMON_HEADER_OFFSET, COMMON_HEADER_LENGTH, COMMON_HEADER_LENGTH);
1389   dissect_common_header(common_header_tvb, pinfo, v5ua_tree);
1390
1391   parameters_tvb    = tvb_new_subset_remaining(tvb, COMMON_HEADER_LENGTH);
1392   dissect_parameters(parameters_tvb, pinfo, tree, v5ua_tree);
1393     if (dlci_efa >= 0 && dlci_efa <= 8175) {
1394           if ((messageclassCopy == 0) || (messageclassCopy == 3) || (messageclassCopy == 4)) {
1395                 messageclassCopy = -1;
1396           }
1397           else {
1398                   col_append_str(pinfo->cinfo, COL_INFO, " | ");
1399                   col_append_fstr(pinfo->cinfo, COL_INFO, "LinkId: %u", linkIdentifier);
1400           }
1401    } else {};
1402
1403    if (sa_bit_id > -1) {
1404                 col_append_str(pinfo->cinfo, COL_INFO, " | ");
1405                 col_append_fstr(pinfo->cinfo, COL_INFO, "SA7bit: %u", sa_bit_id);
1406                 sa_bit_id = -1;
1407    } else {};
1408
1409    if (link_status_operational > -1) {
1410         if (link_status_operational == 0) {
1411                 col_append_str(pinfo->cinfo, COL_INFO, " | operational");
1412         }
1413         else if (link_status_operational == 1) {
1414                 col_append_str(pinfo->cinfo, COL_INFO, " | non-operational");
1415         }else {
1416         }
1417         link_status_operational = -1;
1418    } else {};
1419
1420 }
1421
1422 static void
1423 dissect_v5ua(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1424 {
1425
1426    gint    offset, remaining_length, length, tag, one_bit;
1427
1428
1429 /* Set up structures needed to add the protocol subtree and manage it */
1430         proto_tree *v5ua_tree;
1431         proto_item *ti;
1432
1433 /* Make entries in Protocol column and Info column on summary display */
1434         col_set_str(pinfo->cinfo, COL_PROTOCOL, "V5UA");
1435 /* end */
1436         col_clear(pinfo->cinfo, COL_INFO);
1437         if (tree) {
1438 /* create display subtree for the protocol */
1439                 ti = proto_tree_add_item(tree, proto_v5ua, tvb, 0, -1, FALSE);
1440                 v5ua_tree = proto_item_add_subtree(ti, ett_v5ua);
1441         }
1442         else {
1443                 v5ua_tree=NULL;
1444         };
1445
1446         /* detect version of IUA */
1447    iua_version = RFC;
1448    offset = COMMON_HEADER_LENGTH;
1449
1450    remaining_length = tvb_length_remaining(tvb, offset);
1451
1452    while(remaining_length) {
1453            tag = tvb_get_ntohs(tvb, offset);
1454            /*0x01,0x03: Inerface Id (draft&RFC)*/
1455                 if(tag==0x1){
1456                         length = tvb_get_ntohs(tvb, offset+2);
1457                         tag = tvb_get_ntohs(tvb, offset+length);
1458                         /* tag 0x5 indicates the DLCI in the V5UA-Header accoriding to RFC spec */
1459                         if(tag==0x81){
1460                                 remaining_length = FALSE;
1461                         }
1462                         else{
1463                                 one_bit = tvb_get_guint8(tvb, offset+4+length+1);
1464                                 /* no indication from DLCI by tag (in the V5UA-Header according DRAFT).
1465                                         Thus the ONE-Bit within DLCI have to compare */
1466                                 if((one_bit & 0x01) == 0x01){
1467                                         iua_version = DRAFT;
1468                                         remaining_length = FALSE;
1469                                 }
1470                                 /* an indication to incorrect bit in DLCI.
1471                                         Must be include to decode an incorrect implemented message on Nortels PVG*/
1472                                 else{
1473                                         proto_item_append_text(v5ua_tree, "   !! DLCI INCORRECT !!");
1474
1475                                         iua_version = DRAFT;
1476                                         remaining_length = FALSE;
1477                                 }
1478                         }
1479                 }
1480                 /*0x02: AL Id (draft) following after common msg header without V5UA header*/
1481                 else if(tag==0x02){
1482                         iua_version = DRAFT;
1483                         remaining_length = FALSE;
1484                 }
1485                 /*0x03: Text formatted IId SHALL not be supported by draft*/
1486                 else if(tag==0x03){
1487                         iua_version = RFC;
1488                         remaining_length = FALSE;
1489                 }
1490                 else if(tag==0x11){
1491                         remaining_length = FALSE;
1492                 }
1493                 /*ASP, Notify and Error messages (RFC) only contain common msg header followed by parameter*/
1494                 else if(tag==0x04 || tag == 0x0a || tag == 0x0b || tag == 0x0c || tag == 0x0d){
1495                         remaining_length = FALSE;
1496                 }
1497                 else{
1498                         offset+=2;
1499                         remaining_length = tvb_length_remaining(tvb, offset);
1500                 }
1501                 /* add a notice for the draft version */
1502                 if(iua_version == DRAFT){
1503                         col_set_str(pinfo->cinfo, COL_PROTOCOL, "V5UA (draft)");
1504                 }
1505    }
1506
1507    /* dissect the message */
1508   dissect_v5ua_message(tvb, pinfo, tree, v5ua_tree);
1509 }
1510
1511
1512 /* Register the protocol with Wireshark */
1513
1514 /* this format is require because a script is used to build the C function
1515    that calls all the protocol registration. */
1516
1517 void
1518 proto_register_v5ua(void)
1519 {
1520
1521 /* Setup list of header fields  */
1522         static hf_register_info hf[] = {
1523                 { &hf_version,
1524                         { "Version",                "v5ua.version",
1525                            FT_UINT8,    BASE_DEC, VALS(v5ua_protocol_version_values),0x0,
1526                            NULL, HFILL } },
1527                 { &hf_reserved,
1528                         { "Reserved",               "v5ua.reserved",
1529                            FT_UINT8,    BASE_HEX, NULL,                             0x0,
1530                            NULL, HFILL } },
1531                 { &hf_msg_class,
1532                         { "Message class",          "v5ua.msg_class",
1533                            FT_UINT8,    BASE_DEC, VALS(msg_class_values),           0x0,
1534                            NULL, HFILL } },
1535                 { &hf_msg_type,
1536                         { "Message Type",           "v5ua.msg_type",
1537                            FT_UINT8,    BASE_DEC, NULL,                             0x0,
1538                            NULL, HFILL } },
1539                 { &hf_msg_type_id,
1540                         { "Message Type ID",        "v5ua.msg_type_id",
1541                            FT_UINT8,    BASE_DEC, VALS(msg_class_type_values),      0x0,
1542                            NULL, HFILL } },
1543                 { &hf_msg_length,
1544                         { "Message length",         "v5ua.msg_length",
1545                            FT_UINT32,   BASE_DEC, NULL,                             0x0,
1546                            NULL, HFILL } },
1547                 { &hf_link_id,
1548                         { "Link Identifier",        "v5ua.link_id",
1549                            FT_UINT32,   BASE_DEC, NULL,                           0xffffffe0,
1550                            NULL, HFILL } },
1551                 { &hf_chnl_id,
1552                         { "Channel Identifier",     "v5ua.channel_id",
1553                            FT_UINT8,    BASE_DEC, NULL,                            0x1f,
1554                            NULL, HFILL } },
1555
1556                 { &hf_adaptation_layer_id,
1557                         { "Adaptation Layer ID",    "v5ua.adaptation_layer_id",
1558                            FT_STRING,   BASE_NONE,NULL,                             0x0,
1559                            NULL, HFILL } },
1560                 { &hf_text_if_id,
1561                         { "Text interface identifier","v5ua.text_interface_id",
1562                            FT_STRING,   BASE_NONE,NULL,                             0x0,
1563                            NULL, HFILL } },
1564                 { &hf_scn_protocol_id,
1565                         { "SCN Protocol Identifier","v5ua.scn_protocol_id",
1566                            FT_STRING,   BASE_NONE,NULL,                             0x0,
1567                            NULL, HFILL } },
1568                 { &hf_info_string,
1569                         { "Info String",            "v5ua.info_string",
1570                            FT_STRING,   BASE_NONE,NULL,                             0x0,
1571                            NULL, HFILL } },
1572                 { &hf_asp_identifier,
1573                         { "ASP Identifier",          "v5ua.asp_identifier",
1574                            FT_UINT32,   BASE_HEX, NULL,                                                 0x0,
1575                            NULL, HFILL } },
1576                 { &hf_dlci_zero_bit,
1577                         { "Zero bit",               "v5ua.dlci_zero_bit",
1578                            FT_BOOLEAN,  8,        NULL,                             0x01,
1579                            NULL, HFILL } },
1580                 { &hf_dlci_spare_bit,
1581                         { "Spare bit",              "v5ua.dlci_spare_bit",
1582                            FT_BOOLEAN,  8,        NULL,                             0x02,
1583                            NULL, HFILL } },
1584                 { &hf_dlci_sapi,
1585                         { "SAPI",                   "v5ua.dlci_sapi",
1586                            FT_UINT8,    BASE_HEX, NULL,                             0xfc,
1587                            NULL, HFILL } },
1588                 { &hf_dlci_one_bit,
1589                         { "One bit",                "v5ua.dlci_one_bit",
1590                            FT_BOOLEAN,  8,        NULL,                             0x01,
1591                            NULL, HFILL } },
1592                 { &hf_dlci_tei,
1593                         { "TEI",                    "v5ua.dlci_tei",
1594                            FT_UINT8,    BASE_HEX, NULL,                             0xfe,
1595                            NULL, HFILL } },
1596                 { &hf_efa,
1597                         { "Envelope Function Address","v5ua.efa",
1598                            FT_UINT16,   BASE_DEC, VALS(efa_values),                 0x0,
1599                            NULL, HFILL } },
1600                 { &hf_spare_efa,
1601                         { "Envelope Function Address (spare)","v5ua.efa",
1602                            FT_UINT16,   BASE_DEC, NULL,                              ~7,
1603                            NULL, HFILL } },
1604                 { &hf_asp_reason,
1605                         { "Reason",                 "v5ua.asp_reason",
1606                            FT_UINT32,   BASE_HEX, VALS(asp_reason_values),          0x0,
1607                            NULL, HFILL } },
1608                 { &hf_release_reason,
1609                         { "Release Reason",         "v5ua.release_reason",
1610                            FT_UINT32,   BASE_HEX, VALS(release_reason_values),      0x0,
1611                            NULL, HFILL } },
1612                 { &hf_tei_status,
1613                         { "TEI status",             "v5ua.tei_status",
1614                            FT_UINT32,   BASE_HEX, VALS(tei_status_values),          0x0,
1615                            NULL, HFILL } },
1616                 { &hf_tei_draft_status,
1617                         { "TEI status",             "v5ua.tei_draft_status",
1618                            FT_UINT32,   BASE_HEX, VALS(tei_draft_status_values),    0x0,
1619                            NULL, HFILL } },
1620                 { &hf_link_status,
1621                         { "Link Status",            "v5ua.link_status",
1622                            FT_UINT32,   BASE_HEX, VALS(link_status_values),         0x0,
1623                            NULL, HFILL } },
1624                 { &hf_sa_bit_id,
1625                         { "BIT ID",                 "v5ua.sa_bit_id",
1626                            FT_UINT16,   BASE_HEX, VALS(sa_bit_values),              0x0,
1627                            NULL, HFILL } },
1628                 { &hf_sa_bit_value,
1629                         { "Bit Value",              "v5ua.sa_bit_value",
1630                            FT_UINT16,   BASE_HEX, VALS(sa_bit_values),              0x0,
1631                            NULL, HFILL } },
1632                 { &hf_parameter_tag,
1633                         { "Parameter Tag",          "v5ua.parameter_tag",
1634                            FT_UINT16,   BASE_HEX, VALS(parameter_tag_values),       0x0,
1635                            NULL, HFILL } },
1636                 { &hf_parameter_tag_draft,
1637                         { "Parameter Tag",          "v5ua.parameter_tag",
1638                            FT_UINT16,   BASE_HEX, VALS(parameter_tag_draft_values), 0x0,
1639                            NULL, HFILL } },
1640                 { &hf_parameter_length,
1641                         { "Parameter length",       "v5ua.parameter_length",
1642                            FT_UINT16,   BASE_DEC, NULL,                             0x0,
1643                            NULL, HFILL } },
1644                 { &hf_parameter_value,
1645                         { "Parameter value",        "v5ua.parameter_value",
1646                            FT_BYTES,    BASE_NONE,NULL,                             0x0,
1647                            NULL, HFILL } },
1648                 { &hf_parameter_padding,
1649                         { "Parameter padding",      "v5ua.parameter_padding",
1650                            FT_BYTES,    BASE_NONE,NULL,                             0x0,
1651                            NULL, HFILL } },
1652                 { &hf_diagnostic_info,
1653                         { "Diagnostic Information", "v5ua.diagnostic_info",
1654                            FT_BYTES,    BASE_NONE,NULL,                             0x0,
1655                            NULL, HFILL } },
1656                 { &hf_if_range_start,
1657                         { "Interface range Start",  "v5ua.interface_range_start",
1658                            FT_UINT32,   BASE_HEX, NULL,                             0x0,
1659                            NULL, HFILL } },
1660                 { &hf_if_range_end,
1661                         { "Interface range End",    "v5ua.interface_range_end",
1662                            FT_UINT32,   BASE_HEX, NULL,                             0x0,
1663                            NULL, HFILL } },
1664                 { &hf_heartbeat_data,
1665                         { "Heartbeat data",         "v5ua.heartbeat_data",
1666                            FT_BYTES,    BASE_NONE,NULL,                             0x0,
1667                            NULL, HFILL } },
1668                 { &hf_traffic_mode_type,
1669                         { "Traffic mode type",      "v5ua.traffic_mode_type",
1670                            FT_UINT32,   BASE_HEX, VALS(traffic_mode_type_values),   0x0,
1671                            NULL, HFILL } },
1672                 { &hf_error_code,
1673                         { "Error code",             "v5ua.error_code",
1674                            FT_UINT32,   BASE_HEX, VALS(error_code_values),          0x0,
1675                            NULL, HFILL } },
1676                 { &hf_draft_error_code,
1677                         { "Error code (draft)",     "v5ua.draft_error_code",
1678                            FT_UINT32,   BASE_HEX, VALS(draft_error_code_values),    0x0,
1679                            NULL, HFILL } },
1680                 { &hf_status_type,
1681                         { "Status type",            "v5ua.status_type",
1682                            FT_UINT16,   BASE_DEC, VALS(status_type_values),         0x0,
1683                            NULL, HFILL } },
1684                 { &hf_status_id,
1685                         { "Status identification",  "v5ua.status_id",
1686                            FT_UINT16,   BASE_DEC, NULL,                             0x0,
1687                            NULL, HFILL } },
1688                 { &hf_error_reason,
1689                         { "Error Reason",           "v5ua.error_reason",
1690                            FT_UINT32,   BASE_HEX, VALS(error_reason_values),        0x0,
1691                            NULL, HFILL } }
1692                 };
1693
1694 /* Setup protocol subtree array */
1695         static gint *ett[] = {
1696                 &ett_v5ua,
1697                 &ett_v5ua_common_header,
1698                 &ett_v5ua_parameter,
1699                 &ett_v5ua_layer3
1700         };
1701
1702 /* Register the protocol name and description */
1703         proto_v5ua = proto_register_protocol("V5.2-User Adaptation Layer", "V5UA", "v5ua");
1704
1705 /* Required function calls to register the header fields and subtrees used */
1706         proto_register_field_array(proto_v5ua, hf, array_length(hf));
1707         proto_register_subtree_array(ett, array_length(ett));
1708 }
1709
1710
1711 /* In RFC specification the SCTP registered User Port Number Assignment for V5UA is 5675 */
1712 #define SCTP_PORT_V5UA_RFC         5675
1713 #define SCTP_PORT_V5UA_DRAFT      10001
1714
1715 void
1716 proto_reg_handoff_v5ua(void)
1717 {
1718         dissector_handle_t v5ua_handle;
1719
1720         v5ua_handle = create_dissector_handle(dissect_v5ua, proto_v5ua);
1721         q931_handle = find_dissector("q931");
1722         v52_handle = find_dissector("v52");
1723
1724         dissector_add_uint("sctp.port", SCTP_PORT_V5UA_DRAFT, v5ua_handle);
1725         dissector_add_uint("sctp.port", SCTP_PORT_V5UA_RFC, v5ua_handle);
1726         dissector_add_uint("sctp.ppi",  V5UA_PAYLOAD_PROTOCOL_ID, v5ua_handle);
1727 }