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