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.4 2003/11/16 23:17:15 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)" },
186 /* Generate, into "buf", a string showing the bits of a bitfield.
187 * Return a pointer to the character after that string.
190 my_decode_bitfield_value(char *buf, guint32 val, guint32 mask, int width)
198 bit = 1 << (width - 1);
204 /* This bit is part of the field. Show its value. */
212 /* This bit is not part of the field. */
218 if (i >= width) break;
219 if (i % 4 == 0) *p++ = ' ';
228 my_match_strval(guint32 val, const value_string *vs, gint *idx)
232 while (vs[i].strptr) {
233 if (vs[i].value == val)
236 return(vs[i].strptr);
247 * Ref. ITU-T Q.2630.1 (12/1999)
251 dis_field_compatibility(tvbuff_t *tvb, proto_tree *tree, guint32 *offset, gboolean message)
259 curr_offset = *offset;
262 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
263 curr_offset, 1, "%s %s",
264 message ? "Message" : "Parameter",
265 field_strings[FIELD_COMPATIBILITY]);
267 subtree = proto_item_add_subtree(item, ett_fields[FIELD_COMPATIBILITY]);
269 compat = tvb_get_guint8(tvb, curr_offset);
271 my_decode_bitfield_value(bigbuf, compat, 0x80, 8);
272 proto_tree_add_text(subtree, tvb,
277 my_decode_bitfield_value(bigbuf, compat, 0x40, 8);
278 proto_tree_add_text(subtree, tvb,
280 "%s : Pass-on not possible - %s",
282 (compat & 0x40) ? "Send notification" : "Do not send notification");
284 switch ((compat & 0x30) >> 4)
287 str = "Pass on message or parameter (Release connection)";
293 str = "Discard parameter (Discard message)";
297 str = "Discard parameter";
302 str = "Discard message";
306 str = "Release connection";
310 my_decode_bitfield_value(bigbuf, compat, 0x30, 8);
311 proto_tree_add_text(subtree, tvb,
313 "%s : Pass-on not possible, instruction - %s",
317 my_decode_bitfield_value(bigbuf, compat, 0x08, 8);
318 proto_tree_add_text(subtree, tvb,
323 my_decode_bitfield_value(bigbuf, compat, 0x04, 8);
324 proto_tree_add_text(subtree, tvb,
326 "%s : General action - %s",
328 (compat & 0x04) ? "Send notification" : "Do not send notification");
330 switch (compat & 0x03)
333 str = "Pass on message or parameter";
339 str = "Discard parameter (Discard message)";
343 str = "Discard parameter";
348 str = "Discard message";
352 str = "Release connection";
356 my_decode_bitfield_value(bigbuf, compat, 0x03, 8);
357 proto_tree_add_text(subtree, tvb,
359 "%s : General action, instruction - %s",
367 * Ref. ITU-T Q.2630.1 (12/1999)
371 dis_field_signalling_assoc_id(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset, gboolean destination)
376 curr_offset = *offset;
378 #define FIELD_SIGNALLING_ASSOC_ID_LEN 4
380 SHORT_DATA_CHECK(*len, FIELD_SIGNALLING_ASSOC_ID_LEN);
382 value = tvb_get_ntohl(tvb, curr_offset);
386 proto_tree_add_uint_format(tree, hf_alcap_dsaid, tvb,
387 curr_offset, FIELD_SIGNALLING_ASSOC_ID_LEN, value,
388 "Destination signalling association identifier: %d%s",
390 value ? "" : " (unknown)");
394 proto_tree_add_uint(tree, hf_alcap_osaid, tvb,
395 curr_offset, FIELD_SIGNALLING_ASSOC_ID_LEN, value);
398 curr_offset += FIELD_SIGNALLING_ASSOC_ID_LEN;
400 *len -= (curr_offset - *offset);
401 *offset = curr_offset;
405 * Ref. ITU-T Q.2630.1 (12/1999)
409 dis_field_aal2_path_id(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
414 curr_offset = *offset;
416 #define FIELD_AAL2_PATH_ID_LEN 4
418 SHORT_DATA_CHECK(*len, FIELD_AAL2_PATH_ID_LEN);
420 value = tvb_get_ntohl(tvb, curr_offset);
422 proto_tree_add_uint_format(tree, hf_alcap_aal2_path_id, tvb,
423 curr_offset, FIELD_AAL2_PATH_ID_LEN, value,
424 "AAL2 path identifier: %d%s",
426 value ? "" : " (Null)");
428 curr_offset += FIELD_AAL2_PATH_ID_LEN;
430 *len -= (curr_offset - *offset);
431 *offset = curr_offset;
435 * Ref. ITU-T Q.2630.1 (12/1999)
439 dis_field_channel_id(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
444 curr_offset = *offset;
446 SHORT_DATA_CHECK(*len, 1);
448 oct = tvb_get_guint8(tvb, curr_offset);
450 proto_tree_add_uint_format(tree, hf_alcap_channel_id, tvb,
452 "Channel identifier (CID): %d%s",
454 oct ? "" : " (Null)");
458 *len -= (curr_offset - *offset);
459 *offset = curr_offset;
463 * Ref. ITU-T Q.2630.1 (12/1999)
467 dis_field_organizational_unique_id(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
472 curr_offset = *offset;
474 #define FIELD_ORGANIZATIONAL_UNIQUE_ID_LEN 3
476 SHORT_DATA_CHECK(*len, FIELD_ORGANIZATIONAL_UNIQUE_ID_LEN);
478 octs = tvb_get_ntoh24(tvb, curr_offset);
480 proto_tree_add_uint(tree, hf_alcap_organizational_unique_id, tvb,
481 curr_offset, FIELD_ORGANIZATIONAL_UNIQUE_ID_LEN, octs);
483 curr_offset += FIELD_ORGANIZATIONAL_UNIQUE_ID_LEN;
485 *len -= (curr_offset - *offset);
486 *offset = curr_offset;
490 * Ref. ITU-T Q.2630.1 (12/1999)
494 dis_field_audio_service(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
503 curr_offset = *offset;
505 #define FIELD_AUDIO_SERVICE_LEN 5
507 SHORT_DATA_CHECK(*len, FIELD_AUDIO_SERVICE_LEN);
510 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
511 curr_offset, FIELD_AUDIO_SERVICE_LEN, field_strings[FIELD_AUDIO_SERVICE]);
513 subtree = proto_item_add_subtree(item, ett_fields[FIELD_AUDIO_SERVICE]);
515 oct = tvb_get_guint8(tvb, curr_offset);
517 switch ((oct & 0xc0) >> 6)
519 case 0x00: str = "Designates a profile specified by ITU-T Rec. I.366.2; ignore organizational unique identifier"; break;
520 case 0x01: str = "Designates a profile specified by organizational unique identifier"; break;
521 case 0x02: str = "Designates a custom profile; ignore organizational unique identifier"; break;
522 case 0x03: str = "Reserved"; break;
525 my_decode_bitfield_value(bigbuf, oct, 0xc0, 8);
526 proto_tree_add_text(subtree, tvb,
528 "%s : Profile type, %s",
531 my_decode_bitfield_value(bigbuf, oct, 0x3f, 8);
532 proto_tree_add_text(subtree, tvb,
539 oct = tvb_get_guint8(tvb, curr_offset);
541 proto_tree_add_text(subtree, tvb,
543 "Profile identifier (%d)",
548 oct = tvb_get_guint8(tvb, curr_offset);
550 my_decode_bitfield_value(bigbuf, oct, 0x80, 8);
551 proto_tree_add_text(subtree, tvb,
553 "%s : FRM, transport of frame mode data %s",
555 (oct & 0x80) ? "enabled" : "disabled");
557 my_decode_bitfield_value(bigbuf, oct, 0x40, 8);
558 proto_tree_add_text(subtree, tvb,
560 "%s : CMD, transport of circuit mode data (64 kbit/s) %s",
562 (oct & 0x40) ? "enabled" : "disabled");
564 my_decode_bitfield_value(bigbuf, oct, 0x20, 8);
565 proto_tree_add_text(subtree, tvb,
567 "%s : MF-R2, transport of multi-frequency R2 dialled digits %s",
569 (oct & 0x20) ? "enabled" : "disabled");
571 my_decode_bitfield_value(bigbuf, oct, 0x10, 8);
572 proto_tree_add_text(subtree, tvb,
574 "%s : MF-R1, transport of multi-frequency R1 dialled digits %s",
576 (oct & 0x10) ? "enabled" : "disabled");
578 my_decode_bitfield_value(bigbuf, oct, 0x08, 8);
579 proto_tree_add_text(subtree, tvb,
581 "%s : DTMF, transport of dual tone multi-frequency dialled digits %s",
583 (oct & 0x08) ? "enabled" : "disabled");
585 my_decode_bitfield_value(bigbuf, oct, 0x04, 8);
586 proto_tree_add_text(subtree, tvb,
588 "%s : CAS, transport of channel associated signalling %s",
590 (oct & 0x04) ? "enabled" : "disabled");
592 my_decode_bitfield_value(bigbuf, oct, 0x02, 8);
593 proto_tree_add_text(subtree, tvb,
595 "%s : FAX, transport of demodulated facsimile data %s",
597 (oct & 0x02) ? "enabled" : "disabled");
599 my_decode_bitfield_value(bigbuf, oct, 0x01, 8);
600 proto_tree_add_text(subtree, tvb,
602 "%s : A/mu-law, interpretation of generic PCM coding: %s-law",
604 (oct & 0x01) ? "mu" : "A");
608 value = tvb_get_ntohs(tvb, curr_offset);
610 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
612 "Maximum length of frame mode data (%d)",
617 *len -= (curr_offset - *offset);
618 *offset = curr_offset;
622 * Ref. ITU-T Q.2630.1 (12/1999)
626 dis_field_multirate_service(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
634 curr_offset = *offset;
636 #define FIELD_MULTIRATE_SERVICE_LEN 3
638 SHORT_DATA_CHECK(*len, FIELD_MULTIRATE_SERVICE_LEN);
641 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
642 curr_offset, FIELD_MULTIRATE_SERVICE_LEN, field_strings[FIELD_MULTIRATE_SERVICE]);
644 subtree = proto_item_add_subtree(item, ett_fields[FIELD_MULTIRATE_SERVICE]);
646 oct = tvb_get_guint8(tvb, curr_offset);
648 my_decode_bitfield_value(bigbuf, oct, 0x80, 8);
649 proto_tree_add_text(subtree, tvb,
651 "%s : FRM, transport of frame mode data %s",
653 (oct & 0x80) ? "enabled" : "disabled");
655 my_decode_bitfield_value(bigbuf, oct, 0x60, 8);
656 proto_tree_add_text(subtree, tvb,
661 my_decode_bitfield_value(bigbuf, oct, 0x1f, 8);
662 proto_tree_add_text(subtree, tvb,
664 "%s : Multiplier (%d) for n x 64 kbit/s",
670 value = tvb_get_ntohs(tvb, curr_offset);
672 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
674 "Maximum length of frame mode data (%d)",
679 *len -= (curr_offset - *offset);
680 *offset = curr_offset;
684 * Ref. ITU-T Q.2630.1 (12/1999)
688 dis_field_seg_reassembly_ass(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
695 curr_offset = *offset;
697 #define FIELD_SEG_REASSEMBLY_ASS_LEN 14
699 SHORT_DATA_CHECK(*len, FIELD_SEG_REASSEMBLY_ASS_LEN);
702 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
703 curr_offset, FIELD_SEG_REASSEMBLY_ASS_LEN, field_strings[FIELD_SEG_REASSEMBLY_ASS]);
705 subtree = proto_item_add_subtree(item, ett_fields[FIELD_SEG_REASSEMBLY_ASS]);
707 value = tvb_get_ntoh24(tvb, curr_offset);
709 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
711 "Maximum length of SSSAR-SDU in the forward direction (%d)",
716 value = tvb_get_ntoh24(tvb, curr_offset);
718 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
720 "Maximum length of SSSAR-SDU in the backward direction (%d)",
725 value = tvb_get_ntohs(tvb, curr_offset);
727 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
729 "Maximum length of SSCOP-SDU in the forward direction (%d)",
734 value = tvb_get_ntohs(tvb, curr_offset);
736 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
738 "Maximum length of SSCOP-SDU in the backward direction (%d)",
743 value = tvb_get_ntohs(tvb, curr_offset);
745 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
747 "Maximum length of SSCOP-UU in the forward direction (%d)",
752 value = tvb_get_ntohs(tvb, curr_offset);
754 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
756 "Maximum length of SSCOP-UU in the backward direction (%d)",
761 *len -= (curr_offset - *offset);
762 *offset = curr_offset;
766 * Ref. ITU-T Q.2630.1 (12/1999)
770 dis_field_seg_reassembly_unass(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
778 curr_offset = *offset;
780 #define FIELD_SEG_REASSEMBLY_UNASS_LEN 7
782 SHORT_DATA_CHECK(*len, FIELD_SEG_REASSEMBLY_UNASS_LEN);
785 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
786 curr_offset, FIELD_SEG_REASSEMBLY_UNASS_LEN, field_strings[FIELD_SEG_REASSEMBLY_UNASS]);
788 subtree = proto_item_add_subtree(item, ett_fields[FIELD_SEG_REASSEMBLY_UNASS]);
790 value = tvb_get_ntoh24(tvb, curr_offset);
792 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
794 "Maximum length of SSSAR-SDU in the forward direction (%d)",
799 value = tvb_get_ntoh24(tvb, curr_offset);
801 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
803 "Maximum length of SSSAR-SDU in the backward direction (%d)",
808 oct = tvb_get_guint8(tvb, curr_offset);
810 my_decode_bitfield_value(bigbuf, oct, 0x80, 8);
811 proto_tree_add_text(subtree, tvb,
813 "%s : TED, transmission error detection %s",
815 oct & 0x80 ? "enabled" : "disabled");
817 my_decode_bitfield_value(bigbuf, oct, 0x7f, 8);
818 proto_tree_add_text(subtree, tvb,
825 *len -= (curr_offset - *offset);
826 *offset = curr_offset;
830 * Ref. ITU-T Q.2630.1 (12/1999)
834 dis_field_served_user_gen_ref(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
839 curr_offset = *offset;
841 #define FIELD_SERVED_USER_GEN_REF_LEN 4
843 SHORT_DATA_CHECK(*len, FIELD_SERVED_USER_GEN_REF_LEN);
845 value = tvb_get_ntohl(tvb, curr_offset);
847 proto_tree_add_uint(tree, hf_alcap_served_user_gen_ref, tvb,
848 curr_offset, FIELD_SERVED_USER_GEN_REF_LEN, value);
850 curr_offset += FIELD_SERVED_USER_GEN_REF_LEN;
852 *len -= (curr_offset - *offset);
853 *offset = curr_offset;
857 * Ref. ITU-T Q.2630.1 (12/1999)
861 dis_field_cps_sdu_bit_rate(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset, gboolean maximum)
868 curr_offset = *offset;
870 #define FIELD_CPS_SDU_BIT_RATE_LEN 4
872 SHORT_DATA_CHECK(*len, FIELD_CPS_SDU_BIT_RATE_LEN);
875 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
876 curr_offset, FIELD_CPS_SDU_BIT_RATE_LEN, field_strings[FIELD_MAX_CPS_SDU_BIT_RATE + (maximum ? 0 : 1)]);
878 subtree = proto_item_add_subtree(item, ett_fields[FIELD_MAX_CPS_SDU_BIT_RATE + (maximum ? 0 : 1)]);
880 value = tvb_get_ntohs(tvb, curr_offset);
882 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
884 "CPS-SDU bit rate in the forward direction (%d)",
889 value = tvb_get_ntohs(tvb, curr_offset);
891 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
893 "CPS-SDU bit rate in the backward direction (%d)",
898 *len -= (curr_offset - *offset);
899 *offset = curr_offset;
903 * Ref. ITU-T Q.2630.1 (12/1999)
907 dis_field_cps_sdu_size(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset, gboolean maximum)
914 curr_offset = *offset;
916 #define FIELD_CPS_SDU_SIZE_LEN 2
918 SHORT_DATA_CHECK(*len, FIELD_CPS_SDU_SIZE_LEN);
921 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
922 curr_offset, FIELD_CPS_SDU_SIZE_LEN, field_strings[FIELD_MAX_CPS_SDU_SIZE + (maximum ? 0 : 1)]);
924 subtree = proto_item_add_subtree(item, ett_fields[FIELD_MAX_CPS_SDU_SIZE + (maximum ? 0 : 1)]);
926 oct = tvb_get_guint8(tvb, curr_offset);
928 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
930 "CPS-SDU size in the forward direction (%d)",
935 oct = tvb_get_guint8(tvb, curr_offset);
937 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
939 "CPS-SDU size in the backward direction (%d)",
944 *len -= (curr_offset - *offset);
945 *offset = curr_offset;
949 * Ref. ITU-T Q.2630.1 (12/1999)
953 dis_field_nature_of_address(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
962 curr_offset = *offset;
964 #define FIELD_NATURE_OF_ADDRESS_LEN 1
966 SHORT_DATA_CHECK(*len, FIELD_NATURE_OF_ADDRESS_LEN);
969 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
970 curr_offset, FIELD_NATURE_OF_ADDRESS_LEN, field_strings[FIELD_NATURE_OF_ADDRESS]);
972 subtree = proto_item_add_subtree(item, ett_fields[FIELD_NATURE_OF_ADDRESS]);
974 oct = tvb_get_guint8(tvb, curr_offset);
976 my_decode_bitfield_value(bigbuf, oct, 0x80, 8);
977 proto_tree_add_text(subtree, tvb,
986 case 0x00: str = "spare"; break;
987 case 0x01: str = "subscriber number (national use)"; break;
988 case 0x02: str = "unknown (national use)"; break;
989 case 0x03: str = "national (significant) number"; break;
990 case 0x04: str = "international number"; break;
991 case 0x05: str = "network-specific number (national use)"; break;
993 if ((value >= 0x06) && (value <= 0x6f)) { str = "spare"; break; }
994 else if ((value >= 0x70) && (value <= 0xfe)) { str = "reserved for national use"; break; }
995 else { str = "not given in spec. ???"; break; }
998 my_decode_bitfield_value(bigbuf, oct, 0x7f, 8);
999 proto_tree_add_text(subtree, tvb,
1001 "%s : Nature of address code, %s (%d)",
1008 *len -= (curr_offset - *offset);
1009 *offset = curr_offset;
1013 * Ref. ITU-T Q.2630.1 (12/1999)
1017 dis_field_e164_address(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
1019 guint32 curr_offset;
1021 proto_tree *subtree;
1026 curr_offset = *offset;
1028 SHORT_DATA_CHECK(*len, 1);
1031 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
1032 curr_offset, -1, field_strings[FIELD_E164_ADDRESS]);
1034 subtree = proto_item_add_subtree(item, ett_fields[FIELD_E164_ADDRESS]);
1036 parm_len = tvb_get_guint8(tvb, curr_offset);
1038 proto_item_set_len(item, parm_len + 1);
1040 proto_tree_add_uint(subtree, hf_alcap_length, tvb, curr_offset, 1, parm_len);
1047 while (i < parm_len)
1049 oct = tvb_get_guint8(tvb, curr_offset);
1051 my_decode_bitfield_value(bigbuf, oct, 0xf0, 8);
1052 proto_tree_add_text(subtree, tvb,
1057 bigbuf2[i] = (oct & 0x0f) + 0x30;
1059 my_decode_bitfield_value(bigbuf, oct, 0x0f, 8);
1060 proto_tree_add_text(subtree, tvb,
1062 "%s : Digit %d of address (%d)",
1073 proto_item_append_text(item, " (%s)", bigbuf2);
1076 *len -= (curr_offset - *offset);
1077 *offset = curr_offset;
1081 * Ref. ITU-T Q.2630.1 (12/1999)
1085 dis_field_nsap_address(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
1087 guint32 curr_offset;
1089 curr_offset = *offset;
1091 #define FIELD_NSAP_ADDRESS_LEN 20
1093 SHORT_DATA_CHECK(*len, FIELD_NSAP_ADDRESS_LEN);
1095 proto_tree_add_item(tree, hf_alcap_nsap_address, tvb,
1096 curr_offset, FIELD_NSAP_ADDRESS_LEN, FALSE);
1098 curr_offset += FIELD_NSAP_ADDRESS_LEN;
1100 *len -= (curr_offset - *offset);
1101 *offset = curr_offset;
1105 * Ref. ITU-T Q.2630.1 (12/1999)
1109 dis_field_cause_value(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset, gboolean *compat)
1111 guint32 curr_offset;
1114 proto_tree *subtree;
1118 curr_offset = *offset;
1120 #define FIELD_CAUSE_VALUE_LEN 2
1122 SHORT_DATA_CHECK(*len, FIELD_CAUSE_VALUE_LEN);
1125 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
1126 curr_offset, FIELD_CAUSE_VALUE_LEN, field_strings[FIELD_CAUSE_VALUE]);
1128 subtree = proto_item_add_subtree(item, ett_fields[FIELD_CAUSE_VALUE]);
1130 oct = tvb_get_guint8(tvb, curr_offset);
1132 my_decode_bitfield_value(bigbuf, oct, 0xfc, 8);
1133 proto_tree_add_text(subtree, tvb,
1140 case 0x00: str = "ITU-T standardized coding as described in ITU-T Rec. Q.850 and Q.2610"; break;
1141 case 0x01: str = "ISO/IEC standard"; break;
1142 case 0x02: str = "national standard"; break;
1143 case 0x03: str = "standard defined for the network (either public or private) present on the network side of the interface"; break;
1146 my_decode_bitfield_value(bigbuf, oct, 0x03, 8);
1147 proto_tree_add_text(subtree, tvb,
1149 "%s : Coding standard, %s",
1155 oct = tvb_get_guint8(tvb, curr_offset);
1157 my_decode_bitfield_value(bigbuf, oct, 0x80, 8);
1158 proto_tree_add_text(subtree, tvb,
1165 case 1: str = "Unallocated (unassigned) number"; break;
1166 case 3: str = "No route to destination"; break;
1167 case 31: str = "Normal, unspecified"; break;
1168 case 34: str = "No circuit/channel available"; break;
1169 case 38: str = "Network out of order"; break;
1170 case 41: str = "Temporary failure"; break;
1171 case 42: str = "Switching equipment congestion"; break;
1172 case 44: str = "Requested circuit/channel not available"; break;
1173 case 47: str = "Resource unavailable, unspecified"; break;
1174 case 93: str = "AAL parameters cannot be supported"; break;
1175 case 95: str = "Invalid message, unspecified"; break;
1176 case 96: str = "Mandatory information element is missing"; break;
1177 case 97: str = "Message type non-existent or not implemented"; *compat = TRUE; break;
1178 case 99: str = "Information element/parameter non-existent or not implemented"; *compat = TRUE; break;
1179 case 100: str = "Invalid information element contents"; break;
1180 case 102: str = "Recovery on timer expiry"; break;
1181 case 110: str = "Message with unrecognized parameter, discarded"; *compat = TRUE; break;
1182 default: str = "Unknown"; break;
1185 my_decode_bitfield_value(bigbuf, oct, 0x7f, 8);
1186 proto_tree_add_text(subtree, tvb,
1188 "%s : Cause (%d), %s",
1195 *len -= (curr_offset - *offset);
1196 *offset = curr_offset;
1200 * Ref. ITU-T Q.2630.1 (12/1999)
1204 dis_field_diagnostics(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset, gboolean compat)
1206 guint32 curr_offset;
1209 proto_tree *subtree;
1215 curr_offset = *offset;
1217 SHORT_DATA_CHECK(*len, 1);
1220 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
1221 curr_offset, -1, field_strings[FIELD_DIAGNOSTICS]);
1223 subtree = proto_item_add_subtree(item, ett_fields[FIELD_DIAGNOSTICS]);
1225 parm_len = tvb_get_guint8(tvb, curr_offset);
1227 proto_item_set_len(item, parm_len + 1);
1229 proto_tree_add_uint(subtree, hf_alcap_length, tvb, curr_offset, 1, parm_len);
1238 * compatibility diagnostics
1240 oct = tvb_get_guint8(tvb, curr_offset);
1242 str = my_match_strval(oct, msg_type_strings, &idx);
1244 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1245 curr_offset, 1, (str == NULL) ? "Unknown message identifier" : str);
1250 while ((i+2) <= parm_len)
1252 oct = tvb_get_guint8(tvb, curr_offset);
1254 str = my_match_strval(oct, msg_parm_strings, &idx);
1256 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1257 curr_offset, 1, (str == NULL) ? "Unknown parameter" : str);
1261 oct = tvb_get_guint8(tvb, curr_offset);
1265 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1266 curr_offset, 1, "Whole parameter");
1270 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1271 curr_offset, 1, "Field number %d", oct);
1280 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1281 curr_offset, parm_len - i, "Extraneous Data ???");
1283 curr_offset += (parm_len - i);
1288 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1289 curr_offset, parm_len, "Coded as per ITU-T Rec. Q.2610");
1291 curr_offset += parm_len;
1295 *len -= (curr_offset - *offset);
1296 *offset = curr_offset;
1300 * Ref. ITU-T Q.2630.1 (12/1999)
1304 dis_field_served_user_transport(tvbuff_t *tvb, proto_tree *tree, guint *len, guint32 *offset)
1306 guint32 curr_offset;
1308 proto_tree *subtree;
1311 curr_offset = *offset;
1313 SHORT_DATA_CHECK(*len, 1);
1316 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
1317 curr_offset, -1, field_strings[FIELD_SERVED_USER_TRANSPORT]);
1319 subtree = proto_item_add_subtree(item, ett_fields[FIELD_SERVED_USER_TRANSPORT]);
1321 parm_len = tvb_get_guint8(tvb, curr_offset);
1323 proto_item_set_len(item, parm_len + 1);
1325 proto_tree_add_uint(subtree, hf_alcap_length, tvb, curr_offset, 1, parm_len);
1331 proto_tree_add_none_format(subtree, hf_alcap_none, tvb,
1332 curr_offset, parm_len, "Value");
1334 curr_offset += parm_len;
1337 *len -= (curr_offset - *offset);
1338 *offset = curr_offset;
1342 * Ref. ITU-T Q.2630.1 (12/1999)
1346 dis_parm_cause(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1350 dis_field_cause_value(tvb, tree, &len, &curr_offset, &compat);
1352 dis_field_diagnostics(tvb, tree, &len, &curr_offset, compat);
1354 EXTRANEOUS_DATA_CHECK(len, 0);
1358 * Ref. ITU-T Q.2630.1 (12/1999)
1362 dis_parm_conn_element_id(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1365 dis_field_aal2_path_id(tvb, tree, &len, &curr_offset);
1367 dis_field_channel_id(tvb, tree, &len, &curr_offset);
1369 EXTRANEOUS_DATA_CHECK(len, 0);
1373 * Ref. ITU-T Q.2630.1 (12/1999)
1377 dis_parm_dest_e164_sea(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1380 dis_field_nature_of_address(tvb, tree, &len, &curr_offset);
1382 dis_field_e164_address(tvb, tree, &len, &curr_offset);
1384 EXTRANEOUS_DATA_CHECK(len, 0);
1388 * Ref. ITU-T Q.2630.1 (12/1999)
1392 dis_parm_dest_nsap_sea(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1395 dis_field_nsap_address(tvb, tree, &len, &curr_offset);
1397 EXTRANEOUS_DATA_CHECK(len, 0);
1401 * Ref. ITU-T Q.2630.1 (12/1999)
1405 dis_parm_link_characteristics(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1408 dis_field_cps_sdu_bit_rate(tvb, tree, &len, &curr_offset, TRUE);
1410 dis_field_cps_sdu_bit_rate(tvb, tree, &len, &curr_offset, FALSE);
1412 dis_field_cps_sdu_size(tvb, tree, &len, &curr_offset, TRUE);
1414 dis_field_cps_sdu_size(tvb, tree, &len, &curr_offset, FALSE);
1416 EXTRANEOUS_DATA_CHECK(len, 0);
1420 * Ref. ITU-T Q.2630.1 (12/1999)
1424 dis_parm_osai(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1427 dis_field_signalling_assoc_id(tvb, tree, &len, &curr_offset, FALSE);
1429 EXTRANEOUS_DATA_CHECK(len, 0);
1433 * Ref. ITU-T Q.2630.1 (12/1999)
1437 dis_parm_served_user_gen_ref(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1440 dis_field_served_user_gen_ref(tvb, tree, &len, &curr_offset);
1442 EXTRANEOUS_DATA_CHECK(len, 0);
1446 * Ref. ITU-T Q.2630.1 (12/1999)
1450 dis_parm_served_user_transport(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1453 dis_field_served_user_transport(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_audio(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1466 dis_field_audio_service(tvb, tree, &len, &curr_offset);
1468 dis_field_organizational_unique_id(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_multirate(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1481 dis_field_multirate_service(tvb, tree, &len, &curr_offset);
1483 EXTRANEOUS_DATA_CHECK(len, 0);
1487 * Ref. ITU-T Q.2630.1 (12/1999)
1491 dis_parm_service_specific_info_ass(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1494 dis_field_seg_reassembly_ass(tvb, tree, &len, &curr_offset);
1496 EXTRANEOUS_DATA_CHECK(len, 0);
1500 * Ref. ITU-T Q.2630.1 (12/1999)
1504 dis_parm_service_specific_info_unass(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 curr_offset)
1507 dis_field_seg_reassembly_unass(tvb, tree, &len, &curr_offset);
1509 EXTRANEOUS_DATA_CHECK(len, 0);
1512 static gint ett_parms[NUM_PARMS];
1513 static void (*alcap_parm_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) = {
1514 dis_parm_cause, /* Cause */
1515 dis_parm_conn_element_id, /* Connection element identifier */
1516 dis_parm_dest_e164_sea, /* Destination E.164 service endpoint address */
1517 dis_parm_dest_nsap_sea, /* Destination NSAP service endpoint address */
1518 dis_parm_link_characteristics, /* Link characteristics */
1519 dis_parm_osai, /* Originating signalling association identifier */
1520 dis_parm_served_user_gen_ref, /* Served user generated reference */
1521 dis_parm_served_user_transport, /* Served user transport */
1522 dis_parm_service_specific_info_audio, /* Service specific information (audio) */
1523 dis_parm_service_specific_info_multirate, /* Service specific information (multirate) */
1524 dis_parm_service_specific_info_ass, /* Service specific information (SAR-assured) */
1525 dis_parm_service_specific_info_unass, /* Service specific information (SAR-unassured) */
1526 NULL /* no parms */, /* Test connection identifier */
1530 /* GENERIC ALCAP DISSECTOR FUNCTIONS */
1533 dissect_alcap_parms(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 len)
1535 void (*parm_fcn)(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) = NULL;
1538 guint32 curr_offset, saved_offset;
1542 proto_tree *subtree;
1546 curr_offset = offset;
1548 while (len >= ALCAP_PARM_HEADER_LEN)
1550 saved_offset = curr_offset;
1552 parm = tvb_get_guint8(tvb, curr_offset);
1554 str = my_match_strval(parm, msg_parm_strings, &idx);
1558 ett_parm_idx = ett_parm;
1563 ett_parm_idx = ett_parms[idx];
1564 parm_fcn = alcap_parm_fcn[idx];
1568 proto_tree_add_none_format(tree, hf_alcap_none, tvb,
1569 curr_offset, -1, (str == NULL) ? "Unknown parameter" : str);
1571 subtree = proto_item_add_subtree(item, ett_parm_idx);
1573 proto_tree_add_uint(subtree, hf_alcap_parm_id, tvb,
1574 curr_offset, 1, parm);
1578 dis_field_compatibility(tvb, subtree, &curr_offset, FALSE);
1580 parm_len = tvb_get_guint8(tvb, curr_offset);
1582 proto_tree_add_uint(subtree, hf_alcap_length, tvb, curr_offset, 1, parm_len);
1586 proto_item_set_len(item, (curr_offset - saved_offset) + parm_len);
1590 if (parm_fcn == NULL)
1592 proto_tree_add_none_format(subtree, hf_alcap_none,
1593 tvb, curr_offset, parm_len, "Parameter data");
1597 (*parm_fcn)(tvb, subtree, parm_len, curr_offset);
1601 len -= (ALCAP_PARM_HEADER_LEN + parm_len);
1602 curr_offset += parm_len;
1605 EXTRANEOUS_DATA_CHECK(len, 0);
1609 dissect_alcap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *alcap_tree)
1620 len = tvb_length(tvb);
1623 if (len < ALCAP_MSG_HEADER_LEN)
1625 proto_tree_add_none_format(alcap_tree, hf_alcap_none, tvb,
1626 offset, len, "Message header too short");
1631 dis_field_signalling_assoc_id(tvb, alcap_tree, &temp_len, &offset, TRUE);
1633 msg_type = tvb_get_guint8(tvb, offset);
1635 str = my_match_strval(msg_type, msg_type_strings, &idx);
1639 proto_tree_add_none_format(alcap_tree, hf_alcap_none, tvb,
1640 offset, 1, "Unknown message identifier");
1645 if (check_col(pinfo->cinfo, COL_INFO))
1647 col_set_str(pinfo->cinfo, COL_INFO, str);
1650 proto_tree_add_uint(alcap_tree, hf_alcap_msg_type, tvb,
1651 offset, 1, msg_type);
1655 dis_field_compatibility(tvb, alcap_tree, &offset, TRUE);
1657 if (len > ALCAP_MSG_HEADER_LEN)
1659 dissect_alcap_parms(tvb, alcap_tree, offset, len - ALCAP_MSG_HEADER_LEN);
1664 dissect_alcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1666 proto_item *alcap_item;
1667 proto_tree *alcap_tree = NULL;
1672 * Don't change the Protocol column on summary display
1674 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1676 col_set_str(pinfo->cinfo, COL_PROTOCOL, alcap_proto_name_short);
1679 /* In the interest of speed, if "tree" is NULL, don't do any work not
1680 * necessary to generate protocol tree items.
1687 * create the ALCAP protocol tree
1690 proto_tree_add_protocol_format(tree, proto_alcap, tvb, 0, -1,
1694 proto_item_add_subtree(alcap_item, ett_alcap);
1696 dissect_alcap_message(tvb, pinfo, alcap_tree);
1701 /* Register the protocol with Ethereal */
1703 proto_register_alcap(void)
1707 /* Setup list of header fields */
1708 static hf_register_info hf[] =
1710 { &hf_alcap_msg_type,
1713 FT_UINT8, BASE_DEC, VALS(msg_type_strings), 0,
1716 { "Destination signalling association identifier",
1718 FT_UINT32, BASE_DEC, NULL, 0,
1722 { "Originating signalling association identifier",
1724 FT_UINT32, BASE_DEC, NULL, 0,
1727 { &hf_alcap_aal2_path_id,
1728 { "AAL2 path identifier",
1729 "alcap.aal2_path_id",
1730 FT_UINT32, BASE_DEC, NULL, 0,
1733 { &hf_alcap_channel_id,
1734 { "Channel identifier (CID)",
1736 FT_UINT32, BASE_DEC, NULL, 0,
1739 { &hf_alcap_organizational_unique_id,
1740 { "Organizational unique identifier (OUI)",
1741 "alcap.organizational_unique_id",
1742 FT_UINT24, BASE_DEC, NULL, 0,
1745 { &hf_alcap_served_user_gen_ref,
1746 { "Served user generated reference",
1747 "alcap.served_user_gen_ref",
1748 FT_UINT32, BASE_DEC, NULL, 0,
1751 { &hf_alcap_nsap_address,
1753 "alcap.nsap_address",
1754 FT_BYTES, BASE_NONE, NULL, 0,
1757 { &hf_alcap_parm_id,
1758 { "Parameter identifier",
1760 FT_UINT8, BASE_DEC, NULL, 0,
1763 { "Length", "alcap.len",
1764 FT_UINT8, BASE_DEC, NULL, 0,
1768 { "Subtree", "alcap.none",
1774 /* Setup protocol subtree array */
1775 #define NUM_INDIVIDUAL_PARMS 2
1776 static gint *ett[NUM_INDIVIDUAL_PARMS+NUM_PARMS+NUM_FIELDS];
1778 memset((void *) ett, 0, sizeof(ett));
1780 ett[0] = &ett_alcap;
1783 for (i=0; i < NUM_PARMS; i++)
1786 ett[NUM_INDIVIDUAL_PARMS+i] = &ett_parms[i];
1789 for (i=0; i < NUM_FIELDS; i++)
1792 ett[NUM_INDIVIDUAL_PARMS+NUM_PARMS+i] = &ett_fields[i];
1795 /* Register the protocol name and description */
1797 proto_register_protocol(alcap_proto_name, alcap_proto_name_short, "alcap");
1799 /* Required function calls to register the header fields and subtrees used */
1800 proto_register_field_array(proto_alcap, hf, array_length(hf));
1801 proto_register_subtree_array(ett, array_length(ett));
1806 proto_reg_handoff_alcap(void)
1808 dissector_handle_t alcap_handle;
1810 alcap_handle = create_dissector_handle(dissect_alcap, proto_alcap);
1812 dissector_add("mtp3.service_indicator", ALCAP_SI, alcap_handle);
1814 data_handle = find_dissector("data");