dcerpc-netlogon: maintain netlogon_auth_vars for NetrServerAuthenticateKerberos
[wireshark-sm.git] / epan / dissectors / packet-per.c
blob29121a5341f86f21401f9b2cee53455f6d49f71b
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 offet 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(val_length == 0){
1760 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "unexpected length");
1762 if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
1763 val_tvb = tvb_new_octet_aligned(tvb, offset, val_length * 8);
1764 /* Add new data source if the offet was unaligned */
1765 if ((offset & 7) != 0) {
1766 add_new_data_source(actx->pinfo, val_tvb, "Unaligned OCTET STRING");
1768 end_offset = offset + val_length * 8;
1770 val = asn1_get_real(tvb_get_ptr(val_tvb, 0, val_length), val_length);
1771 actx->created_item = proto_tree_add_double(tree, hf_index, val_tvb, 0, val_length, val);
1773 if (value) *value = val;
1775 return end_offset;
1778 /* 22 Encoding the choice type */
1779 uint32_t
1780 dissect_per_choice(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int ett_index, const per_choice_t *choice, int *value)
1782 bool /*extension_present,*/ extension_flag;
1783 int extension_root_entries;
1784 uint32_t choice_index;
1785 int i, idx, cidx;
1786 uint32_t ext_length = 0;
1787 uint32_t old_offset = offset;
1788 proto_item *choice_item = NULL;
1789 proto_tree *choice_tree = NULL;
1791 DEBUG_ENTRY("dissect_per_choice");
1793 if (value) *value = -1;
1795 /* 22.5 */
1796 if (choice[0].extension == ASN1_NO_EXTENSIONS){
1797 /*extension_present = false; ?? */
1798 extension_flag = false;
1799 } else {
1800 /*extension_present = true; ?? */
1801 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_bit, &extension_flag);
1802 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1805 /* count the number of entries in the extension root and extension addition */
1806 extension_root_entries = 0;
1807 for (i=0; choice[i].p_id; i++) {
1808 switch(choice[i].extension){
1809 case ASN1_NO_EXTENSIONS:
1810 case ASN1_EXTENSION_ROOT:
1811 extension_root_entries++;
1812 break;
1813 case ASN1_NOT_EXTENSION_ROOT:
1814 break;
1818 if (!extension_flag) { /* 22.6, 22.7 */
1819 if (extension_root_entries == 1) { /* 22.5 */
1820 choice_index = 0;
1821 } else {
1822 offset = dissect_per_constrained_integer(tvb, offset, actx,
1823 tree, hf_per_choice_index, 0, extension_root_entries - 1,
1824 &choice_index, false);
1825 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1828 idx = -1; cidx = choice_index;
1829 for (i=0; choice[i].p_id; i++) {
1830 if(choice[i].extension != ASN1_NOT_EXTENSION_ROOT){
1831 if (!cidx) { idx = i; break; }
1832 cidx--;
1835 } else { /* 22.8 */
1836 offset = dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_choice_extension_index, &choice_index);
1837 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &ext_length, NULL);
1839 idx = -1; cidx = choice_index;
1840 for (i=0; choice[i].p_id; i++) {
1841 if(choice[i].extension == ASN1_NOT_EXTENSION_ROOT){
1842 if (!cidx) { idx = i; break; }
1843 cidx--;
1848 if (idx != -1) {
1849 choice_item = proto_tree_add_uint(tree, hf_index, tvb, old_offset>>3, 0, choice[idx].value);
1850 choice_tree = proto_item_add_subtree(choice_item, ett_index);
1851 if (!extension_flag) {
1852 offset = choice[idx].func(tvb, offset, actx, choice_tree, *choice[idx].p_id);
1853 } else {
1854 choice[idx].func(tvb, offset, actx, choice_tree, *choice[idx].p_id);
1855 offset += ext_length * 8;
1857 proto_item_set_len(choice_item, BLEN(old_offset, offset));
1858 } else {
1859 if (!extension_flag) {
1860 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "unknown extension root index in choice");
1861 } else {
1862 offset += ext_length * 8;
1863 proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_choice_extension_unknown,
1864 tvb, old_offset>>3, BLEN(old_offset, offset),
1865 "Choice no. %d in extension", choice_index);
1869 if (value && (idx != -1))
1870 *value = choice[idx].value;
1872 return offset;
1876 static const char *
1877 index_get_optional_name(const per_sequence_t *sequence, int idx)
1879 int i;
1880 header_field_info *hfi;
1882 for(i=0;sequence[i].p_id;i++){
1883 if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1884 if (idx == 0) {
1885 hfi = proto_registrar_get_nth(*sequence[i].p_id);
1886 return (hfi) ? hfi->name : "<unknown field>";
1888 idx--;
1891 return "<unknown type>";
1894 static const char *
1895 index_get_extension_name(const per_sequence_t *sequence, int idx)
1897 int i;
1898 header_field_info *hfi;
1900 for(i=0;sequence[i].p_id;i++){
1901 if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
1902 if (idx == 0) {
1903 if (*sequence[i].p_id == -1 || *sequence[i].p_id == 0) return "extension addition group";
1904 hfi = proto_registrar_get_nth(*sequence[i].p_id);
1905 return (hfi) ? hfi->name : "<unknown field>";
1907 idx--;
1910 return "<unknown type>";
1913 static const char *
1914 index_get_field_name(const per_sequence_t *sequence, int idx)
1916 if (sequence) {
1917 header_field_info *hfi = proto_registrar_get_nth(*sequence[idx].p_id);
1919 if (hfi) {
1920 return hfi->name;
1923 return "<unknown field>";
1926 /* this functions decodes a SEQUENCE
1927 it can only handle SEQUENCES with at most 32 DEFAULT or OPTIONAL fields
1928 18.1 extension bit
1929 18.2 optional/default items in root
1930 18.3 we ignore the case where n>64K
1931 18.4 the root sequence
1932 18.5
1933 18.6
1934 18.7
1935 18.8
1936 18.9
1938 uint32_t
1939 dissect_per_sequence(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, int ett_index, const per_sequence_t *sequence)
1941 bool /*extension_present,*/ extension_flag, optional_field_flag;
1942 proto_item *item;
1943 proto_tree *tree;
1944 uint32_t old_offset=offset;
1945 uint32_t i, j, num_opts;
1946 uint32_t optional_mask[SEQ_MAX_COMPONENTS>>5];
1948 DEBUG_ENTRY("dissect_per_sequence");
1949 DISSECTOR_ASSERT(sequence);
1951 item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, ENC_BIG_ENDIAN);
1952 tree=proto_item_add_subtree(item, ett_index);
1955 /* first check if there should be an extension bit for this CHOICE.
1956 we do this by just checking the first choice arm
1958 /* 18.1 */
1959 extension_flag=0;
1960 if(sequence[0].extension==ASN1_NO_EXTENSIONS){
1961 /*extension_present=0; ?? */
1962 } else {
1963 /*extension_present=1; ?? */
1964 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_bit, &extension_flag);
1965 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1967 /* 18.2 */
1968 num_opts=0;
1969 for(i=0;sequence[i].p_id;i++){
1970 if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1971 num_opts++;
1974 if (num_opts > SEQ_MAX_COMPONENTS) {
1975 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too many optional/default components");
1978 memset(optional_mask, 0, sizeof(optional_mask));
1979 for(i=0;i<num_opts;i++){
1980 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_optional_field_bit, &optional_field_flag);
1981 if (tree) {
1982 proto_item_append_text(actx->created_item, " (%s %s present)",
1983 index_get_optional_name(sequence, i), optional_field_flag?"is":"is NOT");
1985 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1986 if(optional_field_flag){
1987 optional_mask[i>>5]|=0x80000000>>(i&0x1f);
1992 /* 18.4 */
1993 for(i=0,j=0;sequence[i].p_id;i++){
1994 if( (sequence[i].extension==ASN1_NO_EXTENSIONS)
1995 || (sequence[i].extension==ASN1_EXTENSION_ROOT) ){
1996 if(sequence[i].optional==ASN1_OPTIONAL){
1997 bool is_present;
1998 if (num_opts == 0){
1999 continue;
2001 is_present=(0x80000000>>(j&0x1f))&optional_mask[j>>5];
2002 num_opts--;
2003 j++;
2004 if(!is_present){
2005 continue;
2008 if(sequence[i].func){
2009 offset=sequence[i].func(tvb, offset, actx, tree, *sequence[i].p_id);
2010 } else {
2011 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, index_get_field_name(sequence, i));
2017 if(extension_flag){
2018 bool extension_bit;
2019 uint32_t num_known_extensions;
2020 uint32_t num_extensions;
2021 uint32_t extension_mask;
2023 offset=dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_num_sequence_extensions, &num_extensions);
2024 /* the X.691 standard is VERY unclear here.
2025 there is no mention that the lower bound lb for this
2026 (apparently) semiconstrained value is 1,
2027 apart from the NOTE: comment in 18.8 that this value can
2028 not be 0.
2029 In my book, there is a semantic difference between having
2030 a comment that says that the value can not be zero
2031 and stating that the lb is 1.
2032 I don't know if this is right or not but it makes
2033 some of the very few captures I have decode properly.
2035 It could also be that the captures I have are generated by
2036 a broken implementation.
2037 If this is wrong and you don't report it as a bug
2038 then it won't get fixed!
2040 num_extensions+=1;
2041 if (num_extensions > 32) {
2042 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too many extensions");
2045 extension_mask=0;
2046 for(i=0;i<num_extensions;i++){
2047 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_bit);
2048 if (tree) {
2049 proto_item_append_text(actx->created_item, " (%s %s present)",
2050 index_get_extension_name(sequence, i), extension_bit?"is":"is NOT");
2052 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
2054 extension_mask=(extension_mask<<1)|extension_bit;
2057 /* find how many extensions we know about */
2058 num_known_extensions=0;
2059 for(i=0;sequence[i].p_id;i++){
2060 if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
2061 num_known_extensions++;
2065 /* decode the extensions one by one */
2066 for(i=0;i<num_extensions;i++){
2067 uint32_t length;
2068 uint32_t new_offset;
2069 int32_t difference;
2070 uint32_t extension_index;
2071 uint32_t k;
2073 if(!((1U<<(num_extensions-1-i))&extension_mask)){
2074 /* this extension is not encoded in this PDU */
2075 continue;
2078 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &length, NULL);
2080 if(i>=num_known_extensions){
2081 /* we don't know how to decode this extension */
2082 offset+=length*8;
2083 expert_add_info(actx->pinfo, item, &ei_per_sequence_extension_unknown);
2084 continue;
2087 extension_index=0;
2088 for(j=0,k=0;sequence[j].p_id;j++){
2089 if(sequence[j].extension==ASN1_NOT_EXTENSION_ROOT){
2090 if(k==i){
2091 extension_index=j;
2092 break;
2094 k++;
2098 if(sequence[extension_index].func){
2099 new_offset=sequence[extension_index].func(tvb, offset, actx, tree, *sequence[extension_index].p_id);
2100 offset+=length*8;
2101 difference = offset - new_offset;
2102 /* A difference of 7 or less might be byte aligning */
2103 /* Difference could be 8 if open type has no bits and the length is 1 */
2104 if ((length > 1) && (difference > 7)) {
2105 proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_encoding_error, tvb, new_offset>>3, (offset-new_offset)>>3,
2106 "Possible encoding error full length not decoded. Open type length %u, decoded %u",length, length - (difference>>3));
2108 else if (difference < 0) {
2109 proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_encoding_error, tvb, new_offset>>3, (offset-new_offset)>>3,
2110 "Possible encoding error open type length less than dissected bits. Open type length %u, decoded %u", length, length - (difference>>3));
2112 } else {
2113 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, index_get_field_name(sequence, extension_index));
2114 offset+=length*8;
2119 proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
2120 actx->created_item = item;
2121 return offset;
2124 uint32_t
2125 dissect_per_sequence_eag(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, const per_sequence_t *sequence)
2127 bool optional_field_flag;
2128 uint32_t i, j, num_opts;
2129 uint32_t optional_mask[SEQ_MAX_COMPONENTS>>5];
2131 DEBUG_ENTRY("dissect_per_sequence_eag");
2133 num_opts=0;
2134 for(i=0;sequence[i].p_id;i++){
2135 if(sequence[i].optional==ASN1_OPTIONAL){
2136 num_opts++;
2139 if (num_opts > SEQ_MAX_COMPONENTS) {
2140 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too many optional/default components");
2143 memset(optional_mask, 0, sizeof(optional_mask));
2144 for(i=0;i<num_opts;i++){
2145 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_optional_field_bit, &optional_field_flag);
2146 if (tree) {
2147 proto_item_append_text(actx->created_item, " (%s %s present)",
2148 index_get_optional_name(sequence, i), optional_field_flag?"is":"is NOT");
2150 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
2151 if(optional_field_flag){
2152 optional_mask[i>>5]|=0x80000000>>(i&0x1f);
2156 for(i=0,j=0;sequence[i].p_id;i++){
2157 if(sequence[i].optional==ASN1_OPTIONAL){
2158 bool is_present;
2159 if (num_opts == 0){
2160 continue;
2162 is_present=(0x80000000>>(j&0x1f))&optional_mask[j>>5];
2163 num_opts--;
2164 j++;
2165 if(!is_present){
2166 continue;
2169 if(sequence[i].func){
2170 offset=sequence[i].func(tvb, offset, actx, tree, *sequence[i].p_id);
2171 } else {
2172 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, index_get_field_name(sequence, i));
2176 return offset;
2180 /* 15 Encoding the bitstring type
2182 max_len or min_len == NO_BOUND means there is no lower/upper constraint
2186 static tvbuff_t *dissect_per_bit_string_display(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, header_field_info *hfi, uint32_t length, int * const *named_bits, int num_named_bits _U_)
2188 tvbuff_t *out_tvb = NULL;
2189 uint32_t pad_length=0;
2190 uint64_t value;
2192 out_tvb = tvb_new_octet_aligned(tvb, offset, length);
2193 add_new_data_source(actx->pinfo, out_tvb, "Bitstring tvb");
2195 if (hfi) {
2196 actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, -1, ENC_BIG_ENDIAN);
2197 proto_item_append_text(actx->created_item, " [bit length %u", length);
2198 if (length%8) {
2199 pad_length = 8-(length%8);
2200 proto_item_append_text(actx->created_item, ", %u LSB pad bits", pad_length);
2203 if (length<=64) { /* if read into 64 bits also handle length <= 24, 40, 48, 56 bits */
2204 if (length<=8) {
2205 value = tvb_get_bits8(out_tvb, 0, length);
2206 }else if (length<=16) {
2207 value = tvb_get_bits16(out_tvb, 0, length, ENC_BIG_ENDIAN);
2208 }else if (length<=24) { /* first read 16 and then the remaining bits */
2209 value = tvb_get_bits16(out_tvb, 0, 16, ENC_BIG_ENDIAN);
2210 value <<= 8 - pad_length;
2211 value |= tvb_get_bits8(out_tvb, 16, length - 16);
2212 }else if (length<=32) {
2213 value = tvb_get_bits32(out_tvb, 0, length, ENC_BIG_ENDIAN);
2214 }else if (length<=40) { /* first read 32 and then the remaining bits */
2215 value = tvb_get_bits32(out_tvb, 0, 32, ENC_BIG_ENDIAN);
2216 value <<= 8 - pad_length;
2217 value |= tvb_get_bits8(out_tvb, 32, length - 32);
2218 }else if (length<=48) { /* first read 32 and then the remaining bits */
2219 value = tvb_get_bits32(out_tvb, 0, 32, ENC_BIG_ENDIAN);
2220 value <<= 16 - pad_length;
2221 value |= tvb_get_bits16(out_tvb, 32, length - 32, ENC_BIG_ENDIAN);
2222 }else if (length<=56) { /* first read 32 and 16 then the remaining bits */
2223 value = tvb_get_bits32(out_tvb, 0, 32, ENC_BIG_ENDIAN);
2224 value <<= 16;
2225 value |= tvb_get_bits16(out_tvb, 32, 16, ENC_BIG_ENDIAN);
2226 value <<= 8 - pad_length;
2227 value |= tvb_get_bits8(out_tvb, 48, length - 48);
2228 }else {
2229 value = tvb_get_bits64(out_tvb, 0, length, ENC_BIG_ENDIAN);
2231 proto_item_append_text(actx->created_item, ", %s decimal value %" PRIu64,
2232 decode_bits_in_field(actx->pinfo->pool, 0, length, value, ENC_BIG_ENDIAN), value);
2233 if (named_bits) {
2234 const uint32_t named_bits_bytelen = (num_named_bits + 7) / 8;
2235 proto_tree *subtree = proto_item_add_subtree(actx->created_item, ett_per_named_bits);
2236 for (uint32_t i = 0; i < named_bits_bytelen; i++) {
2237 // If less data is available than the number of named bits, then
2238 // the trailing (right) bits are assumed to be 0.
2239 value = 0;
2240 const uint32_t bit_offset = 8 * i;
2241 if (bit_offset < length) {
2242 value = tvb_get_uint8(out_tvb, i);
2245 // Process 8 bits at a time instead of 64, each field masks a
2246 // single byte.
2247 int* const * section_named_bits = named_bits + bit_offset;
2248 int* flags[9];
2249 if (num_named_bits - bit_offset > 8) {
2250 memcpy(&flags[0], named_bits + bit_offset, 8 * sizeof(int*));
2251 flags[8] = NULL;
2252 section_named_bits = flags;
2255 // TODO should non-zero pad bits be masked from the value?
2256 // When trailing zeroes are not present in the data, mark the
2257 // last byte for the lack of a better alternative.
2258 proto_tree_add_bitmask_list_value(subtree, out_tvb, offset + MIN(i, length - 1), 1, section_named_bits, value);
2262 proto_item_append_text(actx->created_item, "]");
2265 return out_tvb;
2267 uint32_t
2268 dissect_per_bit_string(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, bool has_extension, int * const *named_bits, int num_named_bits, tvbuff_t **value_tvb, int *len)
2270 /*int val_start, val_length;*/
2271 uint32_t length, fragmented_length = 0;
2272 header_field_info *hfi;
2273 bool is_fragmented = false;
2274 tvbuff_t *fragmented_tvb = NULL, *out_tvb = NULL, *fragment_tvb = NULL;
2276 hfi = (hf_index <= 0) ? NULL : proto_registrar_get_nth(hf_index);
2278 DEBUG_ENTRY("dissect_per_bit_string");
2279 /* 15.8 if the length is 0 bytes there will be no encoding */
2280 if(max_len==0) {
2281 if (value_tvb)
2282 *value_tvb = out_tvb;
2283 if (len)
2284 *len = 0;
2285 return offset;
2288 if (min_len == NO_BOUND) {
2289 min_len = 0;
2291 /* 15.6 If an extension marker is present in the size constraint specification of the bitstring type,
2292 * a single bit shall be added to the field-list in a bit-field of length one.
2293 * The bit shall be set to 1 if the length of this encoding is not within the range of the extension root,
2294 * and zero otherwise.
2296 if (has_extension) {
2297 bool extension_present;
2298 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
2299 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
2300 if(extension_present){
2301 next_fragment1:
2302 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_bit_string_length, &length, &is_fragmented);
2303 if(length || fragmented_length){
2304 /* align to byte */
2305 if (actx->aligned){
2306 BYTE_ALIGN_OFFSET(offset);
2308 if(is_fragmented){
2309 fragment_tvb = tvb_new_octet_aligned(tvb, offset, length);
2310 if(fragmented_length==0)
2311 fragmented_tvb = tvb_new_composite();
2312 tvb_composite_append(fragmented_tvb, fragment_tvb);
2313 offset += length;
2314 fragmented_length += length;
2315 goto next_fragment1;
2317 if(fragmented_length){
2318 if(length){
2319 tvb_composite_append(fragmented_tvb, tvb_new_octet_aligned(tvb, offset, length));
2320 fragmented_length += length;
2322 tvb_composite_finalize(fragmented_tvb);
2323 add_new_data_source(actx->pinfo, fragmented_tvb, "Fragmented bitstring tvb");
2324 out_tvb = dissect_per_bit_string_display(fragmented_tvb, 0, actx, tree, hf_index, hfi,
2325 fragmented_length, named_bits, num_named_bits);
2327 else
2328 out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, length, named_bits, num_named_bits);
2330 /* XXX: ?? */
2331 /*val_start = offset>>3;*/
2332 /*val_length = (length+7)/8;*/
2333 offset+=length;
2335 if (value_tvb)
2336 *value_tvb = out_tvb;
2337 if (len)
2338 *len = fragmented_length ? fragmented_length : length;
2340 return offset;
2344 /* 15.9 if length is fixed and less than or equal to sixteen bits*/
2345 if ((min_len==max_len) && (max_len<=16)) {
2346 out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, min_len, named_bits, num_named_bits);
2347 offset+=min_len;
2348 if (value_tvb)
2349 *value_tvb = out_tvb;
2350 if (len)
2351 *len = min_len;
2352 return offset;
2356 /* 15.10 if length is fixed and less than to 64kbits*/
2357 if((min_len==max_len)&&(min_len<65536)){
2358 /* (octet-aligned in the ALIGNED variant)
2359 * align to byte
2361 if (actx->aligned){
2362 BYTE_ALIGN_OFFSET(offset);
2364 out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, min_len, named_bits, num_named_bits);
2365 offset+=min_len;
2366 if (value_tvb)
2367 *value_tvb = out_tvb;
2368 if (len)
2369 *len = min_len;
2370 return offset;
2373 /* 15.11 */
2374 if (max_len != NO_BOUND && max_len < 65536) {
2375 offset=dissect_per_constrained_integer(tvb, offset, actx,
2376 tree, hf_per_bit_string_length, min_len, max_len,
2377 &length, false);
2378 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
2379 } else {
2380 next_fragment2:
2381 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_bit_string_length, &length, &is_fragmented);
2383 if(length || fragmented_length){
2384 /* align to byte */
2385 if (actx->aligned){
2386 BYTE_ALIGN_OFFSET(offset);
2388 if(is_fragmented){
2389 fragment_tvb = tvb_new_octet_aligned(tvb, offset, length);
2390 if(fragmented_length==0)
2391 fragmented_tvb = tvb_new_composite();
2392 tvb_composite_append(fragmented_tvb, fragment_tvb);
2393 offset += length;
2394 fragmented_length += length;
2395 goto next_fragment2;
2397 if(fragmented_length){
2398 if(length){
2399 tvb_composite_append(fragmented_tvb, tvb_new_octet_aligned(tvb, offset, length));
2400 fragmented_length += length;
2402 tvb_composite_finalize(fragmented_tvb);
2403 add_new_data_source(actx->pinfo, fragmented_tvb, "Fragmented bitstring tvb");
2404 out_tvb = dissect_per_bit_string_display(fragmented_tvb, 0, actx, tree, hf_index, hfi,
2405 fragmented_length, named_bits, num_named_bits);
2407 else
2408 out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, length, named_bits, num_named_bits);
2410 /* XXX: ?? */
2411 /*val_start = offset>>3;*/
2412 /*val_length = (length+7)/8;*/
2413 offset+=length;
2415 if (value_tvb)
2416 *value_tvb = out_tvb;
2417 if (len)
2418 *len = fragmented_length ? fragmented_length : length;
2420 return offset;
2423 uint32_t dissect_per_bit_string_containing_pdu_new(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, bool has_extension, dissector_t type_cb)
2425 tvbuff_t *val_tvb = NULL;
2426 proto_tree *subtree = tree;
2428 offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, NULL, 0, &val_tvb, NULL);
2430 if (type_cb && val_tvb) {
2431 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2432 type_cb(val_tvb, actx->pinfo, subtree, NULL);
2435 return offset;
2438 /* this function dissects an OCTET STRING
2439 16.1
2440 16.2
2441 16.3
2442 16.4
2443 16.5
2444 16.6
2445 16.7
2446 16.8
2448 max_len or min_len == NO_BOUND means there is no lower/upper constraint
2450 hf_index can either be a FT_BYTES or an FT_STRING
2452 uint32_t
2453 dissect_per_octet_string(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, bool has_extension, tvbuff_t **value_tvb)
2455 int val_start = 0, val_length;
2456 uint32_t length = 0, fragmented_length = 0;
2457 header_field_info *hfi;
2458 bool is_fragmented = false;
2459 tvbuff_t *out_tvb = NULL, *fragment_tvb = NULL;
2461 hfi = (hf_index <= 0) ? NULL : proto_registrar_get_nth(hf_index);
2463 DEBUG_ENTRY("dissect_per_octet_string");
2465 if (has_extension) { /* 16.3 an extension marker is present */
2466 bool extension_present;
2467 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
2468 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
2469 if (extension_present) max_len = NO_BOUND; /* skip to 16.8 */
2472 if (min_len == NO_BOUND) {
2473 min_len = 0;
2475 if (max_len==0) { /* 16.5 if the length is 0 bytes there will be no encoding */
2476 val_start = offset>>3;
2477 val_length = 0;
2479 } else if((min_len==max_len)&&(max_len<=2)) {
2480 /* 16.6 if length is fixed and less than or equal to two bytes*/
2481 val_start = offset>>3;
2482 val_length = min_len;
2483 out_tvb = tvb_new_octet_aligned(tvb, offset, val_length * 8);
2484 /* Add new data source if the offet was unaligned */
2485 if ((offset & 7) != 0) {
2486 add_new_data_source(actx->pinfo, out_tvb, "Unaligned OCTET STRING");
2488 offset+=min_len*8;
2490 } else if ((min_len==max_len)&&(min_len<65536)) {
2491 /* 16.7 if length is fixed and less than to 64k*/
2493 /* align to byte */
2494 if (actx->aligned){
2495 BYTE_ALIGN_OFFSET(offset);
2497 val_start = offset>>3;
2498 val_length = min_len;
2499 out_tvb = tvb_new_octet_aligned(tvb, offset, val_length * 8);
2500 if ((offset & 7) != 0) {
2501 add_new_data_source(actx->pinfo, out_tvb, "Unaligned OCTET STRING");
2503 offset+=min_len*8;
2505 } else { /* 16.8 */
2506 if(max_len>0) {
2507 offset = dissect_per_constrained_integer(tvb, offset, actx, tree,
2508 hf_per_octet_string_length, min_len, max_len, &length, false);
2510 if (!display_internal_per_fields)
2511 proto_item_set_hidden(actx->created_item);
2512 } else {
2513 next_fragment:
2514 offset = dissect_per_length_determinant(tvb, offset, actx, tree,
2515 hf_per_octet_string_length, &length, &is_fragmented);
2518 if(length || fragmented_length){
2519 /* align to byte */
2520 if (actx->aligned){
2521 BYTE_ALIGN_OFFSET(offset);
2523 if (is_fragmented) {
2524 fragment_tvb = tvb_new_octet_aligned(tvb, offset, length * 8);
2525 if (fragmented_length == 0)
2526 out_tvb = tvb_new_composite();
2527 tvb_composite_append(out_tvb, fragment_tvb);
2528 offset += length * 8;
2529 fragmented_length += length;
2530 goto next_fragment;
2532 if (fragmented_length) {
2533 if (length) {
2534 tvb_composite_append(out_tvb, tvb_new_octet_aligned(tvb, offset, length * 8));
2535 fragmented_length += length;
2537 tvb_composite_finalize(out_tvb);
2538 add_new_data_source(actx->pinfo, out_tvb, "Fragmented OCTET STRING");
2539 } else {
2540 out_tvb = tvb_new_octet_aligned(tvb, offset, length * 8);
2541 if ((offset & 7) != 0) {
2542 add_new_data_source(actx->pinfo, out_tvb, "Unaligned OCTET STRING");
2545 } else {
2546 val_start = offset>>3;
2548 val_length = fragmented_length ? fragmented_length : length;
2549 offset+=length*8;
2552 if (hfi) {
2553 if (FT_IS_UINT(hfi->type)||FT_IS_INT(hfi->type)) {
2554 /* If the type has been converted to FT_UINT or FT_INT in the .cnf file
2555 * display the length of this octet string instead of the octetstring itself
2557 if (FT_IS_UINT(hfi->type))
2558 actx->created_item = proto_tree_add_uint(tree, hf_index, out_tvb, 0, val_length, val_length);
2559 else
2560 actx->created_item = proto_tree_add_int(tree, hf_index, out_tvb, 0, val_length, val_length);
2561 proto_item_append_text(actx->created_item, plurality(val_length, " octet", " octets"));
2562 } else {
2563 if(out_tvb){
2564 actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, val_length, ENC_BIG_ENDIAN);
2565 }else{
2566 /* Length = 0 */
2567 actx->created_item = proto_tree_add_item(tree, hf_index, tvb, val_start, val_length, ENC_BIG_ENDIAN);
2572 if (value_tvb)
2573 *value_tvb = (out_tvb) ? out_tvb : tvb_new_subset_length(tvb, val_start, val_length);
2575 return offset;
2578 uint32_t dissect_per_octet_string_containing_pdu_new(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, bool has_extension, dissector_t type_cb)
2580 tvbuff_t *val_tvb = NULL;
2581 proto_tree *subtree = tree;
2583 offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, &val_tvb);
2585 if (type_cb && val_tvb && (tvb_reported_length(val_tvb) > 0)) {
2586 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2587 type_cb(val_tvb, actx->pinfo, subtree, NULL);
2590 return offset;
2593 uint32_t dissect_per_size_constrained_type(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, per_type_fn type_cb, const char *name, int min_len, int max_len, bool has_extension)
2595 asn1_stack_frame_push(actx, name);
2596 asn1_param_push_integer(actx, min_len);
2597 asn1_param_push_integer(actx, max_len);
2598 asn1_param_push_boolean(actx, has_extension);
2600 offset = type_cb(tvb, offset, actx, tree, hf_index);
2602 asn1_stack_frame_pop(actx, name);
2604 return offset;
2607 bool get_size_constraint_from_stack(asn1_ctx_t *actx, const char *name, int *pmin_len, int *pmax_len, bool *phas_extension)
2609 asn1_par_t *par;
2611 if (pmin_len) *pmin_len = NO_BOUND;
2612 if (pmax_len) *pmax_len = NO_BOUND;
2613 if (phas_extension) *phas_extension = false;
2615 if (!actx->stack) return false;
2616 if (strcmp(actx->stack->name, name)) return false;
2618 par = actx->stack->par;
2619 if (!par || (par->ptype != ASN1_PAR_INTEGER)) return false;
2620 if (pmin_len) *pmin_len = par->value.v_integer;
2621 par = par->next;
2622 if (!par || (par->ptype != ASN1_PAR_INTEGER)) return false;
2623 if (pmax_len) *pmax_len = par->value.v_integer;
2624 par = par->next;
2625 if (!par || (par->ptype != ASN1_PAR_BOOLEAN)) return false;
2626 if (phas_extension) *phas_extension = par->value.v_boolean;
2628 return true;
2632 /* 26 Encoding of a value of the external type */
2634 /* code generated from definition in 26.1 */
2636 [UNIVERSAL 8] IMPLICIT SEQUENCE {
2637 direct-reference OBJECT IDENTIFIER OPTIONAL,
2638 indirect-reference INTEGER OPTIONAL,
2639 data-value-descriptor ObjectDescriptor OPTIONAL,
2640 encoding CHOICE {
2641 single-ASN1-type [0] ABSTRACT-SYNTAX.&Type,
2642 octet-aligned [1] IMPLICIT OCTET STRING,
2643 arbitrary [2] IMPLICIT BIT STRING
2647 /* NOTE: This sequence type differs from that in ITU-T Rec. X.680 | ISO/IEC 8824-1 for historical reasons. */
2649 static int
2650 dissect_per_T_direct_reference(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2652 DISSECTOR_ASSERT(actx);
2653 offset = dissect_per_object_identifier_str(tvb, offset, actx, tree, hf_index, &actx->external.direct_reference);
2655 actx->external.direct_ref_present = true;
2656 return offset;
2661 static int
2662 dissect_per_T_indirect_reference(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2663 offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, &actx->external.indirect_reference);
2665 actx->external.indirect_ref_present = true;
2666 return offset;
2671 static int
2672 dissect_per_T_data_value_descriptor(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2673 offset = dissect_per_object_descriptor(tvb, offset, actx, tree, hf_index, &actx->external.data_value_descriptor);
2675 actx->external.data_value_descr_present = true;
2676 return offset;
2681 static int
2682 dissect_per_T_single_ASN1_type(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2683 offset = dissect_per_open_type(tvb, offset, actx, tree, actx->external.hf_index, actx->external.u.per.type_cb);
2685 return offset;
2690 static int
2691 dissect_per_T_octet_aligned(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2692 offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index,
2693 NO_BOUND, NO_BOUND, false, &actx->external.octet_aligned);
2695 if (actx->external.octet_aligned) {
2696 if (actx->external.u.per.type_cb) {
2697 actx->external.u.per.type_cb(actx->external.octet_aligned, 0, actx, tree, actx->external.hf_index);
2698 } else {
2699 actx->created_item = proto_tree_add_expert(tree, actx->pinfo, &ei_per_external_type, actx->external.octet_aligned, 0, -1);
2702 return offset;
2707 static int
2708 dissect_per_T_arbitrary(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2709 offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index,
2710 NO_BOUND, NO_BOUND, false, NULL, 0, &actx->external.arbitrary, NULL);
2712 if (actx->external.arbitrary) {
2713 if (actx->external.u.per.type_cb) {
2714 actx->external.u.per.type_cb(actx->external.arbitrary, 0, actx, tree, actx->external.hf_index);
2715 } else {
2716 actx->created_item = proto_tree_add_expert(tree, actx->pinfo, &ei_per_external_type, actx->external.arbitrary, 0, -1);
2719 return offset;
2723 static const value_string per_External_encoding_vals[] = {
2724 { 0, "single-ASN1-type" },
2725 { 1, "octet-aligned" },
2726 { 2, "arbitrary" },
2727 { 0, NULL }
2730 static const per_choice_t External_encoding_choice[] = {
2731 { 0, &hf_per_single_ASN1_type, ASN1_NO_EXTENSIONS , dissect_per_T_single_ASN1_type },
2732 { 1, &hf_per_octet_aligned , ASN1_NO_EXTENSIONS , dissect_per_T_octet_aligned },
2733 { 2, &hf_per_arbitrary , ASN1_NO_EXTENSIONS , dissect_per_T_arbitrary },
2734 { 0, NULL, 0, NULL }
2737 static int
2738 dissect_per_External_encoding(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2739 // This assertion is used to remove clang's warning.
2740 DISSECTOR_ASSERT(actx);
2741 offset = dissect_per_choice(tvb, offset, actx, tree, hf_index,
2742 ett_per_External_encoding, External_encoding_choice,
2743 &actx->external.encoding);
2745 return offset;
2749 static const per_sequence_t External_sequence[] = {
2750 { &hf_per_direct_reference, ASN1_NO_EXTENSIONS , ASN1_OPTIONAL , dissect_per_T_direct_reference },
2751 { &hf_per_indirect_reference, ASN1_NO_EXTENSIONS , ASN1_OPTIONAL , dissect_per_T_indirect_reference },
2752 { &hf_per_data_value_descriptor, ASN1_NO_EXTENSIONS , ASN1_OPTIONAL , dissect_per_T_data_value_descriptor },
2753 { &hf_per_encoding , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_per_External_encoding },
2754 { NULL, 0, 0, NULL }
2757 static int
2758 dissect_per_External(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2759 offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
2760 ett_per_External, External_sequence);
2762 return offset;
2765 uint32_t
2766 dissect_per_external_type(tvbuff_t *tvb _U_, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree _U_, int hf_index _U_, per_type_fn type_cb)
2768 asn1_ctx_clean_external(actx);
2769 actx->external.u.per.type_cb = type_cb;
2770 offset = dissect_per_External(tvb, offset, actx, tree, hf_index);
2772 asn1_ctx_clean_external(actx);
2773 return offset;
2777 * Calls the callback defined with register_per_oid_dissector() if found.
2778 * Offset is in bits.
2782 call_per_oid_callback(const char *oid, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, asn1_ctx_t *actx, int hf_index)
2784 uint32_t type_length, end_offset, start_offset;
2785 tvbuff_t *val_tvb = NULL;
2787 start_offset = offset;
2788 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &type_length, NULL);
2789 if(type_length == 0){
2790 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "unexpected length");
2792 if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
2793 end_offset = offset + type_length;
2796 /* length in bits */
2797 val_tvb = tvb_new_octet_aligned(tvb, offset, type_length * 8);
2798 if ((offset & 7) != 0) {
2799 add_new_data_source(actx->pinfo, val_tvb, "Unaligned OCTET STRING");
2802 if (oid == NULL ||
2803 (dissector_try_string(per_oid_dissector_table, oid, val_tvb, pinfo, tree, actx)) == 0)
2805 proto_tree_add_expert(tree, pinfo, &ei_per_oid_not_implemented, val_tvb, 0, -1);
2806 dissect_per_open_type(tvb, start_offset, actx, tree, hf_index, NULL);
2809 return end_offset;
2812 void
2813 register_per_oid_dissector(const char *oid, dissector_t dissector, int proto, const char *name)
2815 dissector_handle_t dissector_handle;
2817 /* FIXME: This would be better as register_dissector()
2818 * so the dissector could be referenced by name
2819 * from the command line, Lua, etc.
2820 * But can we blindly trust name to be a unique dissector name,
2821 * or should we prefix "per." or something?
2823 dissector_handle = create_dissector_handle(dissector, proto);
2824 dissector_add_string("per.oid", oid, dissector_handle);
2825 oid_add_from_string(name, oid);
2829 void
2830 proto_register_per(void)
2832 static hf_register_info hf[] = {
2833 { &hf_per_num_sequence_extensions,
2834 { "Number of Sequence Extensions", "per.num_sequence_extensions", FT_UINT32, BASE_DEC,
2835 NULL, 0, "Number of extensions encoded in this sequence", HFILL }},
2836 { &hf_per_choice_index,
2837 { "Choice Index", "per.choice_index", FT_UINT32, BASE_DEC,
2838 NULL, 0, "Which index of the Choice within extension root is encoded", HFILL }},
2839 { &hf_per_choice_extension_index,
2840 { "Choice Extension Index", "per.choice_extension_index", FT_UINT32, BASE_DEC,
2841 NULL, 0, "Which index of the Choice within extension addition is encoded", HFILL }},
2842 { &hf_per_enum_index,
2843 { "Enumerated Index", "per.enum_index", FT_UINT32, BASE_DEC,
2844 NULL, 0, "Which index of the Enumerated within extension root is encoded", HFILL }},
2845 { &hf_per_enum_extension_index,
2846 { "Enumerated Extension Index", "per.enum_extension_index", FT_UINT32, BASE_DEC,
2847 NULL, 0, "Which index of the Enumerated within extension addition is encoded", HFILL }},
2848 { &hf_per_GeneralString_length,
2849 { "GeneralString Length", "per.generalstring_length", FT_UINT32, BASE_DEC,
2850 NULL, 0, "Length of the GeneralString", HFILL }},
2851 { &hf_per_extension_bit,
2852 { "Extension Bit", "per.extension_bit", FT_BOOLEAN, 8,
2853 TFS(&tfs_extension_bit), 0x01, "The extension bit of an aggregate", HFILL }},
2854 { &hf_per_extension_present_bit,
2855 { "Extension Present Bit", "per.extension_present_bit", FT_BOOLEAN, 8,
2856 NULL, 0x01, "Whether this optional extension is present or not", HFILL }},
2857 { &hf_per_small_number_bit,
2858 { "Small Number Bit", "per.small_number_bit", FT_BOOLEAN, 8,
2859 TFS(&tfs_small_number_bit), 0x01, "The small number bit for a section 10.6 integer", HFILL }},
2860 { &hf_per_optional_field_bit,
2861 { "Optional Field Bit", "per.optional_field_bit", FT_BOOLEAN, 8,
2862 NULL, 0x01, "This bit specifies the presence/absence of an optional field", HFILL }},
2863 { &hf_per_sequence_of_length,
2864 { "Sequence-Of Length", "per.sequence_of_length", FT_UINT32, BASE_DEC,
2865 NULL, 0, "Number of items in the Sequence Of", HFILL }},
2866 { &hf_per_object_identifier_length,
2867 { "Object Identifier Length", "per.object_length", FT_UINT32, BASE_DEC,
2868 NULL, 0, "Length of the object identifier", HFILL }},
2869 { &hf_per_open_type_length,
2870 { "Open Type Length", "per.open_type_length", FT_UINT32, BASE_DEC,
2871 NULL, 0, "Length of an open type encoding", HFILL }},
2872 { &hf_per_real_length,
2873 { "Real Length", "per.real_length", FT_UINT32, BASE_DEC,
2874 NULL, 0, "Length of an real encoding", HFILL }},
2875 { &hf_per_octet_string_length,
2876 { "Octet String Length", "per.octet_string_length", FT_UINT32, BASE_DEC,
2877 NULL, 0, "Number of bytes in the Octet String", HFILL }},
2878 { &hf_per_bit_string_length,
2879 { "Bit String Length", "per.bit_string_length", FT_UINT32, BASE_DEC,
2880 NULL, 0, "Number of bits in the Bit String", HFILL }},
2881 { &hf_per_normally_small_nonnegative_whole_number_length,
2882 { "Normally Small Non-negative Whole Number Length", "per.normally_small_nonnegative_whole_number_length", FT_UINT32, BASE_DEC,
2883 NULL, 0, "Number of bytes in the Normally Small Non-negative Whole Number", HFILL }},
2884 { &hf_per_const_int_len,
2885 { "Constrained Integer Length", "per.const_int_len", FT_UINT32, BASE_DEC,
2886 NULL, 0, "Number of bytes in the Constrained Integer", HFILL }},
2887 { &hf_per_direct_reference,
2888 { "direct-reference", "per.direct_reference",
2889 FT_OID, BASE_NONE, NULL, 0,
2890 "per.T_direct_reference", HFILL }},
2891 { &hf_per_indirect_reference,
2892 { "indirect-reference", "per.indirect_reference",
2893 FT_INT32, BASE_DEC, NULL, 0,
2894 "per.T_indirect_reference", HFILL }},
2895 { &hf_per_data_value_descriptor,
2896 { "data-value-descriptor", "per.data_value_descriptor",
2897 FT_STRING, BASE_NONE, NULL, 0,
2898 "per.T_data_value_descriptor", HFILL }},
2899 { &hf_per_encoding,
2900 { "encoding", "per.encoding",
2901 FT_UINT32, BASE_DEC, VALS(per_External_encoding_vals), 0,
2902 "per.External_encoding", HFILL }},
2903 { &hf_per_single_ASN1_type,
2904 { "single-ASN1-type", "per.single_ASN1_type",
2905 FT_NONE, BASE_NONE, NULL, 0,
2906 "per.T_single_ASN1_type", HFILL }},
2907 { &hf_per_octet_aligned,
2908 { "octet-aligned", "per.octet_aligned",
2909 FT_BYTES, BASE_NONE, NULL, 0,
2910 "per.T_octet_aligned", HFILL }},
2911 { &hf_per_arbitrary,
2912 { "arbitrary", "per.arbitrary",
2913 FT_BYTES, BASE_NONE, NULL, 0,
2914 "per.T_arbitrary", HFILL }},
2915 { &hf_per_integer_length,
2916 { "integer length", "per.integer_length",
2917 FT_UINT32, BASE_DEC, NULL, 0,
2918 NULL, HFILL }},
2919 #if 0
2920 { &hf_per_debug_pos,
2921 { "Current bit offset", "per.debug_pos",
2922 FT_UINT32, BASE_DEC, NULL, 0,
2923 NULL, HFILL }},
2924 #endif
2925 { &hf_per_internal_range,
2926 { "Range", "per.internal.range",
2927 FT_UINT64, BASE_DEC, NULL, 0,
2928 NULL, HFILL }},
2929 { &hf_per_internal_num_bits,
2930 { "Bitfield length", "per.internal.num_bits",
2931 FT_UINT32, BASE_DEC, NULL, 0,
2932 NULL, HFILL }},
2933 { &hf_per_internal_min,
2934 { "Min", "per.internal.min",
2935 FT_UINT32, BASE_DEC, NULL, 0,
2936 NULL, HFILL }},
2937 { &hf_per_internal_value,
2938 { "Bits", "per.internal.value",
2939 FT_UINT64, BASE_DEC, NULL, 0,
2940 NULL, HFILL }},
2941 { &hf_per_internal_min_int,
2942 { "Min", "per.internal.min_int",
2943 FT_INT32, BASE_DEC, NULL, 0,
2944 NULL, HFILL } },
2945 { &hf_per_internal_value_int,
2946 { "Bits", "per.internal.value_int",
2947 FT_INT64, BASE_DEC, NULL, 0,
2948 NULL, HFILL } },
2949 { &hf_per_encoding_boiler_plate,
2950 { "PER encoded protocol, to see PER internal fields set protocol PER preferences", "per.encoding_boiler_plate",
2951 FT_NONE, BASE_NONE, NULL, 0x0,
2952 NULL, HFILL } },
2956 static int *ett[] = {
2957 &ett_per_open_type,
2958 &ett_per_containing,
2959 &ett_per_sequence_of_item,
2960 &ett_per_External,
2961 &ett_per_External_encoding,
2962 &ett_per_named_bits,
2964 static ei_register_info ei[] = {
2965 { &ei_per_size_constraint_value,
2966 { "per.size_constraint.value", PI_PROTOCOL, PI_WARN, "Size constraint: value too big", EXPFILL }},
2967 { &ei_per_size_constraint_too_few,
2968 { "per.size_constraint.too_few", PI_PROTOCOL, PI_WARN, "Size constraint: too few items", EXPFILL }},
2969 { &ei_per_size_constraint_too_many,
2970 { "per.size_constraint.too_many", PI_PROTOCOL, PI_WARN, "Size constraint: too many items", EXPFILL }},
2971 { &ei_per_choice_extension_unknown,
2972 { "per.choice_extension_unknown", PI_UNDECODED, PI_NOTE, "unknown choice extension", EXPFILL }},
2973 { &ei_per_sequence_extension_unknown,
2974 { "per.sequence_extension_unknown", PI_UNDECODED, PI_NOTE, "unknown sequence extension", EXPFILL }},
2975 { &ei_per_encoding_error,
2976 { "per.encoding_error", PI_MALFORMED, PI_WARN, "Encoding error", EXPFILL }},
2977 { &ei_per_oid_not_implemented,
2978 { "per.error.oid_not_implemented", PI_UNDECODED, PI_WARN, "PER: Dissector for OID not implemented. Contact Wireshark developers if you want this supported", EXPFILL }},
2979 { &ei_per_undecoded,
2980 { "per.error.undecoded", PI_UNDECODED, PI_WARN, "PER: Something unknown here", EXPFILL }},
2981 { &ei_per_field_not_integer,
2982 { "per.field_not_integer", PI_PROTOCOL, PI_ERROR, "Field is not an integer", EXPFILL }},
2983 { &ei_per_external_type,
2984 { "per.external_type.unknown", PI_PROTOCOL, PI_WARN, "Unknown EXTERNAL Type", EXPFILL }},
2985 { &ei_per_open_type,
2986 { "per.open_type.unknown", PI_PROTOCOL, PI_WARN, "Unknown Open Type", EXPFILL }},
2987 { &ei_per_open_type_len,
2988 { "per.open_type.len", PI_PROTOCOL, PI_ERROR, "Open Type length > available data(tvb)", EXPFILL }}
2991 module_t *per_module;
2992 expert_module_t* expert_per;
2994 proto_per = proto_register_protocol("Packed Encoding Rules (ASN.1 X.691)", "PER", "per");
2995 proto_register_field_array(proto_per, hf, array_length(hf));
2996 proto_register_subtree_array(ett, array_length(ett));
2997 expert_per = expert_register_protocol(proto_per);
2998 expert_register_field_array(expert_per, ei, array_length(ei));
3000 proto_set_cant_toggle(proto_per);
3002 per_module = prefs_register_protocol(proto_per, NULL);
3003 prefs_register_bool_preference(per_module, "display_internal_per_fields",
3004 "Display the internal PER fields in the tree",
3005 "Whether the dissector should put the internal PER data in the tree or if it should hide it",
3006 &display_internal_per_fields);
3008 per_oid_dissector_table = register_dissector_table("per.oid", "PER OID", proto_per, FT_STRING, STRING_CASE_SENSITIVE);
3014 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3016 * Local variables:
3017 * c-basic-offset: 8
3018 * tab-width: 8
3019 * indent-tabs-mode: t
3020 * End:
3022 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3023 * :indentSize=8:tabSize=8:noTabs=false: