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.
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);
343 if (value && check_col(g_pinfo->cinfo, COL_INFO))
344 col_append_fstr(g_pinfo->cinfo, COL_INFO, " SA: %u", value);
348 proto_tree_add_uint_format(tree, hf_alcap_dsaid, tvb,
349 curr_offset, FIELD_SIGNALLING_ASSOC_ID_LEN, value,
350 "Destination signalling association identifier: %u%s",
352 value ? "" : " (unknown)");
356 proto_tree_add_uint(tree, hf_alcap_osaid, tvb,
357 curr_offset, FIELD_SIGNALLING_ASSOC_ID_LEN, value);
360 curr_offset += FIELD_SIGNALLING_ASSOC_ID_LEN;
362 *len -= (curr_offset - *offset);
363 *offset = curr_offset;
367 * Ref. ITU-T Q.2630.1 (12/1999)
371 dis_field_aal2_path_id(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
376 curr_offset = *offset;
378 #define FIELD_AAL2_PATH_ID_LEN 4
380 SHORT_DATA_CHECK(*len, FIELD_AAL2_PATH_ID_LEN);
382 value = tvb_get_ntohl(tvb, curr_offset);
384 if (value && check_col(g_pinfo->cinfo, COL_INFO))
385 col_append_fstr(g_pinfo->cinfo, COL_INFO, " PathId: %u", value);
387 proto_tree_add_uint_format(tree, hf_alcap_aal2_path_id, tvb,
388 curr_offset, FIELD_AAL2_PATH_ID_LEN, value,
389 "AAL2 path identifier: %d%s",
391 value ? "" : " (Null)");
393 curr_offset += FIELD_AAL2_PATH_ID_LEN;
395 *len -= (curr_offset - *offset);
396 *offset = curr_offset;
400 * Ref. ITU-T Q.2630.1 (12/1999)
404 dis_field_channel_id(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
409 curr_offset = *offset;
411 SHORT_DATA_CHECK(*len, 1);
413 oct = tvb_get_guint8(tvb, curr_offset);
415 if (oct && check_col(g_pinfo->cinfo, COL_INFO))
416 col_append_fstr(g_pinfo->cinfo, COL_INFO, " CID: %u", oct);
418 proto_tree_add_uint_format(tree, hf_alcap_channel_id, tvb,
420 "Channel identifier (CID): %d%s",
422 oct ? "" : " (Null)");
426 *len -= (curr_offset - *offset);
427 *offset = curr_offset;
431 * Ref. ITU-T Q.2630.1 (12/1999)
435 dis_field_organizational_unique_id(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
440 curr_offset = *offset;
442 #define FIELD_ORGANIZATIONAL_UNIQUE_ID_LEN 3
444 SHORT_DATA_CHECK(*len, FIELD_ORGANIZATIONAL_UNIQUE_ID_LEN);
446 octs = tvb_get_ntoh24(tvb, curr_offset);
448 proto_tree_add_uint(tree, hf_alcap_organizational_unique_id, tvb,
449 curr_offset, FIELD_ORGANIZATIONAL_UNIQUE_ID_LEN, octs);
451 curr_offset += FIELD_ORGANIZATIONAL_UNIQUE_ID_LEN;
453 *len -= (curr_offset - *offset);
454 *offset = curr_offset;
458 * Ref. ITU-T Q.2630.1 (12/1999)
462 dis_field_audio_service(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
471 curr_offset = *offset;
473 #define FIELD_AUDIO_SERVICE_LEN 5
475 SHORT_DATA_CHECK(*len, FIELD_AUDIO_SERVICE_LEN);
478 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
479 curr_offset, FIELD_AUDIO_SERVICE_LEN, field_strings[FIELD_AUDIO_SERVICE]);
481 subtree = proto_item_add_subtree(item, ett_fields[FIELD_AUDIO_SERVICE]);
483 oct = tvb_get_guint8(tvb, curr_offset);
485 switch ((oct & 0xc0) >> 6)
487 case 0x00: str = "Designates a profile specified by ITU-T Rec. I.366.2; ignore organizational unique identifier"; break;
488 case 0x01: str = "Designates a profile specified by organizational unique identifier"; break;
489 case 0x02: str = "Designates a custom profile; ignore organizational unique identifier"; break;
490 case 0x03: str = "Reserved"; break;
493 other_decode_bitfield_value(bigbuf, oct, 0xc0, 8);
494 proto_tree_add_text(subtree, tvb,
496 "%s : Profile type, %s",
499 other_decode_bitfield_value(bigbuf, oct, 0x3f, 8);
500 proto_tree_add_text(subtree, tvb,
507 oct = tvb_get_guint8(tvb, curr_offset);
509 proto_tree_add_text(subtree, tvb,
511 "Profile identifier (%d)",
516 oct = tvb_get_guint8(tvb, curr_offset);
518 other_decode_bitfield_value(bigbuf, oct, 0x80, 8);
519 proto_tree_add_text(subtree, tvb,
521 "%s : FRM, transport of frame mode data %s",
523 (oct & 0x80) ? "enabled" : "disabled");
525 other_decode_bitfield_value(bigbuf, oct, 0x40, 8);
526 proto_tree_add_text(subtree, tvb,
528 "%s : CMD, transport of circuit mode data (64 kbit/s) %s",
530 (oct & 0x40) ? "enabled" : "disabled");
532 other_decode_bitfield_value(bigbuf, oct, 0x20, 8);
533 proto_tree_add_text(subtree, tvb,
535 "%s : MF-R2, transport of multi-frequency R2 dialled digits %s",
537 (oct & 0x20) ? "enabled" : "disabled");
539 other_decode_bitfield_value(bigbuf, oct, 0x10, 8);
540 proto_tree_add_text(subtree, tvb,
542 "%s : MF-R1, transport of multi-frequency R1 dialled digits %s",
544 (oct & 0x10) ? "enabled" : "disabled");
546 other_decode_bitfield_value(bigbuf, oct, 0x08, 8);
547 proto_tree_add_text(subtree, tvb,
549 "%s : DTMF, transport of dual tone multi-frequency dialled digits %s",
551 (oct & 0x08) ? "enabled" : "disabled");
553 other_decode_bitfield_value(bigbuf, oct, 0x04, 8);
554 proto_tree_add_text(subtree, tvb,
556 "%s : CAS, transport of channel associated signalling %s",
558 (oct & 0x04) ? "enabled" : "disabled");
560 other_decode_bitfield_value(bigbuf, oct, 0x02, 8);
561 proto_tree_add_text(subtree, tvb,
563 "%s : FAX, transport of demodulated facsimile data %s",
565 (oct & 0x02) ? "enabled" : "disabled");
567 other_decode_bitfield_value(bigbuf, oct, 0x01, 8);
568 proto_tree_add_text(subtree, tvb,
570 "%s : A/mu-law, interpretation of generic PCM coding: %s-law",
572 (oct & 0x01) ? "mu" : "A");
576 value = tvb_get_ntohs(tvb, curr_offset);
578 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
580 "Maximum length of frame mode data (%d)",
585 *len -= (curr_offset - *offset);
586 *offset = curr_offset;
590 * Ref. ITU-T Q.2630.1 (12/1999)
594 dis_field_multirate_service(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
602 curr_offset = *offset;
604 #define FIELD_MULTIRATE_SERVICE_LEN 3
606 SHORT_DATA_CHECK(*len, FIELD_MULTIRATE_SERVICE_LEN);
609 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
610 curr_offset, FIELD_MULTIRATE_SERVICE_LEN, field_strings[FIELD_MULTIRATE_SERVICE]);
612 subtree = proto_item_add_subtree(item, ett_fields[FIELD_MULTIRATE_SERVICE]);
614 oct = tvb_get_guint8(tvb, curr_offset);
616 other_decode_bitfield_value(bigbuf, oct, 0x80, 8);
617 proto_tree_add_text(subtree, tvb,
619 "%s : FRM, transport of frame mode data %s",
621 (oct & 0x80) ? "enabled" : "disabled");
623 other_decode_bitfield_value(bigbuf, oct, 0x60, 8);
624 proto_tree_add_text(subtree, tvb,
629 other_decode_bitfield_value(bigbuf, oct, 0x1f, 8);
630 proto_tree_add_text(subtree, tvb,
632 "%s : Multiplier (%d) for n x 64 kbit/s",
638 value = tvb_get_ntohs(tvb, curr_offset);
640 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
642 "Maximum length of frame mode data (%d)",
647 *len -= (curr_offset - *offset);
648 *offset = curr_offset;
652 * Ref. ITU-T Q.2630.1 (12/1999)
656 dis_field_seg_reassembly_ass(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
663 curr_offset = *offset;
665 #define FIELD_SEG_REASSEMBLY_ASS_LEN 14
667 SHORT_DATA_CHECK(*len, FIELD_SEG_REASSEMBLY_ASS_LEN);
670 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
671 curr_offset, FIELD_SEG_REASSEMBLY_ASS_LEN, field_strings[FIELD_SEG_REASSEMBLY_ASS]);
673 subtree = proto_item_add_subtree(item, ett_fields[FIELD_SEG_REASSEMBLY_ASS]);
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 forward direction (%d)",
684 value = tvb_get_ntoh24(tvb, curr_offset);
686 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
688 "Maximum length of SSSAR-SDU in the backward 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 forward 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-SDU in the backward 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 forward direction (%d)",
720 value = tvb_get_ntohs(tvb, curr_offset);
722 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
724 "Maximum length of SSCOP-UU in the backward direction (%d)",
729 *len -= (curr_offset - *offset);
730 *offset = curr_offset;
734 * Ref. ITU-T Q.2630.1 (12/1999)
738 dis_field_seg_reassembly_unass(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
746 curr_offset = *offset;
748 #define FIELD_SEG_REASSEMBLY_UNASS_LEN 7
750 SHORT_DATA_CHECK(*len, FIELD_SEG_REASSEMBLY_UNASS_LEN);
753 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
754 curr_offset, FIELD_SEG_REASSEMBLY_UNASS_LEN, field_strings[FIELD_SEG_REASSEMBLY_UNASS]);
756 subtree = proto_item_add_subtree(item, ett_fields[FIELD_SEG_REASSEMBLY_UNASS]);
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 forward direction (%d)",
767 value = tvb_get_ntoh24(tvb, curr_offset);
769 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
771 "Maximum length of SSSAR-SDU in the backward direction (%d)",
776 oct = tvb_get_guint8(tvb, curr_offset);
778 other_decode_bitfield_value(bigbuf, oct, 0x80, 8);
779 proto_tree_add_text(subtree, tvb,
781 "%s : TED, transmission error detection %s",
783 oct & 0x80 ? "enabled" : "disabled");
785 other_decode_bitfield_value(bigbuf, oct, 0x7f, 8);
786 proto_tree_add_text(subtree, tvb,
793 *len -= (curr_offset - *offset);
794 *offset = curr_offset;
798 * Ref. ITU-T Q.2630.1 (12/1999)
802 dis_field_served_user_gen_ref(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
807 curr_offset = *offset;
809 #define FIELD_SERVED_USER_GEN_REF_LEN 4
811 SHORT_DATA_CHECK(*len, FIELD_SERVED_USER_GEN_REF_LEN);
813 value = tvb_get_ntohl(tvb, curr_offset);
815 if (value && check_col(g_pinfo->cinfo, COL_INFO))
816 col_append_fstr(g_pinfo->cinfo, COL_INFO, " SUGR: %u", value);
818 proto_tree_add_uint(tree, hf_alcap_served_user_gen_ref, tvb,
819 curr_offset, FIELD_SERVED_USER_GEN_REF_LEN, value);
821 curr_offset += FIELD_SERVED_USER_GEN_REF_LEN;
823 *len -= (curr_offset - *offset);
824 *offset = curr_offset;
828 * Ref. ITU-T Q.2630.1 (12/1999)
832 dis_field_cps_sdu_bit_rate(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset, gboolean maximum)
839 curr_offset = *offset;
841 #define FIELD_CPS_SDU_BIT_RATE_LEN 4
843 SHORT_DATA_CHECK(*len, FIELD_CPS_SDU_BIT_RATE_LEN);
846 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
847 curr_offset, FIELD_CPS_SDU_BIT_RATE_LEN, field_strings[FIELD_MAX_CPS_SDU_BIT_RATE + (maximum ? 0 : 1)]);
849 subtree = proto_item_add_subtree(item, ett_fields[FIELD_MAX_CPS_SDU_BIT_RATE + (maximum ? 0 : 1)]);
851 value = tvb_get_ntohs(tvb, curr_offset);
853 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
855 "CPS-SDU bit rate in the forward direction (%d)",
860 value = tvb_get_ntohs(tvb, curr_offset);
862 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
864 "CPS-SDU bit rate in the backward direction (%d)",
869 *len -= (curr_offset - *offset);
870 *offset = curr_offset;
874 * Ref. ITU-T Q.2630.1 (12/1999)
878 dis_field_cps_sdu_size(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset, gboolean maximum)
885 curr_offset = *offset;
887 #define FIELD_CPS_SDU_SIZE_LEN 2
889 SHORT_DATA_CHECK(*len, FIELD_CPS_SDU_SIZE_LEN);
892 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
893 curr_offset, FIELD_CPS_SDU_SIZE_LEN, field_strings[FIELD_MAX_CPS_SDU_SIZE + (maximum ? 0 : 1)]);
895 subtree = proto_item_add_subtree(item, ett_fields[FIELD_MAX_CPS_SDU_SIZE + (maximum ? 0 : 1)]);
897 oct = tvb_get_guint8(tvb, curr_offset);
899 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
901 "CPS-SDU size in the forward direction (%d)",
906 oct = tvb_get_guint8(tvb, curr_offset);
908 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
910 "CPS-SDU size in the backward direction (%d)",
915 *len -= (curr_offset - *offset);
916 *offset = curr_offset;
920 * Ref. ITU-T Q.2630.1 (12/1999)
924 dis_field_nature_of_address(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
933 curr_offset = *offset;
935 #define FIELD_NATURE_OF_ADDRESS_LEN 1
937 SHORT_DATA_CHECK(*len, FIELD_NATURE_OF_ADDRESS_LEN);
940 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
941 curr_offset, FIELD_NATURE_OF_ADDRESS_LEN, field_strings[FIELD_NATURE_OF_ADDRESS]);
943 subtree = proto_item_add_subtree(item, ett_fields[FIELD_NATURE_OF_ADDRESS]);
945 oct = tvb_get_guint8(tvb, curr_offset);
947 other_decode_bitfield_value(bigbuf, oct, 0x80, 8);
948 proto_tree_add_text(subtree, tvb,
957 case 0x00: str = "spare"; break;
958 case 0x01: str = "subscriber number (national use)"; break;
959 case 0x02: str = "unknown (national use)"; break;
960 case 0x03: str = "national (significant) number"; break;
961 case 0x04: str = "international number"; break;
962 case 0x05: str = "network-specific number (national use)"; break;
964 if ((value >= 0x06) && (value <= 0x6f)) { str = "spare"; break; }
965 else if ((value >= 0x70) && (value <= 0xfe)) { str = "reserved for national use"; break; }
966 else { str = "not given in spec. ???"; break; }
969 other_decode_bitfield_value(bigbuf, oct, 0x7f, 8);
970 proto_tree_add_text(subtree, tvb,
972 "%s : Nature of address code, %s (%d)",
979 *len -= (curr_offset - *offset);
980 *offset = curr_offset;
984 * Ref. ITU-T Q.2630.1 (12/1999)
988 dis_field_e164_address(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
997 curr_offset = *offset;
999 SHORT_DATA_CHECK(*len, 1);
1002 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
1003 curr_offset, -1, field_strings[FIELD_E164_ADDRESS]);
1005 subtree = proto_item_add_subtree(item, ett_fields[FIELD_E164_ADDRESS]);
1007 parm_len = tvb_get_guint8(tvb, curr_offset);
1009 proto_item_set_len(item, parm_len + 1);
1011 proto_tree_add_uint(subtree, hf_alcap_length, tvb, curr_offset, 1, parm_len);
1018 while (i < parm_len)
1020 oct = tvb_get_guint8(tvb, curr_offset);
1022 other_decode_bitfield_value(bigbuf, oct, 0xf0, 8);
1023 proto_tree_add_text(subtree, tvb,
1028 bigbuf2[i] = (oct & 0x0f) + 0x30;
1030 other_decode_bitfield_value(bigbuf, oct, 0x0f, 8);
1031 proto_tree_add_text(subtree, tvb,
1033 "%s : Digit %d of address (%d)",
1044 if (check_col(g_pinfo->cinfo, COL_INFO))
1045 col_append_fstr(g_pinfo->cinfo, COL_INFO, " E164: %s", bigbuf2);
1047 proto_item_append_text(item, " (%s)", bigbuf2);
1050 *len -= (curr_offset - *offset);
1051 *offset = curr_offset;
1055 * Ref. ITU-T Q.2630.1 (12/1999)
1059 dis_field_nsap_address(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
1061 guint32 curr_offset;
1063 curr_offset = *offset;
1065 #define FIELD_NSAP_ADDRESS_LEN 20
1067 SHORT_DATA_CHECK(*len, FIELD_NSAP_ADDRESS_LEN);
1069 proto_tree_add_item(tree, hf_alcap_nsap_address, tvb,
1070 curr_offset, FIELD_NSAP_ADDRESS_LEN,FALSE);
1072 curr_offset += FIELD_NSAP_ADDRESS_LEN;
1074 *len -= (curr_offset - *offset);
1075 *offset = curr_offset;
1079 * Ref. ITU-T Q.2630.1 (12/1999)
1083 dis_field_cause_value(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset, gboolean *compat)
1085 guint32 curr_offset;
1088 proto_tree *subtree;
1092 curr_offset = *offset;
1094 #define FIELD_CAUSE_VALUE_LEN 2
1096 SHORT_DATA_CHECK(*len, FIELD_CAUSE_VALUE_LEN);
1099 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
1100 curr_offset, FIELD_CAUSE_VALUE_LEN, field_strings[FIELD_CAUSE_VALUE]);
1102 subtree = proto_item_add_subtree(item, ett_fields[FIELD_CAUSE_VALUE]);
1104 oct = tvb_get_guint8(tvb, curr_offset);
1106 other_decode_bitfield_value(bigbuf, oct, 0xfc, 8);
1107 proto_tree_add_text(subtree, tvb,
1114 case 0x00: str = "ITU-T standardized coding as described in ITU-T Rec. Q.850 and Q.2610"; break;
1115 case 0x01: str = "ISO/IEC standard"; break;
1116 case 0x02: str = "national standard"; break;
1117 case 0x03: str = "standard defined for the network (either public or private) present on the network side of the interface"; break;
1120 other_decode_bitfield_value(bigbuf, oct, 0x03, 8);
1121 proto_tree_add_text(subtree, tvb,
1123 "%s : Coding standard, %s",
1129 oct = tvb_get_guint8(tvb, curr_offset);
1131 other_decode_bitfield_value(bigbuf, oct, 0x80, 8);
1132 proto_tree_add_text(subtree, tvb,
1139 case 1: str = "Unallocated (unassigned) number"; break;
1140 case 3: str = "No route to destination"; break;
1141 case 31: str = "Normal, unspecified"; break;
1142 case 34: str = "No circuit/channel available"; break;
1143 case 38: str = "Network out of order"; break;
1144 case 41: str = "Temporary failure"; break;
1145 case 42: str = "Switching equipment congestion"; break;
1146 case 44: str = "Requested circuit/channel not available"; break;
1147 case 47: str = "Resource unavailable, unspecified"; break;
1148 case 93: str = "AAL parameters cannot be supported"; break;
1149 case 95: str = "Invalid message, unspecified"; break;
1150 case 96: str = "Mandatory information element is missing"; break;
1151 case 97: str = "Message type non-existent or not implemented"; *compat = TRUE; break;
1152 case 99: str = "Information element/parameter non-existent or not implemented"; *compat = TRUE; break;
1153 case 100: str = "Invalid information element contents"; break;
1154 case 102: str = "Recovery on timer expiry"; break;
1155 case 110: str = "Message with unrecognized parameter, discarded"; *compat = TRUE; break;
1156 default: str = "Unknown"; break;
1159 other_decode_bitfield_value(bigbuf, oct, 0x7f, 8);
1160 proto_tree_add_text(subtree, tvb,
1162 "%s : Cause (%d), %s",
1169 *len -= (curr_offset - *offset);
1170 *offset = curr_offset;
1174 * Ref. ITU-T Q.2630.1 (12/1999)
1178 dis_field_diagnostics(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset, gboolean compat)
1180 guint32 curr_offset;
1183 proto_tree *subtree;
1189 curr_offset = *offset;
1191 SHORT_DATA_CHECK(*len, 1);
1194 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
1195 curr_offset, -1, field_strings[FIELD_DIAGNOSTICS]);
1197 subtree = proto_item_add_subtree(item, ett_fields[FIELD_DIAGNOSTICS]);
1199 parm_len = tvb_get_guint8(tvb, curr_offset);
1201 proto_item_set_len(item, parm_len + 1);
1203 proto_tree_add_uint(subtree, hf_alcap_length, tvb, curr_offset, 1, parm_len);
1212 * compatibility diagnostics
1214 oct = tvb_get_guint8(tvb, curr_offset);
1216 str = my_match_strval(oct, msg_type_strings, &idx);
1218 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1219 curr_offset, 1, (str == NULL) ? "Unknown message identifier" : str);
1224 while ((i+2) <= parm_len)
1226 oct = tvb_get_guint8(tvb, curr_offset);
1228 str = my_match_strval(oct, msg_parm_strings, &idx);
1230 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1231 curr_offset, 1, (str == NULL) ? "Unknown parameter" : str);
1235 oct = tvb_get_guint8(tvb, curr_offset);
1239 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1240 curr_offset, 1, "Whole parameter");
1244 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1245 curr_offset, 1, "Field number %d", oct);
1254 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1255 curr_offset, parm_len - i, "Extraneous Data ???");
1257 curr_offset += (parm_len - i);
1262 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1263 curr_offset, parm_len, "Coded as per ITU-T Rec. Q.2610");
1265 curr_offset += parm_len;
1269 *len -= (curr_offset - *offset);
1270 *offset = curr_offset;
1274 * Ref. ITU-T Q.2630.1 (12/1999)
1278 dis_field_served_user_transport(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
1280 guint32 curr_offset;
1282 proto_tree *subtree;
1285 curr_offset = *offset;
1287 SHORT_DATA_CHECK(*len, 1);
1290 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
1291 curr_offset, -1, field_strings[FIELD_SERVED_USER_TRANSPORT]);
1293 subtree = proto_item_add_subtree(item, ett_fields[FIELD_SERVED_USER_TRANSPORT]);
1295 parm_len = tvb_get_guint8(tvb, curr_offset);
1297 proto_item_set_len(item, parm_len + 1);
1299 proto_tree_add_uint(subtree, hf_alcap_length, tvb, curr_offset, 1, parm_len);
1305 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1306 curr_offset, parm_len, "Value");
1308 curr_offset += parm_len;
1311 *len -= (curr_offset - *offset);
1312 *offset = curr_offset;
1316 * Ref. ITU-T Q.2630.1 (12/1999)
1320 dis_parm_cause(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1324 dis_field_cause_value(tvb, tree, &len, &curr_offset, &compat);
1326 dis_field_diagnostics(tvb, tree, &len, &curr_offset, compat);
1328 EXTRANEOUS_DATA_CHECK(len, 0);
1332 * Ref. ITU-T Q.2630.1 (12/1999)
1336 dis_parm_conn_element_id(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1339 dis_field_aal2_path_id(tvb, tree, &len, &curr_offset);
1341 dis_field_channel_id(tvb, tree, &len, &curr_offset);
1343 EXTRANEOUS_DATA_CHECK(len, 0);
1347 * Ref. ITU-T Q.2630.1 (12/1999)
1351 dis_parm_dest_e164_sea(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1354 dis_field_nature_of_address(tvb, tree, &len, &curr_offset);
1356 dis_field_e164_address(tvb, tree, &len, &curr_offset);
1358 EXTRANEOUS_DATA_CHECK(len, 0);
1362 * Ref. ITU-T Q.2630.1 (12/1999)
1366 dis_parm_dest_nsap_sea(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1369 dis_field_nsap_address(tvb, tree, &len, &curr_offset);
1371 EXTRANEOUS_DATA_CHECK(len, 0);
1375 * Ref. ITU-T Q.2630.1 (12/1999)
1379 dis_parm_link_characteristics(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1382 dis_field_cps_sdu_bit_rate(tvb, tree, &len, &curr_offset, TRUE);
1384 dis_field_cps_sdu_bit_rate(tvb, tree, &len, &curr_offset, FALSE);
1386 dis_field_cps_sdu_size(tvb, tree, &len, &curr_offset, TRUE);
1388 dis_field_cps_sdu_size(tvb, tree, &len, &curr_offset, FALSE);
1390 EXTRANEOUS_DATA_CHECK(len, 0);
1394 * Ref. ITU-T Q.2630.1 (12/1999)
1398 dis_parm_osai(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1401 dis_field_signalling_assoc_id(tvb, tree, &len, &curr_offset, FALSE);
1403 EXTRANEOUS_DATA_CHECK(len, 0);
1407 * Ref. ITU-T Q.2630.1 (12/1999)
1411 dis_parm_served_user_gen_ref(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1414 dis_field_served_user_gen_ref(tvb, tree, &len, &curr_offset);
1416 EXTRANEOUS_DATA_CHECK(len, 0);
1420 * Ref. ITU-T Q.2630.1 (12/1999)
1424 dis_parm_served_user_transport(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1427 dis_field_served_user_transport(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_audio(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1440 dis_field_audio_service(tvb, tree, &len, &curr_offset);
1442 dis_field_organizational_unique_id(tvb, tree, &len, &curr_offset);
1444 EXTRANEOUS_DATA_CHECK(len, 0);
1448 * Ref. ITU-T Q.2630.1 (12/1999)
1452 dis_parm_service_specific_info_multirate(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1455 dis_field_multirate_service(tvb, tree, &len, &curr_offset);
1457 EXTRANEOUS_DATA_CHECK(len, 0);
1461 * Ref. ITU-T Q.2630.1 (12/1999)
1465 dis_parm_service_specific_info_ass(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1468 dis_field_seg_reassembly_ass(tvb, tree, &len, &curr_offset);
1470 EXTRANEOUS_DATA_CHECK(len, 0);
1474 * Ref. ITU-T Q.2630.1 (12/1999)
1478 dis_parm_service_specific_info_unass(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1481 dis_field_seg_reassembly_unass(tvb, tree, &len, &curr_offset);
1483 EXTRANEOUS_DATA_CHECK(len, 0);
1486 static gint ett_parms[NUM_PARMS];
1487 static void (*alcap_parm_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) = {
1488 dis_parm_cause, /* Cause */
1489 dis_parm_conn_element_id, /* Connection element identifier */
1490 dis_parm_dest_e164_sea, /* Destination E.164 service endpoint address */
1491 dis_parm_dest_nsap_sea, /* Destination NSAP service endpoint address */
1492 dis_parm_link_characteristics, /* Link characteristics */
1493 dis_parm_osai, /* Originating signalling association identifier */
1494 dis_parm_served_user_gen_ref, /* Served user generated reference */
1495 dis_parm_served_user_transport, /* Served user transport */
1496 dis_parm_service_specific_info_audio, /* Service specific information (audio) */
1497 dis_parm_service_specific_info_multirate, /* Service specific information (multirate) */
1498 dis_parm_service_specific_info_ass, /* Service specific information (SAR-assured) */
1499 dis_parm_service_specific_info_unass, /* Service specific information (SAR-unassured) */
1500 NULL /* no parms */, /* Test connection identifier */
1504 /* GENERIC ALCAP DISSECTOR FUNCTIONS */
1507 dissect_alcap_parms(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 len)
1509 void (*parm_fcn)(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) = NULL;
1512 guint32 curr_offset, saved_offset;
1516 proto_tree *subtree;
1520 curr_offset = offset;
1522 while (len >= ALCAP_PARM_HEADER_LEN)
1524 saved_offset = curr_offset;
1526 parm = tvb_get_guint8(tvb, curr_offset);
1528 str = my_match_strval(parm, msg_parm_strings, &idx);
1532 ett_parm_idx = ett_parm;
1537 ett_parm_idx = ett_parms[idx];
1538 parm_fcn = alcap_parm_fcn[idx];
1541 item = proto_tree_add_none_format(tree, hf_alcap_none, tvb,
1543 (str == NULL) ? "Unknown parameter" : str);
1545 subtree = proto_item_add_subtree(item, ett_parm_idx);
1547 proto_tree_add_uint(subtree, hf_alcap_parm_id, tvb,
1548 curr_offset, 1, parm);
1552 dis_field_compatibility(tvb, subtree, &curr_offset, FALSE);
1554 parm_len = tvb_get_guint8(tvb, curr_offset);
1556 proto_tree_add_uint(subtree, hf_alcap_length, tvb, curr_offset, 1, parm_len);
1560 proto_item_set_len(item, (curr_offset - saved_offset) + parm_len);
1564 if (parm_fcn == NULL)
1566 proto_tree_add_none_format(subtree, hf_alcap_none,
1567 tvb, curr_offset, parm_len, "Parameter data");
1571 (*parm_fcn)(tvb, subtree, parm_len, curr_offset);
1575 len -= (ALCAP_PARM_HEADER_LEN + parm_len);
1576 curr_offset += parm_len;
1579 EXTRANEOUS_DATA_CHECK(len, 0);
1583 dissect_alcap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *alcap_tree)
1594 len = tvb_length(tvb);
1597 if (len < ALCAP_MSG_HEADER_LEN)
1599 proto_tree_add_none_format(alcap_tree, hf_alcap_none, tvb,
1600 offset, len, "Message header too short");
1605 dis_field_signalling_assoc_id(tvb, alcap_tree, &temp_len, &offset, TRUE);
1607 msg_type = tvb_get_guint8(tvb, offset);
1609 str = my_match_strval(msg_type, msg_type_strings, &idx);
1613 proto_tree_add_none_format(alcap_tree, hf_alcap_none, tvb,
1614 offset, 1, "Unknown message identifier");
1619 if (check_col(pinfo->cinfo, COL_INFO))
1621 col_set_str(pinfo->cinfo, COL_INFO, str);
1624 proto_tree_add_uint(alcap_tree, hf_alcap_msg_type, tvb,
1625 offset, 1, msg_type);
1629 dis_field_compatibility(tvb, alcap_tree, &offset, TRUE);
1631 if (len > ALCAP_MSG_HEADER_LEN)
1633 dissect_alcap_parms(tvb, alcap_tree, offset, len - ALCAP_MSG_HEADER_LEN);
1638 dissect_alcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1640 proto_item *alcap_item;
1641 proto_tree *alcap_tree = NULL;
1646 * Don't change the Protocol column on summary display
1648 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1650 col_set_str(pinfo->cinfo, COL_PROTOCOL, alcap_proto_name_short);
1653 /* In the interest of speed, if "tree" is NULL, don't do any work not
1654 * necessary to generate protocol tree items.
1661 * create the ALCAP protocol tree
1664 proto_tree_add_protocol_format(tree, proto_alcap, tvb, 0, -1,
1668 proto_item_add_subtree(alcap_item, ett_alcap);
1672 dissect_alcap_message(tvb, pinfo, alcap_tree);
1677 /* Register the protocol with Ethereal */
1679 proto_register_alcap(void)
1683 /* Setup list of header fields */
1684 static hf_register_info hf[] =
1686 { &hf_alcap_msg_type,
1689 FT_UINT8, BASE_DEC, VALS(msg_type_strings), 0,
1692 { "Destination signalling association identifier",
1694 FT_UINT32, BASE_DEC, NULL, 0,
1698 { "Originating signalling association identifier",
1700 FT_UINT32, BASE_DEC, NULL, 0,
1703 { &hf_alcap_aal2_path_id,
1704 { "AAL2 path identifier",
1706 FT_UINT32, BASE_DEC, NULL, 0,
1709 { &hf_alcap_channel_id,
1710 { "Channel identifier (CID)",
1712 FT_UINT32, BASE_DEC, NULL, 0,
1715 { &hf_alcap_organizational_unique_id,
1716 { "Organizational unique identifier (OUI)",
1718 FT_UINT24, BASE_DEC, NULL, 0,
1721 { &hf_alcap_served_user_gen_ref,
1722 { "Served user generated reference",
1724 FT_UINT32, BASE_DEC, NULL, 0,
1727 { &hf_alcap_nsap_address,
1730 FT_BYTES, BASE_NONE, NULL, 0,
1733 { &hf_alcap_parm_id,
1734 { "Parameter identifier",
1736 FT_UINT8, BASE_DEC, NULL, 0,
1739 { "Length", "alcap.len",
1740 FT_UINT8, BASE_DEC, NULL, 0,
1744 { "Subtree", "alcap.none",
1750 /* Setup protocol subtree array */
1751 #define NUM_INDIVIDUAL_PARMS 2
1752 static gint *ett[NUM_INDIVIDUAL_PARMS+NUM_PARMS+NUM_FIELDS];
1754 memset((void *) ett, 0, sizeof(ett));
1756 ett[0] = &ett_alcap;
1759 for (i=0; i < NUM_PARMS; i++)
1762 ett[NUM_INDIVIDUAL_PARMS+i] = &ett_parms[i];
1765 for (i=0; i < NUM_FIELDS; i++)
1768 ett[NUM_INDIVIDUAL_PARMS+NUM_PARMS+i] = &ett_fields[i];
1771 /* Register the protocol name and description */
1773 proto_register_protocol(alcap_proto_name, alcap_proto_name_short, "alcap");
1775 register_dissector("alcap", dissect_alcap, proto_alcap);
1777 /* Required function calls to register the header fields and subtrees used */
1778 proto_register_field_array(proto_alcap, hf, array_length(hf));
1779 proto_register_subtree_array(ett, array_length(ett));
1784 proto_reg_handoff_alcap(void)
1786 dissector_handle_t alcap_handle;
1788 alcap_handle = create_dissector_handle(dissect_alcap, proto_alcap);
1790 dissector_add("mtp3.service_indicator", ALCAP_SI, alcap_handle);
1792 data_handle = find_dissector("data");