2 XXX all this offset>>3 and calculations of bytes in the tvb everytime
3 we put something in the tree is just silly. should be replaced with some
7 * Routines for dissection of ASN.1 Aligned PER
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
36 #include <epan/packet.h>
43 #include <epan/oids.h>
44 #include <epan/to_str.h>
45 #include <epan/prefs.h>
46 #include <epan/emem.h>
47 #include <epan/asn1.h>
48 #include <epan/strutil.h>
49 #include <epan/expert.h>
50 #include "packet-per.h"
53 static int proto_per = -1;
54 static int hf_per_GeneralString_length = -1;
55 static int hf_per_extension_bit = -1;
56 static int hf_per_extension_present_bit = -1;
57 static int hf_per_choice_index = -1;
58 static int hf_per_choice_extension_index = -1;
59 static int hf_per_enum_index = -1;
60 static int hf_per_enum_extension_index = -1;
61 static int hf_per_num_sequence_extensions = -1;
62 static int hf_per_small_number_bit = -1;
63 static int hf_per_optional_field_bit = -1;
64 static int hf_per_sequence_of_length = -1;
65 static int hf_per_object_identifier_length = -1;
66 static int hf_per_open_type_length = -1;
67 static int hf_per_real_length = -1;
68 static int hf_per_octet_string_length = -1;
69 static int hf_per_bit_string_length = -1;
70 static int hf_per_const_int_len = -1;
71 static int hf_per_direct_reference = -1; /* T_direct_reference */
72 static int hf_per_indirect_reference = -1; /* T_indirect_reference */
73 static int hf_per_data_value_descriptor = -1; /* T_data_value_descriptor */
74 static int hf_per_encoding = -1; /* External_encoding */
75 static int hf_per_single_ASN1_type = -1; /* T_single_ASN1_type */
76 static int hf_per_octet_aligned = -1; /* T_octet_aligned */
77 static int hf_per_arbitrary = -1; /* T_arbitrary */
78 static int hf_per_integer_length = -1; /* Show integer length if "show internal per fields" */
80 static gint ett_per_open_type = -1;
81 static gint ett_per_containing = -1;
82 static gint ett_per_sequence_of_item = -1;
83 static gint ett_per_External = -1;
84 static gint ett_per_External_encoding = -1;
87 #define DEBUG_ENTRY(x) \
88 printf("#%u %s tvb:0x%08x\n",actx->pinfo->fd->num,x,(int)tvb);
90 #define DEBUG_ENTRY(x) \
93 #define BLEN(old_offset, offset) (((offset)>>3)!=((old_offset)>>3)?((offset)>>3)-((old_offset)>>3):1)
95 /* whether the PER helpers should put the internal PER fields into the tree
98 static gboolean display_internal_per_fields = FALSE;
102 static const true_false_string tfs_extension_present_bit = {
106 static const true_false_string tfs_extension_bit = {
107 "Extension bit is set",
108 "Extension bit is clear"
110 static const true_false_string tfs_small_number_bit = {
111 "The number is small, 0-63",
112 "The number is large, >63"
114 static const true_false_string tfs_optional_field_bit = {
120 #define BYTE_ALIGN_OFFSET(offset) if(offset&0x07){offset=(offset&0xfffffff8)+8;}
122 static tvbuff_t *new_octet_aligned_subset(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, guint32 length)
124 tvbuff_t *sub_tvb = NULL;
125 guint32 boffset = offset >> 3;
126 unsigned int i, shift0, shift1;
127 guint8 octet0, octet1, *buf;
128 guint32 actual_length;
130 actual_length = tvb_length_remaining(tvb,boffset);
131 if (length <= actual_length)
132 actual_length = length;
134 if (offset & 0x07) { /* unaligned */
135 shift1 = offset & 0x07;
137 buf = ep_alloc(actual_length);
138 octet0 = tvb_get_guint8(tvb, boffset);
139 for (i=0; i<actual_length; i++) {
141 octet0 = tvb_get_guint8(tvb, boffset + i + 1);
142 buf[i] = (octet1 << shift1) | (octet0 >> shift0);
144 sub_tvb = tvb_new_child_real_data(tvb, buf, actual_length, length);
145 add_new_data_source(actx->pinfo, sub_tvb, "Unaligned OCTET STRING");
146 } else { /* aligned */
147 sub_tvb = tvb_new_subset(tvb, boffset, actual_length, length);
152 static const guint16 bit_mask16[] = {
163 /* Fetch a number of bits to a new tvb right adjusted to the nearest number of bytes.
164 * (add proceeding zeros in case of aligned PER)
166 tvbuff_t *new_octet_aligned_subset_bits(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, guint32 no_of_bits)
168 tvbuff_t *sub_tvb = NULL;
169 guint32 boffset = offset >> 3;
170 unsigned int i, shift0, shift1;
171 guint8 octet0, octet1, *buf;
177 /* Calculate the size reqired */
179 length = no_of_bits/8;
180 remainder = no_of_bits % 8;
184 /* Number of bits = even number of octets */
185 return new_octet_aligned_subset(tvb, offset, actx, length);
187 buf = ep_alloc(length);
191 /* get the 'odd' bits */
192 shift1 = offset & 0x07;
193 word = tvb_get_ntohs(tvb,boffset) & bit_mask16[offset & 0x07];
194 word = word >> (16-(shift1+remainder));
195 buf[0] = word & 0x00ff;
197 offset = offset + remainder;
198 boffset = offset >> 3;
200 shift1 = offset & 0x07;
202 octet0 = tvb_get_guint8(tvb, boffset);
203 for (i=1; i<length; i++) {
205 octet0 = tvb_get_guint8(tvb, boffset + i);
206 buf[i] = (octet1 << shift1) | (octet0 >> shift0);
212 /* Do not preceed with zeros in case of PER unaligned */
214 shift1 = offset & 0x07;
218 octet0 = tvb_get_guint8(tvb, boffset);
219 for (; i < length-1; i++) {
221 octet0 = tvb_get_guint8(tvb, boffset + i + 1);
222 buf[i] = (octet1 << shift1) | (octet0 >> shift0);
225 /* get the 'odd' bits */
226 word = tvb_get_ntohs(tvb,boffset+i) << shift1;
227 word = word & ~bit_mask16[remainder];
229 buf[i] = (guint8) (word & 0x00ff);
231 sub_tvb = tvb_new_child_real_data(tvb, buf, length, length);
232 add_new_data_source(actx->pinfo, sub_tvb, "Unaligned OCTET STRING");
238 /* 10 Encoding procedures -------------------------------------------------- */
240 /* 10.2 Open type fields --------------------------------------------------- */
242 dissect_per_open_type_internal(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, void* type_cb, asn1_cb_variant variant)
244 guint32 type_length, end_offset;
245 tvbuff_t *val_tvb = NULL;
246 header_field_info *hfi;
247 proto_tree *subtree = tree;
249 hfi = (hf_index == -1) ? NULL : proto_registrar_get_nth(hf_index);
251 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &type_length);
252 if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
253 end_offset = offset + type_length * 8;
255 if ((variant==CB_DISSECTOR)||(variant==CB_NEW_DISSECTOR)) {
256 val_tvb = new_octet_aligned_subset(tvb, offset, actx, type_length);
258 if (IS_FT_UINT(hfi->type)||IS_FT_INT(hfi->type)) {
259 if (IS_FT_UINT(hfi->type))
260 actx->created_item = proto_tree_add_uint(tree, hf_index, val_tvb, 0, type_length, type_length);
262 actx->created_item = proto_tree_add_int(tree, hf_index, val_tvb, 0, type_length, type_length);
263 proto_item_append_text(actx->created_item, plurality(type_length, " octet", " octets"));
265 actx->created_item = proto_tree_add_item(tree, hf_index, val_tvb, 0, type_length, FALSE);
267 subtree = proto_item_add_subtree(actx->created_item, ett_per_open_type);
274 ((per_type_fn)type_cb)(tvb, offset, actx, tree, hf_index);
277 ((dissector_t)type_cb)(val_tvb, actx->pinfo, subtree);
279 case CB_NEW_DISSECTOR:
280 ((new_dissector_t)type_cb)(val_tvb, actx->pinfo, subtree);
282 case CB_DISSECTOR_HANDLE:
286 actx->created_item = proto_tree_add_text(tree, tvb, offset>>3, BLEN(offset, end_offset), "Unknown Open Type");
293 dissect_per_open_type(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, per_type_fn type_cb)
295 return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, (void*)type_cb, CB_ASN1_ENC);
299 dissect_per_open_type_pdu(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, dissector_t type_cb)
301 return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, (void*)type_cb, CB_DISSECTOR);
305 dissect_per_open_type_pdu_new(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, new_dissector_t type_cb)
307 return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, (void*)type_cb, CB_NEW_DISSECTOR);
310 /* 10.9 General rules for encoding a length determinant --------------------
312 NOTE 1 - (Tutorial) The procedures of this subclause are invoked when an explicit length field is needed
313 for some part of the encoding regardless of whether the length count is bounded above
314 (by PER-visible constraints) or not. The part of the encoding to which the length applies may
315 be a bit string (with the length count in bits), an octet string (with the length count in octets),
316 a known-multiplier character string (with the length count in characters), or a list of fields
317 (with the length count in components of a sequence-of or set-of).
319 NOTE 2 - (Tutorial) In the case of the ALIGNED variant if the length count is bounded above by an upper bound
320 that is less than 64K, then the constrained whole number encoding is used for the length.
321 For sufficiently small ranges the result is a bit-field, otherwise the unconstrained length ("n" say)
322 is encoded into an octet-aligned bit-field in one of three ways (in order of increasing size):
323 a) ("n" less than 128) a single octet containing "n" with bit 8 set to zero;
324 b) ("n" less than 16K) two octets containing "n" with bit 8 of the first octet set to 1 and bit 7 set to zero;
325 c) (large "n") a single octet containing a count "m" with bit 8 set to 1 and bit 7 set to 1.
326 The count "m" is one to four, and the length indicates that a fragment of the material follows
327 (a multiple "m" of 16K items). For all values of "m", the fragment is then followed by another length encoding
328 for the remainder of the material.
330 NOTE 3 - (Tutorial) In the UNALIGNED variant, if the length count is bounded above by an upper bound that is less
331 than 64K, then the constrained whole number encoding is used to encode the length in the minimum number of
332 bits necessary to represent the range. Otherwise, the unconstrained length ("n" say) is encoded into a bit
333 field in the manner described above in Note 2.
337 dissect_per_length_determinant(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index, guint32 *length)
352 BYTE_ALIGN_OFFSET(offset);
353 byte=tvb_get_guint8(tvb, offset>>3);
360 val_start = offset>>3;
364 g_snprintf(str, 256, " ");
365 for(bit=0;bit<((int)(offset&0x07));bit++){
367 g_strlcat(str, " ", 256);
369 g_strlcat(str,".", 256);
371 /* read the bits for the int */
373 for(i=0;i<num_bits;i++){
375 g_strlcat(str, " ", 256);
378 g_strlcat(str, " ", 256);
381 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &tmp);
385 g_strlcat(str, "1", 256);
386 if (i==0) { /* bit 8 is 1, so not a single byte length */
389 else if (i==1 && val==3) { /* bits 8 and 7 both 1, so unconstrained */
390 PER_NOT_DECODED_YET("10.9 Unconstrained");
394 g_strlcat(str, "0", 256);
397 if((val&0x80)==0 && num_bits==8){
400 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
401 if (display_internal_per_fields)
402 proto_item_append_text(pi," %s", str);
404 PROTO_ITEM_SET_HIDDEN(pi);
409 else if (num_bits==16) {
410 *length = val&0x3fff;
412 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
413 if (display_internal_per_fields)
414 proto_item_append_text(pi," %s", str);
416 PROTO_ITEM_SET_HIDDEN(pi);
421 PER_NOT_DECODED_YET("10.9 Unaligned");
430 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
431 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(pi);
437 if((byte&0xc0)==0x80){
439 *length=((*length)<<8)+tvb_get_guint8(tvb, offset>>3);
442 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-2, 2, *length);
443 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(pi);
447 PER_NOT_DECODED_YET("10.9.3.8.1");
451 /* 10.6 normally small non-negative whole number */
453 dissect_per_normally_small_nonnegative_whole_number(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint32 *length)
455 gboolean small_number, length_bit;
459 DEBUG_ENTRY("dissect_per_normally_small_nonnegative_whole_number");
464 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_small_number_bit, &small_number);
465 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
471 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &length_bit);
478 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset-6)>>3, (offset%8<6)?2:1, *length);
479 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(pi);
485 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_index, length);
492 /* this function reads a GeneralString */
493 /* currently based on pure guesswork since RFC2833 didnt tell me much
494 i guess that the PER encoding for this is a normally-small-whole-number
495 followed by a ascii string.
497 based on pure guesswork. it looks ok in the only capture i have where
498 there is a 1 byte general string encoded
501 dissect_per_GeneralString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index)
505 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_GeneralString_length, &length);
507 proto_tree_add_item(tree, hf_index, tvb, offset>>3, length, FALSE);
514 /* 17 Encoding the null type */
516 dissect_per_null(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) {
519 ti_tmp = proto_tree_add_item(tree, hf_index, tvb, offset>>3, 1, FALSE);
520 proto_item_append_text(ti_tmp, ": NULL");
525 /* 19 this function dissects a sequence of */
527 dissect_per_sequence_of_helper(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, per_type_fn func, int hf_index, guint32 length)
531 DEBUG_ENTRY("dissect_per_sequence_of_helper");
532 for(i=0;i<length;i++){
533 guint32 lold_offset=offset;
537 litem=proto_tree_add_text(tree, tvb, offset>>3, 0, "Item %d", i);
538 ltree=proto_item_add_subtree(litem, ett_per_sequence_of_item);
540 offset=(*func)(tvb, offset, actx, ltree, hf_index);
541 proto_item_set_len(litem, (offset>>3)!=(lold_offset>>3)?(offset>>3)-(lold_offset>>3):1);
547 dissect_per_sequence_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq)
551 guint32 old_offset=offset;
553 header_field_info *hfi;
555 DEBUG_ENTRY("dissect_per_sequence_of");
557 /* semi-constrained whole number for number of elements */
558 /* each element encoded as 10.9 */
560 offset=dissect_per_length_determinant(tvb, offset, actx, parent_tree, hf_per_sequence_of_length, &length);
562 hfi = proto_registrar_get_nth(hf_index);
563 if (IS_FT_UINT(hfi->type)) {
564 item = proto_tree_add_uint(parent_tree, hf_index, tvb, offset>>3, 0, length);
565 proto_item_append_text(item, (length==1)?" item":" items");
567 item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, FALSE);
569 tree=proto_item_add_subtree(item, ett_index);
571 offset=dissect_per_sequence_of_helper(tvb, offset, actx, tree, seq->func, *seq->p_id, length);
574 proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
579 /* dissect a constrained IA5String that consists of the full ASCII set,
580 i.e. no FROM stuff limiting the alphabet
583 dissect_per_IA5String(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len)
585 offset=dissect_per_octet_string(tvb, offset, actx, tree, hf_index, min_len, max_len, FALSE, NULL);
590 /* XXX we dont do >64k length strings yet */
592 dissect_per_restricted_character_string_sorted(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, const char *alphabet, int alphabet_length, tvbuff_t **value_tvb)
595 gboolean byte_aligned;
601 DEBUG_ENTRY("dissect_per_restricted_character_string");
603 /* xx.x if the length is 0 bytes there will be no encoding */
606 *value_tvb = tvb_new_child_real_data(tvb, NULL, 0, 0);
612 if (min_len == NO_BOUND) {
617 /* 27.5.2 depending of the alphabet length, find how many bits
618 are used to encode each character */
622 if(alphabet_length<=2){
624 } else if(alphabet_length<=4){
626 } else if(alphabet_length<=16){
632 if(alphabet_length<=2){
634 } else if(alphabet_length<=4){
636 } else if(alphabet_length<=8){
638 } else if(alphabet_length<=16){
640 } else if(alphabet_length<=32){
642 } else if(alphabet_length<=64){
644 } else if(alphabet_length<=128){
652 if((min_len==max_len)&&(max_len<=2)){
655 if ((max_len != NO_BOUND) && (max_len < 2)) {
661 if (max_len == NO_BOUND) {
662 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_octet_string_length, &length);
663 /* the unconstrained strings are always byte aligned (27.6.3)*/
665 } else if(min_len!=max_len){
666 offset=dissect_per_constrained_integer(tvb, offset, actx,
667 tree, hf_per_octet_string_length, min_len, max_len,
669 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
673 /* there is no string at all, so dont do any byte alignment */
674 /* byte_aligned=FALSE; */
675 /* Advance offset to next 'element' */
676 offset = offset + 1; }
678 if((byte_aligned)&&(actx->aligned)){
679 BYTE_ALIGN_OFFSET(offset);
683 buf = g_malloc(length+1);
685 for(char_pos=0;char_pos<length;char_pos++){
691 for(i=0;i<bits_per_char;i++){
692 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
695 /* ALIGNED PER does not do any remapping of chars if
698 if(bits_per_char==8){
701 if (val < alphabet_length){
702 buf[char_pos]=alphabet[val];
704 buf[char_pos] = '?'; /* XXX - how to mark this? */
709 proto_tree_add_string(tree, hf_index, tvb, (old_offset>>3), (offset>>3)-(old_offset>>3), (char*)buf);
711 *value_tvb = tvb_new_child_real_data(tvb, buf, length, length);
712 tvb_set_free_cb(*value_tvb, g_free);
720 sort_alphabet(char *sorted_alphabet, const char *alphabet, int alphabet_length)
723 char c, c_max, c_min;
726 if (!alphabet_length) return sorted_alphabet;
727 memset(tmp_buf, 0, 256);
728 c_min = c_max = alphabet[0];
729 for (i=0; i<alphabet_length; i++) {
732 if (c > c_max) c_max = c;
733 else if (c < c_min) c_min = c;
735 for (i=c_min,j=0; i<=c_max; i++) {
736 if (tmp_buf[i]) sorted_alphabet[j++] = i;
738 return sorted_alphabet;
742 dissect_per_restricted_character_string(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, const char *alphabet, int alphabet_length, tvbuff_t **value_tvb)
744 const char *alphabet_ptr;
745 char sorted_alphabet[128];
747 if (alphabet_length > 127) {
748 alphabet_ptr = alphabet;
750 alphabet_ptr = sort_alphabet(sorted_alphabet, alphabet, alphabet_length);
752 return dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, alphabet_ptr, alphabet_length, value_tvb);
756 dissect_per_NumericString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len)
758 offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len,
759 " 0123456789", 11, NULL);
764 dissect_per_PrintableString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len)
766 offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len,
767 " '()+,-.*0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 74, NULL);
771 dissect_per_VisibleString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len)
773 offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len,
774 " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", 95, NULL);
778 dissect_per_BMPString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len)
783 /* xx.x if the length is 0 bytes there will be no encoding */
789 if (min_len == NO_BOUND) {
796 if(min_len!=max_len){
797 offset=dissect_per_constrained_integer(tvb, offset, actx,
798 tree, hf_per_octet_string_length, min_len, max_len,
800 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
804 /* align to byte boundary */
805 BYTE_ALIGN_OFFSET(offset);
808 PER_NOT_DECODED_YET("BMPString too long");
812 str = tvb_get_ephemeral_faked_unicode(tvb, offset>>3, length, FALSE);
814 proto_tree_add_string(tree, hf_index, tvb, offset>>3, length*2, str);
816 offset+=(length<<3)*2;
822 dissect_per_object_descriptor(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, tvbuff_t **value_tvb)
824 offset=dissect_per_octet_string(tvb, offset, actx, tree, hf_index, -1, -1, FALSE, value_tvb);
830 /* this function dissects a constrained sequence of */
832 dissect_per_constrained_sequence_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq, int min_len, int max_len, gboolean has_extension _U_)
836 guint32 old_offset=offset;
838 header_field_info *hfi;
840 DEBUG_ENTRY("dissect_per_constrained_sequence_of");
842 /* 19.4 If there is a PER-visible constraint and an extension marker is present in it,
843 * a single bit shall be added to the field-list in a bit-field of length one
846 gboolean extension_present;
847 offset=dissect_per_boolean(tvb, offset, actx, parent_tree, hf_per_extension_present_bit, &extension_present);
848 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
849 if(extension_present){
850 /* 10.9 shall be invoked to add the length determinant as a semi-constrained whole number to the field-list,
851 * followed by the component values
852 * TODO: Handle extension
854 proto_tree_add_text(parent_tree, tvb, (offset>>3), 1, "dissect_per_constrained_sequence_of with extension is not handled");
858 /* 19.5 if min==max and min,max<64k ==> no length determinant */
859 if((min_len==max_len) && (min_len<65536)){
864 /* 19.6 ub>=64k or unset */
865 if ((max_len >= 65536) || (max_len == NO_BOUND)) {
866 /* no constraint, see 10.9.4.2 */
867 offset=dissect_per_length_determinant(tvb, offset, actx, parent_tree, hf_per_sequence_of_length, &length);
871 /* constrained whole number for number of elements */
872 offset=dissect_per_constrained_integer(tvb, offset, actx,
873 parent_tree, hf_per_sequence_of_length, min_len, max_len,
875 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
878 hfi = proto_registrar_get_nth(hf_index);
879 if (IS_FT_UINT(hfi->type)) {
880 item = proto_tree_add_uint(parent_tree, hf_index, tvb, offset>>3, 0, length);
881 proto_item_append_text(item, (length==1)?" item":" items");
883 item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, FALSE);
885 tree=proto_item_add_subtree(item, ett_index);
887 offset=dissect_per_sequence_of_helper(tvb, offset, actx, tree, seq->func, *seq->p_id, length);
890 proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
894 /* this function dissects a constrained set of */
896 dissect_per_constrained_set_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq, int min_len, int max_len, gboolean has_extension)
898 /* for basic-per a set-of is encoded in the same way as a sequence-of */
899 DEBUG_ENTRY("dissect_per_constrained_set_of");
900 offset=dissect_per_constrained_sequence_of(tvb, offset, actx, parent_tree, hf_index, ett_index, seq, min_len, max_len, has_extension);
909 /* this function dissects a set of */
911 dissect_per_set_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq)
913 /* for basic-per a set-of is encoded in the same way as a sequence-of */
914 DEBUG_ENTRY("dissect_per_set_of");
915 offset=dissect_per_sequence_of(tvb, offset, actx, parent_tree, hf_index, ett_index, seq);
922 /* 23 Encoding the object identifier type */
924 dissect_per_object_identifier(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index, tvbuff_t **value_tvb)
928 tvbuff_t *val_tvb = NULL;
929 header_field_info *hfi;
931 DEBUG_ENTRY("dissect_per_object_identifier");
933 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_object_identifier_length, &length);
934 if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
935 val_tvb = new_octet_aligned_subset(tvb, offset, actx, length);
937 hfi = proto_registrar_get_nth(hf_index);
938 if (hfi->type == FT_OID) {
939 actx->created_item = proto_tree_add_item(tree, hf_index, val_tvb, 0, length, FALSE);
940 } else if (IS_FT_STRING(hfi->type)) {
941 str = oid_encoded2string(tvb_get_ptr(val_tvb, 0, length), length);
942 actx->created_item = proto_tree_add_string(tree, hf_index, val_tvb, 0, length, str);
944 DISSECTOR_ASSERT_NOT_REACHED();
947 if (value_tvb) *value_tvb = val_tvb;
949 offset += 8 * length;
955 dissect_per_object_identifier_str(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, const char **value_stringx)
957 tvbuff_t *value_tvb = NULL;
960 offset = dissect_per_object_identifier(tvb, offset, actx, tree, hf_index, (value_stringx) ? &value_tvb : NULL);
963 if (value_tvb && (length = tvb_length(value_tvb))) {
964 *value_stringx = oid_encoded2string(tvb_get_ptr(value_tvb, 0, length), length);
975 /* this function reads a single bit */
977 dissect_per_boolean(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index, gboolean *bool)
981 header_field_info *hfi;
983 DEBUG_ENTRY("dissect_per_boolean");
985 ch=tvb_get_guint8(tvb, offset>>3);
986 mask=1<<(7-(offset&0x07));
994 hfi = proto_registrar_get_nth(hf_index);
996 g_snprintf(str, 256, "%c%c%c%c %c%c%c%c %s: %s",
997 mask&0x80?'0'+value:'.',
998 mask&0x40?'0'+value:'.',
999 mask&0x20?'0'+value:'.',
1000 mask&0x10?'0'+value:'.',
1001 mask&0x08?'0'+value:'.',
1002 mask&0x04?'0'+value:'.',
1003 mask&0x02?'0'+value:'.',
1004 mask&0x01?'0'+value:'.',
1006 value?"True":"False"
1008 actx->created_item = proto_tree_add_boolean_format(tree, hf_index, tvb, offset>>3, 1, value, "%s", str);
1010 actx->created_item = NULL;
1022 /* we currently only handle integers up to 32 bits in length. */
1024 dissect_per_integer(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gint32 *value)
1028 proto_item *it=NULL;
1029 header_field_info *hfi;
1032 offset=dissect_per_length_determinant(tvb, offset, actx, tree,hf_per_integer_length, &length);
1035 PER_NOT_DECODED_YET("too long integer(per_integer)");
1040 for(i=0;i<length;i++){
1042 if(tvb_get_guint8(tvb, offset>>3)&0x80){
1043 /* negative number */
1046 /* positive number */
1050 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1054 hfi = proto_registrar_get_nth(hf_index);
1056 THROW(ReportedBoundsError);
1057 if (IS_FT_INT(hfi->type)) {
1058 it=proto_tree_add_int(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1059 } else if (IS_FT_UINT(hfi->type)) {
1060 it=proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1062 proto_tree_add_text(tree, tvb, (offset>>3)-(length+1), length+1, "Field is not an integer: %s", hfi->abbrev);
1063 REPORT_DISSECTOR_BUG("PER integer field that's not an FT_INT* or FT_UINT*");
1067 actx->created_item = it;
1075 /* 64 bits experimental version, internal for now */
1077 dissect_per_integer64b(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gint64 *value)
1081 proto_item *it=NULL;
1082 header_field_info *hfi;
1085 offset=dissect_per_length_determinant(tvb, offset, actx, tree, -1, &length);
1088 PER_NOT_DECODED_YET("too long integer (64b)");
1093 for(i=0;i<length;i++){
1095 if(tvb_get_guint8(tvb, offset>>3)&0x80){
1096 /* negative number */
1097 val=G_GINT64_CONSTANT(0xffffffffffffffff);
1099 /* positive number */
1103 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1107 hfi = proto_registrar_get_nth(hf_index);
1109 THROW(ReportedBoundsError);
1110 if (IS_FT_INT(hfi->type)) {
1111 it=proto_tree_add_int64(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1112 } else if (IS_FT_UINT(hfi->type)) {
1113 it=proto_tree_add_uint64(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1115 proto_tree_add_text(tree, tvb, (offset>>3)-(length+1), length+1, "Field is not an integer: %s", hfi->abbrev);
1116 REPORT_DISSECTOR_BUG("PER integer field that's not an FT_INT* or FT_UINT*");
1120 actx->created_item = it;
1128 /* this function reads a constrained integer with or without a
1129 PER visible extension marker present
1131 has_extension==TRUE would map to asn constructs such as:
1132 rfc-number INTEGER (1..32768, ...)
1133 while has_extension==FALSE would map to:
1134 t35CountryCode INTEGER (0..255)
1136 it only handles integers that fit inside a 32 bit integer
1139 10.5.3 range=ub-lb+1
1142 10.5.6 unaligned version
1143 10.5.7 aligned version
1144 10.5.7.1 decoding of 0-255 1-8 bits
1145 10.5.7.2 decoding og 0-256 8 bits
1146 10.5.7.3 decoding of 0-65535 16 bits
1150 dissect_per_constrained_integer(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint32 min, guint32 max, guint32 *value, gboolean has_extension)
1152 proto_item *it=NULL;
1154 gint val_start, val_length;
1156 header_field_info *hfi;
1161 DEBUG_ENTRY("dissect_per_constrained_integer");
1163 gboolean extension_present;
1164 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
1165 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1166 if(extension_present){
1167 offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, (gint32*)value);
1172 hfi = proto_registrar_get_nth(hf_index);
1174 /* 10.5.3 Let "range" be defined as the integer value ("ub" - "lb" 1), and let the value to be encoded be "n".
1175 * 10.5.7 In the case of the ALIGNED variant the encoding depends on whether
1176 * d) "range" is greater than 64K (the indefinite length case).
1178 if(((max-min)>65536)&&(actx->aligned)){
1179 /* just set range really big so it will fall through
1180 to the bottom of the encoding */
1183 /* Really ugly hack.
1184 * We should really use guint64 as parameters for min/max.
1185 * This is to prevent range from being 0 if
1186 * the range for a signed integer spans the entire 32 bit range.
1187 * Special case the 2 common cases when this can happen until
1188 * a real fix is implemented.
1190 if( (max==0x7fffffff && min==0x80000000)
1191 || (max==0xffffffff && min==0x00000000) ){
1201 timeval.secs=val; timeval.nsecs=0;
1202 /* 10.5.4 If "range" has the value 1, then the result of the encoding shall be an empty bit-field (no bits).*/
1204 /* something is really wrong if range is 0 */
1205 DISSECTOR_ASSERT(range!=0);
1208 val_start = offset>>3; val_length = 0;
1210 } else if((range<=255)||(!actx->aligned)) {
1212 * 10.5.6 In the case of the UNALIGNED variant the value ("n" - "lb") shall be encoded
1213 * as a non-negative binary integer in a bit field as specified in 10.3 with the minimum
1214 * number of bits necessary to represent the range.
1219 /* We only handle 32 bit integers */
1223 while ((range & mask)== 0){
1228 if ((range & mask2) == 0)
1237 /* prepare the string */
1239 g_snprintf(str, 256, "%s: ", hfi->name);
1240 for(bit=0;bit<((int)(offset&0x07));bit++){
1241 if(bit&&(!(bit%4))){
1242 g_strlcat(str, " ", 256);
1244 g_strlcat(str,".", 256);
1246 /* read the bits for the int */
1247 for(i=0;i<num_bits;i++){
1248 if(bit&&(!(bit%4))){
1249 g_strlcat(str, " ", 256);
1251 if(bit&&(!(bit%8))){
1253 g_strlcat(str, " ", 256);
1256 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &tmp);
1260 g_strlcat(str, "1", 256);
1262 g_strlcat(str, "0", 256);
1266 if(bit&&(!(bit%4))){
1267 g_strlcat(str, " ", 256);
1269 g_strlcat(str,".", 256);
1271 val_start = (offset-num_bits)>>3; val_length = length;
1273 if (display_internal_per_fields)
1274 proto_tree_add_text(tree, tvb, val_start,val_length,"Range = %u Bitfield length %u, %s",range, num_bits, str);
1275 } else if(range==256){
1278 pad=7-(offset&0x07);
1280 /* in the aligned case, align to byte boundary */
1281 BYTE_ALIGN_OFFSET(offset);
1282 val=tvb_get_guint8(tvb, offset>>3);
1285 val_start = (offset>>3)-1; val_length = 1;
1287 } else if(range<=65536){
1290 pad=7-(offset&0x07);
1292 /* in the aligned case, align to byte boundary */
1293 BYTE_ALIGN_OFFSET(offset);
1294 val=tvb_get_guint8(tvb, offset>>3);
1297 val|=tvb_get_guint8(tvb, offset>>3);
1300 val_start = (offset>>3)-2; val_length = 2;
1308 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
1310 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
1311 num_bytes=(num_bytes<<1)|bit;
1313 num_bytes++; /* lower bound for length determinant is 1 */
1314 if (display_internal_per_fields)
1315 proto_tree_add_uint(tree, hf_per_const_int_len, tvb, (offset>>3), 1, num_bytes);
1318 BYTE_ALIGN_OFFSET(offset);
1320 for(i=0;i<num_bytes;i++){
1321 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1324 val_start = (offset>>3)-(num_bytes+1); val_length = num_bytes+1;
1329 if (IS_FT_UINT(hfi->type)) {
1330 it = proto_tree_add_uint(tree, hf_index, tvb, val_start, val_length, val);
1331 } else if (IS_FT_INT(hfi->type)) {
1332 it = proto_tree_add_int(tree, hf_index, tvb, val_start, val_length, val);
1333 } else if (IS_FT_TIME(hfi->type)) {
1334 it = proto_tree_add_time(tree, hf_index, tvb, val_start, val_length, &timeval);
1336 THROW(ReportedBoundsError);
1338 actx->created_item = it;
1339 if (value) *value = val;
1343 dissect_per_constrained_integer_64b(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint64 min, guint64 max, guint64 *value, gboolean has_extension)
1345 proto_item *it=NULL, *int_item=NULL;
1347 gint val_start, val_length;
1349 header_field_info *hfi;
1354 DEBUG_ENTRY("dissect_per_constrained_integer_64b");
1356 gboolean extension_present;
1357 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
1358 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1359 if(extension_present){
1360 offset = dissect_per_integer64b(tvb, offset, actx, tree, hf_index, (gint64*)value);
1365 hfi = proto_registrar_get_nth(hf_index);
1367 /* 10.5.3 Let "range" be defined as the integer value ("ub" - "lb" 1), and let the value to be encoded be "n".
1368 * 10.5.7 In the case of the ALIGNED variant the encoding depends on whether
1369 * d) "range" is greater than 64K (the indefinite length case).
1371 if(((max-min)>65536)&&(actx->aligned)){
1372 /* just set range really big so it will fall through
1373 to the bottom of the encoding */
1374 /* range=1000000; */
1377 range++; /* make it fall trough? */
1379 /* Copied from the 32 bit version, asuming the same problem occures
1380 * at 64 bit boundary.
1382 * We should really use guint64 as parameters for min/max.
1383 * This is to prevent range from being 0 if
1384 * the range for a signed integer spans the entire 32 bit range.
1385 * Special case the 2 common cases when this can happen until
1386 * a real fix is implemented.
1388 if( (max==G_GINT64_CONSTANT(0x7fffffffffffffff) && min==G_GINT64_CONSTANT(0x8000000000000000))
1389 || (max==G_GINT64_CONSTANT(0xffffffffffffffff) && min==0) ){
1390 range=G_GINT64_CONSTANT(0xffffffffffffffff);
1399 timeval.secs=0; timeval.nsecs=0;
1400 /* 10.5.4 If "range" has the value 1, then the result of the encoding shall be an empty bit-field (no bits).*/
1402 /* something is really wrong if range is 0 */
1403 DISSECTOR_ASSERT(range!=0);
1406 val_start = offset>>3; val_length = 0;
1408 } else if((range<=255)||(!actx->aligned)) {
1410 * 10.5.6 In the case of the UNALIGNED variant the value ("n" - "lb") shall be encoded
1411 * as a non-negative binary integer in a bit field as specified in 10.3 with the minimum
1412 * number of bits necessary to represent the range.
1417 /* We only handle 32 bit integers */
1421 while ((range & mask)== 0){
1426 if ((range & mask2) == 0)
1435 /* prepare the string */
1437 g_snprintf(str, 256, "%s: ", hfi->name);
1438 for(bit=0;bit<((int)(offset&0x07));bit++){
1439 if(bit&&(!(bit%4))){
1440 g_strlcat(str, " ", 256);
1442 g_strlcat(str,".", 256);
1444 /* read the bits for the int */
1445 for(i=0;i<num_bits;i++){
1446 if(bit&&(!(bit%4))){
1447 g_strlcat(str, " ", 256);
1449 if(bit&&(!(bit%8))){
1451 g_strlcat(str, " ", 256);
1454 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &tmp);
1458 g_strlcat(str, "1", 256);
1460 g_strlcat(str, "0", 256);
1464 if(bit&&(!(bit%4))){
1465 g_strlcat(str, " ", 256);
1467 g_strlcat(str,".", 256);
1469 val_start = (offset-num_bits)>>3; val_length = length;
1471 if (display_internal_per_fields)
1472 proto_tree_add_text(tree, tvb, val_start,val_length,"Range = (%" G_GINT64_MODIFIER "u) Bitfield length %u, %s",range, num_bits, str);
1473 } else if(range==256){
1476 pad=7-(offset&0x07);
1478 /* in the aligned case, align to byte boundary */
1479 BYTE_ALIGN_OFFSET(offset);
1480 val=tvb_get_guint8(tvb, offset>>3);
1483 val_start = (offset>>3)-1; val_length = 1;
1485 } else if(range<=65536){
1488 pad=7-(offset&0x07);
1490 /* in the aligned case, align to byte boundary */
1491 BYTE_ALIGN_OFFSET(offset);
1492 val=tvb_get_guint8(tvb, offset>>3);
1495 val|=tvb_get_guint8(tvb, offset>>3);
1498 val_start = (offset>>3)-2; val_length = 2;
1501 int i,num_bytes,num_bits;
1505 /* calculate the number of bits to hold the length */
1506 if ((range & G_GINT64_CONSTANT(0xffffffff0000000)) != 0){
1511 num_bytes =tvb_get_bits8(tvb, offset, num_bits);
1512 num_bytes++; /* lower bound for length determinant is 1 */
1513 if (display_internal_per_fields){
1514 int_item = proto_tree_add_bits_item(tree, hf_per_const_int_len, tvb, offset,num_bits, FALSE);
1515 proto_item_append_text(int_item,"+1=%u bytes, Range = (%" G_GINT64_MODIFIER "u)",num_bytes, range);
1517 offset = offset+num_bits;
1519 BYTE_ALIGN_OFFSET(offset);
1521 for(i=0;i<num_bytes;i++){
1522 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1525 val_start = (offset>>3)-(num_bytes+1); val_length = num_bytes+1;
1530 if (IS_FT_UINT(hfi->type)) {
1531 it = proto_tree_add_uint64(tree, hf_index, tvb, val_start, val_length, val);
1532 } else if (IS_FT_INT(hfi->type)) {
1533 it = proto_tree_add_int64(tree, hf_index, tvb, val_start, val_length, val);
1534 } else if (IS_FT_TIME(hfi->type)) {
1535 timeval.secs = (guint32)val;
1536 it = proto_tree_add_time(tree, hf_index, tvb, val_start, val_length, &timeval);
1538 THROW(ReportedBoundsError);
1540 actx->created_item = it;
1541 if (value) *value = val;
1544 /* 13 Encoding the enumerated type */
1546 dissect_per_enumerated(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint32 root_num, guint32 *value, gboolean has_extension, guint32 ext_num, guint32 *value_map)
1549 proto_item *it=NULL;
1550 guint32 enum_index, val;
1551 guint32 start_offset = offset;
1552 gboolean extension_present = FALSE;
1553 header_field_info *hfi;
1555 if (has_extension) {
1557 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
1558 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1561 if (!extension_present) {
1563 offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_per_enum_index, 0, root_num - 1, &enum_index, FALSE);
1564 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1568 /* 10.5.4 If "range" has the value 1,
1569 * then the result of the encoding shall be
1570 * an empty bit-field (no bits).
1574 /* 13.3 ".. and the value shall be added to the field-list as a
1575 * normally small non-negative whole number whose value is the
1576 * enumeration index of the additional enumeration and with "lb" set to 0.."
1578 offset = dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_enum_extension_index, &enum_index);
1580 enum_index += root_num;
1582 val = (value_map && (enum_index<(root_num+ext_num))) ? value_map[enum_index] : enum_index;
1583 hfi = proto_registrar_get_nth(hf_index);
1584 if (IS_FT_UINT(hfi->type)) {
1585 it = proto_tree_add_uint(tree, hf_index, tvb, start_offset>>3, BLEN(start_offset, offset), val);
1587 THROW(ReportedBoundsError);
1589 actx->created_item = it;
1590 if (value) *value = val;
1594 /* 14 Encoding the real type */
1596 dissect_per_real(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, double *value)
1598 guint32 val_length, end_offset;
1602 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_real_length, &val_length);
1603 if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
1604 val_tvb = new_octet_aligned_subset(tvb, offset, actx, val_length);
1605 end_offset = offset + val_length * 8;
1607 val = asn1_get_real(tvb_get_ptr(val_tvb, 0, val_length), val_length);
1608 actx->created_item = proto_tree_add_double(tree, hf_index, val_tvb, 0, val_length, val);
1610 if (value) *value = val;
1615 /* 22 Encoding the choice type */
1617 dissect_per_choice(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gint ett_index, const per_choice_t *choice, gint *value)
1619 gboolean extension_present, extension_flag;
1620 int extension_root_entries;
1621 int extension_addition_entries;
1622 guint32 choice_index;
1625 guint32 old_offset = offset;
1626 proto_item *choice_item = NULL;
1627 proto_tree *choice_tree = NULL;
1629 DEBUG_ENTRY("dissect_per_choice");
1631 if (value) *value = -1;
1634 if (choice[0].extension == ASN1_NO_EXTENSIONS){
1635 extension_present = FALSE;
1636 extension_flag = FALSE;
1638 extension_present = TRUE;
1639 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_bit, &extension_flag);
1640 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1643 /* count the number of entries in the extension root and extension addition */
1644 extension_root_entries = 0;
1645 extension_addition_entries = 0;
1646 for (i=0; choice[i].p_id; i++) {
1647 switch(choice[i].extension){
1648 case ASN1_NO_EXTENSIONS:
1649 case ASN1_EXTENSION_ROOT:
1650 extension_root_entries++;
1652 case ASN1_NOT_EXTENSION_ROOT:
1653 extension_addition_entries++;
1658 if (!extension_flag) { /* 22.6, 22.7 */
1659 if (extension_root_entries == 1) { /* 22.5 */
1662 offset = dissect_per_constrained_integer(tvb, offset, actx,
1663 tree, hf_per_choice_index, 0, extension_root_entries - 1,
1664 &choice_index, FALSE);
1665 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1668 index = -1; cidx = choice_index;
1669 for (i=0; choice[i].p_id; i++) {
1670 if(choice[i].extension != ASN1_NOT_EXTENSION_ROOT){
1671 if (!cidx) { index = i; break; }
1676 offset = dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_choice_extension_index, &choice_index);
1677 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &ext_length);
1679 index = -1; cidx = choice_index;
1680 for (i=0; choice[i].p_id; i++) {
1681 if(choice[i].extension == ASN1_NOT_EXTENSION_ROOT){
1682 if (!cidx) { index = i; break; }
1689 choice_item = proto_tree_add_uint(tree, hf_index, tvb, old_offset>>3, 0, choice[index].value);
1690 choice_tree = proto_item_add_subtree(choice_item, ett_index);
1691 if (!extension_flag) {
1692 offset = choice[index].func(tvb, offset, actx, choice_tree, *choice[index].p_id);
1694 choice[index].func(tvb, offset, actx, choice_tree, *choice[index].p_id);
1695 offset += ext_length * 8;
1697 proto_item_set_len(choice_item, BLEN(old_offset, offset));
1699 if (!extension_flag) {
1700 PER_NOT_DECODED_YET("unknown extension root index in choice");
1702 offset += ext_length * 8;
1703 proto_tree_add_text(tree, tvb, old_offset>>3, BLEN(old_offset, offset), "Choice no. %d in extension", choice_index);
1704 PER_NOT_DECODED_YET("unknown choice extension");
1708 if (value && (index != -1))
1709 *value = choice[index].value;
1716 index_get_optional_name(const per_sequence_t *sequence, int index)
1719 header_field_info *hfi;
1721 for(i=0;sequence[i].p_id;i++){
1722 if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1724 hfi = proto_registrar_get_nth(*sequence[i].p_id);
1725 return (hfi) ? hfi->name : "<unknown filed>";
1730 return "<unknown type>";
1734 index_get_extension_name(const per_sequence_t *sequence, int index)
1737 header_field_info *hfi;
1739 for(i=0;sequence[i].p_id;i++){
1740 if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
1742 hfi = proto_registrar_get_nth(*sequence[i].p_id);
1743 return (hfi) ? hfi->name : "<unknown filed>";
1748 return "<unknown type>";
1752 index_get_field_name(const per_sequence_t *sequence, int index)
1754 header_field_info *hfi;
1756 hfi = proto_registrar_get_nth(*sequence[index].p_id);
1757 return (hfi) ? hfi->name : "<unknown filed>";
1760 /* this functions decodes a SEQUENCE
1761 it can only handle SEQUENCES with at most 32 DEFAULT or OPTIONAL fields
1763 18.2 optinal/default items in root
1764 18.3 we ignore the case where n>64K
1765 18.4 the root sequence
1773 dissect_per_sequence(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *sequence)
1775 gboolean extension_present, extension_flag, optional_field_flag;
1778 guint32 old_offset=offset;
1779 guint32 i, num_opts;
1780 guint32 optional_mask;
1782 DEBUG_ENTRY("dissect_per_sequence");
1784 item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, FALSE);
1785 tree=proto_item_add_subtree(item, ett_index);
1788 /* first check if there should be an extension bit for this CHOICE.
1789 we do this by just checking the first choice arm
1793 if(sequence[0].extension==ASN1_NO_EXTENSIONS){
1794 extension_present=0;
1796 extension_present=1;
1797 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_bit, &extension_flag);
1798 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1802 for(i=0;sequence[i].p_id;i++){
1803 if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1809 for(i=0;i<num_opts;i++){
1810 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_optional_field_bit, &optional_field_flag);
1812 proto_item_append_text(actx->created_item, " (%s %s present)",
1813 index_get_optional_name(sequence, i), optional_field_flag?"is":"is NOT");
1815 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1817 if(optional_field_flag){
1818 optional_mask|=0x01;
1824 for(i=0;sequence[i].p_id;i++){
1825 if( (sequence[i].extension==ASN1_NO_EXTENSIONS)
1826 || (sequence[i].extension==ASN1_EXTENSION_ROOT) ){
1827 if(sequence[i].optional==ASN1_OPTIONAL){
1828 gboolean is_present;
1829 is_present=(1<<(num_opts-1))&optional_mask;
1835 if(sequence[i].func){
1836 offset=sequence[i].func(tvb, offset, actx, tree, *sequence[i].p_id);
1838 PER_NOT_DECODED_YET(index_get_field_name(sequence, i));
1845 gboolean extension_bit;
1846 guint32 num_known_extensions;
1847 guint32 num_extensions;
1848 guint32 extension_mask;
1850 offset=dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_num_sequence_extensions, &num_extensions);
1851 /* the X.691 standard is VERY unclear here.
1852 there is no mention that the lower bound lb for this
1853 (apparently) semiconstrained value is 1,
1854 apart from the NOTE: comment in 18.8 that this value can
1856 In my book, there is a semantic difference between having
1857 a comment that says that the value can not be zero
1858 and stating that the lb is 1.
1859 I dont know if this is right or not but it makes
1860 some of the very few captures I have decode properly.
1862 It could also be that the captures I have are generated by
1863 a broken implementation.
1864 If this is wrong and you dont report it as a bug
1865 then it wont get fixed!
1870 for(i=0;i<num_extensions;i++){
1871 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_bit);
1873 proto_item_append_text(actx->created_item, " (%s %s present)",
1874 index_get_extension_name(sequence, i), extension_bit?"is":"is NOT");
1876 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1878 extension_mask=(extension_mask<<1)|extension_bit;
1881 /* find how many extensions we know about */
1882 num_known_extensions=0;
1883 for(i=0;sequence[i].p_id;i++){
1884 if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
1885 num_known_extensions++;
1889 /* decode the extensions one by one */
1890 for(i=0;i<num_extensions;i++){
1895 guint32 extension_index;
1898 if(!((1L<<(num_extensions-1-i))&extension_mask)){
1899 /* this extension is not encoded in this PDU */
1903 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &length);
1905 if(i>=num_known_extensions){
1906 /* we dont know how to decode this extension */
1908 PER_NOT_DECODED_YET("unknown sequence extension");
1913 for(j=0,k=0;sequence[j].p_id;j++){
1914 if(sequence[j].extension==ASN1_NOT_EXTENSION_ROOT){
1923 if(sequence[extension_index].func){
1924 new_offset=sequence[extension_index].func(tvb, offset, actx, tree, *sequence[extension_index].p_id);
1925 if (new_offset == offset) new_offset += 8; /* OpenType has at least 1 octet */
1927 difference = offset - new_offset;
1928 /* A difference of 7 or less might be byte aligning */
1930 cause=proto_tree_add_text(tree, tvb, new_offset>>3, (offset-new_offset)>>3,
1931 "[Possible encoding error full length not decoded. Open type length %u ,decoded %u]",length, length - (difference>>3));
1932 proto_item_set_expert_flags(cause, PI_MALFORMED, PI_WARN);
1933 expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN,
1934 "Possible encoding error full length not decoded. Open type length %u ,decoded %u",length, length - (difference>>3));
1937 PER_NOT_DECODED_YET(index_get_field_name(sequence, extension_index));
1943 proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
1944 actx->created_item = item;
1950 /* 15 Encoding the bitstring type
1952 max_len or min_len == NO_BOUND means there is no lower/upper constraint
1956 dissect_per_bit_string(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, tvbuff_t **value_tvb)
1958 gint val_start, val_length;
1960 header_field_info *hfi;
1961 tvbuff_t *out_tvb = NULL;
1963 hfi = (hf_index==-1) ? NULL : proto_registrar_get_nth(hf_index);
1965 DEBUG_ENTRY("dissect_per_bit_string");
1966 /* 15.8 if the length is 0 bytes there will be no encoding */
1971 if (min_len == NO_BOUND) {
1975 /* 15.9 if length is fixed and less than or equal to sixteen bits*/
1976 if ((min_len==max_len) && (max_len<=16)) {
1977 out_tvb = new_octet_aligned_subset_bits(tvb, offset, actx, min_len);
1979 actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, -1, FALSE);
1980 proto_item_append_text(actx->created_item, " [bit length %u]", max_len);
1984 *value_tvb = out_tvb;
1989 /* 15.10 if length is fixed and less than to 64kbits*/
1990 if((min_len==max_len)&&(min_len<65536)){
1991 /* (octet-aligned in the ALIGNED variant)
1995 /* TODO the displayed value will be wrong for the unaligned variant */
1996 BYTE_ALIGN_OFFSET(offset);
1998 out_tvb = new_octet_aligned_subset_bits(tvb, offset, actx, min_len);
2000 actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, -1, FALSE);
2001 proto_item_append_text(actx->created_item, " [bit length %u]", max_len);
2005 *value_tvb = out_tvb;
2010 if (max_len != NO_BOUND) {
2011 offset=dissect_per_constrained_integer(tvb, offset, actx,
2012 tree, hf_per_bit_string_length, min_len, max_len,
2013 &length, has_extension);
2014 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
2016 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_bit_string_length, &length);
2021 BYTE_ALIGN_OFFSET(offset);
2023 out_tvb = new_octet_aligned_subset_bits(tvb, offset, actx, length);
2026 actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, -1, FALSE);
2027 proto_item_append_text(actx->created_item, " [bit length %u]", length);
2030 val_start = offset>>3;
2031 val_length = (length+7)/8;
2035 *value_tvb = out_tvb;
2040 guint32 dissect_per_bit_string_containing_pdu(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, dissector_t type_cb)
2042 tvbuff_t *val_tvb = NULL;
2043 proto_tree *subtree = tree;
2045 offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, &val_tvb);
2047 if (type_cb && val_tvb) {
2048 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2049 type_cb(val_tvb, actx->pinfo, subtree);
2055 guint32 dissect_per_bit_string_containing_pdu_new(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, new_dissector_t type_cb)
2057 tvbuff_t *val_tvb = NULL;
2058 proto_tree *subtree = tree;
2060 offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, &val_tvb);
2062 if (type_cb && val_tvb) {
2063 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2064 type_cb(val_tvb, actx->pinfo, subtree);
2070 /* this fucntion dissects an OCTET STRING
2080 max_len or min_len == NO_BOUND means there is no lower/upper constraint
2082 hf_index can either be a FT_BYTES or an FT_STRING
2085 dissect_per_octet_string(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, tvbuff_t **value_tvb)
2087 gint val_start = 0, val_length;
2089 header_field_info *hfi;
2090 tvbuff_t *out_tvb = NULL;
2092 hfi = (hf_index==-1) ? NULL : proto_registrar_get_nth(hf_index);
2094 DEBUG_ENTRY("dissect_per_octet_string");
2096 if (has_extension) { /* 16.3 an extension marker is present */
2097 gboolean extension_present;
2098 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
2099 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
2100 if (extension_present) max_len = NO_BOUND; /* skip to 16.8 */
2103 if (min_len == NO_BOUND) {
2106 if (max_len==0) { /* 16.5 if the length is 0 bytes there will be no encoding */
2107 val_start = offset>>3;
2110 } else if((min_len==max_len)&&(max_len<=2)) {
2111 /* 16.6 if length is fixed and less than or equal to two bytes*/
2112 val_start = offset>>3;
2113 val_length = min_len;
2114 out_tvb = new_octet_aligned_subset(tvb, offset, actx, val_length);
2117 } else if ((min_len==max_len)&&(min_len<65536)) {
2118 /* 16.7 if length is fixed and less than to 64k*/
2122 BYTE_ALIGN_OFFSET(offset);
2124 val_start = offset>>3;
2125 val_length = min_len;
2126 out_tvb = new_octet_aligned_subset(tvb, offset, actx, val_length);
2131 offset = dissect_per_constrained_integer(tvb, offset, actx, tree,
2132 hf_per_octet_string_length, min_len, max_len, &length, FALSE);
2134 if (!display_internal_per_fields)
2135 PROTO_ITEM_SET_HIDDEN(actx->created_item);
2137 offset = dissect_per_length_determinant(tvb, offset, actx, tree,
2138 hf_per_octet_string_length, &length);
2144 BYTE_ALIGN_OFFSET(offset);
2146 out_tvb = new_octet_aligned_subset(tvb, offset, actx, length);
2148 val_start = offset>>3;
2150 val_length = length;
2155 if (IS_FT_UINT(hfi->type)||IS_FT_INT(hfi->type)) {
2156 /* If the type has been converted to FT_UINT or FT_INT in the .cnf file
2157 * display the length of this octet string instead of the octetstring itself
2159 if (IS_FT_UINT(hfi->type))
2160 actx->created_item = proto_tree_add_uint(tree, hf_index, out_tvb, 0, val_length, val_length);
2162 actx->created_item = proto_tree_add_int(tree, hf_index, out_tvb, 0, val_length, val_length);
2163 proto_item_append_text(actx->created_item, plurality(val_length, " octet", " octets"));
2166 actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, val_length, FALSE);
2169 actx->created_item = proto_tree_add_item(tree, hf_index, tvb, val_start, val_length, FALSE);
2175 *value_tvb = (out_tvb) ? out_tvb : tvb_new_subset(tvb, val_start, val_length, val_length);
2180 guint32 dissect_per_octet_string_containing_pdu(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, dissector_t type_cb)
2182 tvbuff_t *val_tvb = NULL;
2183 proto_tree *subtree = tree;
2185 offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, &val_tvb);
2187 if (type_cb && val_tvb) {
2188 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2189 type_cb(val_tvb, actx->pinfo, subtree);
2195 guint32 dissect_per_octet_string_containing_pdu_new(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, new_dissector_t type_cb)
2197 tvbuff_t *val_tvb = NULL;
2198 proto_tree *subtree = tree;
2200 offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, &val_tvb);
2202 if (type_cb && val_tvb) {
2203 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2204 type_cb(val_tvb, actx->pinfo, subtree);
2210 guint32 dissect_per_size_constrained_type(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, per_type_fn type_cb, const gchar *name, int min_len, int max_len, gboolean has_extension)
2212 asn1_stack_frame_push(actx, name);
2213 asn1_param_push_integer(actx, min_len);
2214 asn1_param_push_integer(actx, max_len);
2215 asn1_param_push_boolean(actx, has_extension);
2217 offset = type_cb(tvb, offset, actx, tree, hf_index);
2219 asn1_stack_frame_pop(actx, name);
2224 gboolean get_size_constraint_from_stack(asn1_ctx_t *actx, const gchar *name, int *pmin_len, int *pmax_len, gboolean *phas_extension)
2228 if (pmin_len) *pmin_len = NO_BOUND;
2229 if (pmax_len) *pmax_len = NO_BOUND;
2230 if (phas_extension) *phas_extension = FALSE;
2232 if (!actx->stack) return FALSE;
2233 if (strcmp(actx->stack->name, name)) return FALSE;
2235 par = actx->stack->par;
2236 if (!par || (par->ptype != ASN1_PAR_INTEGER)) return FALSE;
2237 if (pmin_len) *pmin_len = par->value.v_integer;
2239 if (!par || (par->ptype != ASN1_PAR_INTEGER)) return FALSE;
2240 if (pmax_len) *pmax_len = par->value.v_integer;
2242 if (!par || (par->ptype != ASN1_PAR_BOOLEAN)) return FALSE;
2243 if (phas_extension) *phas_extension = par->value.v_boolean;
2249 /* 26 Encoding of a value of the external type */
2251 /* code generated from definition in 26.1 */
2253 [UNIVERSAL 8] IMPLICIT SEQUENCE {
2254 direct-reference OBJECT IDENTIFIER OPTIONAL,
2255 indirect-reference INTEGER OPTIONAL,
2256 data-value-descriptor ObjectDescriptor OPTIONAL,
2258 single-ASN1-type [0] ABSTRACT-SYNTAX.&Type,
2259 octet-aligned [1] IMPLICIT OCTET STRING,
2260 arbitrary [2] IMPLICIT BIT STRING
2264 /* NOTE: This sequence type differs from that in ITU-T Rec. X.680 | ISO/IEC 8824-1 for historical reasons. */
2267 dissect_per_T_direct_reference(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2268 offset = dissect_per_object_identifier_str(tvb, offset, actx, tree, hf_index, &actx->external.direct_reference);
2270 actx->external.direct_ref_present = TRUE;
2277 dissect_per_T_indirect_reference(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2278 offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, &actx->external.indirect_reference);
2280 actx->external.indirect_ref_present = TRUE;
2287 dissect_per_T_data_value_descriptor(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2288 offset = dissect_per_object_descriptor(tvb, offset, actx, tree, hf_index, &actx->external.data_value_descriptor);
2290 actx->external.data_value_descr_present = TRUE;
2297 dissect_per_T_single_ASN1_type(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2298 offset = dissect_per_open_type(tvb, offset, actx, tree, actx->external.hf_index, actx->external.u.per.type_cb);
2306 dissect_per_T_octet_aligned(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2307 offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index,
2308 NO_BOUND, NO_BOUND, FALSE, &actx->external.octet_aligned);
2310 if (actx->external.u.per.type_cb) {
2311 actx->external.u.per.type_cb(actx->external.octet_aligned, 0, actx, tree, actx->external.hf_index);
2313 actx->created_item = proto_tree_add_text(tree, actx->external.octet_aligned, 0, -1, "Unknown EXTERNAL Type");
2321 dissect_per_T_arbitrary(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2322 offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index,
2323 NO_BOUND, NO_BOUND, FALSE, &actx->external.arbitrary);
2325 if (actx->external.u.per.type_cb) {
2326 actx->external.u.per.type_cb(actx->external.arbitrary, 0, actx, tree, actx->external.hf_index);
2328 actx->created_item = proto_tree_add_text(tree, actx->external.arbitrary, 0, -1, "Unknown EXTERNAL Type");
2334 static const value_string per_External_encoding_vals[] = {
2335 { 0, "single-ASN1-type" },
2336 { 1, "octet-aligned" },
2341 static const per_choice_t External_encoding_choice[] = {
2342 { 0, &hf_per_single_ASN1_type, ASN1_NO_EXTENSIONS , dissect_per_T_single_ASN1_type },
2343 { 1, &hf_per_octet_aligned , ASN1_NO_EXTENSIONS , dissect_per_T_octet_aligned },
2344 { 2, &hf_per_arbitrary , ASN1_NO_EXTENSIONS , dissect_per_T_arbitrary },
2345 { 0, NULL, 0, NULL }
2349 dissect_per_External_encoding(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2350 offset = dissect_per_choice(tvb, offset, actx, tree, hf_index,
2351 ett_per_External_encoding, External_encoding_choice,
2352 &actx->external.encoding);
2358 static const per_sequence_t External_sequence[] = {
2359 { &hf_per_direct_reference, ASN1_NO_EXTENSIONS , ASN1_OPTIONAL , dissect_per_T_direct_reference },
2360 { &hf_per_indirect_reference, ASN1_NO_EXTENSIONS , ASN1_OPTIONAL , dissect_per_T_indirect_reference },
2361 { &hf_per_data_value_descriptor, ASN1_NO_EXTENSIONS , ASN1_OPTIONAL , dissect_per_T_data_value_descriptor },
2362 { &hf_per_encoding , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_per_External_encoding },
2363 { NULL, 0, 0, NULL }
2367 dissect_per_External(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2368 offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
2369 ett_per_External, External_sequence);
2375 dissect_per_external_type(tvbuff_t *tvb _U_, guint32 offset, asn1_ctx_t *actx, proto_tree *tree _U_, int hf_index _U_, per_type_fn type_cb)
2377 asn1_ctx_clean_external(actx);
2378 actx->external.u.per.type_cb = type_cb;
2379 offset = dissect_per_External(tvb, offset, actx, tree, hf_index);
2381 asn1_ctx_clean_external(actx);
2387 proto_register_per(void)
2389 static hf_register_info hf[] =
2391 { &hf_per_num_sequence_extensions,
2392 { "Number of Sequence Extensions", "per.num_sequence_extensions", FT_UINT32, BASE_DEC,
2393 NULL, 0, "Number of extensions encoded in this sequence", HFILL }},
2394 { &hf_per_choice_index,
2395 { "Choice Index", "per.choice_index", FT_UINT32, BASE_DEC,
2396 NULL, 0, "Which index of the Choice within extension root is encoded", HFILL }},
2397 { &hf_per_choice_extension_index,
2398 { "Choice Extension Index", "per.choice_extension_index", FT_UINT32, BASE_DEC,
2399 NULL, 0, "Which index of the Choice within extension addition is encoded", HFILL }},
2400 { &hf_per_enum_index,
2401 { "Enumerated Index", "per.enum_index", FT_UINT32, BASE_DEC,
2402 NULL, 0, "Which index of the Enumerated within extension root is encoded", HFILL }},
2403 { &hf_per_enum_extension_index,
2404 { "Enumerated Extension Index", "per.enum_extension_index", FT_UINT32, BASE_DEC,
2405 NULL, 0, "Which index of the Enumerated within extension addition is encoded", HFILL }},
2406 { &hf_per_GeneralString_length,
2407 { "GeneralString Length", "per.generalstring_length", FT_UINT32, BASE_DEC,
2408 NULL, 0, "Length of the GeneralString", HFILL }},
2409 { &hf_per_extension_bit,
2410 { "Extension Bit", "per.extension_bit", FT_BOOLEAN, 8,
2411 TFS(&tfs_extension_bit), 0x01, "The extension bit of an aggregate", HFILL }},
2412 { &hf_per_extension_present_bit,
2413 { "Extension Present Bit", "per.extension_present_bit", FT_BOOLEAN, 8,
2414 TFS(&tfs_extension_present_bit), 0x01, "Whether this optional extension is present or not", HFILL }},
2415 { &hf_per_small_number_bit,
2416 { "Small Number Bit", "per.small_number_bit", FT_BOOLEAN, 8,
2417 TFS(&tfs_small_number_bit), 0x01, "The small number bit for a section 10.6 integer", HFILL }},
2418 { &hf_per_optional_field_bit,
2419 { "Optional Field Bit", "per.optional_field_bit", FT_BOOLEAN, 8,
2420 TFS(&tfs_optional_field_bit), 0x01, "This bit specifies the presence/absence of an optional field", HFILL }},
2421 { &hf_per_sequence_of_length,
2422 { "Sequence-Of Length", "per.sequence_of_length", FT_UINT32, BASE_DEC,
2423 NULL, 0, "Number of items in the Sequence Of", HFILL }},
2424 { &hf_per_object_identifier_length,
2425 { "Object Identifier Length", "per.object_length", FT_UINT32, BASE_DEC,
2426 NULL, 0, "Length of the object identifier", HFILL }},
2427 { &hf_per_open_type_length,
2428 { "Open Type Length", "per.open_type_length", FT_UINT32, BASE_DEC,
2429 NULL, 0, "Length of an open type encoding", HFILL }},
2430 { &hf_per_real_length,
2431 { "Real Length", "per.real_length", FT_UINT32, BASE_DEC,
2432 NULL, 0, "Length of an real encoding", HFILL }},
2433 { &hf_per_octet_string_length,
2434 { "Octet String Length", "per.octet_string_length", FT_UINT32, BASE_DEC,
2435 NULL, 0, "Number of bytes in the Octet String", HFILL }},
2436 { &hf_per_bit_string_length,
2437 { "Bit String Length", "per.bit_string_length", FT_UINT32, BASE_DEC,
2438 NULL, 0, "Number of bits in the Bit String", HFILL }},
2439 { &hf_per_const_int_len,
2440 { "Constrained Integer Length", "per._const_int_len", FT_UINT32, BASE_DEC,
2441 NULL, 0, "Number of bytes in the Constrained Integer", HFILL }},
2442 { &hf_per_direct_reference,
2443 { "direct-reference", "per.direct_reference",
2444 FT_OID, BASE_NONE, NULL, 0,
2445 "per.T_direct_reference", HFILL }},
2446 { &hf_per_indirect_reference,
2447 { "indirect-reference", "per.indirect_reference",
2448 FT_INT32, BASE_DEC, NULL, 0,
2449 "per.T_indirect_reference", HFILL }},
2450 { &hf_per_data_value_descriptor,
2451 { "data-value-descriptor", "per.data_value_descriptor",
2452 FT_STRING, BASE_NONE, NULL, 0,
2453 "per.T_data_value_descriptor", HFILL }},
2455 { "encoding", "per.encoding",
2456 FT_UINT32, BASE_DEC, VALS(per_External_encoding_vals), 0,
2457 "per.External_encoding", HFILL }},
2458 { &hf_per_single_ASN1_type,
2459 { "single-ASN1-type", "per.single_ASN1_type",
2460 FT_NONE, BASE_NONE, NULL, 0,
2461 "per.T_single_ASN1_type", HFILL }},
2462 { &hf_per_octet_aligned,
2463 { "octet-aligned", "per.octet_aligned",
2464 FT_BYTES, BASE_HEX, NULL, 0,
2465 "per.T_octet_aligned", HFILL }},
2466 { &hf_per_arbitrary,
2467 { "arbitrary", "per.arbitrary",
2468 FT_BYTES, BASE_HEX, NULL, 0,
2469 "per.T_arbitrary", HFILL }},
2470 { &hf_per_integer_length,
2471 { "integer length", "per.integer_length",
2472 FT_UINT32, BASE_DEC, NULL, 0,
2475 static gint *ett[] =
2478 &ett_per_containing,
2479 &ett_per_sequence_of_item,
2481 &ett_per_External_encoding,
2483 module_t *per_module;
2485 proto_per = proto_register_protocol("Packed Encoding Rules (ASN.1 X.691)", "PER", "per");
2486 proto_register_field_array(proto_per, hf, array_length(hf));
2487 proto_register_subtree_array(ett, array_length(ett));
2489 proto_set_cant_toggle(proto_per);
2491 per_module = prefs_register_protocol(proto_per, NULL);
2492 prefs_register_bool_preference(per_module, "display_internal_per_fields",
2493 "Display the internal PER fields in the tree",
2494 "Whether the dissector should put the internal PER data in the tree or if it should hide it",
2495 &display_internal_per_fields);
2500 proto_reg_handoff_per(void)