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 offset 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 (actx
->aligned
) BYTE_ALIGN_OFFSET(offset
);
1760 val_tvb
= tvb_new_octet_aligned(tvb
, offset
, val_length
* 8);
1761 /* Add new data source if the offet was unaligned */
1762 if ((offset
& 7) != 0) {
1763 add_new_data_source(actx
->pinfo
, val_tvb
, "Unaligned OCTET STRING");
1765 end_offset
= offset
+ val_length
* 8;
1767 val
= asn1_get_real(tvb_get_ptr(val_tvb
, 0, val_length
), val_length
);
1768 actx
->created_item
= proto_tree_add_double(tree
, hf_index
, val_tvb
, 0, val_length
, val
);
1770 if (value
) *value
= val
;
1775 /* 22 Encoding the choice type */
1777 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
)
1779 bool /*extension_present,*/ extension_flag
;
1780 int extension_root_entries
;
1781 uint32_t choice_index
;
1783 uint32_t ext_length
= 0;
1784 uint32_t old_offset
= offset
;
1785 proto_item
*choice_item
= NULL
;
1786 proto_tree
*choice_tree
= NULL
;
1788 DEBUG_ENTRY("dissect_per_choice");
1790 if (value
) *value
= -1;
1793 if (choice
[0].extension
== ASN1_NO_EXTENSIONS
){
1794 /*extension_present = false; ?? */
1795 extension_flag
= false;
1797 /*extension_present = true; ?? */
1798 offset
= dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_bit
, &extension_flag
);
1799 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
1802 /* count the number of entries in the extension root and extension addition */
1803 extension_root_entries
= 0;
1804 for (i
=0; choice
[i
].p_id
; i
++) {
1805 switch(choice
[i
].extension
){
1806 case ASN1_NO_EXTENSIONS
:
1807 case ASN1_EXTENSION_ROOT
:
1808 extension_root_entries
++;
1810 case ASN1_NOT_EXTENSION_ROOT
:
1815 if (!extension_flag
) { /* 22.6, 22.7 */
1816 if (extension_root_entries
== 1) { /* 22.5 */
1819 offset
= dissect_per_constrained_integer(tvb
, offset
, actx
,
1820 tree
, hf_per_choice_index
, 0, extension_root_entries
- 1,
1821 &choice_index
, false);
1822 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
1825 idx
= -1; cidx
= choice_index
;
1826 for (i
=0; choice
[i
].p_id
; i
++) {
1827 if(choice
[i
].extension
!= ASN1_NOT_EXTENSION_ROOT
){
1828 if (!cidx
) { idx
= i
; break; }
1833 offset
= dissect_per_normally_small_nonnegative_whole_number(tvb
, offset
, actx
, tree
, hf_per_choice_extension_index
, &choice_index
);
1834 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_open_type_length
, &ext_length
, NULL
);
1836 idx
= -1; cidx
= choice_index
;
1837 for (i
=0; choice
[i
].p_id
; i
++) {
1838 if(choice
[i
].extension
== ASN1_NOT_EXTENSION_ROOT
){
1839 if (!cidx
) { idx
= i
; break; }
1846 choice_item
= proto_tree_add_uint(tree
, hf_index
, tvb
, old_offset
>>3, 0, choice
[idx
].value
);
1847 choice_tree
= proto_item_add_subtree(choice_item
, ett_index
);
1848 if (!extension_flag
) {
1849 offset
= choice
[idx
].func(tvb
, offset
, actx
, choice_tree
, *choice
[idx
].p_id
);
1851 choice
[idx
].func(tvb
, offset
, actx
, choice_tree
, *choice
[idx
].p_id
);
1852 offset
+= ext_length
* 8;
1854 proto_item_set_len(choice_item
, BLEN(old_offset
, offset
));
1856 if (!extension_flag
) {
1857 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "unknown extension root index in choice");
1859 offset
+= ext_length
* 8;
1860 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_per_choice_extension_unknown
,
1861 tvb
, old_offset
>>3, BLEN(old_offset
, offset
),
1862 "Choice no. %d in extension", choice_index
);
1866 if (value
&& (idx
!= -1))
1867 *value
= choice
[idx
].value
;
1874 index_get_optional_name(const per_sequence_t
*sequence
, int idx
)
1877 header_field_info
*hfi
;
1879 for(i
=0;sequence
[i
].p_id
;i
++){
1880 if((sequence
[i
].extension
!=ASN1_NOT_EXTENSION_ROOT
)&&(sequence
[i
].optional
==ASN1_OPTIONAL
)){
1882 hfi
= proto_registrar_get_nth(*sequence
[i
].p_id
);
1883 return (hfi
) ? hfi
->name
: "<unknown field>";
1888 return "<unknown type>";
1892 index_get_extension_name(const per_sequence_t
*sequence
, int idx
)
1895 header_field_info
*hfi
;
1897 for(i
=0;sequence
[i
].p_id
;i
++){
1898 if(sequence
[i
].extension
==ASN1_NOT_EXTENSION_ROOT
){
1900 if (*sequence
[i
].p_id
== -1 || *sequence
[i
].p_id
== 0) return "extension addition group";
1901 hfi
= proto_registrar_get_nth(*sequence
[i
].p_id
);
1902 return (hfi
) ? hfi
->name
: "<unknown field>";
1907 return "<unknown type>";
1911 index_get_field_name(const per_sequence_t
*sequence
, int idx
)
1914 header_field_info
*hfi
= proto_registrar_get_nth(*sequence
[idx
].p_id
);
1920 return "<unknown field>";
1923 /* this functions decodes a SEQUENCE
1924 it can only handle SEQUENCES with at most 32 DEFAULT or OPTIONAL fields
1926 18.2 optional/default items in root
1927 18.3 we ignore the case where n>64K
1928 18.4 the root sequence
1936 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
)
1938 bool /*extension_present,*/ extension_flag
, optional_field_flag
;
1941 uint32_t old_offset
=offset
;
1942 uint32_t i
, j
, num_opts
;
1943 uint32_t optional_mask
[SEQ_MAX_COMPONENTS
>>5];
1945 DEBUG_ENTRY("dissect_per_sequence");
1946 DISSECTOR_ASSERT(sequence
);
1948 item
=proto_tree_add_item(parent_tree
, hf_index
, tvb
, offset
>>3, 0, ENC_BIG_ENDIAN
);
1949 tree
=proto_item_add_subtree(item
, ett_index
);
1952 /* first check if there should be an extension bit for this CHOICE.
1953 we do this by just checking the first choice arm
1957 if(sequence
[0].extension
==ASN1_NO_EXTENSIONS
){
1958 /*extension_present=0; ?? */
1960 /*extension_present=1; ?? */
1961 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_bit
, &extension_flag
);
1962 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
1966 for(i
=0;sequence
[i
].p_id
;i
++){
1967 if((sequence
[i
].extension
!=ASN1_NOT_EXTENSION_ROOT
)&&(sequence
[i
].optional
==ASN1_OPTIONAL
)){
1971 if (num_opts
> SEQ_MAX_COMPONENTS
) {
1972 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "too many optional/default components");
1975 memset(optional_mask
, 0, sizeof(optional_mask
));
1976 for(i
=0;i
<num_opts
;i
++){
1977 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_optional_field_bit
, &optional_field_flag
);
1979 proto_item_append_text(actx
->created_item
, " (%s %s present)",
1980 index_get_optional_name(sequence
, i
), optional_field_flag
?"is":"is NOT");
1982 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
1983 if(optional_field_flag
){
1984 optional_mask
[i
>>5]|=0x80000000>>(i
&0x1f);
1990 for(i
=0,j
=0;sequence
[i
].p_id
;i
++){
1991 if( (sequence
[i
].extension
==ASN1_NO_EXTENSIONS
)
1992 || (sequence
[i
].extension
==ASN1_EXTENSION_ROOT
) ){
1993 if(sequence
[i
].optional
==ASN1_OPTIONAL
){
1998 is_present
=(0x80000000>>(j
&0x1f))&optional_mask
[j
>>5];
2005 if(sequence
[i
].func
){
2006 offset
=sequence
[i
].func(tvb
, offset
, actx
, tree
, *sequence
[i
].p_id
);
2008 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, index_get_field_name(sequence
, i
));
2016 uint32_t num_known_extensions
;
2017 uint32_t num_extensions
;
2018 uint32_t extension_mask
;
2020 offset
=dissect_per_normally_small_nonnegative_whole_number(tvb
, offset
, actx
, tree
, hf_per_num_sequence_extensions
, &num_extensions
);
2021 /* the X.691 standard is VERY unclear here.
2022 there is no mention that the lower bound lb for this
2023 (apparently) semiconstrained value is 1,
2024 apart from the NOTE: comment in 18.8 that this value can
2026 In my book, there is a semantic difference between having
2027 a comment that says that the value can not be zero
2028 and stating that the lb is 1.
2029 I don't know if this is right or not but it makes
2030 some of the very few captures I have decode properly.
2032 It could also be that the captures I have are generated by
2033 a broken implementation.
2034 If this is wrong and you don't report it as a bug
2035 then it won't get fixed!
2038 if (num_extensions
> 32) {
2039 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "too many extensions");
2043 for(i
=0;i
<num_extensions
;i
++){
2044 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_bit
);
2046 proto_item_append_text(actx
->created_item
, " (%s %s present)",
2047 index_get_extension_name(sequence
, i
), extension_bit
?"is":"is NOT");
2049 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
2051 extension_mask
=(extension_mask
<<1)|extension_bit
;
2054 /* find how many extensions we know about */
2055 num_known_extensions
=0;
2056 for(i
=0;sequence
[i
].p_id
;i
++){
2057 if(sequence
[i
].extension
==ASN1_NOT_EXTENSION_ROOT
){
2058 num_known_extensions
++;
2062 /* decode the extensions one by one */
2063 for(i
=0;i
<num_extensions
;i
++){
2065 uint32_t new_offset
;
2067 uint32_t extension_index
;
2070 if(!((1U<<(num_extensions
-1-i
))&extension_mask
)){
2071 /* this extension is not encoded in this PDU */
2075 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_open_type_length
, &length
, NULL
);
2077 if(i
>=num_known_extensions
){
2078 /* we don't know how to decode this extension */
2080 expert_add_info(actx
->pinfo
, item
, &ei_per_sequence_extension_unknown
);
2085 for(j
=0,k
=0;sequence
[j
].p_id
;j
++){
2086 if(sequence
[j
].extension
==ASN1_NOT_EXTENSION_ROOT
){
2095 if(sequence
[extension_index
].func
){
2096 new_offset
=sequence
[extension_index
].func(tvb
, offset
, actx
, tree
, *sequence
[extension_index
].p_id
);
2098 difference
= offset
- new_offset
;
2099 /* A difference of 7 or less might be byte aligning */
2100 /* Difference could be 8 if open type has no bits and the length is 1 */
2101 if ((length
> 1) && (difference
> 7)) {
2102 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_per_encoding_error
, tvb
, new_offset
>>3, (offset
-new_offset
)>>3,
2103 "Possible encoding error full length not decoded. Open type length %u, decoded %u",length
, length
- (difference
>>3));
2105 else if (difference
< 0) {
2106 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_per_encoding_error
, tvb
, new_offset
>>3, (offset
-new_offset
)>>3,
2107 "Possible encoding error open type length less than dissected bits. Open type length %u, decoded %u", length
, length
- (difference
>>3));
2110 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, index_get_field_name(sequence
, extension_index
));
2116 proto_item_set_len(item
, (offset
>>3)!=(old_offset
>>3)?(offset
>>3)-(old_offset
>>3):1);
2117 actx
->created_item
= item
;
2122 dissect_per_sequence_eag(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, const per_sequence_t
*sequence
)
2124 bool optional_field_flag
;
2125 uint32_t i
, j
, num_opts
;
2126 uint32_t optional_mask
[SEQ_MAX_COMPONENTS
>>5];
2128 DEBUG_ENTRY("dissect_per_sequence_eag");
2131 for(i
=0;sequence
[i
].p_id
;i
++){
2132 if(sequence
[i
].optional
==ASN1_OPTIONAL
){
2136 if (num_opts
> SEQ_MAX_COMPONENTS
) {
2137 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "too many optional/default components");
2140 memset(optional_mask
, 0, sizeof(optional_mask
));
2141 for(i
=0;i
<num_opts
;i
++){
2142 offset
=dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_optional_field_bit
, &optional_field_flag
);
2144 proto_item_append_text(actx
->created_item
, " (%s %s present)",
2145 index_get_optional_name(sequence
, i
), optional_field_flag
?"is":"is NOT");
2147 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
2148 if(optional_field_flag
){
2149 optional_mask
[i
>>5]|=0x80000000>>(i
&0x1f);
2153 for(i
=0,j
=0;sequence
[i
].p_id
;i
++){
2154 if(sequence
[i
].optional
==ASN1_OPTIONAL
){
2159 is_present
=(0x80000000>>(j
&0x1f))&optional_mask
[j
>>5];
2166 if(sequence
[i
].func
){
2167 offset
=sequence
[i
].func(tvb
, offset
, actx
, tree
, *sequence
[i
].p_id
);
2169 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, index_get_field_name(sequence
, i
));
2177 /* 15 Encoding the bitstring type
2179 max_len or min_len == NO_BOUND means there is no lower/upper constraint
2183 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_
)
2185 tvbuff_t
*out_tvb
= NULL
;
2186 uint32_t pad_length
=0;
2189 out_tvb
= tvb_new_octet_aligned(tvb
, offset
, length
);
2190 add_new_data_source(actx
->pinfo
, out_tvb
, "Bitstring tvb");
2193 actx
->created_item
= proto_tree_add_item(tree
, hf_index
, out_tvb
, 0, -1, ENC_BIG_ENDIAN
);
2194 proto_item_append_text(actx
->created_item
, " [bit length %u", length
);
2196 pad_length
= 8-(length
%8);
2197 proto_item_append_text(actx
->created_item
, ", %u LSB pad bits", pad_length
);
2200 if (length
<=64) { /* if read into 64 bits also handle length <= 24, 40, 48, 56 bits */
2202 value
= tvb_get_bits8(out_tvb
, 0, length
);
2203 }else if (length
<=16) {
2204 value
= tvb_get_bits16(out_tvb
, 0, length
, ENC_BIG_ENDIAN
);
2205 }else if (length
<=24) { /* first read 16 and then the remaining bits */
2206 value
= tvb_get_bits16(out_tvb
, 0, 16, ENC_BIG_ENDIAN
);
2207 value
<<= 8 - pad_length
;
2208 value
|= tvb_get_bits8(out_tvb
, 16, length
- 16);
2209 }else if (length
<=32) {
2210 value
= tvb_get_bits32(out_tvb
, 0, length
, ENC_BIG_ENDIAN
);
2211 }else if (length
<=40) { /* first read 32 and then the remaining bits */
2212 value
= tvb_get_bits32(out_tvb
, 0, 32, ENC_BIG_ENDIAN
);
2213 value
<<= 8 - pad_length
;
2214 value
|= tvb_get_bits8(out_tvb
, 32, length
- 32);
2215 }else if (length
<=48) { /* first read 32 and then the remaining bits */
2216 value
= tvb_get_bits32(out_tvb
, 0, 32, ENC_BIG_ENDIAN
);
2217 value
<<= 16 - pad_length
;
2218 value
|= tvb_get_bits16(out_tvb
, 32, length
- 32, ENC_BIG_ENDIAN
);
2219 }else if (length
<=56) { /* first read 32 and 16 then the remaining bits */
2220 value
= tvb_get_bits32(out_tvb
, 0, 32, ENC_BIG_ENDIAN
);
2222 value
|= tvb_get_bits16(out_tvb
, 32, 16, ENC_BIG_ENDIAN
);
2223 value
<<= 8 - pad_length
;
2224 value
|= tvb_get_bits8(out_tvb
, 48, length
- 48);
2226 value
= tvb_get_bits64(out_tvb
, 0, length
, ENC_BIG_ENDIAN
);
2228 proto_item_append_text(actx
->created_item
, ", %s decimal value %" PRIu64
,
2229 decode_bits_in_field(actx
->pinfo
->pool
, 0, length
, value
, ENC_BIG_ENDIAN
), value
);
2231 const uint32_t named_bits_bytelen
= (num_named_bits
+ 7) / 8;
2232 proto_tree
*subtree
= proto_item_add_subtree(actx
->created_item
, ett_per_named_bits
);
2233 for (uint32_t i
= 0; i
< named_bits_bytelen
; i
++) {
2234 // If less data is available than the number of named bits, then
2235 // the trailing (right) bits are assumed to be 0.
2237 const uint32_t bit_offset
= 8 * i
;
2238 if (bit_offset
< length
) {
2239 value
= tvb_get_uint8(out_tvb
, i
);
2242 // Process 8 bits at a time instead of 64, each field masks a
2244 int* const * section_named_bits
= named_bits
+ bit_offset
;
2246 if (num_named_bits
- bit_offset
> 8) {
2247 memcpy(&flags
[0], named_bits
+ bit_offset
, 8 * sizeof(int*));
2249 section_named_bits
= flags
;
2252 // TODO should non-zero pad bits be masked from the value?
2253 // When trailing zeroes are not present in the data, mark the
2254 // last byte for the lack of a better alternative.
2255 proto_tree_add_bitmask_list_value(subtree
, out_tvb
, offset
+ MIN(i
, length
- 1), 1, section_named_bits
, value
);
2259 proto_item_append_text(actx
->created_item
, "]");
2265 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
)
2267 /*int val_start, val_length;*/
2268 uint32_t length
, fragmented_length
= 0;
2269 header_field_info
*hfi
;
2270 bool is_fragmented
= false;
2271 tvbuff_t
*fragmented_tvb
= NULL
, *out_tvb
= NULL
, *fragment_tvb
= NULL
;
2273 hfi
= (hf_index
<= 0) ? NULL
: proto_registrar_get_nth(hf_index
);
2275 DEBUG_ENTRY("dissect_per_bit_string");
2276 /* 15.8 if the length is 0 bytes there will be no encoding */
2279 *value_tvb
= out_tvb
;
2285 if (min_len
== NO_BOUND
) {
2288 /* 15.6 If an extension marker is present in the size constraint specification of the bitstring type,
2289 * a single bit shall be added to the field-list in a bit-field of length one.
2290 * The bit shall be set to 1 if the length of this encoding is not within the range of the extension root,
2291 * and zero otherwise.
2293 if (has_extension
) {
2294 bool extension_present
;
2295 offset
= dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_present
);
2296 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
2297 if(extension_present
){
2299 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_bit_string_length
, &length
, &is_fragmented
);
2300 if(length
|| fragmented_length
){
2303 BYTE_ALIGN_OFFSET(offset
);
2306 fragment_tvb
= tvb_new_octet_aligned(tvb
, offset
, length
);
2307 if(fragmented_length
==0)
2308 fragmented_tvb
= tvb_new_composite();
2309 tvb_composite_append(fragmented_tvb
, fragment_tvb
);
2311 fragmented_length
+= length
;
2312 goto next_fragment1
;
2314 if(fragmented_length
){
2316 tvb_composite_append(fragmented_tvb
, tvb_new_octet_aligned(tvb
, offset
, length
));
2317 fragmented_length
+= length
;
2319 tvb_composite_finalize(fragmented_tvb
);
2320 add_new_data_source(actx
->pinfo
, fragmented_tvb
, "Fragmented bitstring tvb");
2321 out_tvb
= dissect_per_bit_string_display(fragmented_tvb
, 0, actx
, tree
, hf_index
, hfi
,
2322 fragmented_length
, named_bits
, num_named_bits
);
2325 out_tvb
= dissect_per_bit_string_display(tvb
, offset
, actx
, tree
, hf_index
, hfi
, length
, named_bits
, num_named_bits
);
2328 /*val_start = offset>>3;*/
2329 /*val_length = (length+7)/8;*/
2333 *value_tvb
= out_tvb
;
2335 *len
= fragmented_length
? fragmented_length
: length
;
2341 /* 15.9 if length is fixed and less than or equal to sixteen bits*/
2342 if ((min_len
==max_len
) && (max_len
<=16)) {
2343 out_tvb
= dissect_per_bit_string_display(tvb
, offset
, actx
, tree
, hf_index
, hfi
, min_len
, named_bits
, num_named_bits
);
2346 *value_tvb
= out_tvb
;
2353 /* 15.10 if length is fixed and less than to 64kbits*/
2354 if((min_len
==max_len
)&&(min_len
<65536)){
2355 /* (octet-aligned in the ALIGNED variant)
2359 BYTE_ALIGN_OFFSET(offset
);
2361 out_tvb
= dissect_per_bit_string_display(tvb
, offset
, actx
, tree
, hf_index
, hfi
, min_len
, named_bits
, num_named_bits
);
2364 *value_tvb
= out_tvb
;
2371 if (max_len
!= NO_BOUND
&& max_len
< 65536) {
2372 offset
=dissect_per_constrained_integer(tvb
, offset
, actx
,
2373 tree
, hf_per_bit_string_length
, min_len
, max_len
,
2375 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
2378 offset
=dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_bit_string_length
, &length
, &is_fragmented
);
2380 if(length
|| fragmented_length
){
2383 BYTE_ALIGN_OFFSET(offset
);
2386 fragment_tvb
= tvb_new_octet_aligned(tvb
, offset
, length
);
2387 if(fragmented_length
==0)
2388 fragmented_tvb
= tvb_new_composite();
2389 tvb_composite_append(fragmented_tvb
, fragment_tvb
);
2391 fragmented_length
+= length
;
2392 goto next_fragment2
;
2394 if(fragmented_length
){
2396 tvb_composite_append(fragmented_tvb
, tvb_new_octet_aligned(tvb
, offset
, length
));
2397 fragmented_length
+= length
;
2399 tvb_composite_finalize(fragmented_tvb
);
2400 add_new_data_source(actx
->pinfo
, fragmented_tvb
, "Fragmented bitstring tvb");
2401 out_tvb
= dissect_per_bit_string_display(fragmented_tvb
, 0, actx
, tree
, hf_index
, hfi
,
2402 fragmented_length
, named_bits
, num_named_bits
);
2405 out_tvb
= dissect_per_bit_string_display(tvb
, offset
, actx
, tree
, hf_index
, hfi
, length
, named_bits
, num_named_bits
);
2408 /*val_start = offset>>3;*/
2409 /*val_length = (length+7)/8;*/
2413 *value_tvb
= out_tvb
;
2415 *len
= fragmented_length
? fragmented_length
: length
;
2420 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
)
2422 tvbuff_t
*val_tvb
= NULL
;
2423 proto_tree
*subtree
= tree
;
2425 offset
= dissect_per_bit_string(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
, NULL
, 0, &val_tvb
, NULL
);
2427 if (type_cb
&& val_tvb
) {
2428 subtree
= proto_item_add_subtree(actx
->created_item
, ett_per_containing
);
2429 type_cb(val_tvb
, actx
->pinfo
, subtree
, NULL
);
2435 /* this function dissects an OCTET STRING
2445 max_len or min_len == NO_BOUND means there is no lower/upper constraint
2447 hf_index can either be a FT_BYTES or an FT_STRING
2450 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
)
2452 int val_start
= 0, val_length
;
2453 uint32_t length
= 0, fragmented_length
= 0;
2454 header_field_info
*hfi
;
2455 bool is_fragmented
= false;
2456 tvbuff_t
*out_tvb
= NULL
, *fragment_tvb
= NULL
;
2458 hfi
= (hf_index
<= 0) ? NULL
: proto_registrar_get_nth(hf_index
);
2460 DEBUG_ENTRY("dissect_per_octet_string");
2462 if (has_extension
) { /* 16.3 an extension marker is present */
2463 bool extension_present
;
2464 offset
= dissect_per_boolean(tvb
, offset
, actx
, tree
, hf_per_extension_present_bit
, &extension_present
);
2465 if (!display_internal_per_fields
) proto_item_set_hidden(actx
->created_item
);
2466 if (extension_present
) max_len
= NO_BOUND
; /* skip to 16.8 */
2469 if (min_len
== NO_BOUND
) {
2472 if (max_len
==0) { /* 16.5 if the length is 0 bytes there will be no encoding */
2473 val_start
= offset
>>3;
2476 } else if((min_len
==max_len
)&&(max_len
<=2)) {
2477 /* 16.6 if length is fixed and less than or equal to two bytes*/
2478 val_start
= offset
>>3;
2479 val_length
= min_len
;
2480 out_tvb
= tvb_new_octet_aligned(tvb
, offset
, val_length
* 8);
2481 /* Add new data source if the offet was unaligned */
2482 if ((offset
& 7) != 0) {
2483 add_new_data_source(actx
->pinfo
, out_tvb
, "Unaligned OCTET STRING");
2487 } else if ((min_len
==max_len
)&&(min_len
<65536)) {
2488 /* 16.7 if length is fixed and less than to 64k*/
2492 BYTE_ALIGN_OFFSET(offset
);
2494 val_start
= offset
>>3;
2495 val_length
= min_len
;
2496 out_tvb
= tvb_new_octet_aligned(tvb
, offset
, val_length
* 8);
2497 if ((offset
& 7) != 0) {
2498 add_new_data_source(actx
->pinfo
, out_tvb
, "Unaligned OCTET STRING");
2504 offset
= dissect_per_constrained_integer(tvb
, offset
, actx
, tree
,
2505 hf_per_octet_string_length
, min_len
, max_len
, &length
, false);
2507 if (!display_internal_per_fields
)
2508 proto_item_set_hidden(actx
->created_item
);
2511 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
,
2512 hf_per_octet_string_length
, &length
, &is_fragmented
);
2515 if(length
|| fragmented_length
){
2518 BYTE_ALIGN_OFFSET(offset
);
2520 if (is_fragmented
) {
2521 fragment_tvb
= tvb_new_octet_aligned(tvb
, offset
, length
* 8);
2522 if (fragmented_length
== 0)
2523 out_tvb
= tvb_new_composite();
2524 tvb_composite_append(out_tvb
, fragment_tvb
);
2525 offset
+= length
* 8;
2526 fragmented_length
+= length
;
2529 if (fragmented_length
) {
2531 tvb_composite_append(out_tvb
, tvb_new_octet_aligned(tvb
, offset
, length
* 8));
2532 fragmented_length
+= length
;
2534 tvb_composite_finalize(out_tvb
);
2535 add_new_data_source(actx
->pinfo
, out_tvb
, "Fragmented OCTET STRING");
2537 out_tvb
= tvb_new_octet_aligned(tvb
, offset
, length
* 8);
2538 if ((offset
& 7) != 0) {
2539 add_new_data_source(actx
->pinfo
, out_tvb
, "Unaligned OCTET STRING");
2543 val_start
= offset
>>3;
2545 val_length
= fragmented_length
? fragmented_length
: length
;
2550 if (FT_IS_UINT(hfi
->type
)||FT_IS_INT(hfi
->type
)) {
2551 /* If the type has been converted to FT_UINT or FT_INT in the .cnf file
2552 * display the length of this octet string instead of the octetstring itself
2554 if (FT_IS_UINT(hfi
->type
))
2555 actx
->created_item
= proto_tree_add_uint(tree
, hf_index
, out_tvb
, 0, val_length
, val_length
);
2557 actx
->created_item
= proto_tree_add_int(tree
, hf_index
, out_tvb
, 0, val_length
, val_length
);
2558 proto_item_append_text(actx
->created_item
, plurality(val_length
, " octet", " octets"));
2561 actx
->created_item
= proto_tree_add_item(tree
, hf_index
, out_tvb
, 0, val_length
, ENC_BIG_ENDIAN
);
2564 actx
->created_item
= proto_tree_add_item(tree
, hf_index
, tvb
, val_start
, val_length
, ENC_BIG_ENDIAN
);
2570 *value_tvb
= (out_tvb
) ? out_tvb
: tvb_new_subset_length(tvb
, val_start
, val_length
);
2575 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
)
2577 tvbuff_t
*val_tvb
= NULL
;
2578 proto_tree
*subtree
= tree
;
2580 offset
= dissect_per_octet_string(tvb
, offset
, actx
, tree
, hf_index
, min_len
, max_len
, has_extension
, &val_tvb
);
2582 if (type_cb
&& val_tvb
&& (tvb_reported_length(val_tvb
) > 0)) {
2583 subtree
= proto_item_add_subtree(actx
->created_item
, ett_per_containing
);
2584 type_cb(val_tvb
, actx
->pinfo
, subtree
, NULL
);
2590 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
)
2592 asn1_stack_frame_push(actx
, name
);
2593 asn1_param_push_integer(actx
, min_len
);
2594 asn1_param_push_integer(actx
, max_len
);
2595 asn1_param_push_boolean(actx
, has_extension
);
2597 offset
= type_cb(tvb
, offset
, actx
, tree
, hf_index
);
2599 asn1_stack_frame_pop(actx
, name
);
2604 bool get_size_constraint_from_stack(asn1_ctx_t
*actx
, const char *name
, int *pmin_len
, int *pmax_len
, bool *phas_extension
)
2608 if (pmin_len
) *pmin_len
= NO_BOUND
;
2609 if (pmax_len
) *pmax_len
= NO_BOUND
;
2610 if (phas_extension
) *phas_extension
= false;
2612 if (!actx
->stack
) return false;
2613 if (strcmp(actx
->stack
->name
, name
)) return false;
2615 par
= actx
->stack
->par
;
2616 if (!par
|| (par
->ptype
!= ASN1_PAR_INTEGER
)) return false;
2617 if (pmin_len
) *pmin_len
= par
->value
.v_integer
;
2619 if (!par
|| (par
->ptype
!= ASN1_PAR_INTEGER
)) return false;
2620 if (pmax_len
) *pmax_len
= par
->value
.v_integer
;
2622 if (!par
|| (par
->ptype
!= ASN1_PAR_BOOLEAN
)) return false;
2623 if (phas_extension
) *phas_extension
= par
->value
.v_boolean
;
2629 /* 26 Encoding of a value of the external type */
2631 /* code generated from definition in 26.1 */
2633 [UNIVERSAL 8] IMPLICIT SEQUENCE {
2634 direct-reference OBJECT IDENTIFIER OPTIONAL,
2635 indirect-reference INTEGER OPTIONAL,
2636 data-value-descriptor ObjectDescriptor OPTIONAL,
2638 single-ASN1-type [0] ABSTRACT-SYNTAX.&Type,
2639 octet-aligned [1] IMPLICIT OCTET STRING,
2640 arbitrary [2] IMPLICIT BIT STRING
2644 /* NOTE: This sequence type differs from that in ITU-T Rec. X.680 | ISO/IEC 8824-1 for historical reasons. */
2647 dissect_per_T_direct_reference(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
) {
2649 DISSECTOR_ASSERT(actx
);
2650 offset
= dissect_per_object_identifier_str(tvb
, offset
, actx
, tree
, hf_index
, &actx
->external
.direct_reference
);
2652 actx
->external
.direct_ref_present
= true;
2659 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_
) {
2660 offset
= dissect_per_integer(tvb
, offset
, actx
, tree
, hf_index
, &actx
->external
.indirect_reference
);
2662 actx
->external
.indirect_ref_present
= true;
2669 dissect_per_T_data_value_descriptor(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
) {
2670 offset
= dissect_per_object_descriptor(tvb
, offset
, actx
, tree
, hf_index
, &actx
->external
.data_value_descriptor
);
2672 actx
->external
.data_value_descr_present
= true;
2679 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_
) {
2680 offset
= dissect_per_open_type(tvb
, offset
, actx
, tree
, actx
->external
.hf_index
, actx
->external
.u
.per
.type_cb
);
2688 dissect_per_T_octet_aligned(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
) {
2689 offset
= dissect_per_octet_string(tvb
, offset
, actx
, tree
, hf_index
,
2690 NO_BOUND
, NO_BOUND
, false, &actx
->external
.octet_aligned
);
2692 if (actx
->external
.octet_aligned
) {
2693 if (actx
->external
.u
.per
.type_cb
) {
2694 actx
->external
.u
.per
.type_cb(actx
->external
.octet_aligned
, 0, actx
, tree
, actx
->external
.hf_index
);
2696 actx
->created_item
= proto_tree_add_expert(tree
, actx
->pinfo
, &ei_per_external_type
, actx
->external
.octet_aligned
, 0, -1);
2705 dissect_per_T_arbitrary(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
) {
2706 offset
= dissect_per_bit_string(tvb
, offset
, actx
, tree
, hf_index
,
2707 NO_BOUND
, NO_BOUND
, false, NULL
, 0, &actx
->external
.arbitrary
, NULL
);
2709 if (actx
->external
.arbitrary
) {
2710 if (actx
->external
.u
.per
.type_cb
) {
2711 actx
->external
.u
.per
.type_cb(actx
->external
.arbitrary
, 0, actx
, tree
, actx
->external
.hf_index
);
2713 actx
->created_item
= proto_tree_add_expert(tree
, actx
->pinfo
, &ei_per_external_type
, actx
->external
.arbitrary
, 0, -1);
2720 static const value_string per_External_encoding_vals
[] = {
2721 { 0, "single-ASN1-type" },
2722 { 1, "octet-aligned" },
2727 static const per_choice_t External_encoding_choice
[] = {
2728 { 0, &hf_per_single_ASN1_type
, ASN1_NO_EXTENSIONS
, dissect_per_T_single_ASN1_type
},
2729 { 1, &hf_per_octet_aligned
, ASN1_NO_EXTENSIONS
, dissect_per_T_octet_aligned
},
2730 { 2, &hf_per_arbitrary
, ASN1_NO_EXTENSIONS
, dissect_per_T_arbitrary
},
2731 { 0, NULL
, 0, NULL
}
2735 dissect_per_External_encoding(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
) {
2736 // This assertion is used to remove clang's warning.
2737 DISSECTOR_ASSERT(actx
);
2738 offset
= dissect_per_choice(tvb
, offset
, actx
, tree
, hf_index
,
2739 ett_per_External_encoding
, External_encoding_choice
,
2740 &actx
->external
.encoding
);
2746 static const per_sequence_t External_sequence
[] = {
2747 { &hf_per_direct_reference
, ASN1_NO_EXTENSIONS
, ASN1_OPTIONAL
, dissect_per_T_direct_reference
},
2748 { &hf_per_indirect_reference
, ASN1_NO_EXTENSIONS
, ASN1_OPTIONAL
, dissect_per_T_indirect_reference
},
2749 { &hf_per_data_value_descriptor
, ASN1_NO_EXTENSIONS
, ASN1_OPTIONAL
, dissect_per_T_data_value_descriptor
},
2750 { &hf_per_encoding
, ASN1_NO_EXTENSIONS
, ASN1_NOT_OPTIONAL
, dissect_per_External_encoding
},
2751 { NULL
, 0, 0, NULL
}
2755 dissect_per_External(tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
2756 offset
= dissect_per_sequence(tvb
, offset
, actx
, tree
, hf_index
,
2757 ett_per_External
, External_sequence
);
2763 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
)
2765 asn1_ctx_clean_external(actx
);
2766 actx
->external
.u
.per
.type_cb
= type_cb
;
2767 offset
= dissect_per_External(tvb
, offset
, actx
, tree
, hf_index
);
2769 asn1_ctx_clean_external(actx
);
2774 * Calls the callback defined with register_per_oid_dissector() if found.
2775 * Offset is in bits.
2779 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
)
2781 uint32_t type_length
, end_offset
, start_offset
;
2782 tvbuff_t
*val_tvb
= NULL
;
2784 start_offset
= offset
;
2785 offset
= dissect_per_length_determinant(tvb
, offset
, actx
, tree
, hf_per_open_type_length
, &type_length
, NULL
);
2786 if(type_length
== 0){
2787 dissect_per_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "unexpected length");
2789 if (actx
->aligned
) BYTE_ALIGN_OFFSET(offset
);
2790 end_offset
= offset
+ type_length
;
2793 /* length in bits */
2794 val_tvb
= tvb_new_octet_aligned(tvb
, offset
, type_length
* 8);
2795 if ((offset
& 7) != 0) {
2796 add_new_data_source(actx
->pinfo
, val_tvb
, "Unaligned OCTET STRING");
2800 (dissector_try_string_with_data(per_oid_dissector_table
, oid
, val_tvb
, pinfo
, tree
, true, actx
)) == 0)
2802 proto_tree_add_expert(tree
, pinfo
, &ei_per_oid_not_implemented
, val_tvb
, 0, -1);
2803 dissect_per_open_type(tvb
, start_offset
, actx
, tree
, hf_index
, NULL
);
2810 register_per_oid_dissector(const char *oid
, dissector_t dissector
, int proto
, const char *name
)
2812 dissector_handle_t dissector_handle
;
2814 /* FIXME: This would be better as register_dissector()
2815 * so the dissector could be referenced by name
2816 * from the command line, Lua, etc.
2817 * But can we blindly trust name to be a unique dissector name,
2818 * or should we prefix "per." or something?
2820 dissector_handle
= create_dissector_handle(dissector
, proto
);
2821 dissector_add_string("per.oid", oid
, dissector_handle
);
2822 oid_add_from_string(name
, oid
);
2827 proto_register_per(void)
2829 static hf_register_info hf
[] = {
2830 { &hf_per_num_sequence_extensions
,
2831 { "Number of Sequence Extensions", "per.num_sequence_extensions", FT_UINT32
, BASE_DEC
,
2832 NULL
, 0, "Number of extensions encoded in this sequence", HFILL
}},
2833 { &hf_per_choice_index
,
2834 { "Choice Index", "per.choice_index", FT_UINT32
, BASE_DEC
,
2835 NULL
, 0, "Which index of the Choice within extension root is encoded", HFILL
}},
2836 { &hf_per_choice_extension_index
,
2837 { "Choice Extension Index", "per.choice_extension_index", FT_UINT32
, BASE_DEC
,
2838 NULL
, 0, "Which index of the Choice within extension addition is encoded", HFILL
}},
2839 { &hf_per_enum_index
,
2840 { "Enumerated Index", "per.enum_index", FT_UINT32
, BASE_DEC
,
2841 NULL
, 0, "Which index of the Enumerated within extension root is encoded", HFILL
}},
2842 { &hf_per_enum_extension_index
,
2843 { "Enumerated Extension Index", "per.enum_extension_index", FT_UINT32
, BASE_DEC
,
2844 NULL
, 0, "Which index of the Enumerated within extension addition is encoded", HFILL
}},
2845 { &hf_per_GeneralString_length
,
2846 { "GeneralString Length", "per.generalstring_length", FT_UINT32
, BASE_DEC
,
2847 NULL
, 0, "Length of the GeneralString", HFILL
}},
2848 { &hf_per_extension_bit
,
2849 { "Extension Bit", "per.extension_bit", FT_BOOLEAN
, 8,
2850 TFS(&tfs_extension_bit
), 0x01, "The extension bit of an aggregate", HFILL
}},
2851 { &hf_per_extension_present_bit
,
2852 { "Extension Present Bit", "per.extension_present_bit", FT_BOOLEAN
, 8,
2853 NULL
, 0x01, "Whether this optional extension is present or not", HFILL
}},
2854 { &hf_per_small_number_bit
,
2855 { "Small Number Bit", "per.small_number_bit", FT_BOOLEAN
, 8,
2856 TFS(&tfs_small_number_bit
), 0x01, "The small number bit for a section 10.6 integer", HFILL
}},
2857 { &hf_per_optional_field_bit
,
2858 { "Optional Field Bit", "per.optional_field_bit", FT_BOOLEAN
, 8,
2859 NULL
, 0x01, "This bit specifies the presence/absence of an optional field", HFILL
}},
2860 { &hf_per_sequence_of_length
,
2861 { "Sequence-Of Length", "per.sequence_of_length", FT_UINT32
, BASE_DEC
,
2862 NULL
, 0, "Number of items in the Sequence Of", HFILL
}},
2863 { &hf_per_object_identifier_length
,
2864 { "Object Identifier Length", "per.object_length", FT_UINT32
, BASE_DEC
,
2865 NULL
, 0, "Length of the object identifier", HFILL
}},
2866 { &hf_per_open_type_length
,
2867 { "Open Type Length", "per.open_type_length", FT_UINT32
, BASE_DEC
,
2868 NULL
, 0, "Length of an open type encoding", HFILL
}},
2869 { &hf_per_real_length
,
2870 { "Real Length", "per.real_length", FT_UINT32
, BASE_DEC
,
2871 NULL
, 0, "Length of an real encoding", HFILL
}},
2872 { &hf_per_octet_string_length
,
2873 { "Octet String Length", "per.octet_string_length", FT_UINT32
, BASE_DEC
,
2874 NULL
, 0, "Number of bytes in the Octet String", HFILL
}},
2875 { &hf_per_bit_string_length
,
2876 { "Bit String Length", "per.bit_string_length", FT_UINT32
, BASE_DEC
,
2877 NULL
, 0, "Number of bits in the Bit String", HFILL
}},
2878 { &hf_per_normally_small_nonnegative_whole_number_length
,
2879 { "Normally Small Non-negative Whole Number Length", "per.normally_small_nonnegative_whole_number_length", FT_UINT32
, BASE_DEC
,
2880 NULL
, 0, "Number of bytes in the Normally Small Non-negative Whole Number", HFILL
}},
2881 { &hf_per_const_int_len
,
2882 { "Constrained Integer Length", "per.const_int_len", FT_UINT32
, BASE_DEC
,
2883 NULL
, 0, "Number of bytes in the Constrained Integer", HFILL
}},
2884 { &hf_per_direct_reference
,
2885 { "direct-reference", "per.direct_reference",
2886 FT_OID
, BASE_NONE
, NULL
, 0,
2887 "per.T_direct_reference", HFILL
}},
2888 { &hf_per_indirect_reference
,
2889 { "indirect-reference", "per.indirect_reference",
2890 FT_INT32
, BASE_DEC
, NULL
, 0,
2891 "per.T_indirect_reference", HFILL
}},
2892 { &hf_per_data_value_descriptor
,
2893 { "data-value-descriptor", "per.data_value_descriptor",
2894 FT_STRING
, BASE_NONE
, NULL
, 0,
2895 "per.T_data_value_descriptor", HFILL
}},
2897 { "encoding", "per.encoding",
2898 FT_UINT32
, BASE_DEC
, VALS(per_External_encoding_vals
), 0,
2899 "per.External_encoding", HFILL
}},
2900 { &hf_per_single_ASN1_type
,
2901 { "single-ASN1-type", "per.single_ASN1_type",
2902 FT_NONE
, BASE_NONE
, NULL
, 0,
2903 "per.T_single_ASN1_type", HFILL
}},
2904 { &hf_per_octet_aligned
,
2905 { "octet-aligned", "per.octet_aligned",
2906 FT_BYTES
, BASE_NONE
, NULL
, 0,
2907 "per.T_octet_aligned", HFILL
}},
2908 { &hf_per_arbitrary
,
2909 { "arbitrary", "per.arbitrary",
2910 FT_BYTES
, BASE_NONE
, NULL
, 0,
2911 "per.T_arbitrary", HFILL
}},
2912 { &hf_per_integer_length
,
2913 { "integer length", "per.integer_length",
2914 FT_UINT32
, BASE_DEC
, NULL
, 0,
2917 { &hf_per_debug_pos
,
2918 { "Current bit offset", "per.debug_pos",
2919 FT_UINT32
, BASE_DEC
, NULL
, 0,
2922 { &hf_per_internal_range
,
2923 { "Range", "per.internal.range",
2924 FT_UINT64
, BASE_DEC
, NULL
, 0,
2926 { &hf_per_internal_num_bits
,
2927 { "Bitfield length", "per.internal.num_bits",
2928 FT_UINT32
, BASE_DEC
, NULL
, 0,
2930 { &hf_per_internal_min
,
2931 { "Min", "per.internal.min",
2932 FT_UINT32
, BASE_DEC
, NULL
, 0,
2934 { &hf_per_internal_value
,
2935 { "Bits", "per.internal.value",
2936 FT_UINT64
, BASE_DEC
, NULL
, 0,
2938 { &hf_per_internal_min_int
,
2939 { "Min", "per.internal.min_int",
2940 FT_INT32
, BASE_DEC
, NULL
, 0,
2942 { &hf_per_internal_value_int
,
2943 { "Bits", "per.internal.value_int",
2944 FT_INT64
, BASE_DEC
, NULL
, 0,
2946 { &hf_per_encoding_boiler_plate
,
2947 { "PER encoded protocol, to see PER internal fields set protocol PER preferences", "per.encoding_boiler_plate",
2948 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2953 static int *ett
[] = {
2955 &ett_per_containing
,
2956 &ett_per_sequence_of_item
,
2958 &ett_per_External_encoding
,
2959 &ett_per_named_bits
,
2961 static ei_register_info ei
[] = {
2962 { &ei_per_size_constraint_value
,
2963 { "per.size_constraint.value", PI_PROTOCOL
, PI_WARN
, "Size constraint: value too big", EXPFILL
}},
2964 { &ei_per_size_constraint_too_few
,
2965 { "per.size_constraint.too_few", PI_PROTOCOL
, PI_WARN
, "Size constraint: too few items", EXPFILL
}},
2966 { &ei_per_size_constraint_too_many
,
2967 { "per.size_constraint.too_many", PI_PROTOCOL
, PI_WARN
, "Size constraint: too many items", EXPFILL
}},
2968 { &ei_per_choice_extension_unknown
,
2969 { "per.choice_extension_unknown", PI_UNDECODED
, PI_NOTE
, "unknown choice extension", EXPFILL
}},
2970 { &ei_per_sequence_extension_unknown
,
2971 { "per.sequence_extension_unknown", PI_UNDECODED
, PI_NOTE
, "unknown sequence extension", EXPFILL
}},
2972 { &ei_per_encoding_error
,
2973 { "per.encoding_error", PI_MALFORMED
, PI_WARN
, "Encoding error", EXPFILL
}},
2974 { &ei_per_oid_not_implemented
,
2975 { "per.error.oid_not_implemented", PI_UNDECODED
, PI_WARN
, "PER: Dissector for OID not implemented. Contact Wireshark developers if you want this supported", EXPFILL
}},
2976 { &ei_per_undecoded
,
2977 { "per.error.undecoded", PI_UNDECODED
, PI_WARN
, "PER: Something unknown here", EXPFILL
}},
2978 { &ei_per_field_not_integer
,
2979 { "per.field_not_integer", PI_PROTOCOL
, PI_ERROR
, "Field is not an integer", EXPFILL
}},
2980 { &ei_per_external_type
,
2981 { "per.external_type.unknown", PI_PROTOCOL
, PI_WARN
, "Unknown EXTERNAL Type", EXPFILL
}},
2982 { &ei_per_open_type
,
2983 { "per.open_type.unknown", PI_PROTOCOL
, PI_WARN
, "Unknown Open Type", EXPFILL
}},
2984 { &ei_per_open_type_len
,
2985 { "per.open_type.len", PI_PROTOCOL
, PI_ERROR
, "Open Type length > available data(tvb)", EXPFILL
}}
2988 module_t
*per_module
;
2989 expert_module_t
* expert_per
;
2991 proto_per
= proto_register_protocol("Packed Encoding Rules (ASN.1 X.691)", "PER", "per");
2992 proto_register_field_array(proto_per
, hf
, array_length(hf
));
2993 proto_register_subtree_array(ett
, array_length(ett
));
2994 expert_per
= expert_register_protocol(proto_per
);
2995 expert_register_field_array(expert_per
, ei
, array_length(ei
));
2997 proto_set_cant_toggle(proto_per
);
2999 per_module
= prefs_register_protocol(proto_per
, NULL
);
3000 prefs_register_bool_preference(per_module
, "display_internal_per_fields",
3001 "Display the internal PER fields in the tree",
3002 "Whether the dissector should put the internal PER data in the tree or if it should hide it",
3003 &display_internal_per_fields
);
3005 per_oid_dissector_table
= register_dissector_table("per.oid", "PER OID", proto_per
, FT_STRING
, STRING_CASE_SENSITIVE
);
3011 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3016 * indent-tabs-mode: t
3019 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3020 * :indentSize=8:tabSize=8:noTabs=false: