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