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