Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-per.c
blob0f3d5f42e53a99c17530afd55a3c586778de7e9c
1 /*
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
4 proper helper routines
5 */
6 /* packet-per.c
7 * Routines for dissection of ASN.1 Aligned PER
8 * 2003 Ronnie Sahlberg
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
17 #include "config.h"
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>
26 #include <epan/tfs.h>
27 #include <wsutil/array.h>
28 #include "packet-per.h"
30 void proto_register_per(void);
32 static int proto_per;
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
101 or not.
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"
116 void
117 add_per_encoded_label(tvbuff_t* tvb, packet_info* pinfo _U_, proto_tree* tree)
119 proto_item* ti;
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 --------------------------------------------------- */
168 static uint32_t
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;
175 bool is_fragmented;
176 int captured_pdu_length;
178 hfi = (hf_index <= 0) ? NULL : proto_registrar_get_nth(hf_index);
180 start_offset = offset;
181 do {
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);
184 if (is_fragmented) {
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) {
195 if (type_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");
201 pdu_offset = 0;
202 pdu_length = fragmented_length;
203 } else {
204 pdu_tvb = tvb;
205 pdu_offset = offset;
206 pdu_length = type_length;
208 end_offset = offset + type_length * 8;
210 if (variant==CB_NEW_DISSECTOR) {
211 if (fragmented_length) {
212 val_tvb = pdu_tvb;
213 } else {
214 if (!pdu_length) {
215 return end_offset;
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;
224 } else {
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");
232 if (hfi) {
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);
236 else
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"));
239 } else {
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);
246 if (type_cb) {
247 switch (variant) {
248 case CB_ASN1_ENC:
249 ((per_type_fn)type_cb)(pdu_tvb, pdu_offset, actx, tree, hf_index);
250 break;
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);
254 break;
255 case CB_DISSECTOR_HANDLE:
256 break;
258 } else {
259 actx->created_item = proto_tree_add_expert(tree, actx->pinfo, &ei_per_open_type, tvb, start_offset>>3, BLEN(start_offset, end_offset));
262 return end_offset;
265 uint32_t
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);
271 uint32_t
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.
303 uint32_t
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)
306 uint8_t byte;
307 uint32_t len;
308 proto_item *pi;
309 int num_bits;
310 int i, bit, str_length, str_index;
311 bool tmp;
313 if(!length){
314 length=&len;
316 if (is_fragmented) {
317 *is_fragmented = false;
320 /* byte aligned */
321 if (actx->aligned){
322 BYTE_ALIGN_OFFSET(offset);
323 byte=tvb_get_uint8(tvb, offset>>3);
324 offset+=8;
325 }else{
326 char *str;
327 uint32_t val;
329 val = 0;
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);
334 str_index = 0;
336 str_length = snprintf(str, str_length+1, " ");
337 for(bit=0;bit<((int)(offset&0x07));bit++){
338 if(bit&&(!(bit%4))){
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 */
344 num_bits = 8;
345 for(i=0;i<num_bits;i++){
346 if(bit&&(!(bit%4))){
347 if (str_index < str_length) str[str_index++] = ' ';
349 if(bit&&(!(bit%8))){
350 if (str_index < str_length) str[str_index++] = ' ';
352 bit++;
353 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &tmp);
354 val<<=1;
355 if(tmp){
356 val|=1;
357 if (str_index < str_length) str[str_index++] = '1';
358 if (i==0) { /* bit 8 is 1, so not a single byte length */
359 num_bits = 16;
361 else if (i==1 && val==3) { /* bits 8 and 7 both 1, so unconstrained */
362 if (!is_fragmented) {
363 *length = 0;
364 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "10.9 Unconstrained");
365 return offset;
366 } else {
367 num_bits = 8;
368 *is_fragmented = true;
371 } else {
372 if (str_index < str_length) str[str_index++] = '0';
375 str[str_index] = '\0'; /* Terminate string */
376 if(is_fragmented && *is_fragmented==true){
377 *length = val&0x3f;
378 if (*length>4 || *length==0) {
379 *length = 0;
380 *is_fragmented = false;
381 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "10.9 Unconstrained unexpected fragment count");
382 return offset;
384 *length *= 0x4000;
385 if(hf_index > 0){
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);
389 else
390 proto_item_set_hidden(pi);
393 return offset;
395 else if((val&0x80)==0 && num_bits==8){
396 *length = val;
397 if(hf_index > 0){
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);
401 else
402 proto_item_set_hidden(pi);
405 return offset;
407 else if (num_bits==16) {
408 *length = val&0x3fff;
409 if(hf_index > 0){
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);
413 else
414 proto_item_set_hidden(pi);
417 return offset;
419 *length = 0;
420 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "10.9 Unaligned");
421 return offset;
425 /* 10.9.3.6 */
426 if((byte&0x80)==0){
427 *length=byte;
428 if(hf_index > 0){
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);
432 return offset;
435 /* 10.9.3.7 */
436 if((byte&0xc0)==0x80){
437 *length=(byte&0x3f);
438 *length=((*length)<<8)+tvb_get_uint8(tvb, offset>>3);
439 offset+=8;
440 if(hf_index > 0){
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);
444 return offset;
446 /* 10.9.3.8.1 */
447 else if (is_fragmented){
448 *length = byte&0x3f;
449 if (*length>4 || *length==0) {
450 *length = 0;
451 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "10.9 Unconstrained unexpected fragment count");
452 return offset;
454 *length *= 0x4000;
455 *is_fragmented = true;
456 if(hf_index > 0){
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);
460 return offset;
462 *length = 0;
463 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "10.9.3.8.1");
464 return offset;
467 /* 10.6 normally small non-negative whole number */
468 static uint32_t
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;
473 proto_item *pi;
475 DEBUG_ENTRY("dissect_per_normally_small_nonnegative_whole_number");
476 if(!length){
477 length=&len;
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);
482 if(!small_number){
483 int i;
484 /* 10.6.1 */
485 *length=0;
486 for(i=0;i<6;i++){
487 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &length_bit);
488 *length<<=1;
489 if (length_bit) {
490 *length|=1;
493 if(hf_index > 0){
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);
497 return offset;
500 /* 10.6.2 */
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) {
503 case 0:
504 *length = 0;
505 break;
506 case 1:
507 *length = tvb_get_bits8(tvb, offset, 8);
508 offset += 8;
509 break;
510 case 2:
511 *length = tvb_get_bits16(tvb, offset, 16, ENC_BIG_ENDIAN);
512 offset += 16;
513 break;
514 case 3:
515 *length = tvb_get_bits32(tvb, offset, 24, ENC_BIG_ENDIAN);
516 offset += 24;
517 break;
518 case 4:
519 *length = tvb_get_bits32(tvb, offset, 32, ENC_BIG_ENDIAN);
520 offset += 32;
521 break;
522 default:
523 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too long integer(per_normally_small_nonnegative_whole_number)");
524 offset += 8*length_determinant;
525 *length = 0;
526 return offset;
528 if(hf_index > 0){
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);
533 return offset;
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
546 uint32_t
547 dissect_per_GeneralString(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index)
549 uint32_t length;
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);
555 offset+=length*8;
557 return offset;
560 /* 17 Encoding the null type */
561 uint32_t
562 dissect_per_null(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) {
563 proto_item *ti_tmp;
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");
568 return offset;
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
575 static uint32_t
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)
578 uint32_t i;
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;
584 proto_item *litem;
585 proto_tree *ltree;
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");
596 return offset;
598 uint32_t
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)
601 proto_item *item;
602 proto_tree *tree;
603 uint32_t old_offset=offset;
604 uint32_t length;
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");
618 } else {
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);
627 return offset;
630 /* XXX we don't do >64k length strings yet */
631 static uint32_t
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)
634 uint32_t length;
635 bool byte_aligned, use_canonical_order;
636 wmem_strbuf_t *buf;
637 int str_len;
638 char *str;
639 unsigned char_pos;
640 int bits_per_char;
641 uint32_t old_offset;
643 DEBUG_ENTRY("dissect_per_restricted_character_string");
645 /* xx.x if the length is 0 bytes there will be no encoding */
646 if(max_len==0){
647 if (value_tvb) {
648 *value_tvb = tvb_new_child_real_data(tvb, NULL, 0, 0);
650 return offset;
654 if (min_len == NO_BOUND) {
655 min_len=0;
659 /* 27.5.2 depending of the alphabet length, find how many bits
660 are used to encode each character */
661 /* unaligned PER */
662 if (actx->aligned){
664 if(alphabet_length<=2){
665 bits_per_char=1;
666 } else if(alphabet_length<=4){
667 bits_per_char=2;
668 } else if(alphabet_length<=16){
669 bits_per_char=4;
670 } else {
671 bits_per_char=8;
673 }else{
674 if(alphabet_length<=2){
675 bits_per_char=1;
676 } else if(alphabet_length<=4){
677 bits_per_char=2;
678 } else if(alphabet_length<=8){
679 bits_per_char=3;
680 } else if(alphabet_length<=16){
681 bits_per_char=4;
682 } else if(alphabet_length<=32){
683 bits_per_char=5;
684 } else if(alphabet_length<=64){
685 bits_per_char=6;
686 } else if(alphabet_length<=128){
687 bits_per_char=7;
688 } else {
689 bits_per_char=8;
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.
704 if (has_extension) {
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){
709 min_len = NO_BOUND;
710 max_len = NO_BOUND;
714 byte_aligned=true;
715 if((min_len==max_len)&&(max_len<=2)){
716 byte_aligned=false;
718 if ((max_len != NO_BOUND) && (max_len < 2)) {
719 byte_aligned=false;
722 /* xx.x */
723 length=max_len;
724 old_offset = offset;
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)*/
728 byte_aligned=true;
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,
732 &length, false);
733 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
736 if(!length){
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)
741 offset = offset + 1;
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);
755 old_offset=offset;
756 for(char_pos=0;char_pos<length;char_pos++){
757 unsigned char val;
758 int i;
759 bool bit;
761 val=0;
762 for(i=0;i<bits_per_char;i++){
763 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
764 val=(val<<1)|bit;
766 if(use_canonical_order == false){
767 if (val > ub || val < lb) {
768 wmem_strbuf_append_unichar_repl(buf);
769 } else {
770 wmem_strbuf_append_c(buf, val);
772 } else {
773 if (val < alphabet_length){
774 wmem_strbuf_append_c(buf, alphabet[val]);
775 } else {
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);
784 if (value_tvb) {
785 *value_tvb = tvb_new_child_real_data(tvb, str, str_len, str_len);
787 return offset;
790 static const char*
791 sort_alphabet(char *sorted_alphabet, const char *alphabet, int alphabet_length, uint16_t *lb, uint16_t *ub)
793 int i, j;
794 unsigned char c, c_max, c_min;
795 char tmp_buf[256];
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];
809 tmp_buf[c] = 1;
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;
821 uint32_t
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];
826 uint16_t lb = 0;
827 uint16_t ub = 65535;
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;
834 } else {
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);
846 uint32_t
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);
852 return offset;
855 uint32_t
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);
861 return offset;
863 uint32_t
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);
868 return offset;
870 uint32_t
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);
875 return offset;
877 uint32_t
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_)
880 uint32_t length;
882 /* xx.x if the length is 0 bytes there will be no encoding */
883 if(max_len==0){
884 return offset;
888 if (min_len == NO_BOUND) {
889 min_len = 0;
893 /* xx.x */
894 length=max_len;
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,
898 &length, false);
899 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
903 /* align to byte boundary */
904 BYTE_ALIGN_OFFSET(offset);
906 if(length>=1024){
907 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "BMPString too long");
908 length=1024;
911 proto_tree_add_item(tree, hf_index, tvb, offset>>3, length*2, ENC_UCS_2|ENC_BIG_ENDIAN);
913 offset+=(length<<3)*2;
915 return offset;
917 uint32_t
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_)
920 tvbuff_t *val_tvb;
921 uint32_t length;
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);
932 if(length){
934 /* Unnecessary because the length determinant is aligned. */
935 if(actx->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);
946 } else {
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);
953 offset+=(length<<3);
955 return offset;
958 uint32_t
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);
963 return offset;
967 /* this function dissects a constrained sequence of */
968 uint32_t
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)
971 proto_item *item;
972 proto_tree *tree;
973 uint32_t old_offset=offset;
974 uint32_t length;
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
982 if (has_extension) {
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);
991 goto call_sohelper;
995 /* 19.5 if min==max and min,max<64k ==> no length determinant */
996 if((min_len==max_len) && (min_len<65536)){
997 length=min_len;
998 goto call_sohelper;
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);
1005 goto call_sohelper;
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,
1011 &length, false);
1012 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1014 call_sohelper:
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");
1019 } else {
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)
1029 length = 0;
1030 else if (offset >> 3 == old_offset >> 3)
1031 length = 1;
1032 else
1033 length = (offset >> 3) - (old_offset >> 3);
1035 proto_item_set_len(item, length);
1036 return offset;
1039 /* this function dissects a constrained set of */
1040 uint32_t
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);
1046 return offset;
1054 /* this function dissects a set of */
1055 uint32_t
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);
1061 return offset;
1067 /* 23 Encoding the object identifier type */
1068 static uint32_t
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,
1070 bool is_absolute)
1072 unsigned length;
1073 const char *str;
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);
1080 if(length == 0){
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);
1096 } else {
1097 DISSECTOR_ASSERT_NOT_REACHED();
1100 if (value_tvb) *value_tvb = val_tvb;
1102 offset += 8 * length;
1104 return offset;
1107 uint32_t
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);
1113 uint32_t
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);
1119 static uint32_t
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,
1121 bool is_absolute)
1123 tvbuff_t *value_tvb = NULL;
1124 unsigned length;
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);
1131 } else {
1132 *value_stringx = "";
1136 return offset;
1139 uint32_t
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);
1145 uint32_t
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 */
1153 uint32_t
1154 dissect_per_boolean(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, bool *bool_val)
1156 uint8_t ch, mask;
1157 bool value;
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));
1164 if(ch&mask){
1165 value=1;
1166 } else {
1167 value=0;
1169 if(hf_index > 0){
1170 char bits[10];
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:'.';
1175 bits[4] = ' ';
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:'.';
1180 bits[9] = '\0';
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");
1186 } else {
1187 actx->created_item = NULL;
1190 if(bool_val){
1191 *bool_val=value;
1193 return offset+1;
1199 /* we currently only handle integers up to 32 bits in length. */
1200 uint32_t
1201 dissect_per_integer(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int32_t *value)
1203 uint32_t i, length;
1204 uint32_t val;
1205 tvbuff_t *val_tvb=NULL;
1206 proto_item *it=NULL;
1207 header_field_info *hfi;
1209 /* 12.2.6 b */
1210 offset=dissect_per_length_determinant(tvb, offset, actx, tree,hf_per_integer_length, &length, NULL);
1211 /* gassert here? */
1212 if(length>4){
1213 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too long integer(per_integer)");
1214 length=4;
1217 if(length == 0){
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);
1223 val=0;
1224 for(i=0;i<length;i++){
1225 if(i==0){
1226 if(tvb_get_uint8(val_tvb, i)&0x80){
1227 /* negative number */
1228 val=0xffffffff;
1229 } else {
1230 /* positive number */
1231 val=0;
1234 val=(val<<8)|tvb_get_uint8(val_tvb,i);
1236 offset += length * 8;
1238 hfi = proto_registrar_get_nth(hf_index);
1239 if (! hfi)
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);
1245 } else {
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;
1254 if(value){
1255 *value=val;
1258 return offset;
1260 /* 64 bits experimental version, internal for now */
1261 static uint32_t
1262 dissect_per_integer64b(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int64_t *value)
1264 uint32_t i, length;
1265 uint64_t val;
1266 proto_item *it=NULL;
1267 header_field_info *hfi;
1269 /* 12.2.6 b */
1270 offset=dissect_per_length_determinant(tvb, offset, actx, tree, -1, &length, NULL);
1271 /* gassert here? */
1272 if(length>8){
1273 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too long integer (64b)");
1274 length=8;
1277 val=0;
1278 for(i=0;i<length;i++){
1279 if(i==0){
1280 if(tvb_get_uint8(tvb, offset>>3)&0x80){
1281 /* negative number */
1282 val=UINT64_C(0xffffffffffffffff);
1283 } else {
1284 /* positive number */
1285 val=0;
1288 val=(val<<8)|tvb_get_uint8(tvb,offset>>3);
1289 offset+=8;
1292 hfi = proto_registrar_get_nth(hf_index);
1293 if (! hfi)
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);
1299 } else {
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;
1308 if(value){
1309 *value=(int64_t)val;
1312 return offset;
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
1323 10.5.1 info only
1324 10.5.2 info only
1325 10.5.3 range=ub-lb+1
1326 10.5.4 empty range
1327 10.5.5 info only
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
1333 10.5.7.4
1335 uint32_t
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;
1341 nstime_t timeval;
1342 header_field_info *hfi;
1343 int num_bits;
1345 DEBUG_ENTRY("dissect_per_constrained_integer");
1346 if(has_extension){
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);
1352 return offset;
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 */
1365 range=1000000;
1366 } else {
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) ){
1376 range=0xffffffff;
1377 } else {
1378 range=max-min+1;
1382 val=0;
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);
1389 if(range==1){
1390 val_start = offset>>3; val_length = 0;
1391 val = min;
1392 } else if((range<=255)||(!actx->aligned)) {
1393 /* 10.5.7.1
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.
1398 char *str;
1399 int i, length;
1400 uint32_t mask,mask2;
1401 /* We only handle 32 bit integers */
1402 mask = 0x80000000;
1403 mask2 = 0x7fffffff;
1404 i = 32;
1405 while ((range & mask)== 0){
1406 i = i - 1;
1407 mask = mask>>1;
1408 mask2 = mask2>>1;
1410 if ((range & mask2) == 0)
1411 i = i-1;
1413 num_bits = i;
1414 length=(num_bits+7)>>3;
1415 if(range<=2){
1416 num_bits=1;
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);
1427 } else {
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);
1434 } else {
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 */
1439 val+=min;
1440 offset = offset+num_bits;
1441 } else if(range==256){
1442 /* 10.5.7.2 */
1444 /* in the aligned case, align to byte boundary */
1445 BYTE_ALIGN_OFFSET(offset);
1446 val=tvb_get_uint8(tvb, offset>>3);
1447 offset+=8;
1449 val_start = (offset>>3)-1; val_length = 1;
1450 val+=min;
1451 } else if(range<=65536){
1452 /* 10.5.7.3 */
1454 /* in the aligned case, align to byte boundary */
1455 BYTE_ALIGN_OFFSET(offset);
1456 val=tvb_get_uint8(tvb, offset>>3);
1457 val<<=8;
1458 offset+=8;
1459 val|=tvb_get_uint8(tvb, offset>>3);
1460 offset+=8;
1462 val_start = (offset>>3)-2; val_length = 2;
1463 val+=min;
1464 } else {
1465 int i,num_bytes;
1466 bool bit;
1468 /* 10.5.7.4 */
1469 /* 12.2.6 */
1470 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
1471 num_bytes=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);
1479 /* byte aligned */
1480 BYTE_ALIGN_OFFSET(offset);
1481 val=0;
1482 for(i=0;i<num_bytes;i++){
1483 val=(val<<8)|tvb_get_uint8(tvb,offset>>3);
1484 offset+=8;
1486 val_start = (offset>>3)-(num_bytes+1); val_length = num_bytes+1;
1487 val+=min;
1490 timeval.secs = val;
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);
1499 } else {
1500 THROW(ReportedBoundsError);
1502 actx->created_item = it;
1503 if (value) *value = val;
1504 return offset;
1507 uint32_t
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;
1513 nstime_t timeval;
1514 header_field_info *hfi;
1515 int num_bits;
1516 bool tmp;
1518 DEBUG_ENTRY("dissect_per_constrained_integer_64b");
1519 if(has_extension){
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);
1525 return offset;
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; */
1539 range = max-min;
1540 if (range==65536)
1541 range++; /* make it fall trough? */
1542 } else {
1543 /* Copied from the 32 bit version, assuming the same problem occurs
1544 * at 64 bit boundary.
1545 * Really ugly hack.
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);
1555 } else {
1556 range=max-min+1;
1560 val=0;
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);
1567 if(range==1){
1568 val_start = offset>>3; val_length = 0;
1569 val = min;
1570 } else if((range<=255)||(!actx->aligned)) {
1571 /* 10.5.7.1
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.
1576 char *str;
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);
1582 i = 64;
1583 while ((range & mask)== 0){
1584 i = i - 1;
1585 mask = mask>>1;
1586 mask2 = mask2>>1;
1588 if ((range & mask2) == 0)
1589 i = i-1;
1591 num_bits = i;
1592 length=1;
1593 if(range<=2){
1594 num_bits=1;
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))){
1612 length+=1;
1613 if (str_index < str_length) str[str_index++] = ' ';
1615 bit++;
1616 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &tmp);
1617 val<<=1;
1618 if(tmp){
1619 val|=1;
1620 if (str_index < str_length) str[str_index++] = '1';
1621 } else {
1622 if (str_index < str_length) str[str_index++] = '0';
1625 for(;bit%8;bit++){
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;
1633 val+=min;
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){
1640 /* 10.5.7.2 */
1642 /* in the aligned case, align to byte boundary */
1643 BYTE_ALIGN_OFFSET(offset);
1644 val=tvb_get_uint8(tvb, offset>>3);
1645 offset+=8;
1647 val_start = (offset>>3)-1; val_length = 1;
1648 val+=min;
1649 } else if(range<=65536){
1650 /* 10.5.7.3 */
1652 /* in the aligned case, align to byte boundary */
1653 BYTE_ALIGN_OFFSET(offset);
1654 val=tvb_get_uint8(tvb, offset>>3);
1655 val<<=8;
1656 offset+=8;
1657 val|=tvb_get_uint8(tvb, offset>>3);
1658 offset+=8;
1660 val_start = (offset>>3)-2; val_length = 2;
1661 val+=min;
1662 } else {
1663 int i,num_bytes,n_bits;
1665 /* 10.5.7.4 */
1666 /* 12.2.6 */
1667 /* calculate the number of bits to hold the length */
1668 if ((range & INT64_C(0xffffffff00000000)) != 0){
1669 n_bits=3;
1670 }else{
1671 n_bits=2;
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;
1680 /* byte aligned */
1681 BYTE_ALIGN_OFFSET(offset);
1682 val=0;
1683 for(i=0;i<num_bytes;i++){
1684 val=(val<<8)|tvb_get_uint8(tvb,offset>>3);
1685 offset+=8;
1687 val_start = (offset>>3)-(num_bytes+1); val_length = num_bytes+1;
1688 val+=min;
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);
1701 } else {
1702 THROW(ReportedBoundsError);
1704 actx->created_item = it;
1705 if (value) *value = val;
1706 return offset;
1709 /* 13 Encoding the enumerated type */
1710 uint32_t
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) {
1721 /* Extension bit */
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) {
1727 /* 13.2 */
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);
1730 } else {
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);
1742 } else {
1743 THROW(ReportedBoundsError);
1745 actx->created_item = it;
1746 if (value) *value = val;
1747 return offset;
1750 /* 14 Encoding the real type */
1751 uint32_t
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;
1755 tvbuff_t *val_tvb;
1756 double val = 0;
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;
1772 return end_offset;
1775 /* 22 Encoding the choice type */
1776 uint32_t
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;
1782 int i, idx, cidx;
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;
1792 /* 22.5 */
1793 if (choice[0].extension == ASN1_NO_EXTENSIONS){
1794 /*extension_present = false; ?? */
1795 extension_flag = false;
1796 } else {
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++;
1809 break;
1810 case ASN1_NOT_EXTENSION_ROOT:
1811 break;
1815 if (!extension_flag) { /* 22.6, 22.7 */
1816 if (extension_root_entries == 1) { /* 22.5 */
1817 choice_index = 0;
1818 } else {
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; }
1829 cidx--;
1832 } else { /* 22.8 */
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; }
1840 cidx--;
1845 if (idx != -1) {
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);
1850 } else {
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));
1855 } else {
1856 if (!extension_flag) {
1857 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "unknown extension root index in choice");
1858 } else {
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;
1869 return offset;
1873 static const char *
1874 index_get_optional_name(const per_sequence_t *sequence, int idx)
1876 int i;
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)){
1881 if (idx == 0) {
1882 hfi = proto_registrar_get_nth(*sequence[i].p_id);
1883 return (hfi) ? hfi->name : "<unknown field>";
1885 idx--;
1888 return "<unknown type>";
1891 static const char *
1892 index_get_extension_name(const per_sequence_t *sequence, int idx)
1894 int i;
1895 header_field_info *hfi;
1897 for(i=0;sequence[i].p_id;i++){
1898 if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
1899 if (idx == 0) {
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>";
1904 idx--;
1907 return "<unknown type>";
1910 static const char *
1911 index_get_field_name(const per_sequence_t *sequence, int idx)
1913 if (sequence) {
1914 header_field_info *hfi = proto_registrar_get_nth(*sequence[idx].p_id);
1916 if (hfi) {
1917 return hfi->name;
1920 return "<unknown field>";
1923 /* this functions decodes a SEQUENCE
1924 it can only handle SEQUENCES with at most 32 DEFAULT or OPTIONAL fields
1925 18.1 extension bit
1926 18.2 optional/default items in root
1927 18.3 we ignore the case where n>64K
1928 18.4 the root sequence
1929 18.5
1930 18.6
1931 18.7
1932 18.8
1933 18.9
1935 uint32_t
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;
1939 proto_item *item;
1940 proto_tree *tree;
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
1955 /* 18.1 */
1956 extension_flag=0;
1957 if(sequence[0].extension==ASN1_NO_EXTENSIONS){
1958 /*extension_present=0; ?? */
1959 } else {
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);
1964 /* 18.2 */
1965 num_opts=0;
1966 for(i=0;sequence[i].p_id;i++){
1967 if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1968 num_opts++;
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);
1978 if (tree) {
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);
1989 /* 18.4 */
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){
1994 bool is_present;
1995 if (num_opts == 0){
1996 continue;
1998 is_present=(0x80000000>>(j&0x1f))&optional_mask[j>>5];
1999 num_opts--;
2000 j++;
2001 if(!is_present){
2002 continue;
2005 if(sequence[i].func){
2006 offset=sequence[i].func(tvb, offset, actx, tree, *sequence[i].p_id);
2007 } else {
2008 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, index_get_field_name(sequence, i));
2014 if(extension_flag){
2015 bool extension_bit;
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
2025 not be 0.
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!
2037 num_extensions+=1;
2038 if (num_extensions > 32) {
2039 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too many extensions");
2042 extension_mask=0;
2043 for(i=0;i<num_extensions;i++){
2044 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_bit);
2045 if (tree) {
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++){
2064 uint32_t length;
2065 uint32_t new_offset;
2066 int32_t difference;
2067 uint32_t extension_index;
2068 uint32_t k;
2070 if(!((1U<<(num_extensions-1-i))&extension_mask)){
2071 /* this extension is not encoded in this PDU */
2072 continue;
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 */
2079 offset+=length*8;
2080 expert_add_info(actx->pinfo, item, &ei_per_sequence_extension_unknown);
2081 continue;
2084 extension_index=0;
2085 for(j=0,k=0;sequence[j].p_id;j++){
2086 if(sequence[j].extension==ASN1_NOT_EXTENSION_ROOT){
2087 if(k==i){
2088 extension_index=j;
2089 break;
2091 k++;
2095 if(sequence[extension_index].func){
2096 new_offset=sequence[extension_index].func(tvb, offset, actx, tree, *sequence[extension_index].p_id);
2097 offset+=length*8;
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));
2109 } else {
2110 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, index_get_field_name(sequence, extension_index));
2111 offset+=length*8;
2116 proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
2117 actx->created_item = item;
2118 return offset;
2121 uint32_t
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");
2130 num_opts=0;
2131 for(i=0;sequence[i].p_id;i++){
2132 if(sequence[i].optional==ASN1_OPTIONAL){
2133 num_opts++;
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);
2143 if (tree) {
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){
2155 bool is_present;
2156 if (num_opts == 0){
2157 continue;
2159 is_present=(0x80000000>>(j&0x1f))&optional_mask[j>>5];
2160 num_opts--;
2161 j++;
2162 if(!is_present){
2163 continue;
2166 if(sequence[i].func){
2167 offset=sequence[i].func(tvb, offset, actx, tree, *sequence[i].p_id);
2168 } else {
2169 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, index_get_field_name(sequence, i));
2173 return offset;
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;
2187 uint64_t value;
2189 out_tvb = tvb_new_octet_aligned(tvb, offset, length);
2190 add_new_data_source(actx->pinfo, out_tvb, "Bitstring tvb");
2192 if (hfi) {
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);
2195 if (length%8) {
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 */
2201 if (length<=8) {
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);
2221 value <<= 16;
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);
2225 }else {
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);
2230 if (named_bits) {
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.
2236 value = 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
2243 // single byte.
2244 int* const * section_named_bits = named_bits + bit_offset;
2245 int* flags[9];
2246 if (num_named_bits - bit_offset > 8) {
2247 memcpy(&flags[0], named_bits + bit_offset, 8 * sizeof(int*));
2248 flags[8] = NULL;
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, "]");
2262 return out_tvb;
2264 uint32_t
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 */
2277 if(max_len==0) {
2278 if (value_tvb)
2279 *value_tvb = out_tvb;
2280 if (len)
2281 *len = 0;
2282 return offset;
2285 if (min_len == NO_BOUND) {
2286 min_len = 0;
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){
2298 next_fragment1:
2299 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_bit_string_length, &length, &is_fragmented);
2300 if(length || fragmented_length){
2301 /* align to byte */
2302 if (actx->aligned){
2303 BYTE_ALIGN_OFFSET(offset);
2305 if(is_fragmented){
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);
2310 offset += length;
2311 fragmented_length += length;
2312 goto next_fragment1;
2314 if(fragmented_length){
2315 if(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);
2324 else
2325 out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, length, named_bits, num_named_bits);
2327 /* XXX: ?? */
2328 /*val_start = offset>>3;*/
2329 /*val_length = (length+7)/8;*/
2330 offset+=length;
2332 if (value_tvb)
2333 *value_tvb = out_tvb;
2334 if (len)
2335 *len = fragmented_length ? fragmented_length : length;
2337 return offset;
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);
2344 offset+=min_len;
2345 if (value_tvb)
2346 *value_tvb = out_tvb;
2347 if (len)
2348 *len = min_len;
2349 return offset;
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)
2356 * align to byte
2358 if (actx->aligned){
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);
2362 offset+=min_len;
2363 if (value_tvb)
2364 *value_tvb = out_tvb;
2365 if (len)
2366 *len = min_len;
2367 return offset;
2370 /* 15.11 */
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,
2374 &length, false);
2375 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
2376 } else {
2377 next_fragment2:
2378 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_bit_string_length, &length, &is_fragmented);
2380 if(length || fragmented_length){
2381 /* align to byte */
2382 if (actx->aligned){
2383 BYTE_ALIGN_OFFSET(offset);
2385 if(is_fragmented){
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);
2390 offset += length;
2391 fragmented_length += length;
2392 goto next_fragment2;
2394 if(fragmented_length){
2395 if(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);
2404 else
2405 out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, length, named_bits, num_named_bits);
2407 /* XXX: ?? */
2408 /*val_start = offset>>3;*/
2409 /*val_length = (length+7)/8;*/
2410 offset+=length;
2412 if (value_tvb)
2413 *value_tvb = out_tvb;
2414 if (len)
2415 *len = fragmented_length ? fragmented_length : length;
2417 return offset;
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);
2432 return offset;
2435 /* this function dissects an OCTET STRING
2436 16.1
2437 16.2
2438 16.3
2439 16.4
2440 16.5
2441 16.6
2442 16.7
2443 16.8
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
2449 uint32_t
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) {
2470 min_len = 0;
2472 if (max_len==0) { /* 16.5 if the length is 0 bytes there will be no encoding */
2473 val_start = offset>>3;
2474 val_length = 0;
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");
2485 offset+=min_len*8;
2487 } else if ((min_len==max_len)&&(min_len<65536)) {
2488 /* 16.7 if length is fixed and less than to 64k*/
2490 /* align to byte */
2491 if (actx->aligned){
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");
2500 offset+=min_len*8;
2502 } else { /* 16.8 */
2503 if(max_len>0) {
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);
2509 } else {
2510 next_fragment:
2511 offset = dissect_per_length_determinant(tvb, offset, actx, tree,
2512 hf_per_octet_string_length, &length, &is_fragmented);
2515 if(length || fragmented_length){
2516 /* align to byte */
2517 if (actx->aligned){
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;
2527 goto next_fragment;
2529 if (fragmented_length) {
2530 if (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");
2536 } else {
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");
2542 } else {
2543 val_start = offset>>3;
2545 val_length = fragmented_length ? fragmented_length : length;
2546 offset+=length*8;
2549 if (hfi) {
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);
2556 else
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"));
2559 } else {
2560 if(out_tvb){
2561 actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, val_length, ENC_BIG_ENDIAN);
2562 }else{
2563 /* Length = 0 */
2564 actx->created_item = proto_tree_add_item(tree, hf_index, tvb, val_start, val_length, ENC_BIG_ENDIAN);
2569 if (value_tvb)
2570 *value_tvb = (out_tvb) ? out_tvb : tvb_new_subset_length(tvb, val_start, val_length);
2572 return offset;
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);
2587 return offset;
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);
2601 return offset;
2604 bool get_size_constraint_from_stack(asn1_ctx_t *actx, const char *name, int *pmin_len, int *pmax_len, bool *phas_extension)
2606 asn1_par_t *par;
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;
2618 par = par->next;
2619 if (!par || (par->ptype != ASN1_PAR_INTEGER)) return false;
2620 if (pmax_len) *pmax_len = par->value.v_integer;
2621 par = par->next;
2622 if (!par || (par->ptype != ASN1_PAR_BOOLEAN)) return false;
2623 if (phas_extension) *phas_extension = par->value.v_boolean;
2625 return true;
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,
2637 encoding CHOICE {
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. */
2646 static int
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;
2653 return offset;
2658 static int
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;
2663 return offset;
2668 static int
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;
2673 return offset;
2678 static int
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);
2682 return offset;
2687 static int
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);
2695 } else {
2696 actx->created_item = proto_tree_add_expert(tree, actx->pinfo, &ei_per_external_type, actx->external.octet_aligned, 0, -1);
2699 return offset;
2704 static int
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);
2712 } else {
2713 actx->created_item = proto_tree_add_expert(tree, actx->pinfo, &ei_per_external_type, actx->external.arbitrary, 0, -1);
2716 return offset;
2720 static const value_string per_External_encoding_vals[] = {
2721 { 0, "single-ASN1-type" },
2722 { 1, "octet-aligned" },
2723 { 2, "arbitrary" },
2724 { 0, NULL }
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 }
2734 static int
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);
2742 return offset;
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 }
2754 static int
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);
2759 return offset;
2762 uint32_t
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);
2770 return offset;
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");
2799 if (oid == NULL ||
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);
2806 return end_offset;
2809 void
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);
2826 void
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 }},
2896 { &hf_per_encoding,
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,
2915 NULL, HFILL }},
2916 #if 0
2917 { &hf_per_debug_pos,
2918 { "Current bit offset", "per.debug_pos",
2919 FT_UINT32, BASE_DEC, NULL, 0,
2920 NULL, HFILL }},
2921 #endif
2922 { &hf_per_internal_range,
2923 { "Range", "per.internal.range",
2924 FT_UINT64, BASE_DEC, NULL, 0,
2925 NULL, HFILL }},
2926 { &hf_per_internal_num_bits,
2927 { "Bitfield length", "per.internal.num_bits",
2928 FT_UINT32, BASE_DEC, NULL, 0,
2929 NULL, HFILL }},
2930 { &hf_per_internal_min,
2931 { "Min", "per.internal.min",
2932 FT_UINT32, BASE_DEC, NULL, 0,
2933 NULL, HFILL }},
2934 { &hf_per_internal_value,
2935 { "Bits", "per.internal.value",
2936 FT_UINT64, BASE_DEC, NULL, 0,
2937 NULL, HFILL }},
2938 { &hf_per_internal_min_int,
2939 { "Min", "per.internal.min_int",
2940 FT_INT32, BASE_DEC, NULL, 0,
2941 NULL, HFILL } },
2942 { &hf_per_internal_value_int,
2943 { "Bits", "per.internal.value_int",
2944 FT_INT64, BASE_DEC, NULL, 0,
2945 NULL, HFILL } },
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,
2949 NULL, HFILL } },
2953 static int *ett[] = {
2954 &ett_per_open_type,
2955 &ett_per_containing,
2956 &ett_per_sequence_of_item,
2957 &ett_per_External,
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
3013 * Local variables:
3014 * c-basic-offset: 8
3015 * tab-width: 8
3016 * indent-tabs-mode: t
3017 * End:
3019 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3020 * :indentSize=8:tabSize=8:noTabs=false: