2 XXX all this offset>>3 and calculations of bytes in the tvb every time
3 we put something in the tree is just silly. should be replaced with some
7 * Routines for dissection of ASN.1 Aligned PER
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * SPDX-License-Identifier: GPL-2.0-or-later
19 #include <epan/packet.h>
20 #include <epan/exceptions.h>
21 #include <epan/oids.h>
22 #include <epan/to_str.h>
23 #include <epan/asn1.h>
24 #include <epan/expert.h>
25 #include <wsutil/str_util.h>
27 #include <wsutil/array.h>
28 #include "packet-per.h"
30 void proto_register_per(void);
33 static int hf_per_GeneralString_length
;
34 static int hf_per_extension_bit
;
35 static int hf_per_extension_present_bit
;
36 static int hf_per_choice_index
;
37 static int hf_per_choice_extension_index
;
38 static int hf_per_enum_index
;
39 static int hf_per_enum_extension_index
;
40 static int hf_per_num_sequence_extensions
;
41 static int hf_per_small_number_bit
;
42 static int hf_per_optional_field_bit
;
43 static int hf_per_sequence_of_length
;
44 static int hf_per_object_identifier_length
;
45 static int hf_per_open_type_length
;
46 static int hf_per_real_length
;
47 static int hf_per_octet_string_length
;
48 static int hf_per_bit_string_length
;
49 static int hf_per_normally_small_nonnegative_whole_number_length
;
50 static int hf_per_const_int_len
;
51 static int hf_per_direct_reference
; /* T_direct_reference */
52 static int hf_per_indirect_reference
; /* T_indirect_reference */
53 static int hf_per_data_value_descriptor
; /* T_data_value_descriptor */
54 static int hf_per_encoding
; /* External_encoding */
55 static int hf_per_single_ASN1_type
; /* T_single_ASN1_type */
56 static int hf_per_octet_aligned
; /* T_octet_aligned */
57 static int hf_per_arbitrary
; /* T_arbitrary */
58 static int hf_per_integer_length
; /* Show integer length if "show internal per fields" */
59 /* static int hf_per_debug_pos; */
60 static int hf_per_internal_range
;
61 static int hf_per_internal_num_bits
;
62 static int hf_per_internal_min
;
63 static int hf_per_internal_value
;
64 static int hf_per_internal_min_int
;
65 static int hf_per_internal_value_int
;
67 static int hf_per_encoding_boiler_plate
;
69 static int ett_per_open_type
;
70 static int ett_per_containing
;
71 static int ett_per_sequence_of_item
;
72 static int ett_per_External
;
73 static int ett_per_External_encoding
;
74 static int ett_per_named_bits
;
76 static expert_field ei_per_size_constraint_value
;
77 static expert_field ei_per_size_constraint_too_few
;
78 static expert_field ei_per_size_constraint_too_many
;
79 static expert_field ei_per_choice_extension_unknown
;
80 static expert_field ei_per_sequence_extension_unknown
;
81 static expert_field ei_per_encoding_error
;
82 static expert_field ei_per_oid_not_implemented
;
83 static expert_field ei_per_undecoded
;
84 static expert_field ei_per_field_not_integer
;
85 static expert_field ei_per_external_type
;
86 static expert_field ei_per_open_type
;
87 static expert_field ei_per_open_type_len
;
89 static dissector_table_t per_oid_dissector_table
;
92 #define DEBUG_ENTRY(x) \
93 printf("#%u %s tvb:0x%08x\n",actx->pinfo->num,x,(int)tvb);
95 #define DEBUG_ENTRY(x) \
98 #define BLEN(old_offset, offset) (((offset)>>3)!=((old_offset)>>3)?((offset)>>3)-((old_offset)>>3):1)
100 /* whether the PER helpers should put the internal PER fields into the tree
103 static bool display_internal_per_fields
;
107 static const true_false_string tfs_extension_bit
= {
108 "Extension bit is set",
109 "Extension bit is clear"
111 static const true_false_string tfs_small_number_bit
= {
112 "The number is small, 0-63",
113 "The number is large, >63"
117 add_per_encoded_label(tvbuff_t
* tvb
, packet_info
* pinfo _U_
, proto_tree
* tree
)
121 ti
= proto_tree_add_item(tree
, hf_per_encoding_boiler_plate
, tvb
, 0, -1, ENC_NA
);
122 proto_item_set_generated(ti
);
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(uint32_t value
, uint32_t min_len
, uint32_t max_len
, asn1_ctx_t
*actx
, proto_item
*item
, bool 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) && ((int32_t)value
> (int32_t)max_len
)) {
135 expert_add_info_format(actx
->pinfo
, item
, &ei_per_size_constraint_value
, "Size constraint: value too big: %d (%d .. %d)", (int32_t)value
, (int32_t)min_len
, (int32_t)max_len
);
139 static void per_check_value64(uint64_t value
, uint64_t min_len
, uint64_t max_len
, asn1_ctx_t
*actx
, proto_item
*item
, bool 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: %" PRIu64
" (%" PRIu64
" .. %" PRIu64
")", value
, min_len
, max_len
);
143 } else if ((is_signed
== true) && ((int64_t)value
> (int64_t)max_len
)) {
144 expert_add_info_format(actx
->pinfo
, item
, &ei_per_size_constraint_value
, "Size constraint: value too big: %" PRId64
" (%" PRId64
" .. %" PRId64
")", (int64_t)value
, (int64_t)min_len
, (int64_t)max_len
);
148 static void per_check_items(uint32_t cnt
, int min_len
, int max_len
, asn1_ctx_t
*actx
, proto_item
*item
)
150 if (min_len
!= NO_BOUND
&& cnt
< (uint32_t)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
> (uint32_t)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
);
158 void dissect_per_not_decoded_yet(proto_tree
* tree
, packet_info
* pinfo
, tvbuff_t
*tvb
, const char* reason
)
160 proto_tree_add_expert_format(tree
, pinfo
, &ei_per_undecoded
, tvb
, 0, 0, "something unknown here [%s]",reason
);
161 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "[UNKNOWN PER: %s]", reason
);
162 THROW(ReportedBoundsError
);
165 /* 10 Encoding procedures -------------------------------------------------- */
167 /* 10.2 Open type fields --------------------------------------------------- */
169 dissect_per_open_type_internal(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, void* type_cb
, asn1_cb_variant variant
)
171 int type_length
, start_offset
, end_offset
, fragmented_length
= 0, pdu_length
, pdu_offset
;
172 tvbuff_t
*val_tvb
= NULL
, *pdu_tvb
= NULL
, *fragment_tvb
= NULL
;
173 header_field_info
*hfi
;
174 proto_tree
*subtree
= tree
;
176 int captured_pdu_length
;
178 hfi
= (hf_index
<= 0) ? NULL
: proto_registrar_get_nth(hf_index
);
180 start_offset
= offset
;
182 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_open_type_length
, &type_length
, &is_fragmented
);
183 if (actx
->aligned
) BYTE_ALIGN_OFFSET(offset
);
185 fragment_tvb
= tvb_new_octet_aligned(tvb
, offset
, 8*type_length
);
186 if (fragmented_length
== 0) {
187 pdu_tvb
= tvb_new_composite();
189 tvb_composite_append(pdu_tvb
, fragment_tvb
);
190 offset
+= 8*type_length
;
191 fragmented_length
+= type_length
;
193 } while (is_fragmented
);
194 if (fragmented_length
) {
196 tvb_composite_append(pdu_tvb
, tvb_new_octet_aligned(tvb
, offset
, 8*type_length
));
197 fragmented_length
+= type_length
;
199 tvb_composite_finalize(pdu_tvb
);
200 add_new_data_source(actx
->pinfo
, pdu_tvb
, "Fragmented OCTET STRING");
202 pdu_length
= fragmented_length
;
206 pdu_length
= type_length
;
208 end_offset
= offset
+ type_length
* 8;
210 if (variant
==CB_NEW_DISSECTOR
) {
211 if (fragmented_length
) {
217 /* Check if we have a tvb that holds the whole PDU */
218 captured_pdu_length
= tvb_captured_length(pdu_tvb
) - (pdu_offset
>>3);
219 if(captured_pdu_length
< pdu_length
){
220 val_tvb
= tvb_new_octet_aligned(pdu_tvb
, pdu_offset
, captured_pdu_length
* 8);
221 actx
->created_item
= proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_per_open_type_len
, tvb
, pdu_offset
>> 3,
222 captured_pdu_length
,"Open type length(%i) > available data(%i)", pdu_length
, captured_pdu_length
);
223 pdu_length
= captured_pdu_length
;
225 val_tvb
= tvb_new_octet_aligned(pdu_tvb
, pdu_offset
, pdu_length
* 8);
227 /* Add new data source if the offet was unaligned */
228 if ((pdu_offset
& 7) != 0) {
229 add_new_data_source(actx
->pinfo
, val_tvb
, "Unaligned OCTET STRING");
233 if (FT_IS_UINT(hfi
->type
)||FT_IS_INT(hfi
->type
)) {
234 if (FT_IS_UINT(hfi
->type
))
235 actx
->created_item
= proto_tree_add_uint(tree
, hf_index
, val_tvb
, 0, pdu_length
, pdu_length
);
237 actx
->created_item
= proto_tree_add_int(tree
, hf_index
, val_tvb
, 0, pdu_length
, pdu_length
);
238 proto_item_append_text(actx
->created_item
, plurality(pdu_length
, " octet", " octets"));
240 actx
->created_item
= proto_tree_add_item(tree
, hf_index
, val_tvb
, 0, pdu_length
, ENC_BIG_ENDIAN
);
242 subtree
= proto_item_add_subtree(actx
->created_item
, ett_per_open_type
);
249 ((per_type_fn
)type_cb
)(pdu_tvb
, pdu_offset
, actx
, tree
, hf_index
);
251 case CB_NEW_DISSECTOR
:
252 /* Pas actx->private_data as "data" to the called function */
253 ((dissector_t
)type_cb
)(val_tvb
, actx
->pinfo
, subtree
, actx
->private_data
);
255 case CB_DISSECTOR_HANDLE
:
259 actx
->created_item
= proto_tree_add_expert(tree
, actx
->pinfo
, &ei_per_open_type
, tvb
, start_offset
>>3, BLEN(start_offset
, end_offset
));
266 dissect_per_open_type(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, per_type_fn type_cb
)
268 return dissect_per_open_type_internal(tvb
, offset
, actx
, tree
, hf_index
, (void*)type_cb
, CB_ASN1_ENC
);
272 dissect_per_open_type_pdu_new(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, dissector_t type_cb
)
274 return dissect_per_open_type_internal(tvb
, offset
, actx
, tree
, hf_index
, (void*)type_cb
, CB_NEW_DISSECTOR
);
277 /* 10.9 General rules for encoding a length determinant --------------------
279 NOTE 1 - (Tutorial) The procedures of this subclause are invoked when an explicit length field is needed
280 for some part of the encoding regardless of whether the length count is bounded above
281 (by PER-visible constraints) or not. The part of the encoding to which the length applies may
282 be a bit string (with the length count in bits), an octet string (with the length count in octets),
283 a known-multiplier character string (with the length count in characters), or a list of fields
284 (with the length count in components of a sequence-of or set-of).
286 NOTE 2 - (Tutorial) In the case of the ALIGNED variant if the length count is bounded above by an upper bound
287 that is less than 64K, then the constrained whole number encoding is used for the length.
288 For sufficiently small ranges the result is a bit-field, otherwise the unconstrained length ("n" say)
289 is encoded into an octet-aligned bit-field in one of three ways (in order of increasing size):
290 a) ("n" less than 128) a single octet containing "n" with bit 8 set to zero;
291 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;
292 c) (large "n") a single octet containing a count "m" with bit 8 set to 1 and bit 7 set to 1.
293 The count "m" is one to four, and the length indicates that a fragment of the material follows
294 (a multiple "m" of 16K items). For all values of "m", the fragment is then followed by another length encoding
295 for the remainder of the material.
297 NOTE 3 - (Tutorial) In the UNALIGNED variant, if the length count is bounded above by an upper bound that is less
298 than 64K, then the constrained whole number encoding is used to encode the length in the minimum number of
299 bits necessary to represent the range. Otherwise, the unconstrained length ("n" say) is encoded into a bit
300 field in the manner described above in Note 2.
304 dissect_per_length_determinant(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, uint32_t *length
, bool *is_fragmented
)
310 int i
, bit
, str_length
, str_index
;
317 *is_fragmented
= false;
322 BYTE_ALIGN_OFFSET(offset
);
323 byte
=tvb_get_uint8(tvb
, offset
>>3);
331 /* prepare the string (max number of bits + quartet separators + prepended space) */
332 str_length
= 256+64+1;
333 str
=(char *)wmem_alloc(actx
->pinfo
->pool
, str_length
+1);
336 str_length
= snprintf(str
, str_length
+1, " ");
337 for(bit
=0;bit
<((int)(offset
&0x07));bit
++){
339 if (str_index
< str_length
) str
[str_index
++] = ' ';
341 if (str_index
< str_length
) str
[str_index
++] = '.';
343 /* read the bits for the int */
345 for(i
=0;i
<num_bits
;i
++){
347 if (str_index
< str_length
) str
[str_index
++] = ' ';
350 if (str_index
< str_length
) str
[str_index
++] = ' ';
353 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, -1, &tmp
);
357 if (str_index
< str_length
) str
[str_index
++] = '1';
358 if (i
==0) { /* bit 8 is 1, so not a single byte length */
361 else if (i
==1 && val
==3) { /* bits 8 and 7 both 1, so unconstrained */
362 if (!is_fragmented
) {
364 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "10.9 Unconstrained");
368 *is_fragmented
= true;
372 if (str_index
< str_length
) str
[str_index
++] = '0';
375 str
[str_index
] = '\0'; /* Terminate string */
376 if(is_fragmented
&& *is_fragmented
==true){
378 if (*length
>4 || *length
==0) {
380 *is_fragmented
= false;
381 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "10.9 Unconstrained unexpected fragment count");
386 pi
= proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
>>3)-1, 1, *length
);
387 if (display_internal_per_fields
)
388 proto_item_append_text(pi
," %s", str
);
390 proto_item_set_hidden(pi
);
395 else if((val
&0x80)==0 && num_bits
==8){
398 pi
= proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
>>3)-1, 1, *length
);
399 if (display_internal_per_fields
)
400 proto_item_append_text(pi
," %s", str
);
402 proto_item_set_hidden(pi
);
407 else if (num_bits
==16) {
408 *length
= val
&0x3fff;
410 pi
= proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
>>3)-2, 2, *length
);
411 if (display_internal_per_fields
)
412 proto_item_append_text(pi
," %s", str
);
414 proto_item_set_hidden(pi
);
420 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "10.9 Unaligned");
429 pi
= proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
>>3)-1, 1, *length
);
430 if (!display_internal_per_fields
) proto_item_set_hidden(pi
);
436 if((byte
&0xc0)==0x80){
438 *length
=((*length
)<<8)+tvb_get_uint8(tvb
, offset
>>3);
441 pi
= proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
>>3)-2, 2, *length
);
442 if (!display_internal_per_fields
) proto_item_set_hidden(pi
);
447 else if (is_fragmented
){
449 if (*length
>4 || *length
==0) {
451 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "10.9 Unconstrained unexpected fragment count");
455 *is_fragmented
= true;
457 pi
= proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
>>3)-1, 1, *length
);
458 if (!display_internal_per_fields
) proto_item_set_hidden(pi
);
463 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "10.9.3.8.1");
467 /* 10.6 normally small non-negative whole number */
469 dissect_per_normally_small_nonnegative_whole_number(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, uint32_t *length
)
471 bool small_number
, length_bit
;
472 uint32_t len
, length_determinant
;
475 DEBUG_ENTRY("dissect_per_normally_small_nonnegative_whole_number");
480 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_small_number_bit
, &small_number
);
481 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
487 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, -1, &length_bit
);
494 pi
= proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
-6)>>3, (offset
%8<6)?2:1, *length
);
495 if (!display_internal_per_fields
) proto_item_set_hidden(pi
);
501 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_normally_small_nonnegative_whole_number_length
, &length_determinant
, NULL
);
502 switch (length_determinant
) {
507 *length
= tvb_get_bits8(tvb
, offset
, 8);
511 *length
= tvb_get_bits16(tvb
, offset
, 16, ENC_BIG_ENDIAN
);
515 *length
= tvb_get_bits32(tvb
, offset
, 24, ENC_BIG_ENDIAN
);
519 *length
= tvb_get_bits32(tvb
, offset
, 32, ENC_BIG_ENDIAN
);
523 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "too long integer(per_normally_small_nonnegative_whole_number)");
524 offset
+= 8*length_determinant
;
529 pi
= proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
-(8*length_determinant
))>>3, length_determinant
, *length
);
530 if (!display_internal_per_fields
) proto_item_set_hidden(pi
);
538 /* this function reads a GeneralString */
539 /* currently based on pure guesswork since RFC2833 didn't tell me much
540 i guess that the PER encoding for this is a normally-small-whole-number
541 followed by a ascii string.
543 based on pure guesswork. it looks ok in the only capture i have where
544 there is a 1 byte general string encoded
547 dissect_per_GeneralString(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
)
551 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_GeneralString_length
, &length
, NULL
);
553 proto_tree_add_item(tree
, hf_index
, tvb
, offset
>>3, length
, ENC_BIG_ENDIAN
);
560 /* 17 Encoding the null type */
562 dissect_per_null(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx _U_
, proto_tree
*tree
, int hf_index
) {
565 ti_tmp
= proto_tree_add_item(tree
, hf_index
, tvb
, offset
>>3, 0, ENC_BIG_ENDIAN
);
566 proto_item_append_text(ti_tmp
, ": NULL");
571 /* 19 this function dissects a sequence of */
572 // Arbitrary. Allow a sequence of NULLs, but not too many since we might add
573 // a hierarchy of tree items per NULL
574 #define PER_SEQUENCE_OF_MAX_NULLS 10
576 dissect_per_sequence_of_helper(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, per_type_fn func
, int hf_index
, uint32_t length
)
580 DEBUG_ENTRY("dissect_per_sequence_of_helper");
581 uint32_t old_offset
= offset
;
582 for(i
=0;i
<length
;i
++){
583 uint32_t lold_offset
=offset
;
587 ltree
=proto_tree_add_subtree_format(tree
, tvb
, offset
>>3, 0, ett_per_sequence_of_item
, &litem
, "Item %d", i
);
589 offset
=(*func
)(tvb
, offset
, actx
, ltree
, hf_index
);
590 proto_item_set_len(litem
, (offset
>>3)!=(lold_offset
>>3)?(offset
>>3)-(lold_offset
>>3):1);
591 if (i
>= PER_SEQUENCE_OF_MAX_NULLS
-1 && offset
<= old_offset
) {
592 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "too many nulls in sequence");
599 dissect_per_sequence_of(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*parent_tree
, int hf_index
, int ett_index
, const per_sequence_t
*seq
)
603 uint32_t old_offset
=offset
;
605 header_field_info
*hfi
;
607 DEBUG_ENTRY("dissect_per_sequence_of");
609 /* semi-constrained whole number for number of elements */
610 /* each element encoded as 10.9 */
612 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, parent_tree
, hf_per_sequence_of_length
, &length
, NULL
);
614 hfi
= proto_registrar_get_nth(hf_index
);
615 if (FT_IS_UINT(hfi
->type
)) {
616 item
= proto_tree_add_uint(parent_tree
, hf_index
, tvb
, old_offset
>>3, 0, length
);
617 proto_item_append_text(item
, (length
==1)?" item":" items");
619 item
=proto_tree_add_item(parent_tree
, hf_index
, tvb
, old_offset
>>3, 0, ENC_BIG_ENDIAN
);
621 tree
=proto_item_add_subtree(item
, ett_index
);
623 offset
=dissect_per_sequence_of_helper(tvb
, offset
, actx
, tree
, seq
->func
, *seq
->p_id
, length
);
626 proto_item_set_len(item
, (offset
>>3)!=(old_offset
>>3)?(offset
>>3)-(old_offset
>>3):1);
630 /* XXX we don't do >64k length strings yet */
632 dissect_per_restricted_character_string_sorted(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, bool has_extension
, uint16_t lb
, uint16_t ub
, const char *alphabet
, int alphabet_length
, tvbuff_t
**value_tvb
)
635 bool byte_aligned
, use_canonical_order
;
643 DEBUG_ENTRY("dissect_per_restricted_character_string");
645 /* xx.x if the length is 0 bytes there will be no encoding */
648 *value_tvb
= tvb_new_child_real_data(tvb
, NULL
, 0, 0);
654 if (min_len
== NO_BOUND
) {
659 /* 27.5.2 depending of the alphabet length, find how many bits
660 are used to encode each character */
664 if(alphabet_length
<=2){
666 } else if(alphabet_length
<=4){
668 } else if(alphabet_length
<=16){
674 if(alphabet_length
<=2){
676 } else if(alphabet_length
<=4){
678 } else if(alphabet_length
<=8){
680 } else if(alphabet_length
<=16){
682 } else if(alphabet_length
<=32){
684 } else if(alphabet_length
<=64){
686 } else if(alphabet_length
<=128){
693 /* 27.4 If the type is extensible for PER encodings (see 9.3.16),
694 * then a bit-field consisting of a single bit shall be added to the field-list.
695 * The single bit shall be set to zero if the value is within the range of the extension root,
696 * and to one otherwise. If the value is outside the range of the extension root,
697 * then the following encoding shall be as if there was no effective size constraint,
698 * and shall have an effective permitted-alphabet constraint that consists of the set of characters
699 * of the unconstrained type.
700 * NOTE - Only the known-multiplier character string types can be extensible for PER encodings.
701 * Extensibility markers on other character string types do not affect the PER encoding.
705 bool extension_present
;
706 offset
= dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_present
);
707 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
708 if(extension_present
){
715 if((min_len
==max_len
)&&(max_len
<=2)){
718 if ((max_len
!= NO_BOUND
) && (max_len
< 2)) {
725 if (max_len
== NO_BOUND
) {
726 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_octet_string_length
, &length
, NULL
);
727 /* the unconstrained strings are always byte aligned (27.6.3)*/
729 } else if(min_len
!=max_len
){
730 offset
=dissect_per_constrained_integer(tvb
, offset
, actx
,
731 tree
, hf_per_octet_string_length
, min_len
, max_len
,
733 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
737 /* there is no string at all, so don't do any byte alignment */
738 /* byte_aligned=false; */
739 /* Advance offset to next 'element' */
740 if (offset
== old_offset
)
744 if((byte_aligned
)&&(actx
->aligned
)){
745 BYTE_ALIGN_OFFSET(offset
);
748 /* 30.5: if "ub" is less than or equal to 2^b-1, then "v" is the value specified in above , else
749 the characters are placed in the canonical order defined in ITU-T Rec. X.680 | ISO/IEC 8824-1,
750 clause 43. The first is assigned the value zero and the next in canonical order is assigned a value
751 that is one greater than the value assigned to the previous character in the canonical order. These are the values "v" */
752 use_canonical_order
= (ub
<= ((uint16_t)(1<<bits_per_char
)-1)) ? false : true;
754 buf
= wmem_strbuf_new_len(actx
->pinfo
->pool
, NULL
, length
);
756 for(char_pos
=0;char_pos
<length
;char_pos
++){
762 for(i
=0;i
<bits_per_char
;i
++){
763 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, -1, &bit
);
766 if(use_canonical_order
== false){
767 if (val
> ub
|| val
< lb
) {
768 wmem_strbuf_append_unichar_repl(buf
);
770 wmem_strbuf_append_c(buf
, val
);
773 if (val
< alphabet_length
){
774 wmem_strbuf_append_c(buf
, alphabet
[val
]);
776 wmem_strbuf_append_unichar_repl(buf
);
780 str_len
= (int)wmem_strbuf_get_len(buf
);
781 str
= wmem_strbuf_finalize(buf
);
782 /* Note that str can contain embedded nulls. Length claims any bytes partially used. */
783 proto_tree_add_string(tree
, hf_index
, tvb
, (old_offset
>>3), ((offset
+7)>>3)-(old_offset
>>3), str
);
785 *value_tvb
= tvb_new_child_real_data(tvb
, str
, str_len
, str_len
);
791 sort_alphabet(char *sorted_alphabet
, const char *alphabet
, int alphabet_length
, uint16_t *lb
, uint16_t *ub
)
794 unsigned char c
, c_max
, c_min
;
798 * XXX - presumably all members of alphabet will be in the
799 * range 0 to 127. asn2wrs.py doesn't properly handle the
800 * Quadruple or CharacterStringList types needed for other
801 * characters, nor representing characters outside ASCII
802 * in the "cstring" notation (possibly in UTF-8?)
804 if (!alphabet_length
) return sorted_alphabet
;
805 memset(tmp_buf
, 0, 256);
806 c_min
= c_max
= (unsigned char)alphabet
[0];
807 for (i
=0; i
<alphabet_length
; i
++) {
808 c
= (unsigned char)alphabet
[i
];
810 if (c
> c_max
) c_max
= c
;
811 else if (c
< c_min
) c_min
= c
;
813 for (i
=c_min
,j
=0; i
<=c_max
; i
++) {
814 if (tmp_buf
[i
]) sorted_alphabet
[j
++] = i
;
816 *lb
= (uint16_t)c_min
;
817 *ub
= (uint16_t)c_max
;
818 return sorted_alphabet
;
822 dissect_per_restricted_character_string(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, bool has_extension
, const char *alphabet
, int alphabet_length
, tvbuff_t
**value_tvb
)
824 const char *alphabet_ptr
;
825 char sorted_alphabet
[128];
829 /* XXX: We don't handle permitted-alphabet characters outside the
830 * ASCII range if used in BMPString (UCS2) or UniversalString (UCS4)
832 if (alphabet_length
> 127) {
833 alphabet_ptr
= alphabet
;
835 alphabet_ptr
= sort_alphabet(sorted_alphabet
, alphabet
, alphabet_length
, &lb
, &ub
);
838 /* This is for a restricted character string type with a permitted-
839 * alphabet constraint type. Such constraints are only PER-visible for
840 * the known-multiplier character string types.
843 return dissect_per_restricted_character_string_sorted(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
, lb
, ub
, alphabet_ptr
, alphabet_length
, value_tvb
);
847 dissect_per_IA5String(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, bool has_extension
, tvbuff_t
**value_tvb
)
849 offset
=dissect_per_restricted_character_string_sorted(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
,
850 0, 127, NULL
, 128, value_tvb
);
856 dissect_per_NumericString(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, bool has_extension
, tvbuff_t
**value_tvb
)
858 offset
=dissect_per_restricted_character_string_sorted(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
,
859 32, 57, " 0123456789", 11, value_tvb
);
864 dissect_per_PrintableString(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, bool has_extension
, tvbuff_t
**value_tvb
)
866 offset
=dissect_per_restricted_character_string_sorted(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
,
867 32, 122, " '()+,-.*0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 74, value_tvb
);
871 dissect_per_VisibleString(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, bool has_extension
, tvbuff_t
**value_tvb
)
873 offset
=dissect_per_restricted_character_string_sorted(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
,
874 32, 126, " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", 95, value_tvb
);
878 dissect_per_BMPString(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, bool has_extension _U_
)
882 /* xx.x if the length is 0 bytes there will be no encoding */
888 if (min_len
== NO_BOUND
) {
895 if(min_len
!=max_len
){
896 offset
=dissect_per_constrained_integer(tvb
, offset
, actx
,
897 tree
, hf_per_octet_string_length
, min_len
, max_len
,
899 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
903 /* align to byte boundary */
904 BYTE_ALIGN_OFFSET(offset
);
907 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "BMPString too long");
911 proto_tree_add_item(tree
, hf_index
, tvb
, offset
>>3, length
*2, ENC_UCS_2
|ENC_BIG_ENDIAN
);
913 offset
+=(length
<<3)*2;
918 dissect_per_UTF8String(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len _U_
, int max_len _U_
, bool has_extension _U_
)
923 /* UTF8String is not a known-multiplier character string (UTF8
924 * characters are variable width.) Hence subclause 27.6 applies,
925 * and "constraints are never PER-visible, and the type can never
926 * be extensible for PER encoding."
929 /* 27.6.3 unconstrained length determinant with "n" in octets */
930 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_octet_string_length
, &length
, NULL
);
934 /* Unnecessary because the length determinant is aligned. */
936 BYTE_ALIGN_OFFSET(offset
);
939 val_tvb
= tvb_new_octet_aligned(tvb
, offset
, length
* 8);
940 /* Add new data source if the offset was unaligned */
941 if ((offset
& 7) != 0) {
942 add_new_data_source(actx
->pinfo
, val_tvb
, "Unaligned UTF8String");
945 proto_tree_add_item(tree
, hf_index
, val_tvb
, 0, length
, ENC_UTF_8
);
947 /* tvb_new_octet_aligned doesn't like zero length.
948 * length zero indicates a present but empty string, so add it
950 proto_tree_add_item(tree
, hf_index
, tvb
, (offset
-1)>>3, length
, ENC_UTF_8
);
959 dissect_per_object_descriptor(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, tvbuff_t
**value_tvb
)
961 offset
=dissect_per_octet_string(tvb
, offset
, actx
, tree
, hf_index
, -1, -1, false, value_tvb
);
967 /* this function dissects a constrained sequence of */
969 dissect_per_constrained_sequence_of(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*parent_tree
, int hf_index
, int ett_index
, const per_sequence_t
*seq
, int min_len
, int max_len
, bool has_extension
)
973 uint32_t old_offset
=offset
;
975 header_field_info
*hfi
;
977 DEBUG_ENTRY("dissect_per_constrained_sequence_of");
979 /* 19.4 If there is a PER-visible constraint and an extension marker is present in it,
980 * a single bit shall be added to the field-list in a bit-field of length one
983 bool extension_present
;
984 offset
=dissect_per_boolean(tvb
, offset
, actx
, parent_tree
, hf_per_extension_present_bit
, &extension_present
);
985 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
986 if (extension_present
){
987 /* 10.9 shall be invoked to add the length determinant as a semi-constrained whole number to the field-list,
988 * followed by the component values
990 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, parent_tree
, hf_per_sequence_of_length
, &length
, NULL
);
995 /* 19.5 if min==max and min,max<64k ==> no length determinant */
996 if((min_len
==max_len
) && (min_len
<65536)){
1001 /* 19.6 ub>=64k or unset */
1002 if ((max_len
>= 65536) || (max_len
== NO_BOUND
)) {
1003 /* no constraint, see 10.9.4.2 */
1004 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, parent_tree
, hf_per_sequence_of_length
, &length
, NULL
);
1008 /* constrained whole number for number of elements */
1009 offset
=dissect_per_constrained_integer(tvb
, offset
, actx
,
1010 parent_tree
, hf_per_sequence_of_length
, min_len
, max_len
,
1012 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
1015 hfi
= proto_registrar_get_nth(hf_index
);
1016 if (FT_IS_UINT(hfi
->type
)) {
1017 item
= proto_tree_add_uint(parent_tree
, hf_index
, tvb
, offset
>>3, 0, length
);
1018 proto_item_append_text(item
, (length
==1)?" item":" items");
1020 item
=proto_tree_add_item(parent_tree
, hf_index
, tvb
, offset
>>3, 0, ENC_BIG_ENDIAN
);
1022 tree
=proto_item_add_subtree(item
, ett_index
);
1023 per_check_items(length
, min_len
, max_len
, actx
, item
);
1025 old_offset
= offset
;
1026 offset
=dissect_per_sequence_of_helper(tvb
, offset
, actx
, tree
, seq
->func
, *seq
->p_id
, length
);
1028 if (offset
== old_offset
)
1030 else if (offset
>> 3 == old_offset
>> 3)
1033 length
= (offset
>> 3) - (old_offset
>> 3);
1035 proto_item_set_len(item
, length
);
1039 /* this function dissects a constrained set of */
1041 dissect_per_constrained_set_of(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*parent_tree
, int hf_index
, int ett_index
, const per_sequence_t
*seq
, int min_len
, int max_len
, bool has_extension
)
1043 /* for basic-per a set-of is encoded in the same way as a sequence-of */
1044 DEBUG_ENTRY("dissect_per_constrained_set_of");
1045 offset
=dissect_per_constrained_sequence_of(tvb
, offset
, actx
, parent_tree
, hf_index
, ett_index
, seq
, min_len
, max_len
, has_extension
);
1054 /* this function dissects a set of */
1056 dissect_per_set_of(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*parent_tree
, int hf_index
, int ett_index
, const per_sequence_t
*seq
)
1058 /* for basic-per a set-of is encoded in the same way as a sequence-of */
1059 DEBUG_ENTRY("dissect_per_set_of");
1060 offset
=dissect_per_sequence_of(tvb
, offset
, actx
, parent_tree
, hf_index
, ett_index
, seq
);
1067 /* 23 Encoding the object identifier type */
1069 dissect_per_any_oid(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, tvbuff_t
**value_tvb
,
1074 tvbuff_t
*val_tvb
= NULL
;
1075 header_field_info
*hfi
;
1077 DEBUG_ENTRY("dissect_per_any_oid");
1079 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_object_identifier_length
, &length
, NULL
);
1081 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "unexpected length");
1083 if (actx
->aligned
) BYTE_ALIGN_OFFSET(offset
);
1084 val_tvb
= tvb_new_octet_aligned(tvb
, offset
, length
* 8);
1085 /* Add new data source if the offet was unaligned */
1086 if ((offset
& 7) != 0) {
1087 add_new_data_source(actx
->pinfo
, val_tvb
, "Unaligned OCTET STRING");
1090 hfi
= proto_registrar_get_nth(hf_index
);
1091 if ((is_absolute
&& hfi
->type
== FT_OID
) || (is_absolute
&& hfi
->type
== FT_REL_OID
)) {
1092 actx
->created_item
= proto_tree_add_item(tree
, hf_index
, val_tvb
, 0, length
, ENC_BIG_ENDIAN
);
1093 } else if (FT_IS_STRING(hfi
->type
)) {
1094 str
= oid_encoded2string(actx
->pinfo
->pool
, tvb_get_ptr(val_tvb
, 0, length
), length
);
1095 actx
->created_item
= proto_tree_add_string(tree
, hf_index
, val_tvb
, 0, length
, str
);
1097 DISSECTOR_ASSERT_NOT_REACHED();
1100 if (value_tvb
) *value_tvb
= val_tvb
;
1102 offset
+= 8 * length
;
1108 dissect_per_object_identifier(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, tvbuff_t
**value_tvb
)
1110 return dissect_per_any_oid(tvb
, offset
, actx
, tree
, hf_index
, value_tvb
, true);
1114 dissect_per_relative_oid(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, tvbuff_t
**value_tvb
)
1116 return dissect_per_any_oid(tvb
, offset
, actx
, tree
, hf_index
, value_tvb
, false);
1120 dissect_per_any_oid_str(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, const char **value_stringx
,
1123 tvbuff_t
*value_tvb
= NULL
;
1126 offset
= dissect_per_any_oid(tvb
, offset
, actx
, tree
, hf_index
, (value_stringx
) ? &value_tvb
: NULL
, is_absolute
);
1128 if (value_stringx
) {
1129 if (value_tvb
&& (length
= tvb_captured_length(value_tvb
))) {
1130 *value_stringx
= oid_encoded2string(actx
->pinfo
->pool
, tvb_get_ptr(value_tvb
, 0, length
), length
);
1132 *value_stringx
= "";
1140 dissect_per_object_identifier_str(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, const char **value_stringx
)
1142 return dissect_per_any_oid_str(tvb
, offset
, actx
, tree
, hf_index
, value_stringx
, true);
1146 dissect_per_relative_oid_str(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, const char **value_stringx
)
1148 return dissect_per_any_oid_str(tvb
, offset
, actx
, tree
, hf_index
, value_stringx
, false);
1152 /* this function reads a single bit */
1154 dissect_per_boolean(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, bool *bool_val
)
1158 header_field_info
*hfi
;
1160 DEBUG_ENTRY("dissect_per_boolean");
1162 ch
=tvb_get_uint8(tvb
, offset
>>3);
1163 mask
=1<<(7-(offset
&0x07));
1171 bits
[0] = mask
&0x80?'0'+value
:'.';
1172 bits
[1] = mask
&0x40?'0'+value
:'.';
1173 bits
[2] = mask
&0x20?'0'+value
:'.';
1174 bits
[3] = mask
&0x10?'0'+value
:'.';
1176 bits
[5] = mask
&0x08?'0'+value
:'.';
1177 bits
[6] = mask
&0x04?'0'+value
:'.';
1178 bits
[7] = mask
&0x02?'0'+value
:'.';
1179 bits
[8] = mask
&0x01?'0'+value
:'.';
1182 hfi
= proto_registrar_get_nth(hf_index
);
1183 actx
->created_item
= proto_tree_add_boolean_format(tree
, hf_index
, tvb
, offset
>>3, 1, value
,
1184 "%s %s: %s", bits
, hfi
->name
,
1185 value
?"True":"False");
1187 actx
->created_item
= NULL
;
1199 /* we currently only handle integers up to 32 bits in length. */
1201 dissect_per_integer(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int32_t *value
)
1205 tvbuff_t
*val_tvb
=NULL
;
1206 proto_item
*it
=NULL
;
1207 header_field_info
*hfi
;
1210 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
,hf_per_integer_length
, &length
, NULL
);
1213 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "too long integer(per_integer)");
1218 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "unexpected length");
1221 if (actx
->aligned
) BYTE_ALIGN_OFFSET(offset
);
1222 val_tvb
= tvb_new_octet_aligned(tvb
, offset
, length
* 8);
1224 for(i
=0;i
<length
;i
++){
1226 if(tvb_get_uint8(val_tvb
, i
)&0x80){
1227 /* negative number */
1230 /* positive number */
1234 val
=(val
<<8)|tvb_get_uint8(val_tvb
,i
);
1236 offset
+= length
* 8;
1238 hfi
= proto_registrar_get_nth(hf_index
);
1240 THROW(ReportedBoundsError
);
1241 if (FT_IS_INT(hfi
->type
)) {
1242 it
=proto_tree_add_int(tree
, hf_index
, tvb
, (offset
>>3)-(length
+1), length
+1, val
);
1243 } else if (FT_IS_UINT(hfi
->type
)) {
1244 it
=proto_tree_add_uint(tree
, hf_index
, tvb
, (offset
>>3)-(length
+1), length
+1, val
);
1246 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_per_field_not_integer
, tvb
, (offset
>>3)-(length
+1), length
+1,
1247 "Field is not an integer: %s", hfi
->abbrev
);
1248 REPORT_DISSECTOR_BUG("PER integer field that's not an FT_INT* or FT_UINT*");
1252 actx
->created_item
= it
;
1260 /* 64 bits experimental version, internal for now */
1262 dissect_per_integer64b(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int64_t *value
)
1266 proto_item
*it
=NULL
;
1267 header_field_info
*hfi
;
1270 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
, -1, &length
, NULL
);
1273 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "too long integer (64b)");
1278 for(i
=0;i
<length
;i
++){
1280 if(tvb_get_uint8(tvb
, offset
>>3)&0x80){
1281 /* negative number */
1282 val
=UINT64_C(0xffffffffffffffff);
1284 /* positive number */
1288 val
=(val
<<8)|tvb_get_uint8(tvb
,offset
>>3);
1292 hfi
= proto_registrar_get_nth(hf_index
);
1294 THROW(ReportedBoundsError
);
1295 if (FT_IS_INT(hfi
->type
)) {
1296 it
=proto_tree_add_int64(tree
, hf_index
, tvb
, (offset
>>3)-(length
+1), length
+1, (int64_t)val
);
1297 } else if (FT_IS_UINT(hfi
->type
)) {
1298 it
=proto_tree_add_uint64(tree
, hf_index
, tvb
, (offset
>>3)-(length
+1), length
+1, val
);
1300 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_per_field_not_integer
, tvb
, (offset
>>3)-(length
+1), length
+1,
1301 "Field is not an integer: %s", hfi
->abbrev
);
1302 REPORT_DISSECTOR_BUG("PER integer field that's not an FT_INT* or FT_UINT*");
1306 actx
->created_item
= it
;
1309 *value
=(int64_t)val
;
1314 /* this function reads a constrained integer with or without a
1315 PER visible extension marker present
1317 has_extension==true would map to asn constructs such as:
1318 rfc-number INTEGER (1..32768, ...)
1319 while has_extension==false would map to:
1320 t35CountryCode INTEGER (0..255)
1322 it only handles integers that fit inside a 32 bit integer
1325 10.5.3 range=ub-lb+1
1328 10.5.6 unaligned version
1329 10.5.7 aligned version
1330 10.5.7.1 decoding of 0-255 1-8 bits
1331 10.5.7.2 decoding og 0-256 8 bits
1332 10.5.7.3 decoding of 0-65535 16 bits
1336 dissect_per_constrained_integer(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, uint32_t min
, uint32_t max
, uint32_t *value
, bool has_extension
)
1338 proto_item
*it
=NULL
;
1339 uint32_t range
, val
;
1340 int val_start
, val_length
;
1342 header_field_info
*hfi
;
1345 DEBUG_ENTRY("dissect_per_constrained_integer");
1347 bool extension_present
;
1348 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_present
);
1349 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
1350 if(extension_present
){
1351 offset
= dissect_per_integer(tvb
, offset
, actx
, tree
, hf_index
, (int32_t*)value
);
1356 hfi
= proto_registrar_get_nth(hf_index
);
1358 /* 10.5.3 Let "range" be defined as the integer value ("ub" - "lb" 1), and let the value to be encoded be "n".
1359 * 10.5.7 In the case of the ALIGNED variant the encoding depends on whether
1360 * d) "range" is greater than 64K (the indefinite length case).
1362 if(((max
-min
)>65536)&&(actx
->aligned
)){
1363 /* just set range really big so it will fall through
1364 to the bottom of the encoding */
1367 /* Really ugly hack.
1368 * We should really use uint64_t as parameters for min/max.
1369 * This is to prevent range from being 0 if
1370 * the range for a signed integer spans the entire 32 bit range.
1371 * Special case the 2 common cases when this can happen until
1372 * a real fix is implemented.
1374 if( (max
==0x7fffffff && min
==0x80000000)
1375 || (max
==0xffffffff && min
==0x00000000) ){
1383 timeval
.secs
=val
; timeval
.nsecs
=0;
1384 /* 10.5.4 If "range" has the value 1, then the result of the encoding shall be an empty bit-field (no bits).*/
1386 /* something is really wrong if range is 0 */
1387 DISSECTOR_ASSERT(range
!=0);
1390 val_start
= offset
>>3; val_length
= 0;
1392 } else if((range
<=255)||(!actx
->aligned
)) {
1394 * 10.5.6 In the case of the UNALIGNED variant the value ("n" - "lb") shall be encoded
1395 * as a non-negative binary integer in a bit field as specified in 10.3 with the minimum
1396 * number of bits necessary to represent the range.
1400 uint32_t mask
,mask2
;
1401 /* We only handle 32 bit integers */
1405 while ((range
& mask
)== 0){
1410 if ((range
& mask2
) == 0)
1414 length
=(num_bits
+7)>>3;
1419 val_start
= (offset
)>>3;
1420 val_length
= length
;
1421 val
= (uint32_t)tvb_get_bits64(tvb
,offset
,num_bits
,ENC_BIG_ENDIAN
);
1423 if (display_internal_per_fields
){
1424 str
= decode_bits_in_field(actx
->pinfo
->pool
, (offset
&0x07),num_bits
,val
,ENC_BIG_ENDIAN
);
1425 if (FT_IS_INT(hfi
->type
)) {
1426 proto_tree_add_int(tree
, hf_per_internal_min_int
, tvb
, val_start
, val_length
, min
);
1428 proto_tree_add_uint(tree
, hf_per_internal_min
, tvb
, val_start
, val_length
, min
);
1430 proto_tree_add_uint64(tree
, hf_per_internal_range
, tvb
, val_start
, val_length
, range
);
1431 proto_tree_add_uint(tree
, hf_per_internal_num_bits
, tvb
, val_start
, val_length
, num_bits
);
1432 if (FT_IS_INT(hfi
->type
)) {
1433 proto_tree_add_int64_format_value(tree
, hf_per_internal_value_int
, tvb
, val_start
, val_length
, val
+ min
, "%s decimal value: %i", str
, val
+ min
);
1435 proto_tree_add_uint64_format_value(tree
, hf_per_internal_value
, tvb
, val_start
, val_length
, val
+ min
, "%s decimal value: %u", str
, val
+ min
);
1438 /* The actual value */
1440 offset
= offset
+num_bits
;
1441 } else if(range
==256){
1444 /* in the aligned case, align to byte boundary */
1445 BYTE_ALIGN_OFFSET(offset
);
1446 val
=tvb_get_uint8(tvb
, offset
>>3);
1449 val_start
= (offset
>>3)-1; val_length
= 1;
1451 } else if(range
<=65536){
1454 /* in the aligned case, align to byte boundary */
1455 BYTE_ALIGN_OFFSET(offset
);
1456 val
=tvb_get_uint8(tvb
, offset
>>3);
1459 val
|=tvb_get_uint8(tvb
, offset
>>3);
1462 val_start
= (offset
>>3)-2; val_length
= 2;
1470 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, -1, &bit
);
1472 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, -1, &bit
);
1473 num_bytes
=(num_bytes
<<1)|bit
;
1475 num_bytes
++; /* lower bound for length determinant is 1 */
1476 if (display_internal_per_fields
)
1477 proto_tree_add_uint(tree
, hf_per_const_int_len
, tvb
, (offset
>>3), 1, num_bytes
);
1480 BYTE_ALIGN_OFFSET(offset
);
1482 for(i
=0;i
<num_bytes
;i
++){
1483 val
=(val
<<8)|tvb_get_uint8(tvb
,offset
>>3);
1486 val_start
= (offset
>>3)-(num_bytes
+1); val_length
= num_bytes
+1;
1491 if (FT_IS_UINT(hfi
->type
)) {
1492 it
= proto_tree_add_uint(tree
, hf_index
, tvb
, val_start
, val_length
, val
);
1493 per_check_value(val
, min
, max
, actx
, it
, false);
1494 } else if (FT_IS_INT(hfi
->type
)) {
1495 it
= proto_tree_add_int(tree
, hf_index
, tvb
, val_start
, val_length
, val
);
1496 per_check_value(val
, min
, max
, actx
, it
, true);
1497 } else if (FT_IS_TIME(hfi
->type
)) {
1498 it
= proto_tree_add_time(tree
, hf_index
, tvb
, val_start
, val_length
, &timeval
);
1500 THROW(ReportedBoundsError
);
1502 actx
->created_item
= it
;
1503 if (value
) *value
= val
;
1508 dissect_per_constrained_integer_64b(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, uint64_t min
, uint64_t max
, uint64_t *value
, bool has_extension
)
1510 proto_item
*it
=NULL
, *int_item
=NULL
;
1511 uint64_t range
, val
;
1512 int val_start
, val_length
;
1514 header_field_info
*hfi
;
1518 DEBUG_ENTRY("dissect_per_constrained_integer_64b");
1520 bool extension_present
;
1521 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_present
);
1522 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
1523 if(extension_present
){
1524 offset
= dissect_per_integer64b(tvb
, offset
, actx
, tree
, hf_index
, (int64_t*)value
);
1529 hfi
= proto_registrar_get_nth(hf_index
);
1531 /* 10.5.3 Let "range" be defined as the integer value ("ub" - "lb" 1), and let the value to be encoded be "n".
1532 * 10.5.7 In the case of the ALIGNED variant the encoding depends on whether
1533 * d) "range" is greater than 64K (the indefinite length case).
1535 if(((max
-min
)>65536)&&(actx
->aligned
)){
1536 /* just set range really big so it will fall through
1537 to the bottom of the encoding */
1538 /* range=1000000; */
1541 range
++; /* make it fall trough? */
1543 /* Copied from the 32 bit version, assuming the same problem occurs
1544 * at 64 bit boundary.
1546 * We should really use uint64_t as parameters for min/max.
1547 * This is to prevent range from being 0 if
1548 * the range for a signed integer spans the entire 32 bit range.
1549 * Special case the 2 common cases when this can happen until
1550 * a real fix is implemented.
1552 if( (max
==INT64_C(0x7fffffffffffffff) && min
==INT64_C(0x8000000000000000))
1553 || (max
==INT64_C(0xffffffffffffffff) && min
==0) ){
1554 range
=INT64_C(0xffffffffffffffff);
1561 timeval
.secs
=0; timeval
.nsecs
=0;
1562 /* 10.5.4 If "range" has the value 1, then the result of the encoding shall be an empty bit-field (no bits).*/
1564 /* something is really wrong if range is 0 */
1565 DISSECTOR_ASSERT(range
!=0);
1568 val_start
= offset
>>3; val_length
= 0;
1570 } else if((range
<=255)||(!actx
->aligned
)) {
1572 * 10.5.6 In the case of the UNALIGNED variant the value ("n" - "lb") shall be encoded
1573 * as a non-negative binary integer in a bit field as specified in 10.3 with the minimum
1574 * number of bits necessary to represent the range.
1577 int i
, bit
, length
, str_length
, str_index
= 0;
1578 uint64_t mask
,mask2
;
1579 /* We only handle 64 bit integers */
1580 mask
= UINT64_C(0x8000000000000000);
1581 mask2
= UINT64_C(0x7fffffffffffffff);
1583 while ((range
& mask
)== 0){
1588 if ((range
& mask2
) == 0)
1597 /* prepare the string (max number of bits + quartet separators) */
1598 str_length
= 512+128;
1599 str
= (char *)wmem_alloc(actx
->pinfo
->pool
, str_length
+1);
1600 for(bit
=0;bit
<((int)(offset
&0x07));bit
++){
1601 if(bit
&&(!(bit
%4))){
1602 if (str_index
< str_length
) str
[str_index
++] = ' ';
1604 if (str_index
< str_length
) str
[str_index
++] = '.';
1606 /* read the bits for the int */
1607 for(i
=0;i
<num_bits
;i
++){
1608 if(bit
&&(!(bit
%4))){
1609 if (str_index
< str_length
) str
[str_index
++] = ' ';
1611 if(bit
&&(!(bit
%8))){
1613 if (str_index
< str_length
) str
[str_index
++] = ' ';
1616 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, -1, &tmp
);
1620 if (str_index
< str_length
) str
[str_index
++] = '1';
1622 if (str_index
< str_length
) str
[str_index
++] = '0';
1626 if(bit
&&(!(bit
%4))){
1627 if (str_index
< str_length
) str
[str_index
++] = ' ';
1629 if (str_index
< str_length
) str
[str_index
++] = '.';
1631 str
[str_index
] = '\0'; /* Terminate string */
1632 val_start
= (offset
-num_bits
)>>3; val_length
= length
;
1634 if (display_internal_per_fields
) {
1635 proto_tree_add_uint64(tree
, hf_per_internal_range
, tvb
, val_start
, val_length
, range
);
1636 proto_tree_add_uint(tree
, hf_per_internal_num_bits
, tvb
, val_start
,val_length
, num_bits
);
1637 proto_tree_add_uint64_format_value(tree
, hf_per_internal_value
, tvb
, val_start
, val_length
, val
, "%s decimal value: %" PRIu64
, str
, val
);
1639 } else if(range
==256){
1642 /* in the aligned case, align to byte boundary */
1643 BYTE_ALIGN_OFFSET(offset
);
1644 val
=tvb_get_uint8(tvb
, offset
>>3);
1647 val_start
= (offset
>>3)-1; val_length
= 1;
1649 } else if(range
<=65536){
1652 /* in the aligned case, align to byte boundary */
1653 BYTE_ALIGN_OFFSET(offset
);
1654 val
=tvb_get_uint8(tvb
, offset
>>3);
1657 val
|=tvb_get_uint8(tvb
, offset
>>3);
1660 val_start
= (offset
>>3)-2; val_length
= 2;
1663 int i
,num_bytes
,n_bits
;
1667 /* calculate the number of bits to hold the length */
1668 if ((range
& INT64_C(0xffffffff00000000)) != 0){
1673 num_bytes
=tvb_get_bits8(tvb
, offset
, n_bits
);
1674 num_bytes
++; /* lower bound for length determinant is 1 */
1675 if (display_internal_per_fields
){
1676 int_item
= proto_tree_add_bits_item(tree
, hf_per_const_int_len
, tvb
, offset
,n_bits
, ENC_BIG_ENDIAN
);
1677 proto_item_append_text(int_item
,"+1=%u bytes, Range = (%" PRIu64
")",num_bytes
, range
);
1679 offset
= offset
+n_bits
;
1681 BYTE_ALIGN_OFFSET(offset
);
1683 for(i
=0;i
<num_bytes
;i
++){
1684 val
=(val
<<8)|tvb_get_uint8(tvb
,offset
>>3);
1687 val_start
= (offset
>>3)-(num_bytes
+1); val_length
= num_bytes
+1;
1692 if (FT_IS_UINT(hfi
->type
)) {
1693 it
= proto_tree_add_uint64(tree
, hf_index
, tvb
, val_start
, val_length
, val
);
1694 per_check_value64(val
, min
, max
, actx
, it
, false);
1695 } else if (FT_IS_INT(hfi
->type
)) {
1696 it
= proto_tree_add_int64(tree
, hf_index
, tvb
, val_start
, val_length
, val
);
1697 per_check_value64(val
, min
, max
, actx
, it
, true);
1698 } else if (FT_IS_TIME(hfi
->type
)) {
1699 timeval
.secs
= (uint32_t)val
;
1700 it
= proto_tree_add_time(tree
, hf_index
, tvb
, val_start
, val_length
, &timeval
);
1702 THROW(ReportedBoundsError
);
1704 actx
->created_item
= it
;
1705 if (value
) *value
= val
;
1709 /* 13 Encoding the enumerated type */
1711 dissect_per_enumerated(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, uint32_t root_num
, uint32_t *value
, bool has_extension
, uint32_t ext_num
, uint32_t *value_map
)
1714 proto_item
*it
=NULL
;
1715 uint32_t enum_index
, val
;
1716 uint32_t start_offset
= offset
;
1717 bool extension_present
= false;
1718 header_field_info
*hfi
;
1720 if (has_extension
) {
1722 offset
= dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_present
);
1723 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
1726 if (!extension_present
) {
1728 offset
= dissect_per_constrained_integer(tvb
, offset
, actx
, tree
, hf_per_enum_index
, 0, root_num
- 1, &enum_index
, false);
1729 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
1731 /* 13.3 ".. and the value shall be added to the field-list as a
1732 * normally small non-negative whole number whose value is the
1733 * enumeration index of the additional enumeration and with "lb" set to 0.."
1735 offset
= dissect_per_normally_small_nonnegative_whole_number(tvb
, offset
, actx
, tree
, hf_per_enum_extension_index
, &enum_index
);
1736 enum_index
+= root_num
;
1738 val
= (value_map
&& (enum_index
<(root_num
+ext_num
))) ? value_map
[enum_index
] : enum_index
;
1739 hfi
= proto_registrar_get_nth(hf_index
);
1740 if (FT_IS_UINT(hfi
->type
)) {
1741 it
= proto_tree_add_uint(tree
, hf_index
, tvb
, start_offset
>>3, BLEN(start_offset
, offset
), val
);
1743 THROW(ReportedBoundsError
);
1745 actx
->created_item
= it
;
1746 if (value
) *value
= val
;
1750 /* 14 Encoding the real type */
1752 dissect_per_real(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, double *value
)
1754 uint32_t val_length
, end_offset
;
1758 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_real_length
, &val_length
, NULL
);
1759 if(val_length
== 0){
1760 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "unexpected length");
1762 if (actx
->aligned
) BYTE_ALIGN_OFFSET(offset
);
1763 val_tvb
= tvb_new_octet_aligned(tvb
, offset
, val_length
* 8);
1764 /* Add new data source if the offet was unaligned */
1765 if ((offset
& 7) != 0) {
1766 add_new_data_source(actx
->pinfo
, val_tvb
, "Unaligned OCTET STRING");
1768 end_offset
= offset
+ val_length
* 8;
1770 val
= asn1_get_real(tvb_get_ptr(val_tvb
, 0, val_length
), val_length
);
1771 actx
->created_item
= proto_tree_add_double(tree
, hf_index
, val_tvb
, 0, val_length
, val
);
1773 if (value
) *value
= val
;
1778 /* 22 Encoding the choice type */
1780 dissect_per_choice(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int ett_index
, const per_choice_t
*choice
, int *value
)
1782 bool /*extension_present,*/ extension_flag
;
1783 int extension_root_entries
;
1784 uint32_t choice_index
;
1786 uint32_t ext_length
= 0;
1787 uint32_t old_offset
= offset
;
1788 proto_item
*choice_item
= NULL
;
1789 proto_tree
*choice_tree
= NULL
;
1791 DEBUG_ENTRY("dissect_per_choice");
1793 if (value
) *value
= -1;
1796 if (choice
[0].extension
== ASN1_NO_EXTENSIONS
){
1797 /*extension_present = false; ?? */
1798 extension_flag
= false;
1800 /*extension_present = true; ?? */
1801 offset
= dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_bit
, &extension_flag
);
1802 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
1805 /* count the number of entries in the extension root and extension addition */
1806 extension_root_entries
= 0;
1807 for (i
=0; choice
[i
].p_id
; i
++) {
1808 switch(choice
[i
].extension
){
1809 case ASN1_NO_EXTENSIONS
:
1810 case ASN1_EXTENSION_ROOT
:
1811 extension_root_entries
++;
1813 case ASN1_NOT_EXTENSION_ROOT
:
1818 if (!extension_flag
) { /* 22.6, 22.7 */
1819 if (extension_root_entries
== 1) { /* 22.5 */
1822 offset
= dissect_per_constrained_integer(tvb
, offset
, actx
,
1823 tree
, hf_per_choice_index
, 0, extension_root_entries
- 1,
1824 &choice_index
, false);
1825 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
1828 idx
= -1; cidx
= choice_index
;
1829 for (i
=0; choice
[i
].p_id
; i
++) {
1830 if(choice
[i
].extension
!= ASN1_NOT_EXTENSION_ROOT
){
1831 if (!cidx
) { idx
= i
; break; }
1836 offset
= dissect_per_normally_small_nonnegative_whole_number(tvb
, offset
, actx
, tree
, hf_per_choice_extension_index
, &choice_index
);
1837 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_open_type_length
, &ext_length
, NULL
);
1839 idx
= -1; cidx
= choice_index
;
1840 for (i
=0; choice
[i
].p_id
; i
++) {
1841 if(choice
[i
].extension
== ASN1_NOT_EXTENSION_ROOT
){
1842 if (!cidx
) { idx
= i
; break; }
1849 choice_item
= proto_tree_add_uint(tree
, hf_index
, tvb
, old_offset
>>3, 0, choice
[idx
].value
);
1850 choice_tree
= proto_item_add_subtree(choice_item
, ett_index
);
1851 if (!extension_flag
) {
1852 offset
= choice
[idx
].func(tvb
, offset
, actx
, choice_tree
, *choice
[idx
].p_id
);
1854 choice
[idx
].func(tvb
, offset
, actx
, choice_tree
, *choice
[idx
].p_id
);
1855 offset
+= ext_length
* 8;
1857 proto_item_set_len(choice_item
, BLEN(old_offset
, offset
));
1859 if (!extension_flag
) {
1860 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "unknown extension root index in choice");
1862 offset
+= ext_length
* 8;
1863 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_per_choice_extension_unknown
,
1864 tvb
, old_offset
>>3, BLEN(old_offset
, offset
),
1865 "Choice no. %d in extension", choice_index
);
1869 if (value
&& (idx
!= -1))
1870 *value
= choice
[idx
].value
;
1877 index_get_optional_name(const per_sequence_t
*sequence
, int idx
)
1880 header_field_info
*hfi
;
1882 for(i
=0;sequence
[i
].p_id
;i
++){
1883 if((sequence
[i
].extension
!=ASN1_NOT_EXTENSION_ROOT
)&&(sequence
[i
].optional
==ASN1_OPTIONAL
)){
1885 hfi
= proto_registrar_get_nth(*sequence
[i
].p_id
);
1886 return (hfi
) ? hfi
->name
: "<unknown field>";
1891 return "<unknown type>";
1895 index_get_extension_name(const per_sequence_t
*sequence
, int idx
)
1898 header_field_info
*hfi
;
1900 for(i
=0;sequence
[i
].p_id
;i
++){
1901 if(sequence
[i
].extension
==ASN1_NOT_EXTENSION_ROOT
){
1903 if (*sequence
[i
].p_id
== -1 || *sequence
[i
].p_id
== 0) return "extension addition group";
1904 hfi
= proto_registrar_get_nth(*sequence
[i
].p_id
);
1905 return (hfi
) ? hfi
->name
: "<unknown field>";
1910 return "<unknown type>";
1914 index_get_field_name(const per_sequence_t
*sequence
, int idx
)
1917 header_field_info
*hfi
= proto_registrar_get_nth(*sequence
[idx
].p_id
);
1923 return "<unknown field>";
1926 /* this functions decodes a SEQUENCE
1927 it can only handle SEQUENCES with at most 32 DEFAULT or OPTIONAL fields
1929 18.2 optional/default items in root
1930 18.3 we ignore the case where n>64K
1931 18.4 the root sequence
1939 dissect_per_sequence(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*parent_tree
, int hf_index
, int ett_index
, const per_sequence_t
*sequence
)
1941 bool /*extension_present,*/ extension_flag
, optional_field_flag
;
1944 uint32_t old_offset
=offset
;
1945 uint32_t i
, j
, num_opts
;
1946 uint32_t optional_mask
[SEQ_MAX_COMPONENTS
>>5];
1948 DEBUG_ENTRY("dissect_per_sequence");
1949 DISSECTOR_ASSERT(sequence
);
1951 item
=proto_tree_add_item(parent_tree
, hf_index
, tvb
, offset
>>3, 0, ENC_BIG_ENDIAN
);
1952 tree
=proto_item_add_subtree(item
, ett_index
);
1955 /* first check if there should be an extension bit for this CHOICE.
1956 we do this by just checking the first choice arm
1960 if(sequence
[0].extension
==ASN1_NO_EXTENSIONS
){
1961 /*extension_present=0; ?? */
1963 /*extension_present=1; ?? */
1964 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_bit
, &extension_flag
);
1965 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
1969 for(i
=0;sequence
[i
].p_id
;i
++){
1970 if((sequence
[i
].extension
!=ASN1_NOT_EXTENSION_ROOT
)&&(sequence
[i
].optional
==ASN1_OPTIONAL
)){
1974 if (num_opts
> SEQ_MAX_COMPONENTS
) {
1975 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "too many optional/default components");
1978 memset(optional_mask
, 0, sizeof(optional_mask
));
1979 for(i
=0;i
<num_opts
;i
++){
1980 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_optional_field_bit
, &optional_field_flag
);
1982 proto_item_append_text(actx
->created_item
, " (%s %s present)",
1983 index_get_optional_name(sequence
, i
), optional_field_flag
?"is":"is NOT");
1985 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
1986 if(optional_field_flag
){
1987 optional_mask
[i
>>5]|=0x80000000>>(i
&0x1f);
1993 for(i
=0,j
=0;sequence
[i
].p_id
;i
++){
1994 if( (sequence
[i
].extension
==ASN1_NO_EXTENSIONS
)
1995 || (sequence
[i
].extension
==ASN1_EXTENSION_ROOT
) ){
1996 if(sequence
[i
].optional
==ASN1_OPTIONAL
){
2001 is_present
=(0x80000000>>(j
&0x1f))&optional_mask
[j
>>5];
2008 if(sequence
[i
].func
){
2009 offset
=sequence
[i
].func(tvb
, offset
, actx
, tree
, *sequence
[i
].p_id
);
2011 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, index_get_field_name(sequence
, i
));
2019 uint32_t num_known_extensions
;
2020 uint32_t num_extensions
;
2021 uint32_t extension_mask
;
2023 offset
=dissect_per_normally_small_nonnegative_whole_number(tvb
, offset
, actx
, tree
, hf_per_num_sequence_extensions
, &num_extensions
);
2024 /* the X.691 standard is VERY unclear here.
2025 there is no mention that the lower bound lb for this
2026 (apparently) semiconstrained value is 1,
2027 apart from the NOTE: comment in 18.8 that this value can
2029 In my book, there is a semantic difference between having
2030 a comment that says that the value can not be zero
2031 and stating that the lb is 1.
2032 I don't know if this is right or not but it makes
2033 some of the very few captures I have decode properly.
2035 It could also be that the captures I have are generated by
2036 a broken implementation.
2037 If this is wrong and you don't report it as a bug
2038 then it won't get fixed!
2041 if (num_extensions
> 32) {
2042 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "too many extensions");
2046 for(i
=0;i
<num_extensions
;i
++){
2047 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_bit
);
2049 proto_item_append_text(actx
->created_item
, " (%s %s present)",
2050 index_get_extension_name(sequence
, i
), extension_bit
?"is":"is NOT");
2052 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
2054 extension_mask
=(extension_mask
<<1)|extension_bit
;
2057 /* find how many extensions we know about */
2058 num_known_extensions
=0;
2059 for(i
=0;sequence
[i
].p_id
;i
++){
2060 if(sequence
[i
].extension
==ASN1_NOT_EXTENSION_ROOT
){
2061 num_known_extensions
++;
2065 /* decode the extensions one by one */
2066 for(i
=0;i
<num_extensions
;i
++){
2068 uint32_t new_offset
;
2070 uint32_t extension_index
;
2073 if(!((1U<<(num_extensions
-1-i
))&extension_mask
)){
2074 /* this extension is not encoded in this PDU */
2078 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_open_type_length
, &length
, NULL
);
2080 if(i
>=num_known_extensions
){
2081 /* we don't know how to decode this extension */
2083 expert_add_info(actx
->pinfo
, item
, &ei_per_sequence_extension_unknown
);
2088 for(j
=0,k
=0;sequence
[j
].p_id
;j
++){
2089 if(sequence
[j
].extension
==ASN1_NOT_EXTENSION_ROOT
){
2098 if(sequence
[extension_index
].func
){
2099 new_offset
=sequence
[extension_index
].func(tvb
, offset
, actx
, tree
, *sequence
[extension_index
].p_id
);
2101 difference
= offset
- new_offset
;
2102 /* A difference of 7 or less might be byte aligning */
2103 /* Difference could be 8 if open type has no bits and the length is 1 */
2104 if ((length
> 1) && (difference
> 7)) {
2105 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_per_encoding_error
, tvb
, new_offset
>>3, (offset
-new_offset
)>>3,
2106 "Possible encoding error full length not decoded. Open type length %u, decoded %u",length
, length
- (difference
>>3));
2108 else if (difference
< 0) {
2109 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_per_encoding_error
, tvb
, new_offset
>>3, (offset
-new_offset
)>>3,
2110 "Possible encoding error open type length less than dissected bits. Open type length %u, decoded %u", length
, length
- (difference
>>3));
2113 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, index_get_field_name(sequence
, extension_index
));
2119 proto_item_set_len(item
, (offset
>>3)!=(old_offset
>>3)?(offset
>>3)-(old_offset
>>3):1);
2120 actx
->created_item
= item
;
2125 dissect_per_sequence_eag(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, const per_sequence_t
*sequence
)
2127 bool optional_field_flag
;
2128 uint32_t i
, j
, num_opts
;
2129 uint32_t optional_mask
[SEQ_MAX_COMPONENTS
>>5];
2131 DEBUG_ENTRY("dissect_per_sequence_eag");
2134 for(i
=0;sequence
[i
].p_id
;i
++){
2135 if(sequence
[i
].optional
==ASN1_OPTIONAL
){
2139 if (num_opts
> SEQ_MAX_COMPONENTS
) {
2140 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "too many optional/default components");
2143 memset(optional_mask
, 0, sizeof(optional_mask
));
2144 for(i
=0;i
<num_opts
;i
++){
2145 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_optional_field_bit
, &optional_field_flag
);
2147 proto_item_append_text(actx
->created_item
, " (%s %s present)",
2148 index_get_optional_name(sequence
, i
), optional_field_flag
?"is":"is NOT");
2150 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
2151 if(optional_field_flag
){
2152 optional_mask
[i
>>5]|=0x80000000>>(i
&0x1f);
2156 for(i
=0,j
=0;sequence
[i
].p_id
;i
++){
2157 if(sequence
[i
].optional
==ASN1_OPTIONAL
){
2162 is_present
=(0x80000000>>(j
&0x1f))&optional_mask
[j
>>5];
2169 if(sequence
[i
].func
){
2170 offset
=sequence
[i
].func(tvb
, offset
, actx
, tree
, *sequence
[i
].p_id
);
2172 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, index_get_field_name(sequence
, i
));
2180 /* 15 Encoding the bitstring type
2182 max_len or min_len == NO_BOUND means there is no lower/upper constraint
2186 static tvbuff_t
*dissect_per_bit_string_display(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, header_field_info
*hfi
, uint32_t length
, int * const *named_bits
, int num_named_bits _U_
)
2188 tvbuff_t
*out_tvb
= NULL
;
2189 uint32_t pad_length
=0;
2192 out_tvb
= tvb_new_octet_aligned(tvb
, offset
, length
);
2193 add_new_data_source(actx
->pinfo
, out_tvb
, "Bitstring tvb");
2196 actx
->created_item
= proto_tree_add_item(tree
, hf_index
, out_tvb
, 0, -1, ENC_BIG_ENDIAN
);
2197 proto_item_append_text(actx
->created_item
, " [bit length %u", length
);
2199 pad_length
= 8-(length
%8);
2200 proto_item_append_text(actx
->created_item
, ", %u LSB pad bits", pad_length
);
2203 if (length
<=64) { /* if read into 64 bits also handle length <= 24, 40, 48, 56 bits */
2205 value
= tvb_get_bits8(out_tvb
, 0, length
);
2206 }else if (length
<=16) {
2207 value
= tvb_get_bits16(out_tvb
, 0, length
, ENC_BIG_ENDIAN
);
2208 }else if (length
<=24) { /* first read 16 and then the remaining bits */
2209 value
= tvb_get_bits16(out_tvb
, 0, 16, ENC_BIG_ENDIAN
);
2210 value
<<= 8 - pad_length
;
2211 value
|= tvb_get_bits8(out_tvb
, 16, length
- 16);
2212 }else if (length
<=32) {
2213 value
= tvb_get_bits32(out_tvb
, 0, length
, ENC_BIG_ENDIAN
);
2214 }else if (length
<=40) { /* first read 32 and then the remaining bits */
2215 value
= tvb_get_bits32(out_tvb
, 0, 32, ENC_BIG_ENDIAN
);
2216 value
<<= 8 - pad_length
;
2217 value
|= tvb_get_bits8(out_tvb
, 32, length
- 32);
2218 }else if (length
<=48) { /* first read 32 and then the remaining bits */
2219 value
= tvb_get_bits32(out_tvb
, 0, 32, ENC_BIG_ENDIAN
);
2220 value
<<= 16 - pad_length
;
2221 value
|= tvb_get_bits16(out_tvb
, 32, length
- 32, ENC_BIG_ENDIAN
);
2222 }else if (length
<=56) { /* first read 32 and 16 then the remaining bits */
2223 value
= tvb_get_bits32(out_tvb
, 0, 32, ENC_BIG_ENDIAN
);
2225 value
|= tvb_get_bits16(out_tvb
, 32, 16, ENC_BIG_ENDIAN
);
2226 value
<<= 8 - pad_length
;
2227 value
|= tvb_get_bits8(out_tvb
, 48, length
- 48);
2229 value
= tvb_get_bits64(out_tvb
, 0, length
, ENC_BIG_ENDIAN
);
2231 proto_item_append_text(actx
->created_item
, ", %s decimal value %" PRIu64
,
2232 decode_bits_in_field(actx
->pinfo
->pool
, 0, length
, value
, ENC_BIG_ENDIAN
), value
);
2234 const uint32_t named_bits_bytelen
= (num_named_bits
+ 7) / 8;
2235 proto_tree
*subtree
= proto_item_add_subtree(actx
->created_item
, ett_per_named_bits
);
2236 for (uint32_t i
= 0; i
< named_bits_bytelen
; i
++) {
2237 // If less data is available than the number of named bits, then
2238 // the trailing (right) bits are assumed to be 0.
2240 const uint32_t bit_offset
= 8 * i
;
2241 if (bit_offset
< length
) {
2242 value
= tvb_get_uint8(out_tvb
, i
);
2245 // Process 8 bits at a time instead of 64, each field masks a
2247 int* const * section_named_bits
= named_bits
+ bit_offset
;
2249 if (num_named_bits
- bit_offset
> 8) {
2250 memcpy(&flags
[0], named_bits
+ bit_offset
, 8 * sizeof(int*));
2252 section_named_bits
= flags
;
2255 // TODO should non-zero pad bits be masked from the value?
2256 // When trailing zeroes are not present in the data, mark the
2257 // last byte for the lack of a better alternative.
2258 proto_tree_add_bitmask_list_value(subtree
, out_tvb
, offset
+ MIN(i
, length
- 1), 1, section_named_bits
, value
);
2262 proto_item_append_text(actx
->created_item
, "]");
2268 dissect_per_bit_string(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, bool has_extension
, int * const *named_bits
, int num_named_bits
, tvbuff_t
**value_tvb
, int *len
)
2270 /*int val_start, val_length;*/
2271 uint32_t length
, fragmented_length
= 0;
2272 header_field_info
*hfi
;
2273 bool is_fragmented
= false;
2274 tvbuff_t
*fragmented_tvb
= NULL
, *out_tvb
= NULL
, *fragment_tvb
= NULL
;
2276 hfi
= (hf_index
<= 0) ? NULL
: proto_registrar_get_nth(hf_index
);
2278 DEBUG_ENTRY("dissect_per_bit_string");
2279 /* 15.8 if the length is 0 bytes there will be no encoding */
2282 *value_tvb
= out_tvb
;
2288 if (min_len
== NO_BOUND
) {
2291 /* 15.6 If an extension marker is present in the size constraint specification of the bitstring type,
2292 * a single bit shall be added to the field-list in a bit-field of length one.
2293 * The bit shall be set to 1 if the length of this encoding is not within the range of the extension root,
2294 * and zero otherwise.
2296 if (has_extension
) {
2297 bool extension_present
;
2298 offset
= dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_present
);
2299 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
2300 if(extension_present
){
2302 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_bit_string_length
, &length
, &is_fragmented
);
2303 if(length
|| fragmented_length
){
2306 BYTE_ALIGN_OFFSET(offset
);
2309 fragment_tvb
= tvb_new_octet_aligned(tvb
, offset
, length
);
2310 if(fragmented_length
==0)
2311 fragmented_tvb
= tvb_new_composite();
2312 tvb_composite_append(fragmented_tvb
, fragment_tvb
);
2314 fragmented_length
+= length
;
2315 goto next_fragment1
;
2317 if(fragmented_length
){
2319 tvb_composite_append(fragmented_tvb
, tvb_new_octet_aligned(tvb
, offset
, length
));
2320 fragmented_length
+= length
;
2322 tvb_composite_finalize(fragmented_tvb
);
2323 add_new_data_source(actx
->pinfo
, fragmented_tvb
, "Fragmented bitstring tvb");
2324 out_tvb
= dissect_per_bit_string_display(fragmented_tvb
, 0, actx
, tree
, hf_index
, hfi
,
2325 fragmented_length
, named_bits
, num_named_bits
);
2328 out_tvb
= dissect_per_bit_string_display(tvb
, offset
, actx
, tree
, hf_index
, hfi
, length
, named_bits
, num_named_bits
);
2331 /*val_start = offset>>3;*/
2332 /*val_length = (length+7)/8;*/
2336 *value_tvb
= out_tvb
;
2338 *len
= fragmented_length
? fragmented_length
: length
;
2344 /* 15.9 if length is fixed and less than or equal to sixteen bits*/
2345 if ((min_len
==max_len
) && (max_len
<=16)) {
2346 out_tvb
= dissect_per_bit_string_display(tvb
, offset
, actx
, tree
, hf_index
, hfi
, min_len
, named_bits
, num_named_bits
);
2349 *value_tvb
= out_tvb
;
2356 /* 15.10 if length is fixed and less than to 64kbits*/
2357 if((min_len
==max_len
)&&(min_len
<65536)){
2358 /* (octet-aligned in the ALIGNED variant)
2362 BYTE_ALIGN_OFFSET(offset
);
2364 out_tvb
= dissect_per_bit_string_display(tvb
, offset
, actx
, tree
, hf_index
, hfi
, min_len
, named_bits
, num_named_bits
);
2367 *value_tvb
= out_tvb
;
2374 if (max_len
!= NO_BOUND
&& max_len
< 65536) {
2375 offset
=dissect_per_constrained_integer(tvb
, offset
, actx
,
2376 tree
, hf_per_bit_string_length
, min_len
, max_len
,
2378 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
2381 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_bit_string_length
, &length
, &is_fragmented
);
2383 if(length
|| fragmented_length
){
2386 BYTE_ALIGN_OFFSET(offset
);
2389 fragment_tvb
= tvb_new_octet_aligned(tvb
, offset
, length
);
2390 if(fragmented_length
==0)
2391 fragmented_tvb
= tvb_new_composite();
2392 tvb_composite_append(fragmented_tvb
, fragment_tvb
);
2394 fragmented_length
+= length
;
2395 goto next_fragment2
;
2397 if(fragmented_length
){
2399 tvb_composite_append(fragmented_tvb
, tvb_new_octet_aligned(tvb
, offset
, length
));
2400 fragmented_length
+= length
;
2402 tvb_composite_finalize(fragmented_tvb
);
2403 add_new_data_source(actx
->pinfo
, fragmented_tvb
, "Fragmented bitstring tvb");
2404 out_tvb
= dissect_per_bit_string_display(fragmented_tvb
, 0, actx
, tree
, hf_index
, hfi
,
2405 fragmented_length
, named_bits
, num_named_bits
);
2408 out_tvb
= dissect_per_bit_string_display(tvb
, offset
, actx
, tree
, hf_index
, hfi
, length
, named_bits
, num_named_bits
);
2411 /*val_start = offset>>3;*/
2412 /*val_length = (length+7)/8;*/
2416 *value_tvb
= out_tvb
;
2418 *len
= fragmented_length
? fragmented_length
: length
;
2423 uint32_t dissect_per_bit_string_containing_pdu_new(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, bool has_extension
, dissector_t type_cb
)
2425 tvbuff_t
*val_tvb
= NULL
;
2426 proto_tree
*subtree
= tree
;
2428 offset
= dissect_per_bit_string(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
, NULL
, 0, &val_tvb
, NULL
);
2430 if (type_cb
&& val_tvb
) {
2431 subtree
= proto_item_add_subtree(actx
->created_item
, ett_per_containing
);
2432 type_cb(val_tvb
, actx
->pinfo
, subtree
, NULL
);
2438 /* this function dissects an OCTET STRING
2448 max_len or min_len == NO_BOUND means there is no lower/upper constraint
2450 hf_index can either be a FT_BYTES or an FT_STRING
2453 dissect_per_octet_string(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, bool has_extension
, tvbuff_t
**value_tvb
)
2455 int val_start
= 0, val_length
;
2456 uint32_t length
= 0, fragmented_length
= 0;
2457 header_field_info
*hfi
;
2458 bool is_fragmented
= false;
2459 tvbuff_t
*out_tvb
= NULL
, *fragment_tvb
= NULL
;
2461 hfi
= (hf_index
<= 0) ? NULL
: proto_registrar_get_nth(hf_index
);
2463 DEBUG_ENTRY("dissect_per_octet_string");
2465 if (has_extension
) { /* 16.3 an extension marker is present */
2466 bool extension_present
;
2467 offset
= dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_present
);
2468 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
2469 if (extension_present
) max_len
= NO_BOUND
; /* skip to 16.8 */
2472 if (min_len
== NO_BOUND
) {
2475 if (max_len
==0) { /* 16.5 if the length is 0 bytes there will be no encoding */
2476 val_start
= offset
>>3;
2479 } else if((min_len
==max_len
)&&(max_len
<=2)) {
2480 /* 16.6 if length is fixed and less than or equal to two bytes*/
2481 val_start
= offset
>>3;
2482 val_length
= min_len
;
2483 out_tvb
= tvb_new_octet_aligned(tvb
, offset
, val_length
* 8);
2484 /* Add new data source if the offet was unaligned */
2485 if ((offset
& 7) != 0) {
2486 add_new_data_source(actx
->pinfo
, out_tvb
, "Unaligned OCTET STRING");
2490 } else if ((min_len
==max_len
)&&(min_len
<65536)) {
2491 /* 16.7 if length is fixed and less than to 64k*/
2495 BYTE_ALIGN_OFFSET(offset
);
2497 val_start
= offset
>>3;
2498 val_length
= min_len
;
2499 out_tvb
= tvb_new_octet_aligned(tvb
, offset
, val_length
* 8);
2500 if ((offset
& 7) != 0) {
2501 add_new_data_source(actx
->pinfo
, out_tvb
, "Unaligned OCTET STRING");
2507 offset
= dissect_per_constrained_integer(tvb
, offset
, actx
, tree
,
2508 hf_per_octet_string_length
, min_len
, max_len
, &length
, false);
2510 if (!display_internal_per_fields
)
2511 proto_item_set_hidden(actx
->created_item
);
2514 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
,
2515 hf_per_octet_string_length
, &length
, &is_fragmented
);
2518 if(length
|| fragmented_length
){
2521 BYTE_ALIGN_OFFSET(offset
);
2523 if (is_fragmented
) {
2524 fragment_tvb
= tvb_new_octet_aligned(tvb
, offset
, length
* 8);
2525 if (fragmented_length
== 0)
2526 out_tvb
= tvb_new_composite();
2527 tvb_composite_append(out_tvb
, fragment_tvb
);
2528 offset
+= length
* 8;
2529 fragmented_length
+= length
;
2532 if (fragmented_length
) {
2534 tvb_composite_append(out_tvb
, tvb_new_octet_aligned(tvb
, offset
, length
* 8));
2535 fragmented_length
+= length
;
2537 tvb_composite_finalize(out_tvb
);
2538 add_new_data_source(actx
->pinfo
, out_tvb
, "Fragmented OCTET STRING");
2540 out_tvb
= tvb_new_octet_aligned(tvb
, offset
, length
* 8);
2541 if ((offset
& 7) != 0) {
2542 add_new_data_source(actx
->pinfo
, out_tvb
, "Unaligned OCTET STRING");
2546 val_start
= offset
>>3;
2548 val_length
= fragmented_length
? fragmented_length
: length
;
2553 if (FT_IS_UINT(hfi
->type
)||FT_IS_INT(hfi
->type
)) {
2554 /* If the type has been converted to FT_UINT or FT_INT in the .cnf file
2555 * display the length of this octet string instead of the octetstring itself
2557 if (FT_IS_UINT(hfi
->type
))
2558 actx
->created_item
= proto_tree_add_uint(tree
, hf_index
, out_tvb
, 0, val_length
, val_length
);
2560 actx
->created_item
= proto_tree_add_int(tree
, hf_index
, out_tvb
, 0, val_length
, val_length
);
2561 proto_item_append_text(actx
->created_item
, plurality(val_length
, " octet", " octets"));
2564 actx
->created_item
= proto_tree_add_item(tree
, hf_index
, out_tvb
, 0, val_length
, ENC_BIG_ENDIAN
);
2567 actx
->created_item
= proto_tree_add_item(tree
, hf_index
, tvb
, val_start
, val_length
, ENC_BIG_ENDIAN
);
2573 *value_tvb
= (out_tvb
) ? out_tvb
: tvb_new_subset_length(tvb
, val_start
, val_length
);
2578 uint32_t dissect_per_octet_string_containing_pdu_new(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int min_len
, int max_len
, bool has_extension
, dissector_t type_cb
)
2580 tvbuff_t
*val_tvb
= NULL
;
2581 proto_tree
*subtree
= tree
;
2583 offset
= dissect_per_octet_string(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
, &val_tvb
);
2585 if (type_cb
&& val_tvb
&& (tvb_reported_length(val_tvb
) > 0)) {
2586 subtree
= proto_item_add_subtree(actx
->created_item
, ett_per_containing
);
2587 type_cb(val_tvb
, actx
->pinfo
, subtree
, NULL
);
2593 uint32_t dissect_per_size_constrained_type(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, per_type_fn type_cb
, const char *name
, int min_len
, int max_len
, bool has_extension
)
2595 asn1_stack_frame_push(actx
, name
);
2596 asn1_param_push_integer(actx
, min_len
);
2597 asn1_param_push_integer(actx
, max_len
);
2598 asn1_param_push_boolean(actx
, has_extension
);
2600 offset
= type_cb(tvb
, offset
, actx
, tree
, hf_index
);
2602 asn1_stack_frame_pop(actx
, name
);
2607 bool get_size_constraint_from_stack(asn1_ctx_t
*actx
, const char *name
, int *pmin_len
, int *pmax_len
, bool *phas_extension
)
2611 if (pmin_len
) *pmin_len
= NO_BOUND
;
2612 if (pmax_len
) *pmax_len
= NO_BOUND
;
2613 if (phas_extension
) *phas_extension
= false;
2615 if (!actx
->stack
) return false;
2616 if (strcmp(actx
->stack
->name
, name
)) return false;
2618 par
= actx
->stack
->par
;
2619 if (!par
|| (par
->ptype
!= ASN1_PAR_INTEGER
)) return false;
2620 if (pmin_len
) *pmin_len
= par
->value
.v_integer
;
2622 if (!par
|| (par
->ptype
!= ASN1_PAR_INTEGER
)) return false;
2623 if (pmax_len
) *pmax_len
= par
->value
.v_integer
;
2625 if (!par
|| (par
->ptype
!= ASN1_PAR_BOOLEAN
)) return false;
2626 if (phas_extension
) *phas_extension
= par
->value
.v_boolean
;
2632 /* 26 Encoding of a value of the external type */
2634 /* code generated from definition in 26.1 */
2636 [UNIVERSAL 8] IMPLICIT SEQUENCE {
2637 direct-reference OBJECT IDENTIFIER OPTIONAL,
2638 indirect-reference INTEGER OPTIONAL,
2639 data-value-descriptor ObjectDescriptor OPTIONAL,
2641 single-ASN1-type [0] ABSTRACT-SYNTAX.&Type,
2642 octet-aligned [1] IMPLICIT OCTET STRING,
2643 arbitrary [2] IMPLICIT BIT STRING
2647 /* NOTE: This sequence type differs from that in ITU-T Rec. X.680 | ISO/IEC 8824-1 for historical reasons. */
2650 dissect_per_T_direct_reference(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
) {
2652 DISSECTOR_ASSERT(actx
);
2653 offset
= dissect_per_object_identifier_str(tvb
, offset
, actx
, tree
, hf_index
, &actx
->external
.direct_reference
);
2655 actx
->external
.direct_ref_present
= true;
2662 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_
) {
2663 offset
= dissect_per_integer(tvb
, offset
, actx
, tree
, hf_index
, &actx
->external
.indirect_reference
);
2665 actx
->external
.indirect_ref_present
= true;
2672 dissect_per_T_data_value_descriptor(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
) {
2673 offset
= dissect_per_object_descriptor(tvb
, offset
, actx
, tree
, hf_index
, &actx
->external
.data_value_descriptor
);
2675 actx
->external
.data_value_descr_present
= true;
2682 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_
) {
2683 offset
= dissect_per_open_type(tvb
, offset
, actx
, tree
, actx
->external
.hf_index
, actx
->external
.u
.per
.type_cb
);
2691 dissect_per_T_octet_aligned(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
) {
2692 offset
= dissect_per_octet_string(tvb
, offset
, actx
, tree
, hf_index
,
2693 NO_BOUND
, NO_BOUND
, false, &actx
->external
.octet_aligned
);
2695 if (actx
->external
.octet_aligned
) {
2696 if (actx
->external
.u
.per
.type_cb
) {
2697 actx
->external
.u
.per
.type_cb(actx
->external
.octet_aligned
, 0, actx
, tree
, actx
->external
.hf_index
);
2699 actx
->created_item
= proto_tree_add_expert(tree
, actx
->pinfo
, &ei_per_external_type
, actx
->external
.octet_aligned
, 0, -1);
2708 dissect_per_T_arbitrary(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
) {
2709 offset
= dissect_per_bit_string(tvb
, offset
, actx
, tree
, hf_index
,
2710 NO_BOUND
, NO_BOUND
, false, NULL
, 0, &actx
->external
.arbitrary
, NULL
);
2712 if (actx
->external
.arbitrary
) {
2713 if (actx
->external
.u
.per
.type_cb
) {
2714 actx
->external
.u
.per
.type_cb(actx
->external
.arbitrary
, 0, actx
, tree
, actx
->external
.hf_index
);
2716 actx
->created_item
= proto_tree_add_expert(tree
, actx
->pinfo
, &ei_per_external_type
, actx
->external
.arbitrary
, 0, -1);
2723 static const value_string per_External_encoding_vals
[] = {
2724 { 0, "single-ASN1-type" },
2725 { 1, "octet-aligned" },
2730 static const per_choice_t External_encoding_choice
[] = {
2731 { 0, &hf_per_single_ASN1_type
, ASN1_NO_EXTENSIONS
, dissect_per_T_single_ASN1_type
},
2732 { 1, &hf_per_octet_aligned
, ASN1_NO_EXTENSIONS
, dissect_per_T_octet_aligned
},
2733 { 2, &hf_per_arbitrary
, ASN1_NO_EXTENSIONS
, dissect_per_T_arbitrary
},
2734 { 0, NULL
, 0, NULL
}
2738 dissect_per_External_encoding(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
) {
2739 // This assertion is used to remove clang's warning.
2740 DISSECTOR_ASSERT(actx
);
2741 offset
= dissect_per_choice(tvb
, offset
, actx
, tree
, hf_index
,
2742 ett_per_External_encoding
, External_encoding_choice
,
2743 &actx
->external
.encoding
);
2749 static const per_sequence_t External_sequence
[] = {
2750 { &hf_per_direct_reference
, ASN1_NO_EXTENSIONS
, ASN1_OPTIONAL
, dissect_per_T_direct_reference
},
2751 { &hf_per_indirect_reference
, ASN1_NO_EXTENSIONS
, ASN1_OPTIONAL
, dissect_per_T_indirect_reference
},
2752 { &hf_per_data_value_descriptor
, ASN1_NO_EXTENSIONS
, ASN1_OPTIONAL
, dissect_per_T_data_value_descriptor
},
2753 { &hf_per_encoding
, ASN1_NO_EXTENSIONS
, ASN1_NOT_OPTIONAL
, dissect_per_External_encoding
},
2754 { NULL
, 0, 0, NULL
}
2758 dissect_per_External(tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
2759 offset
= dissect_per_sequence(tvb
, offset
, actx
, tree
, hf_index
,
2760 ett_per_External
, External_sequence
);
2766 dissect_per_external_type(tvbuff_t
*tvb _U_
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree _U_
, int hf_index _U_
, per_type_fn type_cb
)
2768 asn1_ctx_clean_external(actx
);
2769 actx
->external
.u
.per
.type_cb
= type_cb
;
2770 offset
= dissect_per_External(tvb
, offset
, actx
, tree
, hf_index
);
2772 asn1_ctx_clean_external(actx
);
2777 * Calls the callback defined with register_per_oid_dissector() if found.
2778 * Offset is in bits.
2782 call_per_oid_callback(const char *oid
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
, asn1_ctx_t
*actx
, int hf_index
)
2784 uint32_t type_length
, end_offset
, start_offset
;
2785 tvbuff_t
*val_tvb
= NULL
;
2787 start_offset
= offset
;
2788 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_open_type_length
, &type_length
, NULL
);
2789 if(type_length
== 0){
2790 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "unexpected length");
2792 if (actx
->aligned
) BYTE_ALIGN_OFFSET(offset
);
2793 end_offset
= offset
+ type_length
;
2796 /* length in bits */
2797 val_tvb
= tvb_new_octet_aligned(tvb
, offset
, type_length
* 8);
2798 if ((offset
& 7) != 0) {
2799 add_new_data_source(actx
->pinfo
, val_tvb
, "Unaligned OCTET STRING");
2803 (dissector_try_string(per_oid_dissector_table
, oid
, val_tvb
, pinfo
, tree
, actx
)) == 0)
2805 proto_tree_add_expert(tree
, pinfo
, &ei_per_oid_not_implemented
, val_tvb
, 0, -1);
2806 dissect_per_open_type(tvb
, start_offset
, actx
, tree
, hf_index
, NULL
);
2813 register_per_oid_dissector(const char *oid
, dissector_t dissector
, int proto
, const char *name
)
2815 dissector_handle_t dissector_handle
;
2817 /* FIXME: This would be better as register_dissector()
2818 * so the dissector could be referenced by name
2819 * from the command line, Lua, etc.
2820 * But can we blindly trust name to be a unique dissector name,
2821 * or should we prefix "per." or something?
2823 dissector_handle
= create_dissector_handle(dissector
, proto
);
2824 dissector_add_string("per.oid", oid
, dissector_handle
);
2825 oid_add_from_string(name
, oid
);
2830 proto_register_per(void)
2832 static hf_register_info hf
[] = {
2833 { &hf_per_num_sequence_extensions
,
2834 { "Number of Sequence Extensions", "per.num_sequence_extensions", FT_UINT32
, BASE_DEC
,
2835 NULL
, 0, "Number of extensions encoded in this sequence", HFILL
}},
2836 { &hf_per_choice_index
,
2837 { "Choice Index", "per.choice_index", FT_UINT32
, BASE_DEC
,
2838 NULL
, 0, "Which index of the Choice within extension root is encoded", HFILL
}},
2839 { &hf_per_choice_extension_index
,
2840 { "Choice Extension Index", "per.choice_extension_index", FT_UINT32
, BASE_DEC
,
2841 NULL
, 0, "Which index of the Choice within extension addition is encoded", HFILL
}},
2842 { &hf_per_enum_index
,
2843 { "Enumerated Index", "per.enum_index", FT_UINT32
, BASE_DEC
,
2844 NULL
, 0, "Which index of the Enumerated within extension root is encoded", HFILL
}},
2845 { &hf_per_enum_extension_index
,
2846 { "Enumerated Extension Index", "per.enum_extension_index", FT_UINT32
, BASE_DEC
,
2847 NULL
, 0, "Which index of the Enumerated within extension addition is encoded", HFILL
}},
2848 { &hf_per_GeneralString_length
,
2849 { "GeneralString Length", "per.generalstring_length", FT_UINT32
, BASE_DEC
,
2850 NULL
, 0, "Length of the GeneralString", HFILL
}},
2851 { &hf_per_extension_bit
,
2852 { "Extension Bit", "per.extension_bit", FT_BOOLEAN
, 8,
2853 TFS(&tfs_extension_bit
), 0x01, "The extension bit of an aggregate", HFILL
}},
2854 { &hf_per_extension_present_bit
,
2855 { "Extension Present Bit", "per.extension_present_bit", FT_BOOLEAN
, 8,
2856 NULL
, 0x01, "Whether this optional extension is present or not", HFILL
}},
2857 { &hf_per_small_number_bit
,
2858 { "Small Number Bit", "per.small_number_bit", FT_BOOLEAN
, 8,
2859 TFS(&tfs_small_number_bit
), 0x01, "The small number bit for a section 10.6 integer", HFILL
}},
2860 { &hf_per_optional_field_bit
,
2861 { "Optional Field Bit", "per.optional_field_bit", FT_BOOLEAN
, 8,
2862 NULL
, 0x01, "This bit specifies the presence/absence of an optional field", HFILL
}},
2863 { &hf_per_sequence_of_length
,
2864 { "Sequence-Of Length", "per.sequence_of_length", FT_UINT32
, BASE_DEC
,
2865 NULL
, 0, "Number of items in the Sequence Of", HFILL
}},
2866 { &hf_per_object_identifier_length
,
2867 { "Object Identifier Length", "per.object_length", FT_UINT32
, BASE_DEC
,
2868 NULL
, 0, "Length of the object identifier", HFILL
}},
2869 { &hf_per_open_type_length
,
2870 { "Open Type Length", "per.open_type_length", FT_UINT32
, BASE_DEC
,
2871 NULL
, 0, "Length of an open type encoding", HFILL
}},
2872 { &hf_per_real_length
,
2873 { "Real Length", "per.real_length", FT_UINT32
, BASE_DEC
,
2874 NULL
, 0, "Length of an real encoding", HFILL
}},
2875 { &hf_per_octet_string_length
,
2876 { "Octet String Length", "per.octet_string_length", FT_UINT32
, BASE_DEC
,
2877 NULL
, 0, "Number of bytes in the Octet String", HFILL
}},
2878 { &hf_per_bit_string_length
,
2879 { "Bit String Length", "per.bit_string_length", FT_UINT32
, BASE_DEC
,
2880 NULL
, 0, "Number of bits in the Bit String", HFILL
}},
2881 { &hf_per_normally_small_nonnegative_whole_number_length
,
2882 { "Normally Small Non-negative Whole Number Length", "per.normally_small_nonnegative_whole_number_length", FT_UINT32
, BASE_DEC
,
2883 NULL
, 0, "Number of bytes in the Normally Small Non-negative Whole Number", HFILL
}},
2884 { &hf_per_const_int_len
,
2885 { "Constrained Integer Length", "per.const_int_len", FT_UINT32
, BASE_DEC
,
2886 NULL
, 0, "Number of bytes in the Constrained Integer", HFILL
}},
2887 { &hf_per_direct_reference
,
2888 { "direct-reference", "per.direct_reference",
2889 FT_OID
, BASE_NONE
, NULL
, 0,
2890 "per.T_direct_reference", HFILL
}},
2891 { &hf_per_indirect_reference
,
2892 { "indirect-reference", "per.indirect_reference",
2893 FT_INT32
, BASE_DEC
, NULL
, 0,
2894 "per.T_indirect_reference", HFILL
}},
2895 { &hf_per_data_value_descriptor
,
2896 { "data-value-descriptor", "per.data_value_descriptor",
2897 FT_STRING
, BASE_NONE
, NULL
, 0,
2898 "per.T_data_value_descriptor", HFILL
}},
2900 { "encoding", "per.encoding",
2901 FT_UINT32
, BASE_DEC
, VALS(per_External_encoding_vals
), 0,
2902 "per.External_encoding", HFILL
}},
2903 { &hf_per_single_ASN1_type
,
2904 { "single-ASN1-type", "per.single_ASN1_type",
2905 FT_NONE
, BASE_NONE
, NULL
, 0,
2906 "per.T_single_ASN1_type", HFILL
}},
2907 { &hf_per_octet_aligned
,
2908 { "octet-aligned", "per.octet_aligned",
2909 FT_BYTES
, BASE_NONE
, NULL
, 0,
2910 "per.T_octet_aligned", HFILL
}},
2911 { &hf_per_arbitrary
,
2912 { "arbitrary", "per.arbitrary",
2913 FT_BYTES
, BASE_NONE
, NULL
, 0,
2914 "per.T_arbitrary", HFILL
}},
2915 { &hf_per_integer_length
,
2916 { "integer length", "per.integer_length",
2917 FT_UINT32
, BASE_DEC
, NULL
, 0,
2920 { &hf_per_debug_pos
,
2921 { "Current bit offset", "per.debug_pos",
2922 FT_UINT32
, BASE_DEC
, NULL
, 0,
2925 { &hf_per_internal_range
,
2926 { "Range", "per.internal.range",
2927 FT_UINT64
, BASE_DEC
, NULL
, 0,
2929 { &hf_per_internal_num_bits
,
2930 { "Bitfield length", "per.internal.num_bits",
2931 FT_UINT32
, BASE_DEC
, NULL
, 0,
2933 { &hf_per_internal_min
,
2934 { "Min", "per.internal.min",
2935 FT_UINT32
, BASE_DEC
, NULL
, 0,
2937 { &hf_per_internal_value
,
2938 { "Bits", "per.internal.value",
2939 FT_UINT64
, BASE_DEC
, NULL
, 0,
2941 { &hf_per_internal_min_int
,
2942 { "Min", "per.internal.min_int",
2943 FT_INT32
, BASE_DEC
, NULL
, 0,
2945 { &hf_per_internal_value_int
,
2946 { "Bits", "per.internal.value_int",
2947 FT_INT64
, BASE_DEC
, NULL
, 0,
2949 { &hf_per_encoding_boiler_plate
,
2950 { "PER encoded protocol, to see PER internal fields set protocol PER preferences", "per.encoding_boiler_plate",
2951 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2956 static int *ett
[] = {
2958 &ett_per_containing
,
2959 &ett_per_sequence_of_item
,
2961 &ett_per_External_encoding
,
2962 &ett_per_named_bits
,
2964 static ei_register_info ei
[] = {
2965 { &ei_per_size_constraint_value
,
2966 { "per.size_constraint.value", PI_PROTOCOL
, PI_WARN
, "Size constraint: value too big", EXPFILL
}},
2967 { &ei_per_size_constraint_too_few
,
2968 { "per.size_constraint.too_few", PI_PROTOCOL
, PI_WARN
, "Size constraint: too few items", EXPFILL
}},
2969 { &ei_per_size_constraint_too_many
,
2970 { "per.size_constraint.too_many", PI_PROTOCOL
, PI_WARN
, "Size constraint: too many items", EXPFILL
}},
2971 { &ei_per_choice_extension_unknown
,
2972 { "per.choice_extension_unknown", PI_UNDECODED
, PI_NOTE
, "unknown choice extension", EXPFILL
}},
2973 { &ei_per_sequence_extension_unknown
,
2974 { "per.sequence_extension_unknown", PI_UNDECODED
, PI_NOTE
, "unknown sequence extension", EXPFILL
}},
2975 { &ei_per_encoding_error
,
2976 { "per.encoding_error", PI_MALFORMED
, PI_WARN
, "Encoding error", EXPFILL
}},
2977 { &ei_per_oid_not_implemented
,
2978 { "per.error.oid_not_implemented", PI_UNDECODED
, PI_WARN
, "PER: Dissector for OID not implemented. Contact Wireshark developers if you want this supported", EXPFILL
}},
2979 { &ei_per_undecoded
,
2980 { "per.error.undecoded", PI_UNDECODED
, PI_WARN
, "PER: Something unknown here", EXPFILL
}},
2981 { &ei_per_field_not_integer
,
2982 { "per.field_not_integer", PI_PROTOCOL
, PI_ERROR
, "Field is not an integer", EXPFILL
}},
2983 { &ei_per_external_type
,
2984 { "per.external_type.unknown", PI_PROTOCOL
, PI_WARN
, "Unknown EXTERNAL Type", EXPFILL
}},
2985 { &ei_per_open_type
,
2986 { "per.open_type.unknown", PI_PROTOCOL
, PI_WARN
, "Unknown Open Type", EXPFILL
}},
2987 { &ei_per_open_type_len
,
2988 { "per.open_type.len", PI_PROTOCOL
, PI_ERROR
, "Open Type length > available data(tvb)", EXPFILL
}}
2991 module_t
*per_module
;
2992 expert_module_t
* expert_per
;
2994 proto_per
= proto_register_protocol("Packed Encoding Rules (ASN.1 X.691)", "PER", "per");
2995 proto_register_field_array(proto_per
, hf
, array_length(hf
));
2996 proto_register_subtree_array(ett
, array_length(ett
));
2997 expert_per
= expert_register_protocol(proto_per
);
2998 expert_register_field_array(expert_per
, ei
, array_length(ei
));
3000 proto_set_cant_toggle(proto_per
);
3002 per_module
= prefs_register_protocol(proto_per
, NULL
);
3003 prefs_register_bool_preference(per_module
, "display_internal_per_fields",
3004 "Display the internal PER fields in the tree",
3005 "Whether the dissector should put the internal PER data in the tree or if it should hide it",
3006 &display_internal_per_fields
);
3008 per_oid_dissector_table
= register_dissector_table("per.oid", "PER OID", proto_per
, FT_STRING
, STRING_CASE_SENSITIVE
);
3014 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3019 * indent-tabs-mode: t
3022 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3023 * :indentSize=8:tabSize=8:noTabs=false: