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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
38 #include <epan/packet.h>
39 #include <epan/exceptions.h>
40 #include <epan/oids.h>
41 #include <epan/to_str.h>
42 #include <epan/prefs.h>
43 #include <epan/wmem/wmem.h>
44 #include <epan/asn1.h>
45 #include <epan/strutil.h>
46 #include <epan/expert.h>
47 #include "packet-per.h"
50 static int proto_per
= -1;
51 static int hf_per_GeneralString_length
= -1;
52 static int hf_per_extension_bit
= -1;
53 static int hf_per_extension_present_bit
= -1;
54 static int hf_per_choice_index
= -1;
55 static int hf_per_choice_extension_index
= -1;
56 static int hf_per_enum_index
= -1;
57 static int hf_per_enum_extension_index
= -1;
58 static int hf_per_num_sequence_extensions
= -1;
59 static int hf_per_small_number_bit
= -1;
60 static int hf_per_optional_field_bit
= -1;
61 static int hf_per_sequence_of_length
= -1;
62 static int hf_per_object_identifier_length
= -1;
63 static int hf_per_open_type_length
= -1;
64 static int hf_per_real_length
= -1;
65 static int hf_per_octet_string_length
= -1;
66 static int hf_per_bit_string_length
= -1;
67 static int hf_per_normally_small_nonnegative_whole_number_length
= -1;
68 static int hf_per_const_int_len
= -1;
69 static int hf_per_direct_reference
= -1; /* T_direct_reference */
70 static int hf_per_indirect_reference
= -1; /* T_indirect_reference */
71 static int hf_per_data_value_descriptor
= -1; /* T_data_value_descriptor */
72 static int hf_per_encoding
= -1; /* External_encoding */
73 static int hf_per_single_ASN1_type
= -1; /* T_single_ASN1_type */
74 static int hf_per_octet_aligned
= -1; /* T_octet_aligned */
75 static int hf_per_arbitrary
= -1; /* T_arbitrary */
76 static int hf_per_integer_length
= -1; /* Show integer length if "show internal per fields" */
77 /* static int hf_per_debug_pos = -1; */
79 static gint ett_per_open_type
= -1;
80 static gint ett_per_containing
= -1;
81 static gint ett_per_sequence_of_item
= -1;
82 static gint ett_per_External
= -1;
83 static gint ett_per_External_encoding
= -1;
85 static expert_field ei_per_size_constraint_value
= EI_INIT
;
86 static expert_field ei_per_size_constraint_too_few
= EI_INIT
;
87 static expert_field ei_per_size_constraint_too_many
= EI_INIT
;
88 static expert_field ei_per_choice_extension_unknown
= EI_INIT
;
89 static expert_field ei_per_sequence_extension_unknown
= EI_INIT
;
90 static expert_field ei_per_encoding_error
= EI_INIT
;
93 #define DEBUG_ENTRY(x) \
94 printf("#%u %s tvb:0x%08x\n",actx->pinfo->fd->num,x,(int)tvb);
96 #define DEBUG_ENTRY(x) \
99 #define BLEN(old_offset, offset) (((offset)>>3)!=((old_offset)>>3)?((offset)>>3)-((old_offset)>>3):1)
101 /* whether the PER helpers should put the internal PER fields into the tree
104 static gboolean display_internal_per_fields
= FALSE
;
108 static const true_false_string tfs_extension_present_bit
= {
112 static const true_false_string tfs_extension_bit
= {
113 "Extension bit is set",
114 "Extension bit is clear"
116 static const true_false_string tfs_small_number_bit
= {
117 "The number is small, 0-63",
118 "The number is large, >63"
120 static const true_false_string tfs_optional_field_bit
= {
126 #define BYTE_ALIGN_OFFSET(offset) if(offset&0x07){offset=(offset&0xfffffff8)+8;}
128 #define SEQ_MAX_COMPONENTS 128
130 static void per_check_value(guint32 value
, guint32 min_len
, guint32 max_len
, asn1_ctx_t
*actx
, proto_item
*item
, gboolean is_signed
)
132 if ((is_signed
== FALSE
) && (value
> max_len
)) {
133 expert_add_info_format(actx
->pinfo
, item
, &ei_per_size_constraint_value
, "Size constraint: value too big: %u (%u .. %u)", value
, min_len
, max_len
);
134 } else if ((is_signed
== TRUE
) && ((gint32
)value
> (gint32
)max_len
)) {
135 expert_add_info_format(actx
->pinfo
, item
, &ei_per_size_constraint_value
, "Size constraint: value too big: %d (%d .. %d)", (gint32
)value
, (gint32
)min_len
, (gint32
)max_len
);
139 static void per_check_value64(guint64 value
, guint64 min_len
, guint64 max_len
, asn1_ctx_t
*actx
, proto_item
*item
, gboolean is_signed
)
141 if ((is_signed
== FALSE
) && (value
> max_len
)) {
142 expert_add_info_format(actx
->pinfo
, item
, &ei_per_size_constraint_value
, "Size constraint: value too big: %" G_GINT64_MODIFIER
"u (%" G_GINT64_MODIFIER
"u .. %" G_GINT64_MODIFIER
"u)", value
, min_len
, max_len
);
143 } else if ((is_signed
== TRUE
) && ((gint64
)value
> (gint64
)max_len
)) {
144 expert_add_info_format(actx
->pinfo
, item
, &ei_per_size_constraint_value
, "Size constraint: value too big: %" G_GINT64_MODIFIER
"d (%" G_GINT64_MODIFIER
"d .. %" G_GINT64_MODIFIER
"d)", (gint64
)value
, (gint64
)min_len
, (gint64
)max_len
);
148 static void per_check_items(guint32 cnt
, int min_len
, int max_len
, asn1_ctx_t
*actx
, proto_item
*item
)
150 if (min_len
!= NO_BOUND
&& cnt
< (guint32
)min_len
) {
151 expert_add_info_format(actx
->pinfo
, item
, &ei_per_size_constraint_too_few
, "Size constraint: too few items: %d (%d .. %d)", cnt
, min_len
, max_len
);
152 } else if (max_len
!= NO_BOUND
&& cnt
> (guint32
)max_len
) {
153 expert_add_info_format(actx
->pinfo
, item
, &ei_per_size_constraint_too_many
, "Size constraint: too many items: %d (%d .. %d)", cnt
, min_len
, max_len
);
157 static tvbuff_t
*new_octet_aligned_subset(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, guint32 length
)
159 tvbuff_t
*sub_tvb
= NULL
;
160 guint32 boffset
= offset
>> 3;
161 unsigned int i
, shift0
, shift1
;
162 guint8 octet0
, octet1
, *buf
;
163 guint32 actual_length
;
165 /* XXX - why are we doing this? Shouldn't we throw an exception if we've
166 * been asked to decode more octets than exist?
168 actual_length
= tvb_length_remaining(tvb
,boffset
);
169 if (length
<= actual_length
)
170 actual_length
= length
;
172 if (offset
& 0x07) { /* unaligned */
173 shift1
= offset
& 0x07;
175 buf
= (guint8
*)wmem_alloc(actx
->pinfo
->pool
, actual_length
);
176 octet0
= tvb_get_guint8(tvb
, boffset
);
177 for (i
=0; i
<actual_length
; i
++) {
179 octet0
= tvb_get_guint8(tvb
, boffset
+ i
+ 1);
180 buf
[i
] = (octet1
<< shift1
) | (octet0
>> shift0
);
182 sub_tvb
= tvb_new_child_real_data(tvb
, buf
, actual_length
, length
);
183 add_new_data_source(actx
->pinfo
, sub_tvb
, "Unaligned OCTET STRING");
184 } else { /* aligned */
185 sub_tvb
= tvb_new_subset(tvb
, boffset
, actual_length
, length
);
190 /* 10 Encoding procedures -------------------------------------------------- */
192 /* 10.2 Open type fields --------------------------------------------------- */
194 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
)
196 guint32 type_length
, end_offset
;
197 tvbuff_t
*val_tvb
= NULL
;
198 header_field_info
*hfi
;
199 proto_tree
*subtree
= tree
;
201 hfi
= (hf_index
== -1) ? NULL
: proto_registrar_get_nth(hf_index
);
203 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_open_type_length
, &type_length
);
204 if (actx
->aligned
) BYTE_ALIGN_OFFSET(offset
);
205 end_offset
= offset
+ type_length
* 8;
207 if ((variant
==CB_DISSECTOR
)||(variant
==CB_NEW_DISSECTOR
)) {
208 val_tvb
= new_octet_aligned_subset(tvb
, offset
, actx
, type_length
);
210 if (IS_FT_UINT(hfi
->type
)||IS_FT_INT(hfi
->type
)) {
211 if (IS_FT_UINT(hfi
->type
))
212 actx
->created_item
= proto_tree_add_uint(tree
, hf_index
, val_tvb
, 0, type_length
, type_length
);
214 actx
->created_item
= proto_tree_add_int(tree
, hf_index
, val_tvb
, 0, type_length
, type_length
);
215 proto_item_append_text(actx
->created_item
, plurality(type_length
, " octet", " octets"));
217 actx
->created_item
= proto_tree_add_item(tree
, hf_index
, val_tvb
, 0, type_length
, ENC_BIG_ENDIAN
);
219 subtree
= proto_item_add_subtree(actx
->created_item
, ett_per_open_type
);
226 ((per_type_fn
)type_cb
)(tvb
, offset
, actx
, tree
, hf_index
);
229 ((dissector_t
)type_cb
)(val_tvb
, actx
->pinfo
, subtree
);
231 case CB_NEW_DISSECTOR
:
232 ((new_dissector_t
)type_cb
)(val_tvb
, actx
->pinfo
, subtree
, NULL
);
234 case CB_DISSECTOR_HANDLE
:
238 actx
->created_item
= proto_tree_add_text(tree
, tvb
, offset
>>3, BLEN(offset
, end_offset
), "Unknown Open Type");
245 dissect_per_open_type(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, per_type_fn type_cb
)
247 return dissect_per_open_type_internal(tvb
, offset
, actx
, tree
, hf_index
, (void*)type_cb
, CB_ASN1_ENC
);
251 dissect_per_open_type_pdu(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, dissector_t type_cb
)
253 return dissect_per_open_type_internal(tvb
, offset
, actx
, tree
, hf_index
, (void*)type_cb
, CB_DISSECTOR
);
257 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
)
259 return dissect_per_open_type_internal(tvb
, offset
, actx
, tree
, hf_index
, (void*)type_cb
, CB_NEW_DISSECTOR
);
262 /* 10.9 General rules for encoding a length determinant --------------------
264 NOTE 1 - (Tutorial) The procedures of this subclause are invoked when an explicit length field is needed
265 for some part of the encoding regardless of whether the length count is bounded above
266 (by PER-visible constraints) or not. The part of the encoding to which the length applies may
267 be a bit string (with the length count in bits), an octet string (with the length count in octets),
268 a known-multiplier character string (with the length count in characters), or a list of fields
269 (with the length count in components of a sequence-of or set-of).
271 NOTE 2 - (Tutorial) In the case of the ALIGNED variant if the length count is bounded above by an upper bound
272 that is less than 64K, then the constrained whole number encoding is used for the length.
273 For sufficiently small ranges the result is a bit-field, otherwise the unconstrained length ("n" say)
274 is encoded into an octet-aligned bit-field in one of three ways (in order of increasing size):
275 a) ("n" less than 128) a single octet containing "n" with bit 8 set to zero;
276 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;
277 c) (large "n") a single octet containing a count "m" with bit 8 set to 1 and bit 7 set to 1.
278 The count "m" is one to four, and the length indicates that a fragment of the material follows
279 (a multiple "m" of 16K items). For all values of "m", the fragment is then followed by another length encoding
280 for the remainder of the material.
282 NOTE 3 - (Tutorial) In the UNALIGNED variant, if the length count is bounded above by an upper bound that is less
283 than 64K, then the constrained whole number encoding is used to encode the length in the minimum number of
284 bits necessary to represent the range. Otherwise, the unconstrained length ("n" say) is encoded into a bit
285 field in the manner described above in Note 2.
289 dissect_per_length_determinant(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx _U_
, proto_tree
*tree
, int hf_index
, guint32
*length
)
295 int i
, bit
, str_length
, str_index
;
304 BYTE_ALIGN_OFFSET(offset
);
305 byte
=tvb_get_guint8(tvb
, offset
>>3);
313 /* prepare the string (max number of bits + quartet separators + prepended space) */
314 str_length
= 256+64+1;
315 str
=(char *)wmem_alloc(wmem_packet_scope(), str_length
+1);
318 str_length
= g_snprintf(str
, str_length
+1, " ");
319 for(bit
=0;bit
<((int)(offset
&0x07));bit
++){
321 if (str_index
< str_length
) str
[str_index
++] = ' ';
323 if (str_index
< str_length
) str
[str_index
++] = '.';
325 /* read the bits for the int */
327 for(i
=0;i
<num_bits
;i
++){
329 if (str_index
< str_length
) str
[str_index
++] = ' ';
332 if (str_index
< str_length
) str
[str_index
++] = ' ';
335 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, -1, &tmp
);
339 if (str_index
< str_length
) str
[str_index
++] = '1';
340 if (i
==0) { /* bit 8 is 1, so not a single byte length */
343 else if (i
==1 && val
==3) { /* bits 8 and 7 both 1, so unconstrained */
345 PER_NOT_DECODED_YET("10.9 Unconstrained");
349 if (str_index
< str_length
) str
[str_index
++] = '0';
352 str
[str_index
] = '\0'; /* Terminate string */
353 if((val
&0x80)==0 && num_bits
==8){
356 pi
= proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
>>3)-1, 1, *length
);
357 if (display_internal_per_fields
)
358 proto_item_append_text(pi
," %s", str
);
360 PROTO_ITEM_SET_HIDDEN(pi
);
365 else if (num_bits
==16) {
366 *length
= val
&0x3fff;
368 pi
= proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
>>3)-1, 1, *length
);
369 if (display_internal_per_fields
)
370 proto_item_append_text(pi
," %s", str
);
372 PROTO_ITEM_SET_HIDDEN(pi
);
378 PER_NOT_DECODED_YET("10.9 Unaligned");
387 pi
= proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
>>3)-1, 1, *length
);
388 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(pi
);
394 if((byte
&0xc0)==0x80){
396 *length
=((*length
)<<8)+tvb_get_guint8(tvb
, offset
>>3);
399 pi
= proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
>>3)-2, 2, *length
);
400 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(pi
);
405 PER_NOT_DECODED_YET("10.9.3.8.1");
409 /* 10.6 normally small non-negative whole number */
411 dissect_per_normally_small_nonnegative_whole_number(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, guint32
*length
)
413 gboolean small_number
, length_bit
;
414 guint32 len
, length_determinant
;
417 DEBUG_ENTRY("dissect_per_normally_small_nonnegative_whole_number");
422 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_small_number_bit
, &small_number
);
423 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
429 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, -1, &length_bit
);
436 pi
= proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
-6)>>3, (offset
%8<6)?2:1, *length
);
437 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(pi
);
443 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_normally_small_nonnegative_whole_number_length
, &length_determinant
);
444 switch (length_determinant
) {
449 *length
= tvb_get_bits8(tvb
, offset
, 8);
453 *length
= tvb_get_bits16(tvb
, offset
, 16, ENC_BIG_ENDIAN
);
457 *length
= tvb_get_bits32(tvb
, offset
, 24, ENC_BIG_ENDIAN
);
461 *length
= tvb_get_bits32(tvb
, offset
, 32, ENC_BIG_ENDIAN
);
465 PER_NOT_DECODED_YET("too long integer(per_normally_small_nonnegative_whole_number)");
466 offset
+= 8*length_determinant
;
471 pi
= proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
-(8*length_determinant
))>>3, length_determinant
, *length
);
472 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(pi
);
480 /* this function reads a GeneralString */
481 /* currently based on pure guesswork since RFC2833 didnt tell me much
482 i guess that the PER encoding for this is a normally-small-whole-number
483 followed by a ascii string.
485 based on pure guesswork. it looks ok in the only capture i have where
486 there is a 1 byte general string encoded
489 dissect_per_GeneralString(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
)
493 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_GeneralString_length
, &length
);
495 proto_tree_add_item(tree
, hf_index
, tvb
, offset
>>3, length
, ENC_BIG_ENDIAN
);
502 /* 17 Encoding the null type */
504 dissect_per_null(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx _U_
, proto_tree
*tree
, int hf_index
) {
507 ti_tmp
= proto_tree_add_item(tree
, hf_index
, tvb
, offset
>>3, 1, ENC_BIG_ENDIAN
);
508 proto_item_append_text(ti_tmp
, ": NULL");
513 /* 19 this function dissects a sequence of */
515 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
)
519 DEBUG_ENTRY("dissect_per_sequence_of_helper");
520 for(i
=0;i
<length
;i
++){
521 guint32 lold_offset
=offset
;
525 litem
=proto_tree_add_text(tree
, tvb
, offset
>>3, 0, "Item %d", i
);
526 ltree
=proto_item_add_subtree(litem
, ett_per_sequence_of_item
);
528 offset
=(*func
)(tvb
, offset
, actx
, ltree
, hf_index
);
529 proto_item_set_len(litem
, (offset
>>3)!=(lold_offset
>>3)?(offset
>>3)-(lold_offset
>>3):1);
535 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
)
539 guint32 old_offset
=offset
;
541 header_field_info
*hfi
;
543 DEBUG_ENTRY("dissect_per_sequence_of");
545 /* semi-constrained whole number for number of elements */
546 /* each element encoded as 10.9 */
548 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, parent_tree
, hf_per_sequence_of_length
, &length
);
550 hfi
= proto_registrar_get_nth(hf_index
);
551 if (IS_FT_UINT(hfi
->type
)) {
552 item
= proto_tree_add_uint(parent_tree
, hf_index
, tvb
, old_offset
>>3, 0, length
);
553 proto_item_append_text(item
, (length
==1)?" item":" items");
555 item
=proto_tree_add_item(parent_tree
, hf_index
, tvb
, old_offset
>>3, 0, ENC_BIG_ENDIAN
);
557 tree
=proto_item_add_subtree(item
, ett_index
);
559 offset
=dissect_per_sequence_of_helper(tvb
, offset
, actx
, tree
, seq
->func
, *seq
->p_id
, length
);
562 proto_item_set_len(item
, (offset
>>3)!=(old_offset
>>3)?(offset
>>3)-(old_offset
>>3):1);
567 /* XXX we don't do >64k length strings yet */
569 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
, gboolean has_extension _U_
,const char *alphabet
, int alphabet_length
, tvbuff_t
**value_tvb
)
572 gboolean byte_aligned
;
578 DEBUG_ENTRY("dissect_per_restricted_character_string");
580 /* xx.x if the length is 0 bytes there will be no encoding */
583 *value_tvb
= tvb_new_child_real_data(tvb
, NULL
, 0, 0);
589 if (min_len
== NO_BOUND
) {
594 /* 27.5.2 depending of the alphabet length, find how many bits
595 are used to encode each character */
599 if(alphabet_length
<=2){
601 } else if(alphabet_length
<=4){
603 } else if(alphabet_length
<=16){
609 if(alphabet_length
<=2){
611 } else if(alphabet_length
<=4){
613 } else if(alphabet_length
<=8){
615 } else if(alphabet_length
<=16){
617 } else if(alphabet_length
<=32){
619 } else if(alphabet_length
<=64){
621 } else if(alphabet_length
<=128){
627 /* 27.4 If the type is extensible for PER encodings (see 9.3.16),
628 * then a bit-field consisting of a single bit shall be added to the field-list.
629 * The single bit shall be set to zero if the value is within the range of the extension root,
630 * and to one otherwise. If the value is outside the range of the extension root,
631 * then the following encoding shall be as if there was no effective size constraint,
632 * and shall have an effective permitted-alphabet constraint that consists of the set of characters
633 * of the unconstrained type.
634 * NOTE - Only the known-multiplier character string types can be extensible for PER encodings.
635 * Extensibility markers on other character string types do not affect the PER encoding.
639 gboolean extension_present
;
640 offset
= dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_present
);
641 if(extension_present
){
648 if((min_len
==max_len
)&&(max_len
<=2)){
651 if ((max_len
!= NO_BOUND
) && (max_len
< 2)) {
657 if (max_len
== NO_BOUND
) {
658 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_octet_string_length
, &length
);
659 /* the unconstrained strings are always byte aligned (27.6.3)*/
661 } else if(min_len
!=max_len
){
662 offset
=dissect_per_constrained_integer(tvb
, offset
, actx
,
663 tree
, hf_per_octet_string_length
, min_len
, max_len
,
665 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
669 /* there is no string at all, so don't do any byte alignment */
670 /* byte_aligned=FALSE; */
671 /* Advance offset to next 'element' */
672 offset
= offset
+ 1; }
674 if((byte_aligned
)&&(actx
->aligned
)){
675 BYTE_ALIGN_OFFSET(offset
);
679 buf
= (guint8
*)wmem_alloc(actx
->pinfo
->pool
, length
+1);
681 for(char_pos
=0;char_pos
<length
;char_pos
++){
687 for(i
=0;i
<bits_per_char
;i
++){
688 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, -1, &bit
);
691 /* ALIGNED PER does not do any remapping of chars if
694 /* If alphabet is not provided, do not do any remapping either */
695 if((bits_per_char
==8) || (alphabet
==NULL
)){
698 if (val
< alphabet_length
){
699 buf
[char_pos
]=alphabet
[val
];
701 buf
[char_pos
] = '?'; /* XXX - how to mark this? */
706 proto_tree_add_string(tree
, hf_index
, tvb
, (old_offset
>>3), (offset
>>3)-(old_offset
>>3), (char*)buf
);
708 *value_tvb
= tvb_new_child_real_data(tvb
, buf
, length
, length
);
714 sort_alphabet(char *sorted_alphabet
, const char *alphabet
, int alphabet_length
)
717 char c
, c_max
, c_min
;
720 if (!alphabet_length
) return sorted_alphabet
;
721 memset(tmp_buf
, 0, 256);
722 c_min
= c_max
= alphabet
[0];
723 for (i
=0; i
<alphabet_length
; i
++) {
726 if (c
> c_max
) c_max
= c
;
727 else if (c
< c_min
) c_min
= c
;
729 for (i
=c_min
,j
=0; i
<=c_max
; i
++) {
730 if (tmp_buf
[i
]) sorted_alphabet
[j
++] = i
;
732 return sorted_alphabet
;
736 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
, gboolean has_extension
, const char *alphabet
, int alphabet_length
, tvbuff_t
**value_tvb
)
738 const char *alphabet_ptr
;
739 char sorted_alphabet
[128];
741 if (alphabet_length
> 127) {
742 alphabet_ptr
= alphabet
;
744 alphabet_ptr
= sort_alphabet(sorted_alphabet
, alphabet
, alphabet_length
);
746 return dissect_per_restricted_character_string_sorted(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
, alphabet_ptr
, alphabet_length
, value_tvb
);
749 /* dissect a constrained IA5String that consists of the full ASCII set,
750 i.e. no FROM stuff limiting the alphabet
753 dissect_per_IA5String(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, gboolean has_extension
)
755 offset
=dissect_per_restricted_character_string_sorted(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
,
762 dissect_per_NumericString(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, gboolean has_extension
)
764 offset
=dissect_per_restricted_character_string_sorted(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
,
765 " 0123456789", 11, NULL
);
770 dissect_per_PrintableString(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, gboolean has_extension
)
772 offset
=dissect_per_restricted_character_string_sorted(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
,
773 " '()+,-.*0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 74, NULL
);
777 dissect_per_VisibleString(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, gboolean has_extension
)
779 offset
=dissect_per_restricted_character_string_sorted(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
,
780 " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", 95, NULL
);
784 dissect_per_BMPString(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, gboolean has_extension _U_
)
789 /* xx.x if the length is 0 bytes there will be no encoding */
795 if (min_len
== NO_BOUND
) {
802 if(min_len
!=max_len
){
803 offset
=dissect_per_constrained_integer(tvb
, offset
, actx
,
804 tree
, hf_per_octet_string_length
, min_len
, max_len
,
806 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
810 /* align to byte boundary */
811 BYTE_ALIGN_OFFSET(offset
);
814 PER_NOT_DECODED_YET("BMPString too long");
818 str
= tvb_get_unicode_string(wmem_packet_scope(), tvb
, offset
>>3, length
*2, ENC_BIG_ENDIAN
);
820 proto_tree_add_string(tree
, hf_index
, tvb
, offset
>>3, length
*2, str
);
822 offset
+=(length
<<3)*2;
827 dissect_per_UTF8String(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, gboolean has_extension _U_
)
829 offset
=dissect_per_restricted_character_string_sorted(tvb
, offset
, actx
, tree
,
830 hf_index
, min_len
, max_len
, has_extension
, NULL
, 256, NULL
);
835 dissect_per_object_descriptor(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, tvbuff_t
**value_tvb
)
837 offset
=dissect_per_octet_string(tvb
, offset
, actx
, tree
, hf_index
, -1, -1, FALSE
, value_tvb
);
843 /* this function dissects a constrained sequence of */
845 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_
)
849 guint32 old_offset
=offset
;
851 header_field_info
*hfi
;
853 DEBUG_ENTRY("dissect_per_constrained_sequence_of");
855 /* 19.4 If there is a PER-visible constraint and an extension marker is present in it,
856 * a single bit shall be added to the field-list in a bit-field of length one
859 gboolean extension_present
;
860 offset
=dissect_per_boolean(tvb
, offset
, actx
, parent_tree
, hf_per_extension_present_bit
, &extension_present
);
861 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
862 if(extension_present
){
863 /* 10.9 shall be invoked to add the length determinant as a semi-constrained whole number to the field-list,
864 * followed by the component values
865 * TODO: Handle extension
867 proto_tree_add_text(parent_tree
, tvb
, (offset
>>3), 1, "dissect_per_constrained_sequence_of with extension is not handled");
871 /* 19.5 if min==max and min,max<64k ==> no length determinant */
872 if((min_len
==max_len
) && (min_len
<65536)){
877 /* 19.6 ub>=64k or unset */
878 if ((max_len
>= 65536) || (max_len
== NO_BOUND
)) {
879 /* no constraint, see 10.9.4.2 */
880 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, parent_tree
, hf_per_sequence_of_length
, &length
);
884 /* constrained whole number for number of elements */
885 offset
=dissect_per_constrained_integer(tvb
, offset
, actx
,
886 parent_tree
, hf_per_sequence_of_length
, min_len
, max_len
,
888 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
891 hfi
= proto_registrar_get_nth(hf_index
);
892 if (IS_FT_UINT(hfi
->type
)) {
893 item
= proto_tree_add_uint(parent_tree
, hf_index
, tvb
, offset
>>3, 0, length
);
894 proto_item_append_text(item
, (length
==1)?" item":" items");
896 item
=proto_tree_add_item(parent_tree
, hf_index
, tvb
, offset
>>3, 0, ENC_BIG_ENDIAN
);
898 tree
=proto_item_add_subtree(item
, ett_index
);
899 per_check_items(length
, min_len
, max_len
, actx
, item
);
902 offset
=dissect_per_sequence_of_helper(tvb
, offset
, actx
, tree
, seq
->func
, *seq
->p_id
, length
);
904 if (offset
== old_offset
)
906 else if (offset
>> 3 == old_offset
>> 3)
909 length
= (offset
>> 3) - (old_offset
>> 3);
911 proto_item_set_len(item
, length
);
915 /* this function dissects a constrained set of */
917 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
)
919 /* for basic-per a set-of is encoded in the same way as a sequence-of */
920 DEBUG_ENTRY("dissect_per_constrained_set_of");
921 offset
=dissect_per_constrained_sequence_of(tvb
, offset
, actx
, parent_tree
, hf_index
, ett_index
, seq
, min_len
, max_len
, has_extension
);
930 /* this function dissects a set of */
932 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
)
934 /* for basic-per a set-of is encoded in the same way as a sequence-of */
935 DEBUG_ENTRY("dissect_per_set_of");
936 offset
=dissect_per_sequence_of(tvb
, offset
, actx
, parent_tree
, hf_index
, ett_index
, seq
);
943 /* 23 Encoding the object identifier type */
945 dissect_per_any_oid(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, tvbuff_t
**value_tvb
,
946 gboolean is_absolute
)
950 tvbuff_t
*val_tvb
= NULL
;
951 header_field_info
*hfi
;
953 DEBUG_ENTRY("dissect_per_any_oid");
955 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_object_identifier_length
, &length
);
956 if (actx
->aligned
) BYTE_ALIGN_OFFSET(offset
);
957 val_tvb
= new_octet_aligned_subset(tvb
, offset
, actx
, length
);
959 hfi
= proto_registrar_get_nth(hf_index
);
960 if ((is_absolute
&& hfi
->type
== FT_OID
) || (is_absolute
&& hfi
->type
== FT_REL_OID
)) {
961 actx
->created_item
= proto_tree_add_item(tree
, hf_index
, val_tvb
, 0, length
, ENC_BIG_ENDIAN
);
962 } else if (IS_FT_STRING(hfi
->type
)) {
963 str
= oid_encoded2string(tvb_get_ptr(val_tvb
, 0, length
), length
);
964 actx
->created_item
= proto_tree_add_string(tree
, hf_index
, val_tvb
, 0, length
, str
);
966 DISSECTOR_ASSERT_NOT_REACHED();
969 if (value_tvb
) *value_tvb
= val_tvb
;
971 offset
+= 8 * length
;
977 dissect_per_object_identifier(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, tvbuff_t
**value_tvb
)
979 return dissect_per_any_oid(tvb
, offset
, actx
, tree
, hf_index
, value_tvb
, TRUE
);
983 dissect_per_relative_oid(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, tvbuff_t
**value_tvb
)
985 return dissect_per_any_oid(tvb
, offset
, actx
, tree
, hf_index
, value_tvb
, FALSE
);
989 dissect_per_any_oid_str(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, const char **value_stringx
,
990 gboolean is_absolute
)
992 tvbuff_t
*value_tvb
= NULL
;
995 offset
= dissect_per_any_oid(tvb
, offset
, actx
, tree
, hf_index
, (value_stringx
) ? &value_tvb
: NULL
, is_absolute
);
998 if (value_tvb
&& (length
= tvb_length(value_tvb
))) {
999 *value_stringx
= oid_encoded2string(tvb_get_ptr(value_tvb
, 0, length
), length
);
1001 *value_stringx
= "";
1009 dissect_per_object_identifier_str(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, const char **value_stringx
)
1011 return dissect_per_any_oid_str(tvb
, offset
, actx
, tree
, hf_index
, value_stringx
, TRUE
);
1015 dissect_per_relative_oid_str(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, const char **value_stringx
)
1017 return dissect_per_any_oid_str(tvb
, offset
, actx
, tree
, hf_index
, value_stringx
, FALSE
);
1021 /* this function reads a single bit */
1023 dissect_per_boolean(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, gboolean
*bool_val
)
1027 header_field_info
*hfi
;
1029 DEBUG_ENTRY("dissect_per_boolean");
1031 ch
=tvb_get_guint8(tvb
, offset
>>3);
1032 mask
=1<<(7-(offset
&0x07));
1040 bits
[0] = mask
&0x80?'0'+value
:'.';
1041 bits
[1] = mask
&0x40?'0'+value
:'.';
1042 bits
[2] = mask
&0x20?'0'+value
:'.';
1043 bits
[3] = mask
&0x10?'0'+value
:'.';
1045 bits
[5] = mask
&0x08?'0'+value
:'.';
1046 bits
[6] = mask
&0x04?'0'+value
:'.';
1047 bits
[7] = mask
&0x02?'0'+value
:'.';
1048 bits
[8] = mask
&0x01?'0'+value
:'.';
1051 hfi
= proto_registrar_get_nth(hf_index
);
1052 actx
->created_item
= proto_tree_add_boolean_format(tree
, hf_index
, tvb
, offset
>>3, 1, value
,
1053 "%s %s: %s", bits
, hfi
->name
,
1054 value
?"True":"False");
1056 actx
->created_item
= NULL
;
1068 /* we currently only handle integers up to 32 bits in length. */
1070 dissect_per_integer(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, gint32
*value
)
1074 proto_item
*it
=NULL
;
1075 header_field_info
*hfi
;
1078 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
,hf_per_integer_length
, &length
);
1081 PER_NOT_DECODED_YET("too long integer(per_integer)");
1086 for(i
=0;i
<length
;i
++){
1088 if(tvb_get_guint8(tvb
, offset
>>3)&0x80){
1089 /* negative number */
1092 /* positive number */
1096 val
=(val
<<8)|tvb_get_guint8(tvb
,offset
>>3);
1100 hfi
= proto_registrar_get_nth(hf_index
);
1102 THROW(ReportedBoundsError
);
1103 if (IS_FT_INT(hfi
->type
)) {
1104 it
=proto_tree_add_int(tree
, hf_index
, tvb
, (offset
>>3)-(length
+1), length
+1, val
);
1105 } else if (IS_FT_UINT(hfi
->type
)) {
1106 it
=proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
>>3)-(length
+1), length
+1, val
);
1108 proto_tree_add_text(tree
, tvb
, (offset
>>3)-(length
+1), length
+1, "Field is not an integer: %s", hfi
->abbrev
);
1109 REPORT_DISSECTOR_BUG("PER integer field that's not an FT_INT* or FT_UINT*");
1113 actx
->created_item
= it
;
1121 /* 64 bits experimental version, internal for now */
1123 dissect_per_integer64b(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, gint64
*value
)
1127 proto_item
*it
=NULL
;
1128 header_field_info
*hfi
;
1131 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
, -1, &length
);
1134 PER_NOT_DECODED_YET("too long integer (64b)");
1139 for(i
=0;i
<length
;i
++){
1141 if(tvb_get_guint8(tvb
, offset
>>3)&0x80){
1142 /* negative number */
1143 val
=G_GINT64_CONSTANT(0xffffffffffffffff);
1145 /* positive number */
1149 val
=(val
<<8)|tvb_get_guint8(tvb
,offset
>>3);
1153 hfi
= proto_registrar_get_nth(hf_index
);
1155 THROW(ReportedBoundsError
);
1156 if (IS_FT_INT(hfi
->type
)) {
1157 it
=proto_tree_add_int64(tree
, hf_index
, tvb
, (offset
>>3)-(length
+1), length
+1, val
);
1158 } else if (IS_FT_UINT(hfi
->type
)) {
1159 it
=proto_tree_add_uint64(tree
, hf_index
, tvb
, (offset
>>3)-(length
+1), length
+1, val
);
1161 proto_tree_add_text(tree
, tvb
, (offset
>>3)-(length
+1), length
+1, "Field is not an integer: %s", hfi
->abbrev
);
1162 REPORT_DISSECTOR_BUG("PER integer field that's not an FT_INT* or FT_UINT*");
1166 actx
->created_item
= it
;
1174 /* this function reads a constrained integer with or without a
1175 PER visible extension marker present
1177 has_extension==TRUE would map to asn constructs such as:
1178 rfc-number INTEGER (1..32768, ...)
1179 while has_extension==FALSE would map to:
1180 t35CountryCode INTEGER (0..255)
1182 it only handles integers that fit inside a 32 bit integer
1185 10.5.3 range=ub-lb+1
1188 10.5.6 unaligned version
1189 10.5.7 aligned version
1190 10.5.7.1 decoding of 0-255 1-8 bits
1191 10.5.7.2 decoding og 0-256 8 bits
1192 10.5.7.3 decoding of 0-65535 16 bits
1196 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
)
1198 proto_item
*it
=NULL
;
1200 gint val_start
, val_length
;
1202 header_field_info
*hfi
;
1205 DEBUG_ENTRY("dissect_per_constrained_integer");
1207 gboolean extension_present
;
1208 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_present
);
1209 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
1210 if(extension_present
){
1211 offset
= dissect_per_integer(tvb
, offset
, actx
, tree
, hf_index
, (gint32
*)value
);
1216 hfi
= proto_registrar_get_nth(hf_index
);
1218 /* 10.5.3 Let "range" be defined as the integer value ("ub" - "lb" 1), and let the value to be encoded be "n".
1219 * 10.5.7 In the case of the ALIGNED variant the encoding depends on whether
1220 * d) "range" is greater than 64K (the indefinite length case).
1222 if(((max
-min
)>65536)&&(actx
->aligned
)){
1223 /* just set range really big so it will fall through
1224 to the bottom of the encoding */
1227 /* Really ugly hack.
1228 * We should really use guint64 as parameters for min/max.
1229 * This is to prevent range from being 0 if
1230 * the range for a signed integer spans the entire 32 bit range.
1231 * Special case the 2 common cases when this can happen until
1232 * a real fix is implemented.
1234 if( (max
==0x7fffffff && min
==0x80000000)
1235 || (max
==0xffffffff && min
==0x00000000) ){
1243 timeval
.secs
=val
; timeval
.nsecs
=0;
1244 /* 10.5.4 If "range" has the value 1, then the result of the encoding shall be an empty bit-field (no bits).*/
1246 /* something is really wrong if range is 0 */
1247 DISSECTOR_ASSERT(range
!=0);
1250 val_start
= offset
>>3; val_length
= 0;
1252 } else if((range
<=255)||(!actx
->aligned
)) {
1254 * 10.5.6 In the case of the UNALIGNED variant the value ("n" - "lb") shall be encoded
1255 * as a non-negative binary integer in a bit field as specified in 10.3 with the minimum
1256 * number of bits necessary to represent the range.
1261 /* We only handle 32 bit integers */
1265 while ((range
& mask
)== 0){
1270 if ((range
& mask2
) == 0)
1279 val_start
= (offset
)>>3;
1280 val_length
= length
;
1281 val
= (guint32
)tvb_get_bits64(tvb
,offset
,num_bits
, ENC_BIG_ENDIAN
);
1283 if (display_internal_per_fields
){
1284 str
= decode_bits_in_field((offset
&0x07),num_bits
,val
);
1285 proto_tree_add_text(tree
, tvb
, val_start
,val_length
,"MIN %u Range = %u Bitfield length %u, %s: %s value: %u",min
, range
, num_bits
, hfi
->name
, str
, val
+min
);
1287 /* The actual value */
1289 offset
= offset
+num_bits
;
1290 } else if(range
==256){
1293 /* in the aligned case, align to byte boundary */
1294 BYTE_ALIGN_OFFSET(offset
);
1295 val
=tvb_get_guint8(tvb
, offset
>>3);
1298 val_start
= (offset
>>3)-1; val_length
= 1;
1300 } else if(range
<=65536){
1303 /* in the aligned case, align to byte boundary */
1304 BYTE_ALIGN_OFFSET(offset
);
1305 val
=tvb_get_guint8(tvb
, offset
>>3);
1308 val
|=tvb_get_guint8(tvb
, offset
>>3);
1311 val_start
= (offset
>>3)-2; val_length
= 2;
1319 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, -1, &bit
);
1321 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, -1, &bit
);
1322 num_bytes
=(num_bytes
<<1)|bit
;
1324 num_bytes
++; /* lower bound for length determinant is 1 */
1325 if (display_internal_per_fields
)
1326 proto_tree_add_uint(tree
, hf_per_const_int_len
, tvb
, (offset
>>3), 1, num_bytes
);
1329 BYTE_ALIGN_OFFSET(offset
);
1331 for(i
=0;i
<num_bytes
;i
++){
1332 val
=(val
<<8)|tvb_get_guint8(tvb
,offset
>>3);
1335 val_start
= (offset
>>3)-(num_bytes
+1); val_length
= num_bytes
+1;
1340 if (IS_FT_UINT(hfi
->type
)) {
1341 it
= proto_tree_add_uint(tree
, hf_index
, tvb
, val_start
, val_length
, val
);
1342 per_check_value(val
, min
, max
, actx
, it
, FALSE
);
1343 } else if (IS_FT_INT(hfi
->type
)) {
1344 it
= proto_tree_add_int(tree
, hf_index
, tvb
, val_start
, val_length
, val
);
1345 per_check_value(val
, min
, max
, actx
, it
, TRUE
);
1346 } else if (IS_FT_TIME(hfi
->type
)) {
1347 it
= proto_tree_add_time(tree
, hf_index
, tvb
, val_start
, val_length
, &timeval
);
1349 THROW(ReportedBoundsError
);
1351 actx
->created_item
= it
;
1352 if (value
) *value
= val
;
1357 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
)
1359 proto_item
*it
=NULL
, *int_item
=NULL
;
1361 gint val_start
, val_length
;
1363 header_field_info
*hfi
;
1367 DEBUG_ENTRY("dissect_per_constrained_integer_64b");
1369 gboolean extension_present
;
1370 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_present
);
1371 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
1372 if(extension_present
){
1373 offset
= dissect_per_integer64b(tvb
, offset
, actx
, tree
, hf_index
, (gint64
*)value
);
1378 hfi
= proto_registrar_get_nth(hf_index
);
1380 /* 10.5.3 Let "range" be defined as the integer value ("ub" - "lb" 1), and let the value to be encoded be "n".
1381 * 10.5.7 In the case of the ALIGNED variant the encoding depends on whether
1382 * d) "range" is greater than 64K (the indefinite length case).
1384 if(((max
-min
)>65536)&&(actx
->aligned
)){
1385 /* just set range really big so it will fall through
1386 to the bottom of the encoding */
1387 /* range=1000000; */
1390 range
++; /* make it fall trough? */
1392 /* Copied from the 32 bit version, assuming the same problem occurs
1393 * at 64 bit boundary.
1395 * We should really use guint64 as parameters for min/max.
1396 * This is to prevent range from being 0 if
1397 * the range for a signed integer spans the entire 32 bit range.
1398 * Special case the 2 common cases when this can happen until
1399 * a real fix is implemented.
1401 if( (max
==G_GINT64_CONSTANT(0x7fffffffffffffff) && min
==G_GINT64_CONSTANT(0x8000000000000000))
1402 || (max
==G_GINT64_CONSTANT(0xffffffffffffffff) && min
==0) ){
1403 range
=G_GINT64_CONSTANT(0xffffffffffffffff);
1410 timeval
.secs
=0; timeval
.nsecs
=0;
1411 /* 10.5.4 If "range" has the value 1, then the result of the encoding shall be an empty bit-field (no bits).*/
1413 /* something is really wrong if range is 0 */
1414 DISSECTOR_ASSERT(range
!=0);
1417 val_start
= offset
>>3; val_length
= 0;
1419 } else if((range
<=255)||(!actx
->aligned
)) {
1421 * 10.5.6 In the case of the UNALIGNED variant the value ("n" - "lb") shall be encoded
1422 * as a non-negative binary integer in a bit field as specified in 10.3 with the minimum
1423 * number of bits necessary to represent the range.
1426 int i
, bit
, length
, str_length
, str_index
;
1428 /* We only handle 64 bit integers */
1429 mask
= G_GINT64_CONSTANT(0x8000000000000000);
1430 mask2
= G_GINT64_CONSTANT(0x7fffffffffffffff);
1432 while ((range
& mask
)== 0){
1437 if ((range
& mask2
) == 0)
1446 /* prepare the string (max number of bits + quartet separators + field name + ": ") */
1447 str_length
= 512+128+(int)strlen(hfi
->name
)+2;
1448 str
= (char *)wmem_alloc(wmem_packet_scope(), str_length
+1);
1449 str_index
= g_snprintf(str
, str_length
+1, "%s: ", hfi
->name
);
1450 for(bit
=0;bit
<((int)(offset
&0x07));bit
++){
1451 if(bit
&&(!(bit
%4))){
1452 if (str_index
< str_length
) str
[str_index
++] = ' ';
1454 if (str_index
< str_length
) str
[str_index
++] = '.';
1456 /* read the bits for the int */
1457 for(i
=0;i
<num_bits
;i
++){
1458 if(bit
&&(!(bit
%4))){
1459 if (str_index
< str_length
) str
[str_index
++] = ' ';
1461 if(bit
&&(!(bit
%8))){
1463 if (str_index
< str_length
) str
[str_index
++] = ' ';
1466 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, -1, &tmp
);
1470 if (str_index
< str_length
) str
[str_index
++] = '1';
1472 if (str_index
< str_length
) str
[str_index
++] = '0';
1476 if(bit
&&(!(bit
%4))){
1477 if (str_index
< str_length
) str
[str_index
++] = ' ';
1479 if (str_index
< str_length
) str
[str_index
++] = '.';
1481 str
[str_index
] = '\0'; /* Terminate string */
1482 val_start
= (offset
-num_bits
)>>3; val_length
= length
;
1484 if (display_internal_per_fields
)
1485 proto_tree_add_text(tree
, tvb
, val_start
,val_length
,"Range = (%" G_GINT64_MODIFIER
"u) Bitfield length %u, %s",range
, num_bits
, str
);
1486 } else if(range
==256){
1489 /* in the aligned case, align to byte boundary */
1490 BYTE_ALIGN_OFFSET(offset
);
1491 val
=tvb_get_guint8(tvb
, offset
>>3);
1494 val_start
= (offset
>>3)-1; val_length
= 1;
1496 } else if(range
<=65536){
1499 /* in the aligned case, align to byte boundary */
1500 BYTE_ALIGN_OFFSET(offset
);
1501 val
=tvb_get_guint8(tvb
, offset
>>3);
1504 val
|=tvb_get_guint8(tvb
, offset
>>3);
1507 val_start
= (offset
>>3)-2; val_length
= 2;
1510 int i
,num_bytes
,n_bits
;
1514 /* calculate the number of bits to hold the length */
1515 if ((range
& G_GINT64_CONSTANT(0xffffffff0000000)) != 0){
1520 num_bytes
=tvb_get_bits8(tvb
, offset
, n_bits
);
1521 num_bytes
++; /* lower bound for length determinant is 1 */
1522 if (display_internal_per_fields
){
1523 int_item
= proto_tree_add_bits_item(tree
, hf_per_const_int_len
, tvb
, offset
,n_bits
, ENC_BIG_ENDIAN
);
1524 proto_item_append_text(int_item
,"+1=%u bytes, Range = (%" G_GINT64_MODIFIER
"u)",num_bytes
, range
);
1526 offset
= offset
+n_bits
;
1528 BYTE_ALIGN_OFFSET(offset
);
1530 for(i
=0;i
<num_bytes
;i
++){
1531 val
=(val
<<8)|tvb_get_guint8(tvb
,offset
>>3);
1534 val_start
= (offset
>>3)-(num_bytes
+1); val_length
= num_bytes
+1;
1539 if (IS_FT_UINT(hfi
->type
)) {
1540 it
= proto_tree_add_uint64(tree
, hf_index
, tvb
, val_start
, val_length
, val
);
1541 per_check_value64(val
, min
, max
, actx
, it
, FALSE
);
1542 } else if (IS_FT_INT(hfi
->type
)) {
1543 it
= proto_tree_add_int64(tree
, hf_index
, tvb
, val_start
, val_length
, val
);
1544 per_check_value64(val
, min
, max
, actx
, it
, TRUE
);
1545 } else if (IS_FT_TIME(hfi
->type
)) {
1546 timeval
.secs
= (guint32
)val
;
1547 it
= proto_tree_add_time(tree
, hf_index
, tvb
, val_start
, val_length
, &timeval
);
1549 THROW(ReportedBoundsError
);
1551 actx
->created_item
= it
;
1552 if (value
) *value
= val
;
1556 /* 13 Encoding the enumerated type */
1558 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
)
1561 proto_item
*it
=NULL
;
1562 guint32 enum_index
, val
;
1563 guint32 start_offset
= offset
;
1564 gboolean extension_present
= FALSE
;
1565 header_field_info
*hfi
;
1567 if (has_extension
) {
1569 offset
= dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_present
);
1570 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
1573 if (!extension_present
) {
1575 offset
= dissect_per_constrained_integer(tvb
, offset
, actx
, tree
, hf_per_enum_index
, 0, root_num
- 1, &enum_index
, FALSE
);
1576 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
1580 /* 10.5.4 If "range" has the value 1,
1581 * then the result of the encoding shall be
1582 * an empty bit-field (no bits).
1586 /* 13.3 ".. and the value shall be added to the field-list as a
1587 * normally small non-negative whole number whose value is the
1588 * enumeration index of the additional enumeration and with "lb" set to 0.."
1590 offset
= dissect_per_normally_small_nonnegative_whole_number(tvb
, offset
, actx
, tree
, hf_per_enum_extension_index
, &enum_index
);
1592 enum_index
+= root_num
;
1594 val
= (value_map
&& (enum_index
<(root_num
+ext_num
))) ? value_map
[enum_index
] : enum_index
;
1595 hfi
= proto_registrar_get_nth(hf_index
);
1596 if (IS_FT_UINT(hfi
->type
)) {
1597 it
= proto_tree_add_uint(tree
, hf_index
, tvb
, start_offset
>>3, BLEN(start_offset
, offset
), val
);
1599 THROW(ReportedBoundsError
);
1601 actx
->created_item
= it
;
1602 if (value
) *value
= val
;
1606 /* 14 Encoding the real type */
1608 dissect_per_real(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, double *value
)
1610 guint32 val_length
, end_offset
;
1614 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_real_length
, &val_length
);
1615 if (actx
->aligned
) BYTE_ALIGN_OFFSET(offset
);
1616 val_tvb
= new_octet_aligned_subset(tvb
, offset
, actx
, val_length
);
1617 end_offset
= offset
+ val_length
* 8;
1619 val
= asn1_get_real(tvb_get_ptr(val_tvb
, 0, val_length
), val_length
);
1620 actx
->created_item
= proto_tree_add_double(tree
, hf_index
, val_tvb
, 0, val_length
, val
);
1622 if (value
) *value
= val
;
1627 /* 22 Encoding the choice type */
1629 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
)
1631 gboolean
/*extension_present,*/ extension_flag
;
1632 int extension_root_entries
;
1633 int extension_addition_entries
;
1634 guint32 choice_index
;
1637 guint32 old_offset
= offset
;
1638 proto_item
*choice_item
= NULL
;
1639 proto_tree
*choice_tree
= NULL
;
1641 DEBUG_ENTRY("dissect_per_choice");
1643 if (value
) *value
= -1;
1646 if (choice
[0].extension
== ASN1_NO_EXTENSIONS
){
1647 /*extension_present = FALSE; ?? */
1648 extension_flag
= FALSE
;
1650 /*extension_present = TRUE; ?? */
1651 offset
= dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_bit
, &extension_flag
);
1652 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
1655 /* count the number of entries in the extension root and extension addition */
1656 extension_root_entries
= 0;
1657 extension_addition_entries
= 0;
1658 for (i
=0; choice
[i
].p_id
; i
++) {
1659 switch(choice
[i
].extension
){
1660 case ASN1_NO_EXTENSIONS
:
1661 case ASN1_EXTENSION_ROOT
:
1662 extension_root_entries
++;
1664 case ASN1_NOT_EXTENSION_ROOT
:
1665 extension_addition_entries
++;
1670 if (!extension_flag
) { /* 22.6, 22.7 */
1671 if (extension_root_entries
== 1) { /* 22.5 */
1674 offset
= dissect_per_constrained_integer(tvb
, offset
, actx
,
1675 tree
, hf_per_choice_index
, 0, extension_root_entries
- 1,
1676 &choice_index
, FALSE
);
1677 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
1680 idx
= -1; cidx
= choice_index
;
1681 for (i
=0; choice
[i
].p_id
; i
++) {
1682 if(choice
[i
].extension
!= ASN1_NOT_EXTENSION_ROOT
){
1683 if (!cidx
) { idx
= i
; break; }
1688 offset
= dissect_per_normally_small_nonnegative_whole_number(tvb
, offset
, actx
, tree
, hf_per_choice_extension_index
, &choice_index
);
1689 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_open_type_length
, &ext_length
);
1691 idx
= -1; cidx
= choice_index
;
1692 for (i
=0; choice
[i
].p_id
; i
++) {
1693 if(choice
[i
].extension
== ASN1_NOT_EXTENSION_ROOT
){
1694 if (!cidx
) { idx
= i
; break; }
1701 choice_item
= proto_tree_add_uint(tree
, hf_index
, tvb
, old_offset
>>3, 0, choice
[idx
].value
);
1702 choice_tree
= proto_item_add_subtree(choice_item
, ett_index
);
1703 if (!extension_flag
) {
1704 offset
= choice
[idx
].func(tvb
, offset
, actx
, choice_tree
, *choice
[idx
].p_id
);
1706 choice
[idx
].func(tvb
, offset
, actx
, choice_tree
, *choice
[idx
].p_id
);
1707 offset
+= ext_length
* 8;
1709 proto_item_set_len(choice_item
, BLEN(old_offset
, offset
));
1711 if (!extension_flag
) {
1712 PER_NOT_DECODED_YET("unknown extension root index in choice");
1714 offset
+= ext_length
* 8;
1715 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_per_choice_extension_unknown
,
1716 tvb
, old_offset
>>3, BLEN(old_offset
, offset
),
1717 "Choice no. %d in extension", choice_index
);
1721 if (value
&& (idx
!= -1))
1722 *value
= choice
[idx
].value
;
1729 index_get_optional_name(const per_sequence_t
*sequence
, int idx
)
1732 header_field_info
*hfi
;
1734 for(i
=0;sequence
[i
].p_id
;i
++){
1735 if((sequence
[i
].extension
!=ASN1_NOT_EXTENSION_ROOT
)&&(sequence
[i
].optional
==ASN1_OPTIONAL
)){
1737 hfi
= proto_registrar_get_nth(*sequence
[i
].p_id
);
1738 return (hfi
) ? hfi
->name
: "<unknown filed>";
1743 return "<unknown type>";
1747 index_get_extension_name(const per_sequence_t
*sequence
, int idx
)
1750 header_field_info
*hfi
;
1752 for(i
=0;sequence
[i
].p_id
;i
++){
1753 if(sequence
[i
].extension
==ASN1_NOT_EXTENSION_ROOT
){
1755 if (*sequence
[i
].p_id
== -1) return "extension addition group";
1756 hfi
= proto_registrar_get_nth(*sequence
[i
].p_id
);
1757 return (hfi
) ? hfi
->name
: "<unknown filed>";
1762 return "<unknown type>";
1766 index_get_field_name(const per_sequence_t
*sequence
, int idx
)
1768 header_field_info
*hfi
;
1770 hfi
= proto_registrar_get_nth(*sequence
[idx
].p_id
);
1771 return (hfi
) ? hfi
->name
: "<unknown filed>";
1774 /* this functions decodes a SEQUENCE
1775 it can only handle SEQUENCES with at most 32 DEFAULT or OPTIONAL fields
1777 18.2 optinal/default items in root
1778 18.3 we ignore the case where n>64K
1779 18.4 the root sequence
1787 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
)
1789 gboolean
/*extension_present,*/ extension_flag
, optional_field_flag
;
1792 guint32 old_offset
=offset
;
1793 guint32 i
, j
, num_opts
;
1794 guint32 optional_mask
[SEQ_MAX_COMPONENTS
>>5];
1796 DEBUG_ENTRY("dissect_per_sequence");
1798 item
=proto_tree_add_item(parent_tree
, hf_index
, tvb
, offset
>>3, 0, ENC_BIG_ENDIAN
);
1799 tree
=proto_item_add_subtree(item
, ett_index
);
1802 /* first check if there should be an extension bit for this CHOICE.
1803 we do this by just checking the first choice arm
1807 if(sequence
[0].extension
==ASN1_NO_EXTENSIONS
){
1808 /*extension_present=0; ?? */
1810 /*extension_present=1; ?? */
1811 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_bit
, &extension_flag
);
1812 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
1816 for(i
=0;sequence
[i
].p_id
;i
++){
1817 if((sequence
[i
].extension
!=ASN1_NOT_EXTENSION_ROOT
)&&(sequence
[i
].optional
==ASN1_OPTIONAL
)){
1821 if (num_opts
> SEQ_MAX_COMPONENTS
) {
1822 PER_NOT_DECODED_YET("too many optional/default components");
1825 memset(optional_mask
, 0, sizeof(optional_mask
));
1826 for(i
=0;i
<num_opts
;i
++){
1827 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_optional_field_bit
, &optional_field_flag
);
1829 proto_item_append_text(actx
->created_item
, " (%s %s present)",
1830 index_get_optional_name(sequence
, i
), optional_field_flag
?"is":"is NOT");
1832 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
1833 if(optional_field_flag
){
1834 optional_mask
[i
>>5]|=0x80000000>>(i
&0x1f);
1840 for(i
=0,j
=0;sequence
[i
].p_id
;i
++){
1841 if( (sequence
[i
].extension
==ASN1_NO_EXTENSIONS
)
1842 || (sequence
[i
].extension
==ASN1_EXTENSION_ROOT
) ){
1843 if(sequence
[i
].optional
==ASN1_OPTIONAL
){
1844 gboolean is_present
;
1848 is_present
=(0x80000000>>(j
&0x1f))&optional_mask
[j
>>5];
1855 if(sequence
[i
].func
){
1856 offset
=sequence
[i
].func(tvb
, offset
, actx
, tree
, *sequence
[i
].p_id
);
1858 PER_NOT_DECODED_YET(index_get_field_name(sequence
, i
));
1865 gboolean extension_bit
;
1866 guint32 num_known_extensions
;
1867 guint32 num_extensions
;
1868 guint32 extension_mask
;
1870 offset
=dissect_per_normally_small_nonnegative_whole_number(tvb
, offset
, actx
, tree
, hf_per_num_sequence_extensions
, &num_extensions
);
1871 /* the X.691 standard is VERY unclear here.
1872 there is no mention that the lower bound lb for this
1873 (apparently) semiconstrained value is 1,
1874 apart from the NOTE: comment in 18.8 that this value can
1876 In my book, there is a semantic difference between having
1877 a comment that says that the value can not be zero
1878 and stating that the lb is 1.
1879 I don't know if this is right or not but it makes
1880 some of the very few captures I have decode properly.
1882 It could also be that the captures I have are generated by
1883 a broken implementation.
1884 If this is wrong and you don't report it as a bug
1885 then it won't get fixed!
1888 if (num_extensions
> 32) {
1889 PER_NOT_DECODED_YET("too many extensions");
1893 for(i
=0;i
<num_extensions
;i
++){
1894 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_bit
);
1896 proto_item_append_text(actx
->created_item
, " (%s %s present)",
1897 index_get_extension_name(sequence
, i
), extension_bit
?"is":"is NOT");
1899 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
1901 extension_mask
=(extension_mask
<<1)|extension_bit
;
1904 /* find how many extensions we know about */
1905 num_known_extensions
=0;
1906 for(i
=0;sequence
[i
].p_id
;i
++){
1907 if(sequence
[i
].extension
==ASN1_NOT_EXTENSION_ROOT
){
1908 num_known_extensions
++;
1912 /* decode the extensions one by one */
1913 for(i
=0;i
<num_extensions
;i
++){
1917 guint32 extension_index
;
1920 if(!((1L<<(num_extensions
-1-i
))&extension_mask
)){
1921 /* this extension is not encoded in this PDU */
1925 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_open_type_length
, &length
);
1927 if(i
>=num_known_extensions
){
1928 /* we don't know how to decode this extension */
1930 expert_add_info(actx
->pinfo
, item
, &ei_per_sequence_extension_unknown
);
1935 for(j
=0,k
=0;sequence
[j
].p_id
;j
++){
1936 if(sequence
[j
].extension
==ASN1_NOT_EXTENSION_ROOT
){
1945 if(sequence
[extension_index
].func
){
1946 new_offset
=sequence
[extension_index
].func(tvb
, offset
, actx
, tree
, *sequence
[extension_index
].p_id
);
1948 difference
= offset
- new_offset
;
1949 /* A difference of 7 or less might be byte aligning */
1950 /* Difference could be 8 if open type has no bits and the length is 1 */
1951 if ((length
> 1) && (difference
> 7)) {
1952 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_per_encoding_error
, tvb
, new_offset
>>3, (offset
-new_offset
)>>3,
1953 "Possible encoding error full length not decoded. Open type length %u ,decoded %u",length
, length
- (difference
>>3));
1956 PER_NOT_DECODED_YET(index_get_field_name(sequence
, extension_index
));
1962 proto_item_set_len(item
, (offset
>>3)!=(old_offset
>>3)?(offset
>>3)-(old_offset
>>3):1);
1963 actx
->created_item
= item
;
1968 dissect_per_sequence_eag(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, const per_sequence_t
*sequence
)
1970 gboolean optional_field_flag
;
1971 guint32 i
, j
, num_opts
;
1972 guint32 optional_mask
[SEQ_MAX_COMPONENTS
>>5];
1974 DEBUG_ENTRY("dissect_per_sequence_eag");
1977 for(i
=0;sequence
[i
].p_id
;i
++){
1978 if(sequence
[i
].optional
==ASN1_OPTIONAL
){
1982 if (num_opts
> SEQ_MAX_COMPONENTS
) {
1983 PER_NOT_DECODED_YET("too many optional/default components");
1986 memset(optional_mask
, 0, sizeof(optional_mask
));
1987 for(i
=0;i
<num_opts
;i
++){
1988 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_optional_field_bit
, &optional_field_flag
);
1990 proto_item_append_text(actx
->created_item
, " (%s %s present)",
1991 index_get_optional_name(sequence
, i
), optional_field_flag
?"is":"is NOT");
1993 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
1994 if(optional_field_flag
){
1995 optional_mask
[i
>>5]|=0x80000000>>(i
&0x1f);
1999 for(i
=0,j
=0;sequence
[i
].p_id
;i
++){
2000 if(sequence
[i
].optional
==ASN1_OPTIONAL
){
2001 gboolean is_present
;
2005 is_present
=(0x80000000>>(j
&0x1f))&optional_mask
[j
>>5];
2012 if(sequence
[i
].func
){
2013 offset
=sequence
[i
].func(tvb
, offset
, actx
, tree
, *sequence
[i
].p_id
);
2015 PER_NOT_DECODED_YET(index_get_field_name(sequence
, i
));
2023 /* 15 Encoding the bitstring type
2025 max_len or min_len == NO_BOUND means there is no lower/upper constraint
2029 static tvbuff_t
*dissect_per_bit_string_display(tvbuff_t
*tvb
, guint32 offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, header_field_info
*hfi
, guint32 length
)
2031 tvbuff_t
*out_tvb
= NULL
;
2032 guint32 pad_length
=0;
2035 out_tvb
= tvb_new_octet_aligned(tvb
, offset
, length
);
2036 add_new_data_source(actx
->pinfo
, out_tvb
, "Bitstring tvb");
2039 actx
->created_item
= proto_tree_add_item(tree
, hf_index
, out_tvb
, 0, -1, ENC_BIG_ENDIAN
);
2040 proto_item_append_text(actx
->created_item
, " [bit length %u", length
);
2042 pad_length
= 8-(length
%8);
2043 proto_item_append_text(actx
->created_item
, ", %u LSB pad bits", pad_length
);
2046 if (length
<=64) { /* if read into 64 bits also handle length <= 24, 40, 48, 56 bits */
2048 value
= tvb_get_bits8(out_tvb
, 0, length
);
2049 }else if (length
<=16) {
2050 value
= tvb_get_bits16(out_tvb
, 0, length
, ENC_BIG_ENDIAN
);
2051 }else if (length
<=24) { /* first read 16 and then the remaining bits */
2052 value
= tvb_get_bits16(out_tvb
, 0, 16, ENC_BIG_ENDIAN
);
2053 value
<<= 8 - pad_length
;
2054 value
|= tvb_get_bits8(out_tvb
, 16, length
- 16);
2055 }else if (length
<=32) {
2056 value
= tvb_get_bits32(out_tvb
, 0, length
, ENC_BIG_ENDIAN
);
2057 }else if (length
<=40) { /* first read 32 and then the remaining bits */
2058 value
= tvb_get_bits32(out_tvb
, 0, 32, ENC_BIG_ENDIAN
);
2059 value
<<= 8 - pad_length
;
2060 value
|= tvb_get_bits8(out_tvb
, 32, length
- 32);
2061 }else if (length
<=48) { /* first read 32 and then the remaining bits */
2062 value
= tvb_get_bits32(out_tvb
, 0, 32, ENC_BIG_ENDIAN
);
2063 value
<<= 16 - pad_length
;
2064 value
|= tvb_get_bits16(out_tvb
, 32, length
- 32, ENC_BIG_ENDIAN
);
2065 }else if (length
<=56) { /* first read 32 and 16 then the remaining bits */
2066 value
= tvb_get_bits32(out_tvb
, 0, 32, ENC_BIG_ENDIAN
);
2068 value
|= tvb_get_bits16(out_tvb
, 32, 16, ENC_BIG_ENDIAN
);
2069 value
<<= 8 - pad_length
;
2070 value
|= tvb_get_bits8(out_tvb
, 48, length
- 48);
2072 value
= tvb_get_bits64(out_tvb
, 0, length
, ENC_BIG_ENDIAN
);
2074 proto_item_append_text(actx
->created_item
, ", %s decimal value %" G_GINT64_MODIFIER
"u",
2075 decode_bits_in_field(0, length
, value
), value
);
2077 proto_item_append_text(actx
->created_item
, "]");
2083 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
)
2085 /*gint val_start, val_length;*/
2087 header_field_info
*hfi
;
2088 tvbuff_t
*out_tvb
= NULL
;
2090 hfi
= (hf_index
==-1) ? NULL
: proto_registrar_get_nth(hf_index
);
2092 DEBUG_ENTRY("dissect_per_bit_string");
2093 /* 15.8 if the length is 0 bytes there will be no encoding */
2096 *value_tvb
= out_tvb
;
2100 if (min_len
== NO_BOUND
) {
2103 /* 15.6 If an extension marker is present in the size constraint specification of the bitstring type,
2104 * a single bit shall be added to the field-list in a bit-field of length one.
2105 * The bit shall be set to 1 if the length of this encoding is not within the range of the extension root,
2106 * and zero otherwise.
2108 if (has_extension
) {
2109 gboolean extension_present
;
2110 offset
= dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_present
);
2111 if(extension_present
){
2112 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_bit_string_length
, &length
);
2116 BYTE_ALIGN_OFFSET(offset
);
2118 out_tvb
= dissect_per_bit_string_display(tvb
, offset
, actx
, tree
, hf_index
, hfi
, length
);
2121 /*val_start = offset>>3;*/
2122 /*val_length = (length+7)/8;*/
2126 *value_tvb
= out_tvb
;
2132 /* 15.9 if length is fixed and less than or equal to sixteen bits*/
2133 if ((min_len
==max_len
) && (max_len
<=16)) {
2134 out_tvb
= dissect_per_bit_string_display(tvb
, offset
, actx
, tree
, hf_index
, hfi
, min_len
);
2137 *value_tvb
= out_tvb
;
2142 /* 15.10 if length is fixed and less than to 64kbits*/
2143 if((min_len
==max_len
)&&(min_len
<65536)){
2144 /* (octet-aligned in the ALIGNED variant)
2148 BYTE_ALIGN_OFFSET(offset
);
2150 out_tvb
= dissect_per_bit_string_display(tvb
, offset
, actx
, tree
, hf_index
, hfi
, min_len
);
2153 *value_tvb
= out_tvb
;
2158 if (max_len
!= NO_BOUND
) {
2159 offset
=dissect_per_constrained_integer(tvb
, offset
, actx
,
2160 tree
, hf_per_bit_string_length
, min_len
, max_len
,
2162 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
2164 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_bit_string_length
, &length
);
2169 BYTE_ALIGN_OFFSET(offset
);
2171 out_tvb
= dissect_per_bit_string_display(tvb
, offset
, actx
, tree
, hf_index
, hfi
, length
);
2174 /*val_start = offset>>3;*/
2175 /*val_length = (length+7)/8;*/
2179 *value_tvb
= out_tvb
;
2184 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
)
2186 tvbuff_t
*val_tvb
= NULL
;
2187 proto_tree
*subtree
= tree
;
2189 offset
= dissect_per_bit_string(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
, &val_tvb
);
2191 if (type_cb
&& val_tvb
) {
2192 subtree
= proto_item_add_subtree(actx
->created_item
, ett_per_containing
);
2193 type_cb(val_tvb
, actx
->pinfo
, subtree
);
2199 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
)
2201 tvbuff_t
*val_tvb
= NULL
;
2202 proto_tree
*subtree
= tree
;
2204 offset
= dissect_per_bit_string(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
, &val_tvb
);
2206 if (type_cb
&& val_tvb
) {
2207 subtree
= proto_item_add_subtree(actx
->created_item
, ett_per_containing
);
2208 type_cb(val_tvb
, actx
->pinfo
, subtree
, NULL
);
2214 /* this fucntion dissects an OCTET STRING
2224 max_len or min_len == NO_BOUND means there is no lower/upper constraint
2226 hf_index can either be a FT_BYTES or an FT_STRING
2229 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
)
2231 gint val_start
= 0, val_length
;
2233 header_field_info
*hfi
;
2234 tvbuff_t
*out_tvb
= NULL
;
2236 hfi
= (hf_index
==-1) ? NULL
: proto_registrar_get_nth(hf_index
);
2238 DEBUG_ENTRY("dissect_per_octet_string");
2240 if (has_extension
) { /* 16.3 an extension marker is present */
2241 gboolean extension_present
;
2242 offset
= dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_present
);
2243 if (!display_internal_per_fields
) PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
2244 if (extension_present
) max_len
= NO_BOUND
; /* skip to 16.8 */
2247 if (min_len
== NO_BOUND
) {
2250 if (max_len
==0) { /* 16.5 if the length is 0 bytes there will be no encoding */
2251 val_start
= offset
>>3;
2254 } else if((min_len
==max_len
)&&(max_len
<=2)) {
2255 /* 16.6 if length is fixed and less than or equal to two bytes*/
2256 val_start
= offset
>>3;
2257 val_length
= min_len
;
2258 out_tvb
= new_octet_aligned_subset(tvb
, offset
, actx
, val_length
);
2261 } else if ((min_len
==max_len
)&&(min_len
<65536)) {
2262 /* 16.7 if length is fixed and less than to 64k*/
2266 BYTE_ALIGN_OFFSET(offset
);
2268 val_start
= offset
>>3;
2269 val_length
= min_len
;
2270 out_tvb
= new_octet_aligned_subset(tvb
, offset
, actx
, val_length
);
2275 offset
= dissect_per_constrained_integer(tvb
, offset
, actx
, tree
,
2276 hf_per_octet_string_length
, min_len
, max_len
, &length
, FALSE
);
2278 if (!display_internal_per_fields
)
2279 PROTO_ITEM_SET_HIDDEN(actx
->created_item
);
2281 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
,
2282 hf_per_octet_string_length
, &length
);
2288 BYTE_ALIGN_OFFSET(offset
);
2290 out_tvb
= new_octet_aligned_subset(tvb
, offset
, actx
, length
);
2292 val_start
= offset
>>3;
2294 val_length
= length
;
2299 if (IS_FT_UINT(hfi
->type
)||IS_FT_INT(hfi
->type
)) {
2300 /* If the type has been converted to FT_UINT or FT_INT in the .cnf file
2301 * display the length of this octet string instead of the octetstring itself
2303 if (IS_FT_UINT(hfi
->type
))
2304 actx
->created_item
= proto_tree_add_uint(tree
, hf_index
, out_tvb
, 0, val_length
, val_length
);
2306 actx
->created_item
= proto_tree_add_int(tree
, hf_index
, out_tvb
, 0, val_length
, val_length
);
2307 proto_item_append_text(actx
->created_item
, plurality(val_length
, " octet", " octets"));
2310 actx
->created_item
= proto_tree_add_item(tree
, hf_index
, out_tvb
, 0, val_length
, ENC_BIG_ENDIAN
);
2313 actx
->created_item
= proto_tree_add_item(tree
, hf_index
, tvb
, val_start
, val_length
, ENC_BIG_ENDIAN
);
2319 *value_tvb
= (out_tvb
) ? out_tvb
: tvb_new_subset(tvb
, val_start
, val_length
, val_length
);
2324 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
)
2326 tvbuff_t
*val_tvb
= NULL
;
2327 proto_tree
*subtree
= tree
;
2329 offset
= dissect_per_octet_string(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
, &val_tvb
);
2331 if (type_cb
&& val_tvb
) {
2332 subtree
= proto_item_add_subtree(actx
->created_item
, ett_per_containing
);
2333 type_cb(val_tvb
, actx
->pinfo
, subtree
);
2339 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
)
2341 tvbuff_t
*val_tvb
= NULL
;
2342 proto_tree
*subtree
= tree
;
2344 offset
= dissect_per_octet_string(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
, &val_tvb
);
2346 if (type_cb
&& val_tvb
) {
2347 subtree
= proto_item_add_subtree(actx
->created_item
, ett_per_containing
);
2348 type_cb(val_tvb
, actx
->pinfo
, subtree
, NULL
);
2354 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
)
2356 asn1_stack_frame_push(actx
, name
);
2357 asn1_param_push_integer(actx
, min_len
);
2358 asn1_param_push_integer(actx
, max_len
);
2359 asn1_param_push_boolean(actx
, has_extension
);
2361 offset
= type_cb(tvb
, offset
, actx
, tree
, hf_index
);
2363 asn1_stack_frame_pop(actx
, name
);
2368 gboolean
get_size_constraint_from_stack(asn1_ctx_t
*actx
, const gchar
*name
, int *pmin_len
, int *pmax_len
, gboolean
*phas_extension
)
2372 if (pmin_len
) *pmin_len
= NO_BOUND
;
2373 if (pmax_len
) *pmax_len
= NO_BOUND
;
2374 if (phas_extension
) *phas_extension
= FALSE
;
2376 if (!actx
->stack
) return FALSE
;
2377 if (strcmp(actx
->stack
->name
, name
)) return FALSE
;
2379 par
= actx
->stack
->par
;
2380 if (!par
|| (par
->ptype
!= ASN1_PAR_INTEGER
)) return FALSE
;
2381 if (pmin_len
) *pmin_len
= par
->value
.v_integer
;
2383 if (!par
|| (par
->ptype
!= ASN1_PAR_INTEGER
)) return FALSE
;
2384 if (pmax_len
) *pmax_len
= par
->value
.v_integer
;
2386 if (!par
|| (par
->ptype
!= ASN1_PAR_BOOLEAN
)) return FALSE
;
2387 if (phas_extension
) *phas_extension
= par
->value
.v_boolean
;
2393 /* 26 Encoding of a value of the external type */
2395 /* code generated from definition in 26.1 */
2397 [UNIVERSAL 8] IMPLICIT SEQUENCE {
2398 direct-reference OBJECT IDENTIFIER OPTIONAL,
2399 indirect-reference INTEGER OPTIONAL,
2400 data-value-descriptor ObjectDescriptor OPTIONAL,
2402 single-ASN1-type [0] ABSTRACT-SYNTAX.&Type,
2403 octet-aligned [1] IMPLICIT OCTET STRING,
2404 arbitrary [2] IMPLICIT BIT STRING
2408 /* NOTE: This sequence type differs from that in ITU-T Rec. X.680 | ISO/IEC 8824-1 for historical reasons. */
2411 dissect_per_T_direct_reference(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
) {
2412 offset
= dissect_per_object_identifier_str(tvb
, offset
, actx
, tree
, hf_index
, &actx
->external
.direct_reference
);
2414 actx
->external
.direct_ref_present
= TRUE
;
2421 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_
) {
2422 offset
= dissect_per_integer(tvb
, offset
, actx
, tree
, hf_index
, &actx
->external
.indirect_reference
);
2424 actx
->external
.indirect_ref_present
= TRUE
;
2431 dissect_per_T_data_value_descriptor(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
) {
2432 offset
= dissect_per_object_descriptor(tvb
, offset
, actx
, tree
, hf_index
, &actx
->external
.data_value_descriptor
);
2434 actx
->external
.data_value_descr_present
= TRUE
;
2441 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_
) {
2442 offset
= dissect_per_open_type(tvb
, offset
, actx
, tree
, actx
->external
.hf_index
, actx
->external
.u
.per
.type_cb
);
2450 dissect_per_T_octet_aligned(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
) {
2451 offset
= dissect_per_octet_string(tvb
, offset
, actx
, tree
, hf_index
,
2452 NO_BOUND
, NO_BOUND
, FALSE
, &actx
->external
.octet_aligned
);
2454 if (actx
->external
.octet_aligned
) {
2455 if (actx
->external
.u
.per
.type_cb
) {
2456 actx
->external
.u
.per
.type_cb(actx
->external
.octet_aligned
, 0, actx
, tree
, actx
->external
.hf_index
);
2458 actx
->created_item
= proto_tree_add_text(tree
, actx
->external
.octet_aligned
, 0, -1, "Unknown EXTERNAL Type");
2467 dissect_per_T_arbitrary(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
) {
2468 offset
= dissect_per_bit_string(tvb
, offset
, actx
, tree
, hf_index
,
2469 NO_BOUND
, NO_BOUND
, FALSE
, &actx
->external
.arbitrary
);
2471 if (actx
->external
.arbitrary
) {
2472 if (actx
->external
.u
.per
.type_cb
) {
2473 actx
->external
.u
.per
.type_cb(actx
->external
.arbitrary
, 0, actx
, tree
, actx
->external
.hf_index
);
2475 actx
->created_item
= proto_tree_add_text(tree
, actx
->external
.arbitrary
, 0, -1, "Unknown EXTERNAL Type");
2482 static const value_string per_External_encoding_vals
[] = {
2483 { 0, "single-ASN1-type" },
2484 { 1, "octet-aligned" },
2489 static const per_choice_t External_encoding_choice
[] = {
2490 { 0, &hf_per_single_ASN1_type
, ASN1_NO_EXTENSIONS
, dissect_per_T_single_ASN1_type
},
2491 { 1, &hf_per_octet_aligned
, ASN1_NO_EXTENSIONS
, dissect_per_T_octet_aligned
},
2492 { 2, &hf_per_arbitrary
, ASN1_NO_EXTENSIONS
, dissect_per_T_arbitrary
},
2493 { 0, NULL
, 0, NULL
}
2497 dissect_per_External_encoding(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
) {
2498 offset
= dissect_per_choice(tvb
, offset
, actx
, tree
, hf_index
,
2499 ett_per_External_encoding
, External_encoding_choice
,
2500 &actx
->external
.encoding
);
2506 static const per_sequence_t External_sequence
[] = {
2507 { &hf_per_direct_reference
, ASN1_NO_EXTENSIONS
, ASN1_OPTIONAL
, dissect_per_T_direct_reference
},
2508 { &hf_per_indirect_reference
, ASN1_NO_EXTENSIONS
, ASN1_OPTIONAL
, dissect_per_T_indirect_reference
},
2509 { &hf_per_data_value_descriptor
, ASN1_NO_EXTENSIONS
, ASN1_OPTIONAL
, dissect_per_T_data_value_descriptor
},
2510 { &hf_per_encoding
, ASN1_NO_EXTENSIONS
, ASN1_NOT_OPTIONAL
, dissect_per_External_encoding
},
2511 { NULL
, 0, 0, NULL
}
2515 dissect_per_External(tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
2516 offset
= dissect_per_sequence(tvb
, offset
, actx
, tree
, hf_index
,
2517 ett_per_External
, External_sequence
);
2523 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
)
2525 asn1_ctx_clean_external(actx
);
2526 actx
->external
.u
.per
.type_cb
= type_cb
;
2527 offset
= dissect_per_External(tvb
, offset
, actx
, tree
, hf_index
);
2529 asn1_ctx_clean_external(actx
);
2535 proto_register_per(void)
2537 static hf_register_info hf
[] =
2539 { &hf_per_num_sequence_extensions
,
2540 { "Number of Sequence Extensions", "per.num_sequence_extensions", FT_UINT32
, BASE_DEC
,
2541 NULL
, 0, "Number of extensions encoded in this sequence", HFILL
}},
2542 { &hf_per_choice_index
,
2543 { "Choice Index", "per.choice_index", FT_UINT32
, BASE_DEC
,
2544 NULL
, 0, "Which index of the Choice within extension root is encoded", HFILL
}},
2545 { &hf_per_choice_extension_index
,
2546 { "Choice Extension Index", "per.choice_extension_index", FT_UINT32
, BASE_DEC
,
2547 NULL
, 0, "Which index of the Choice within extension addition is encoded", HFILL
}},
2548 { &hf_per_enum_index
,
2549 { "Enumerated Index", "per.enum_index", FT_UINT32
, BASE_DEC
,
2550 NULL
, 0, "Which index of the Enumerated within extension root is encoded", HFILL
}},
2551 { &hf_per_enum_extension_index
,
2552 { "Enumerated Extension Index", "per.enum_extension_index", FT_UINT32
, BASE_DEC
,
2553 NULL
, 0, "Which index of the Enumerated within extension addition is encoded", HFILL
}},
2554 { &hf_per_GeneralString_length
,
2555 { "GeneralString Length", "per.generalstring_length", FT_UINT32
, BASE_DEC
,
2556 NULL
, 0, "Length of the GeneralString", HFILL
}},
2557 { &hf_per_extension_bit
,
2558 { "Extension Bit", "per.extension_bit", FT_BOOLEAN
, 8,
2559 TFS(&tfs_extension_bit
), 0x01, "The extension bit of an aggregate", HFILL
}},
2560 { &hf_per_extension_present_bit
,
2561 { "Extension Present Bit", "per.extension_present_bit", FT_BOOLEAN
, 8,
2562 TFS(&tfs_extension_present_bit
), 0x01, "Whether this optional extension is present or not", HFILL
}},
2563 { &hf_per_small_number_bit
,
2564 { "Small Number Bit", "per.small_number_bit", FT_BOOLEAN
, 8,
2565 TFS(&tfs_small_number_bit
), 0x01, "The small number bit for a section 10.6 integer", HFILL
}},
2566 { &hf_per_optional_field_bit
,
2567 { "Optional Field Bit", "per.optional_field_bit", FT_BOOLEAN
, 8,
2568 TFS(&tfs_optional_field_bit
), 0x01, "This bit specifies the presence/absence of an optional field", HFILL
}},
2569 { &hf_per_sequence_of_length
,
2570 { "Sequence-Of Length", "per.sequence_of_length", FT_UINT32
, BASE_DEC
,
2571 NULL
, 0, "Number of items in the Sequence Of", HFILL
}},
2572 { &hf_per_object_identifier_length
,
2573 { "Object Identifier Length", "per.object_length", FT_UINT32
, BASE_DEC
,
2574 NULL
, 0, "Length of the object identifier", HFILL
}},
2575 { &hf_per_open_type_length
,
2576 { "Open Type Length", "per.open_type_length", FT_UINT32
, BASE_DEC
,
2577 NULL
, 0, "Length of an open type encoding", HFILL
}},
2578 { &hf_per_real_length
,
2579 { "Real Length", "per.real_length", FT_UINT32
, BASE_DEC
,
2580 NULL
, 0, "Length of an real encoding", HFILL
}},
2581 { &hf_per_octet_string_length
,
2582 { "Octet String Length", "per.octet_string_length", FT_UINT32
, BASE_DEC
,
2583 NULL
, 0, "Number of bytes in the Octet String", HFILL
}},
2584 { &hf_per_bit_string_length
,
2585 { "Bit String Length", "per.bit_string_length", FT_UINT32
, BASE_DEC
,
2586 NULL
, 0, "Number of bits in the Bit String", HFILL
}},
2587 { &hf_per_normally_small_nonnegative_whole_number_length
,
2588 { "Normally Small Non-negative Whole Number Length", "per.normally_small_nonnegative_whole_number_length", FT_UINT32
, BASE_DEC
,
2589 NULL
, 0, "Number of bytes in the Normally Small Non-negative Whole Number", HFILL
}},
2590 { &hf_per_const_int_len
,
2591 { "Constrained Integer Length", "per.const_int_len", FT_UINT32
, BASE_DEC
,
2592 NULL
, 0, "Number of bytes in the Constrained Integer", HFILL
}},
2593 { &hf_per_direct_reference
,
2594 { "direct-reference", "per.direct_reference",
2595 FT_OID
, BASE_NONE
, NULL
, 0,
2596 "per.T_direct_reference", HFILL
}},
2597 { &hf_per_indirect_reference
,
2598 { "indirect-reference", "per.indirect_reference",
2599 FT_INT32
, BASE_DEC
, NULL
, 0,
2600 "per.T_indirect_reference", HFILL
}},
2601 { &hf_per_data_value_descriptor
,
2602 { "data-value-descriptor", "per.data_value_descriptor",
2603 FT_STRING
, BASE_NONE
, NULL
, 0,
2604 "per.T_data_value_descriptor", HFILL
}},
2606 { "encoding", "per.encoding",
2607 FT_UINT32
, BASE_DEC
, VALS(per_External_encoding_vals
), 0,
2608 "per.External_encoding", HFILL
}},
2609 { &hf_per_single_ASN1_type
,
2610 { "single-ASN1-type", "per.single_ASN1_type",
2611 FT_NONE
, BASE_NONE
, NULL
, 0,
2612 "per.T_single_ASN1_type", HFILL
}},
2613 { &hf_per_octet_aligned
,
2614 { "octet-aligned", "per.octet_aligned",
2615 FT_BYTES
, BASE_NONE
, NULL
, 0,
2616 "per.T_octet_aligned", HFILL
}},
2617 { &hf_per_arbitrary
,
2618 { "arbitrary", "per.arbitrary",
2619 FT_BYTES
, BASE_NONE
, NULL
, 0,
2620 "per.T_arbitrary", HFILL
}},
2621 { &hf_per_integer_length
,
2622 { "integer length", "per.integer_length",
2623 FT_UINT32
, BASE_DEC
, NULL
, 0,
2626 { &hf_per_debug_pos
,
2627 { "Current bit offset", "per.debug_pos",
2628 FT_UINT32
, BASE_DEC
, NULL
, 0,
2632 static gint
*ett
[] =
2635 &ett_per_containing
,
2636 &ett_per_sequence_of_item
,
2638 &ett_per_External_encoding
,
2640 static ei_register_info ei
[] = {
2641 { &ei_per_size_constraint_value
, { "per.size_constraint.value", PI_PROTOCOL
, PI_WARN
, "Size constraint: value too big", EXPFILL
}},
2642 { &ei_per_size_constraint_too_few
, { "per.size_constraint.too_few", PI_PROTOCOL
, PI_WARN
, "Size constraint: too few items", EXPFILL
}},
2643 { &ei_per_size_constraint_too_many
, { "per.size_constraint.too_many", PI_PROTOCOL
, PI_WARN
, "Size constraint: too many items", EXPFILL
}},
2644 { &ei_per_choice_extension_unknown
, { "per.choice_extension_unknown", PI_UNDECODED
, PI_NOTE
, "unknown choice extension", EXPFILL
}},
2645 { &ei_per_sequence_extension_unknown
, { "per.sequence_extension_unknown", PI_UNDECODED
, PI_NOTE
, "unknown sequence extension", EXPFILL
}},
2646 { &ei_per_encoding_error
, { "per.encoding_error", PI_MALFORMED
, PI_WARN
, "Encoding error", EXPFILL
}},
2649 module_t
*per_module
;
2650 expert_module_t
* expert_per
;
2652 proto_per
= proto_register_protocol("Packed Encoding Rules (ASN.1 X.691)", "PER", "per");
2653 proto_register_field_array(proto_per
, hf
, array_length(hf
));
2654 proto_register_subtree_array(ett
, array_length(ett
));
2655 expert_per
= expert_register_protocol(proto_per
);
2656 expert_register_field_array(expert_per
, ei
, array_length(ei
));
2658 proto_set_cant_toggle(proto_per
);
2660 per_module
= prefs_register_protocol(proto_per
, NULL
);
2661 prefs_register_bool_preference(per_module
, "display_internal_per_fields",
2662 "Display the internal PER fields in the tree",
2663 "Whether the dissector should put the internal PER data in the tree or if it should hide it",
2664 &display_internal_per_fields
);
2669 proto_reg_handoff_per(void)
2674 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2679 * indent-tabs-mode: t
2682 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2683 * :indentSize=8:tabSize=8:noTabs=false: