2 * Routines for ALCAP (Q.2630.1) dissection
3 * AAL type 2 signalling protocol - Capability set 1
6 * Copyright 2003, Michael Lum <mlum [AT] telostech.com>
7 * In association with Telos Technology Inc.
9 * $Id: packet-alcap.c,v 1.5 2003/12/08 23:40:11 guy Exp $
11 * Ethereal - Network traffic analyzer
12 * By Gerald Combs <gerald@ethereal.com>
13 * Copyright 1998 Gerald Combs
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 #ifdef HAVE_SYS_TYPES_H
39 # include <sys/types.h>
42 #ifdef HAVE_NETINET_IN_H
43 # include <netinet/in.h>
48 #include "epan/packet.h"
51 #define ALCAP_MSG_HEADER_LEN 6
52 #define ALCAP_PARM_HEADER_LEN 3
56 #define EXTRANEOUS_DATA_CHECK(edc_len, edc_max_len) \
57 if ((edc_len) > (edc_max_len)) \
59 proto_tree_add_none_format(tree, hf_alcap_none, tvb, \
60 curr_offset, (edc_len) - (edc_max_len), "Extraneous Data"); \
63 #define SHORT_DATA_CHECK(sdc_len, sdc_min_len) \
64 if ((sdc_len) < (sdc_min_len)) \
66 proto_tree_add_none_format(tree, hf_alcap_none, tvb, \
67 curr_offset, (sdc_len), "Short Data (?)"); \
71 #define EXACT_DATA_CHECK(edc_len, edc_eq_len) \
72 if ((edc_len) != (edc_eq_len)) \
74 proto_tree_add_none_format(tree, hf_alcap_none, tvb, \
75 curr_offset, (edc_len), "Unexpected Data Length"); \
79 static const value_string msg_parm_strings[] = {
81 { 2, "Connection element identifier (CEID)" },
82 { 3, "Destination E.164 service endpoint address (ESEA)" },
83 { 4, "Destination NSAP service endpoint address (NSEA)" },
84 { 5, "Link characteristics (ALC)" },
85 { 6, "Originating signalling association identifier (OSAID)" },
86 { 7, "Served user generated reference (SUGR)" },
87 { 8, "Served user transport (SUT)" },
88 { 9, "Service specific information (audio) (SSIA)" },
89 { 10, "Service specific information (multirate) (SSIM)" },
90 { 11, "Service specific information (SAR-assured) (SSISA)" },
91 { 12, "Service specific information (SAR-unassured) (SSISU)" },
92 { 13, "Test connection identifier (TCI)" },
95 #define NUM_PARMS (sizeof(msg_parm_strings)/sizeof(value_string))
97 static char *alcap_proto_name = "AAL type 2 signalling protocol - Capability set 1 (Q.2630.1)";
98 static char *alcap_proto_name_short = "ALCAP";
100 /* Initialize the subtree pointers */
101 static gint ett_alcap = -1;
102 static gint ett_parm = -1;
104 /* Initialize the protocol and registered fields */
105 static int proto_alcap = -1;
106 static int hf_alcap_msg_type = -1;
107 static int hf_alcap_length = -1;
108 static int hf_alcap_parm_id = -1;
109 static int hf_alcap_none = -1;
110 static int hf_alcap_dsaid = -1;
111 static int hf_alcap_osaid = -1;
112 static int hf_alcap_aal2_path_id = -1;
113 static int hf_alcap_channel_id = -1;
114 static int hf_alcap_organizational_unique_id = -1;
115 static int hf_alcap_served_user_gen_ref = -1;
116 static int hf_alcap_nsap_address = -1;
118 static char bigbuf[1024];
119 static char bigbuf2[1024];
120 static dissector_handle_t data_handle;
121 static packet_info *g_pinfo;
122 static proto_tree *g_tree;
124 #define FIELD_COMPATIBILITY 0
125 #define FIELD_SIGNALLING_ASSOC_ID 1
126 #define FIELD_AAL2_PATH_ID 2
127 #define FIELD_CHANNEL_ID 3
128 #define FIELD_ORGANIZATIONAL_UNIQUE_ID 4
129 #define FIELD_AUDIO_SERVICE 5
130 #define FIELD_MULTIRATE_SERVICE 6
131 #define FIELD_SEG_REASSEMBLY_ASS 7
132 #define FIELD_SEG_REASSEMBLY_UNASS 8
133 #define FIELD_SERVED_USER_GEN_REF 9
134 #define FIELD_MAX_CPS_SDU_BIT_RATE 10
135 #define FIELD_AVG_CPS_SDU_BIT_RATE 11
136 #define FIELD_MAX_CPS_SDU_SIZE 12
137 #define FIELD_AVG_CPS_SDU_SIZE 13
138 #define FIELD_NATURE_OF_ADDRESS 14
139 #define FIELD_E164_ADDRESS 15
140 #define FIELD_NSAP_ADDRESS 16
141 #define FIELD_CAUSE_VALUE 17
142 #define FIELD_DIAGNOSTICS 18
143 #define FIELD_SERVED_USER_TRANSPORT 19
144 static const char * field_strings[] = {
146 "Signalling association identifier",
147 "AAL type 2 path identifier",
148 "Channel identifier (CID)",
149 "Organizational unique identifier (OUI)",
152 "Segmentation and reassembly (assured data transfer)",
153 "Segmentation and reassembly (unassured data transfer)",
154 "Served user generated reference",
155 "Maximum CPS-SDU bit rate",
156 "Average CPS-SDU bit rate",
157 "Maximum CPS-SDU size",
158 "Average CPS-SDU size",
164 "Served user transport"
166 #define NUM_FIELDS (sizeof(field_strings)/sizeof(char *))
167 static gint ett_fields[NUM_FIELDS];
169 static const value_string msg_type_strings[] = {
170 { 1, "Block confirm (BLC)" },
171 { 2, "Block request (BLO)" },
172 { 3, "Confusion (CFN)" },
173 { 4, "Establish confirm (ECF)" },
174 { 5, "Establish request (ERQ)" },
175 { 6, "Release confirm (RLC)" },
176 { 7, "Release request (REL)" },
177 { 8, "Reset confirm (RSC)" },
178 { 9, "Reset request (RES)" },
179 { 10, "Unblock confirm (UBC)" },
180 { 11, "Unblock request (UBL)" },
187 my_match_strval(guint32 val, const value_string *vs, gint *idx)
191 while (vs[i].strptr) {
192 if (vs[i].value == val)
195 return(vs[i].strptr);
206 * Ref. ITU-T Q.2630.1 (12/1999)
210 dis_field_compatibility(tvbuff_t *tvb, proto_tree *tree, guint32 *offset, gboolean message)
218 curr_offset = *offset;
221 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
222 curr_offset, 1, "%s %s",
223 message ? "Message" : "Parameter",
224 field_strings[FIELD_COMPATIBILITY]);
226 subtree = proto_item_add_subtree(item, ett_fields[FIELD_COMPATIBILITY]);
228 compat = tvb_get_guint8(tvb, curr_offset);
230 other_decode_bitfield_value(bigbuf, compat, 0x80, 8);
231 proto_tree_add_text(subtree, tvb,
236 other_decode_bitfield_value(bigbuf, compat, 0x40, 8);
237 proto_tree_add_text(subtree, tvb,
239 "%s : Pass-on not possible - %s",
241 (compat & 0x40) ? "Send notification" : "Do not send notification");
243 switch ((compat & 0x30) >> 4)
246 str = "Pass on message or parameter (Release connection)";
252 str = "Discard parameter (Discard message)";
256 str = "Discard parameter";
261 str = "Discard message";
265 str = "Release connection";
269 other_decode_bitfield_value(bigbuf, compat, 0x30, 8);
270 proto_tree_add_text(subtree, tvb,
272 "%s : Pass-on not possible, instruction - %s",
276 other_decode_bitfield_value(bigbuf, compat, 0x08, 8);
277 proto_tree_add_text(subtree, tvb,
282 other_decode_bitfield_value(bigbuf, compat, 0x04, 8);
283 proto_tree_add_text(subtree, tvb,
285 "%s : General action - %s",
287 (compat & 0x04) ? "Send notification" : "Do not send notification");
289 switch (compat & 0x03)
292 str = "Pass on message or parameter";
298 str = "Discard parameter (Discard message)";
302 str = "Discard parameter";
307 str = "Discard message";
311 str = "Release connection";
315 other_decode_bitfield_value(bigbuf, compat, 0x03, 8);
316 proto_tree_add_text(subtree, tvb,
318 "%s : General action, instruction - %s",
326 * Ref. ITU-T Q.2630.1 (12/1999)
330 dis_field_signalling_assoc_id(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset, gboolean destination)
335 curr_offset = *offset;
337 #define FIELD_SIGNALLING_ASSOC_ID_LEN 4
339 SHORT_DATA_CHECK(*len, FIELD_SIGNALLING_ASSOC_ID_LEN);
341 value = tvb_get_ntohl(tvb, curr_offset);
345 proto_tree_add_uint_format(tree, hf_alcap_dsaid, tvb,
346 curr_offset, FIELD_SIGNALLING_ASSOC_ID_LEN, value,
347 "Destination signalling association identifier: %d%s",
349 value ? "" : " (unknown)");
353 proto_tree_add_uint(tree, hf_alcap_osaid, tvb,
354 curr_offset, FIELD_SIGNALLING_ASSOC_ID_LEN, value);
357 curr_offset += FIELD_SIGNALLING_ASSOC_ID_LEN;
359 *len -= (curr_offset - *offset);
360 *offset = curr_offset;
364 * Ref. ITU-T Q.2630.1 (12/1999)
368 dis_field_aal2_path_id(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
373 curr_offset = *offset;
375 #define FIELD_AAL2_PATH_ID_LEN 4
377 SHORT_DATA_CHECK(*len, FIELD_AAL2_PATH_ID_LEN);
379 value = tvb_get_ntohl(tvb, curr_offset);
381 proto_tree_add_uint_format(tree, hf_alcap_aal2_path_id, tvb,
382 curr_offset, FIELD_AAL2_PATH_ID_LEN, value,
383 "AAL2 path identifier: %d%s",
385 value ? "" : " (Null)");
387 curr_offset += FIELD_AAL2_PATH_ID_LEN;
389 *len -= (curr_offset - *offset);
390 *offset = curr_offset;
394 * Ref. ITU-T Q.2630.1 (12/1999)
398 dis_field_channel_id(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
403 curr_offset = *offset;
405 SHORT_DATA_CHECK(*len, 1);
407 oct = tvb_get_guint8(tvb, curr_offset);
409 proto_tree_add_uint_format(tree, hf_alcap_channel_id, tvb,
411 "Channel identifier (CID): %d%s",
413 oct ? "" : " (Null)");
417 *len -= (curr_offset - *offset);
418 *offset = curr_offset;
422 * Ref. ITU-T Q.2630.1 (12/1999)
426 dis_field_organizational_unique_id(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
431 curr_offset = *offset;
433 #define FIELD_ORGANIZATIONAL_UNIQUE_ID_LEN 3
435 SHORT_DATA_CHECK(*len, FIELD_ORGANIZATIONAL_UNIQUE_ID_LEN);
437 octs = tvb_get_ntoh24(tvb, curr_offset);
439 proto_tree_add_uint(tree, hf_alcap_organizational_unique_id, tvb,
440 curr_offset, FIELD_ORGANIZATIONAL_UNIQUE_ID_LEN, octs);
442 curr_offset += FIELD_ORGANIZATIONAL_UNIQUE_ID_LEN;
444 *len -= (curr_offset - *offset);
445 *offset = curr_offset;
449 * Ref. ITU-T Q.2630.1 (12/1999)
453 dis_field_audio_service(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
462 curr_offset = *offset;
464 #define FIELD_AUDIO_SERVICE_LEN 5
466 SHORT_DATA_CHECK(*len, FIELD_AUDIO_SERVICE_LEN);
469 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
470 curr_offset, FIELD_AUDIO_SERVICE_LEN, field_strings[FIELD_AUDIO_SERVICE]);
472 subtree = proto_item_add_subtree(item, ett_fields[FIELD_AUDIO_SERVICE]);
474 oct = tvb_get_guint8(tvb, curr_offset);
476 switch ((oct & 0xc0) >> 6)
478 case 0x00: str = "Designates a profile specified by ITU-T Rec. I.366.2; ignore organizational unique identifier"; break;
479 case 0x01: str = "Designates a profile specified by organizational unique identifier"; break;
480 case 0x02: str = "Designates a custom profile; ignore organizational unique identifier"; break;
481 case 0x03: str = "Reserved"; break;
484 other_decode_bitfield_value(bigbuf, oct, 0xc0, 8);
485 proto_tree_add_text(subtree, tvb,
487 "%s : Profile type, %s",
490 other_decode_bitfield_value(bigbuf, oct, 0x3f, 8);
491 proto_tree_add_text(subtree, tvb,
498 oct = tvb_get_guint8(tvb, curr_offset);
500 proto_tree_add_text(subtree, tvb,
502 "Profile identifier (%d)",
507 oct = tvb_get_guint8(tvb, curr_offset);
509 other_decode_bitfield_value(bigbuf, oct, 0x80, 8);
510 proto_tree_add_text(subtree, tvb,
512 "%s : FRM, transport of frame mode data %s",
514 (oct & 0x80) ? "enabled" : "disabled");
516 other_decode_bitfield_value(bigbuf, oct, 0x40, 8);
517 proto_tree_add_text(subtree, tvb,
519 "%s : CMD, transport of circuit mode data (64 kbit/s) %s",
521 (oct & 0x40) ? "enabled" : "disabled");
523 other_decode_bitfield_value(bigbuf, oct, 0x20, 8);
524 proto_tree_add_text(subtree, tvb,
526 "%s : MF-R2, transport of multi-frequency R2 dialled digits %s",
528 (oct & 0x20) ? "enabled" : "disabled");
530 other_decode_bitfield_value(bigbuf, oct, 0x10, 8);
531 proto_tree_add_text(subtree, tvb,
533 "%s : MF-R1, transport of multi-frequency R1 dialled digits %s",
535 (oct & 0x10) ? "enabled" : "disabled");
537 other_decode_bitfield_value(bigbuf, oct, 0x08, 8);
538 proto_tree_add_text(subtree, tvb,
540 "%s : DTMF, transport of dual tone multi-frequency dialled digits %s",
542 (oct & 0x08) ? "enabled" : "disabled");
544 other_decode_bitfield_value(bigbuf, oct, 0x04, 8);
545 proto_tree_add_text(subtree, tvb,
547 "%s : CAS, transport of channel associated signalling %s",
549 (oct & 0x04) ? "enabled" : "disabled");
551 other_decode_bitfield_value(bigbuf, oct, 0x02, 8);
552 proto_tree_add_text(subtree, tvb,
554 "%s : FAX, transport of demodulated facsimile data %s",
556 (oct & 0x02) ? "enabled" : "disabled");
558 other_decode_bitfield_value(bigbuf, oct, 0x01, 8);
559 proto_tree_add_text(subtree, tvb,
561 "%s : A/mu-law, interpretation of generic PCM coding: %s-law",
563 (oct & 0x01) ? "mu" : "A");
567 value = tvb_get_ntohs(tvb, curr_offset);
569 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
571 "Maximum length of frame mode data (%d)",
576 *len -= (curr_offset - *offset);
577 *offset = curr_offset;
581 * Ref. ITU-T Q.2630.1 (12/1999)
585 dis_field_multirate_service(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
593 curr_offset = *offset;
595 #define FIELD_MULTIRATE_SERVICE_LEN 3
597 SHORT_DATA_CHECK(*len, FIELD_MULTIRATE_SERVICE_LEN);
600 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
601 curr_offset, FIELD_MULTIRATE_SERVICE_LEN, field_strings[FIELD_MULTIRATE_SERVICE]);
603 subtree = proto_item_add_subtree(item, ett_fields[FIELD_MULTIRATE_SERVICE]);
605 oct = tvb_get_guint8(tvb, curr_offset);
607 other_decode_bitfield_value(bigbuf, oct, 0x80, 8);
608 proto_tree_add_text(subtree, tvb,
610 "%s : FRM, transport of frame mode data %s",
612 (oct & 0x80) ? "enabled" : "disabled");
614 other_decode_bitfield_value(bigbuf, oct, 0x60, 8);
615 proto_tree_add_text(subtree, tvb,
620 other_decode_bitfield_value(bigbuf, oct, 0x1f, 8);
621 proto_tree_add_text(subtree, tvb,
623 "%s : Multiplier (%d) for n x 64 kbit/s",
629 value = tvb_get_ntohs(tvb, curr_offset);
631 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
633 "Maximum length of frame mode data (%d)",
638 *len -= (curr_offset - *offset);
639 *offset = curr_offset;
643 * Ref. ITU-T Q.2630.1 (12/1999)
647 dis_field_seg_reassembly_ass(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
654 curr_offset = *offset;
656 #define FIELD_SEG_REASSEMBLY_ASS_LEN 14
658 SHORT_DATA_CHECK(*len, FIELD_SEG_REASSEMBLY_ASS_LEN);
661 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
662 curr_offset, FIELD_SEG_REASSEMBLY_ASS_LEN, field_strings[FIELD_SEG_REASSEMBLY_ASS]);
664 subtree = proto_item_add_subtree(item, ett_fields[FIELD_SEG_REASSEMBLY_ASS]);
666 value = tvb_get_ntoh24(tvb, curr_offset);
668 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
670 "Maximum length of SSSAR-SDU in the forward direction (%d)",
675 value = tvb_get_ntoh24(tvb, curr_offset);
677 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
679 "Maximum length of SSSAR-SDU in the backward direction (%d)",
684 value = tvb_get_ntohs(tvb, curr_offset);
686 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
688 "Maximum length of SSCOP-SDU in the forward direction (%d)",
693 value = tvb_get_ntohs(tvb, curr_offset);
695 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
697 "Maximum length of SSCOP-SDU in the backward direction (%d)",
702 value = tvb_get_ntohs(tvb, curr_offset);
704 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
706 "Maximum length of SSCOP-UU in the forward direction (%d)",
711 value = tvb_get_ntohs(tvb, curr_offset);
713 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
715 "Maximum length of SSCOP-UU in the backward direction (%d)",
720 *len -= (curr_offset - *offset);
721 *offset = curr_offset;
725 * Ref. ITU-T Q.2630.1 (12/1999)
729 dis_field_seg_reassembly_unass(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
737 curr_offset = *offset;
739 #define FIELD_SEG_REASSEMBLY_UNASS_LEN 7
741 SHORT_DATA_CHECK(*len, FIELD_SEG_REASSEMBLY_UNASS_LEN);
744 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
745 curr_offset, FIELD_SEG_REASSEMBLY_UNASS_LEN, field_strings[FIELD_SEG_REASSEMBLY_UNASS]);
747 subtree = proto_item_add_subtree(item, ett_fields[FIELD_SEG_REASSEMBLY_UNASS]);
749 value = tvb_get_ntoh24(tvb, curr_offset);
751 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
753 "Maximum length of SSSAR-SDU in the forward direction (%d)",
758 value = tvb_get_ntoh24(tvb, curr_offset);
760 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
762 "Maximum length of SSSAR-SDU in the backward direction (%d)",
767 oct = tvb_get_guint8(tvb, curr_offset);
769 other_decode_bitfield_value(bigbuf, oct, 0x80, 8);
770 proto_tree_add_text(subtree, tvb,
772 "%s : TED, transmission error detection %s",
774 oct & 0x80 ? "enabled" : "disabled");
776 other_decode_bitfield_value(bigbuf, oct, 0x7f, 8);
777 proto_tree_add_text(subtree, tvb,
784 *len -= (curr_offset - *offset);
785 *offset = curr_offset;
789 * Ref. ITU-T Q.2630.1 (12/1999)
793 dis_field_served_user_gen_ref(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
798 curr_offset = *offset;
800 #define FIELD_SERVED_USER_GEN_REF_LEN 4
802 SHORT_DATA_CHECK(*len, FIELD_SERVED_USER_GEN_REF_LEN);
804 value = tvb_get_ntohl(tvb, curr_offset);
806 proto_tree_add_uint(tree, hf_alcap_served_user_gen_ref, tvb,
807 curr_offset, FIELD_SERVED_USER_GEN_REF_LEN, value);
809 curr_offset += FIELD_SERVED_USER_GEN_REF_LEN;
811 *len -= (curr_offset - *offset);
812 *offset = curr_offset;
816 * Ref. ITU-T Q.2630.1 (12/1999)
820 dis_field_cps_sdu_bit_rate(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset, gboolean maximum)
827 curr_offset = *offset;
829 #define FIELD_CPS_SDU_BIT_RATE_LEN 4
831 SHORT_DATA_CHECK(*len, FIELD_CPS_SDU_BIT_RATE_LEN);
834 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
835 curr_offset, FIELD_CPS_SDU_BIT_RATE_LEN, field_strings[FIELD_MAX_CPS_SDU_BIT_RATE + (maximum ? 0 : 1)]);
837 subtree = proto_item_add_subtree(item, ett_fields[FIELD_MAX_CPS_SDU_BIT_RATE + (maximum ? 0 : 1)]);
839 value = tvb_get_ntohs(tvb, curr_offset);
841 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
843 "CPS-SDU bit rate in the forward direction (%d)",
848 value = tvb_get_ntohs(tvb, curr_offset);
850 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
852 "CPS-SDU bit rate in the backward direction (%d)",
857 *len -= (curr_offset - *offset);
858 *offset = curr_offset;
862 * Ref. ITU-T Q.2630.1 (12/1999)
866 dis_field_cps_sdu_size(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset, gboolean maximum)
873 curr_offset = *offset;
875 #define FIELD_CPS_SDU_SIZE_LEN 2
877 SHORT_DATA_CHECK(*len, FIELD_CPS_SDU_SIZE_LEN);
880 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
881 curr_offset, FIELD_CPS_SDU_SIZE_LEN, field_strings[FIELD_MAX_CPS_SDU_SIZE + (maximum ? 0 : 1)]);
883 subtree = proto_item_add_subtree(item, ett_fields[FIELD_MAX_CPS_SDU_SIZE + (maximum ? 0 : 1)]);
885 oct = tvb_get_guint8(tvb, curr_offset);
887 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
889 "CPS-SDU size in the forward direction (%d)",
894 oct = tvb_get_guint8(tvb, curr_offset);
896 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
898 "CPS-SDU size in the backward direction (%d)",
903 *len -= (curr_offset - *offset);
904 *offset = curr_offset;
908 * Ref. ITU-T Q.2630.1 (12/1999)
912 dis_field_nature_of_address(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
921 curr_offset = *offset;
923 #define FIELD_NATURE_OF_ADDRESS_LEN 1
925 SHORT_DATA_CHECK(*len, FIELD_NATURE_OF_ADDRESS_LEN);
928 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
929 curr_offset, FIELD_NATURE_OF_ADDRESS_LEN, field_strings[FIELD_NATURE_OF_ADDRESS]);
931 subtree = proto_item_add_subtree(item, ett_fields[FIELD_NATURE_OF_ADDRESS]);
933 oct = tvb_get_guint8(tvb, curr_offset);
935 other_decode_bitfield_value(bigbuf, oct, 0x80, 8);
936 proto_tree_add_text(subtree, tvb,
945 case 0x00: str = "spare"; break;
946 case 0x01: str = "subscriber number (national use)"; break;
947 case 0x02: str = "unknown (national use)"; break;
948 case 0x03: str = "national (significant) number"; break;
949 case 0x04: str = "international number"; break;
950 case 0x05: str = "network-specific number (national use)"; break;
952 if ((value >= 0x06) && (value <= 0x6f)) { str = "spare"; break; }
953 else if ((value >= 0x70) && (value <= 0xfe)) { str = "reserved for national use"; break; }
954 else { str = "not given in spec. ???"; break; }
957 other_decode_bitfield_value(bigbuf, oct, 0x7f, 8);
958 proto_tree_add_text(subtree, tvb,
960 "%s : Nature of address code, %s (%d)",
967 *len -= (curr_offset - *offset);
968 *offset = curr_offset;
972 * Ref. ITU-T Q.2630.1 (12/1999)
976 dis_field_e164_address(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
985 curr_offset = *offset;
987 SHORT_DATA_CHECK(*len, 1);
990 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
991 curr_offset, -1, field_strings[FIELD_E164_ADDRESS]);
993 subtree = proto_item_add_subtree(item, ett_fields[FIELD_E164_ADDRESS]);
995 parm_len = tvb_get_guint8(tvb, curr_offset);
997 proto_item_set_len(item, parm_len + 1);
999 proto_tree_add_uint(subtree, hf_alcap_length, tvb, curr_offset, 1, parm_len);
1006 while (i < parm_len)
1008 oct = tvb_get_guint8(tvb, curr_offset);
1010 other_decode_bitfield_value(bigbuf, oct, 0xf0, 8);
1011 proto_tree_add_text(subtree, tvb,
1016 bigbuf2[i] = (oct & 0x0f) + 0x30;
1018 other_decode_bitfield_value(bigbuf, oct, 0x0f, 8);
1019 proto_tree_add_text(subtree, tvb,
1021 "%s : Digit %d of address (%d)",
1032 proto_item_append_text(item, " (%s)", bigbuf2);
1035 *len -= (curr_offset - *offset);
1036 *offset = curr_offset;
1040 * Ref. ITU-T Q.2630.1 (12/1999)
1044 dis_field_nsap_address(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
1046 guint32 curr_offset;
1048 curr_offset = *offset;
1050 #define FIELD_NSAP_ADDRESS_LEN 20
1052 SHORT_DATA_CHECK(*len, FIELD_NSAP_ADDRESS_LEN);
1054 proto_tree_add_item(tree, hf_alcap_nsap_address, tvb,
1055 curr_offset, FIELD_NSAP_ADDRESS_LEN, FALSE);
1057 curr_offset += FIELD_NSAP_ADDRESS_LEN;
1059 *len -= (curr_offset - *offset);
1060 *offset = curr_offset;
1064 * Ref. ITU-T Q.2630.1 (12/1999)
1068 dis_field_cause_value(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset, gboolean *compat)
1070 guint32 curr_offset;
1073 proto_tree *subtree;
1077 curr_offset = *offset;
1079 #define FIELD_CAUSE_VALUE_LEN 2
1081 SHORT_DATA_CHECK(*len, FIELD_CAUSE_VALUE_LEN);
1084 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
1085 curr_offset, FIELD_CAUSE_VALUE_LEN, field_strings[FIELD_CAUSE_VALUE]);
1087 subtree = proto_item_add_subtree(item, ett_fields[FIELD_CAUSE_VALUE]);
1089 oct = tvb_get_guint8(tvb, curr_offset);
1091 other_decode_bitfield_value(bigbuf, oct, 0xfc, 8);
1092 proto_tree_add_text(subtree, tvb,
1099 case 0x00: str = "ITU-T standardized coding as described in ITU-T Rec. Q.850 and Q.2610"; break;
1100 case 0x01: str = "ISO/IEC standard"; break;
1101 case 0x02: str = "national standard"; break;
1102 case 0x03: str = "standard defined for the network (either public or private) present on the network side of the interface"; break;
1105 other_decode_bitfield_value(bigbuf, oct, 0x03, 8);
1106 proto_tree_add_text(subtree, tvb,
1108 "%s : Coding standard, %s",
1114 oct = tvb_get_guint8(tvb, curr_offset);
1116 other_decode_bitfield_value(bigbuf, oct, 0x80, 8);
1117 proto_tree_add_text(subtree, tvb,
1124 case 1: str = "Unallocated (unassigned) number"; break;
1125 case 3: str = "No route to destination"; break;
1126 case 31: str = "Normal, unspecified"; break;
1127 case 34: str = "No circuit/channel available"; break;
1128 case 38: str = "Network out of order"; break;
1129 case 41: str = "Temporary failure"; break;
1130 case 42: str = "Switching equipment congestion"; break;
1131 case 44: str = "Requested circuit/channel not available"; break;
1132 case 47: str = "Resource unavailable, unspecified"; break;
1133 case 93: str = "AAL parameters cannot be supported"; break;
1134 case 95: str = "Invalid message, unspecified"; break;
1135 case 96: str = "Mandatory information element is missing"; break;
1136 case 97: str = "Message type non-existent or not implemented"; *compat = TRUE; break;
1137 case 99: str = "Information element/parameter non-existent or not implemented"; *compat = TRUE; break;
1138 case 100: str = "Invalid information element contents"; break;
1139 case 102: str = "Recovery on timer expiry"; break;
1140 case 110: str = "Message with unrecognized parameter, discarded"; *compat = TRUE; break;
1141 default: str = "Unknown"; break;
1144 other_decode_bitfield_value(bigbuf, oct, 0x7f, 8);
1145 proto_tree_add_text(subtree, tvb,
1147 "%s : Cause (%d), %s",
1154 *len -= (curr_offset - *offset);
1155 *offset = curr_offset;
1159 * Ref. ITU-T Q.2630.1 (12/1999)
1163 dis_field_diagnostics(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset, gboolean compat)
1165 guint32 curr_offset;
1168 proto_tree *subtree;
1174 curr_offset = *offset;
1176 SHORT_DATA_CHECK(*len, 1);
1179 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
1180 curr_offset, -1, field_strings[FIELD_DIAGNOSTICS]);
1182 subtree = proto_item_add_subtree(item, ett_fields[FIELD_DIAGNOSTICS]);
1184 parm_len = tvb_get_guint8(tvb, curr_offset);
1186 proto_item_set_len(item, parm_len + 1);
1188 proto_tree_add_uint(subtree, hf_alcap_length, tvb, curr_offset, 1, parm_len);
1197 * compatibility diagnostics
1199 oct = tvb_get_guint8(tvb, curr_offset);
1201 str = my_match_strval(oct, msg_type_strings, &idx);
1203 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1204 curr_offset, 1, (str == NULL) ? "Unknown message identifier" : str);
1209 while ((i+2) <= parm_len)
1211 oct = tvb_get_guint8(tvb, curr_offset);
1213 str = my_match_strval(oct, msg_parm_strings, &idx);
1215 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1216 curr_offset, 1, (str == NULL) ? "Unknown parameter" : str);
1220 oct = tvb_get_guint8(tvb, curr_offset);
1224 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1225 curr_offset, 1, "Whole parameter");
1229 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1230 curr_offset, 1, "Field number %d", oct);
1239 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1240 curr_offset, parm_len - i, "Extraneous Data ???");
1242 curr_offset += (parm_len - i);
1247 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1248 curr_offset, parm_len, "Coded as per ITU-T Rec. Q.2610");
1250 curr_offset += parm_len;
1254 *len -= (curr_offset - *offset);
1255 *offset = curr_offset;
1259 * Ref. ITU-T Q.2630.1 (12/1999)
1263 dis_field_served_user_transport(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
1265 guint32 curr_offset;
1267 proto_tree *subtree;
1270 curr_offset = *offset;
1272 SHORT_DATA_CHECK(*len, 1);
1275 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
1276 curr_offset, -1, field_strings[FIELD_SERVED_USER_TRANSPORT]);
1278 subtree = proto_item_add_subtree(item, ett_fields[FIELD_SERVED_USER_TRANSPORT]);
1280 parm_len = tvb_get_guint8(tvb, curr_offset);
1282 proto_item_set_len(item, parm_len + 1);
1284 proto_tree_add_uint(subtree, hf_alcap_length, tvb, curr_offset, 1, parm_len);
1290 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1291 curr_offset, parm_len, "Value");
1293 curr_offset += parm_len;
1296 *len -= (curr_offset - *offset);
1297 *offset = curr_offset;
1301 * Ref. ITU-T Q.2630.1 (12/1999)
1305 dis_parm_cause(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1309 dis_field_cause_value(tvb, tree, &len, &curr_offset, &compat);
1311 dis_field_diagnostics(tvb, tree, &len, &curr_offset, compat);
1313 EXTRANEOUS_DATA_CHECK(len, 0);
1317 * Ref. ITU-T Q.2630.1 (12/1999)
1321 dis_parm_conn_element_id(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1324 dis_field_aal2_path_id(tvb, tree, &len, &curr_offset);
1326 dis_field_channel_id(tvb, tree, &len, &curr_offset);
1328 EXTRANEOUS_DATA_CHECK(len, 0);
1332 * Ref. ITU-T Q.2630.1 (12/1999)
1336 dis_parm_dest_e164_sea(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1339 dis_field_nature_of_address(tvb, tree, &len, &curr_offset);
1341 dis_field_e164_address(tvb, tree, &len, &curr_offset);
1343 EXTRANEOUS_DATA_CHECK(len, 0);
1347 * Ref. ITU-T Q.2630.1 (12/1999)
1351 dis_parm_dest_nsap_sea(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1354 dis_field_nsap_address(tvb, tree, &len, &curr_offset);
1356 EXTRANEOUS_DATA_CHECK(len, 0);
1360 * Ref. ITU-T Q.2630.1 (12/1999)
1364 dis_parm_link_characteristics(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1367 dis_field_cps_sdu_bit_rate(tvb, tree, &len, &curr_offset, TRUE);
1369 dis_field_cps_sdu_bit_rate(tvb, tree, &len, &curr_offset, FALSE);
1371 dis_field_cps_sdu_size(tvb, tree, &len, &curr_offset, TRUE);
1373 dis_field_cps_sdu_size(tvb, tree, &len, &curr_offset, FALSE);
1375 EXTRANEOUS_DATA_CHECK(len, 0);
1379 * Ref. ITU-T Q.2630.1 (12/1999)
1383 dis_parm_osai(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1386 dis_field_signalling_assoc_id(tvb, tree, &len, &curr_offset, FALSE);
1388 EXTRANEOUS_DATA_CHECK(len, 0);
1392 * Ref. ITU-T Q.2630.1 (12/1999)
1396 dis_parm_served_user_gen_ref(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1399 dis_field_served_user_gen_ref(tvb, tree, &len, &curr_offset);
1401 EXTRANEOUS_DATA_CHECK(len, 0);
1405 * Ref. ITU-T Q.2630.1 (12/1999)
1409 dis_parm_served_user_transport(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1412 dis_field_served_user_transport(tvb, tree, &len, &curr_offset);
1414 EXTRANEOUS_DATA_CHECK(len, 0);
1418 * Ref. ITU-T Q.2630.1 (12/1999)
1422 dis_parm_service_specific_info_audio(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1425 dis_field_audio_service(tvb, tree, &len, &curr_offset);
1427 dis_field_organizational_unique_id(tvb, tree, &len, &curr_offset);
1429 EXTRANEOUS_DATA_CHECK(len, 0);
1433 * Ref. ITU-T Q.2630.1 (12/1999)
1437 dis_parm_service_specific_info_multirate(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1440 dis_field_multirate_service(tvb, tree, &len, &curr_offset);
1442 EXTRANEOUS_DATA_CHECK(len, 0);
1446 * Ref. ITU-T Q.2630.1 (12/1999)
1450 dis_parm_service_specific_info_ass(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1453 dis_field_seg_reassembly_ass(tvb, tree, &len, &curr_offset);
1455 EXTRANEOUS_DATA_CHECK(len, 0);
1459 * Ref. ITU-T Q.2630.1 (12/1999)
1463 dis_parm_service_specific_info_unass(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1466 dis_field_seg_reassembly_unass(tvb, tree, &len, &curr_offset);
1468 EXTRANEOUS_DATA_CHECK(len, 0);
1471 static gint ett_parms[NUM_PARMS];
1472 static void (*alcap_parm_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) = {
1473 dis_parm_cause, /* Cause */
1474 dis_parm_conn_element_id, /* Connection element identifier */
1475 dis_parm_dest_e164_sea, /* Destination E.164 service endpoint address */
1476 dis_parm_dest_nsap_sea, /* Destination NSAP service endpoint address */
1477 dis_parm_link_characteristics, /* Link characteristics */
1478 dis_parm_osai, /* Originating signalling association identifier */
1479 dis_parm_served_user_gen_ref, /* Served user generated reference */
1480 dis_parm_served_user_transport, /* Served user transport */
1481 dis_parm_service_specific_info_audio, /* Service specific information (audio) */
1482 dis_parm_service_specific_info_multirate, /* Service specific information (multirate) */
1483 dis_parm_service_specific_info_ass, /* Service specific information (SAR-assured) */
1484 dis_parm_service_specific_info_unass, /* Service specific information (SAR-unassured) */
1485 NULL /* no parms */, /* Test connection identifier */
1489 /* GENERIC ALCAP DISSECTOR FUNCTIONS */
1492 dissect_alcap_parms(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 len)
1494 void (*parm_fcn)(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) = NULL;
1497 guint32 curr_offset, saved_offset;
1501 proto_tree *subtree;
1505 curr_offset = offset;
1507 while (len >= ALCAP_PARM_HEADER_LEN)
1509 saved_offset = curr_offset;
1511 parm = tvb_get_guint8(tvb, curr_offset);
1513 str = my_match_strval(parm, msg_parm_strings, &idx);
1517 ett_parm_idx = ett_parm;
1522 ett_parm_idx = ett_parms[idx];
1523 parm_fcn = alcap_parm_fcn[idx];
1527 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
1528 curr_offset, -1, (str == NULL) ? "Unknown parameter" : str);
1530 subtree = proto_item_add_subtree(item, ett_parm_idx);
1532 proto_tree_add_uint(subtree, hf_alcap_parm_id, tvb,
1533 curr_offset, 1, parm);
1537 dis_field_compatibility(tvb, subtree, &curr_offset, FALSE);
1539 parm_len = tvb_get_guint8(tvb, curr_offset);
1541 proto_tree_add_uint(subtree, hf_alcap_length, tvb, curr_offset, 1, parm_len);
1545 proto_item_set_len(item, (curr_offset - saved_offset) + parm_len);
1549 if (parm_fcn == NULL)
1551 proto_tree_add_none_format(subtree, hf_alcap_none,
1552 tvb, curr_offset, parm_len, "Parameter data");
1556 (*parm_fcn)(tvb, subtree, parm_len, curr_offset);
1560 len -= (ALCAP_PARM_HEADER_LEN + parm_len);
1561 curr_offset += parm_len;
1564 EXTRANEOUS_DATA_CHECK(len, 0);
1568 dissect_alcap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *alcap_tree)
1579 len = tvb_length(tvb);
1582 if (len < ALCAP_MSG_HEADER_LEN)
1584 proto_tree_add_none_format(alcap_tree, hf_alcap_none, tvb,
1585 offset, len, "Message header too short");
1590 dis_field_signalling_assoc_id(tvb, alcap_tree, &temp_len, &offset, TRUE);
1592 msg_type = tvb_get_guint8(tvb, offset);
1594 str = my_match_strval(msg_type, msg_type_strings, &idx);
1598 proto_tree_add_none_format(alcap_tree, hf_alcap_none, tvb,
1599 offset, 1, "Unknown message identifier");
1604 if (check_col(pinfo->cinfo, COL_INFO))
1606 col_set_str(pinfo->cinfo, COL_INFO, str);
1609 proto_tree_add_uint(alcap_tree, hf_alcap_msg_type, tvb,
1610 offset, 1, msg_type);
1614 dis_field_compatibility(tvb, alcap_tree, &offset, TRUE);
1616 if (len > ALCAP_MSG_HEADER_LEN)
1618 dissect_alcap_parms(tvb, alcap_tree, offset, len - ALCAP_MSG_HEADER_LEN);
1623 dissect_alcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1625 proto_item *alcap_item;
1626 proto_tree *alcap_tree = NULL;
1631 * Don't change the Protocol column on summary display
1633 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1635 col_set_str(pinfo->cinfo, COL_PROTOCOL, alcap_proto_name_short);
1638 /* In the interest of speed, if "tree" is NULL, don't do any work not
1639 * necessary to generate protocol tree items.
1646 * create the ALCAP protocol tree
1649 proto_tree_add_protocol_format(tree, proto_alcap, tvb, 0, -1,
1653 proto_item_add_subtree(alcap_item, ett_alcap);
1655 dissect_alcap_message(tvb, pinfo, alcap_tree);
1660 /* Register the protocol with Ethereal */
1662 proto_register_alcap(void)
1666 /* Setup list of header fields */
1667 static hf_register_info hf[] =
1669 { &hf_alcap_msg_type,
1672 FT_UINT8, BASE_DEC, VALS(msg_type_strings), 0,
1675 { "Destination signalling association identifier",
1677 FT_UINT32, BASE_DEC, NULL, 0,
1681 { "Originating signalling association identifier",
1683 FT_UINT32, BASE_DEC, NULL, 0,
1686 { &hf_alcap_aal2_path_id,
1687 { "AAL2 path identifier",
1688 "alcap.aal2_path_id",
1689 FT_UINT32, BASE_DEC, NULL, 0,
1692 { &hf_alcap_channel_id,
1693 { "Channel identifier (CID)",
1695 FT_UINT32, BASE_DEC, NULL, 0,
1698 { &hf_alcap_organizational_unique_id,
1699 { "Organizational unique identifier (OUI)",
1700 "alcap.organizational_unique_id",
1701 FT_UINT24, BASE_DEC, NULL, 0,
1704 { &hf_alcap_served_user_gen_ref,
1705 { "Served user generated reference",
1706 "alcap.served_user_gen_ref",
1707 FT_UINT32, BASE_DEC, NULL, 0,
1710 { &hf_alcap_nsap_address,
1712 "alcap.nsap_address",
1713 FT_BYTES, BASE_NONE, NULL, 0,
1716 { &hf_alcap_parm_id,
1717 { "Parameter identifier",
1719 FT_UINT8, BASE_DEC, NULL, 0,
1722 { "Length", "alcap.len",
1723 FT_UINT8, BASE_DEC, NULL, 0,
1727 { "Subtree", "alcap.none",
1733 /* Setup protocol subtree array */
1734 #define NUM_INDIVIDUAL_PARMS 2
1735 static gint *ett[NUM_INDIVIDUAL_PARMS+NUM_PARMS+NUM_FIELDS];
1737 memset((void *) ett, 0, sizeof(ett));
1739 ett[0] = &ett_alcap;
1742 for (i=0; i < NUM_PARMS; i++)
1745 ett[NUM_INDIVIDUAL_PARMS+i] = &ett_parms[i];
1748 for (i=0; i < NUM_FIELDS; i++)
1751 ett[NUM_INDIVIDUAL_PARMS+NUM_PARMS+i] = &ett_fields[i];
1754 /* Register the protocol name and description */
1756 proto_register_protocol(alcap_proto_name, alcap_proto_name_short, "alcap");
1758 /* Required function calls to register the header fields and subtrees used */
1759 proto_register_field_array(proto_alcap, hf, array_length(hf));
1760 proto_register_subtree_array(ett, array_length(ett));
1765 proto_reg_handoff_alcap(void)
1767 dissector_handle_t alcap_handle;
1769 alcap_handle = create_dissector_handle(dissect_alcap, proto_alcap);
1771 dissector_add("mtp3.service_indicator", ALCAP_SI, alcap_handle);
1773 data_handle = find_dissector("data");