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