HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-per.c
blob267b21347f44f2f236b414eeb2996d11fd72aa12
1 /*
2 XXX all this offset>>3 and calculations of bytes in the tvb everytime
3 we put something in the tree is just silly. should be replaced with some
4 proper helper routines
5 */
6 /* packet-per.c
7 * Routines for dissection of ASN.1 Aligned PER
8 * 2003 Ronnie Sahlberg
10 * $Id$
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include "config.h"
33 #include <string.h>
34 #include <math.h>
36 #include <glib.h>
38 #include <epan/packet.h>
39 #include <epan/exceptions.h>
40 #include <epan/oids.h>
41 #include <epan/to_str.h>
42 #include <epan/prefs.h>
43 #include <epan/wmem/wmem.h>
44 #include <epan/asn1.h>
45 #include <epan/strutil.h>
46 #include <epan/expert.h>
47 #include "packet-per.h"
50 static int proto_per = -1;
51 static int hf_per_GeneralString_length = -1;
52 static int hf_per_extension_bit = -1;
53 static int hf_per_extension_present_bit = -1;
54 static int hf_per_choice_index = -1;
55 static int hf_per_choice_extension_index = -1;
56 static int hf_per_enum_index = -1;
57 static int hf_per_enum_extension_index = -1;
58 static int hf_per_num_sequence_extensions = -1;
59 static int hf_per_small_number_bit = -1;
60 static int hf_per_optional_field_bit = -1;
61 static int hf_per_sequence_of_length = -1;
62 static int hf_per_object_identifier_length = -1;
63 static int hf_per_open_type_length = -1;
64 static int hf_per_real_length = -1;
65 static int hf_per_octet_string_length = -1;
66 static int hf_per_bit_string_length = -1;
67 static int hf_per_normally_small_nonnegative_whole_number_length = -1;
68 static int hf_per_const_int_len = -1;
69 static int hf_per_direct_reference = -1; /* T_direct_reference */
70 static int hf_per_indirect_reference = -1; /* T_indirect_reference */
71 static int hf_per_data_value_descriptor = -1; /* T_data_value_descriptor */
72 static int hf_per_encoding = -1; /* External_encoding */
73 static int hf_per_single_ASN1_type = -1; /* T_single_ASN1_type */
74 static int hf_per_octet_aligned = -1; /* T_octet_aligned */
75 static int hf_per_arbitrary = -1; /* T_arbitrary */
76 static int hf_per_integer_length = -1; /* Show integer length if "show internal per fields" */
77 /* static int hf_per_debug_pos = -1; */
79 static gint ett_per_open_type = -1;
80 static gint ett_per_containing = -1;
81 static gint ett_per_sequence_of_item = -1;
82 static gint ett_per_External = -1;
83 static gint ett_per_External_encoding = -1;
85 static expert_field ei_per_size_constraint_value = EI_INIT;
86 static expert_field ei_per_size_constraint_too_few = EI_INIT;
87 static expert_field ei_per_size_constraint_too_many = EI_INIT;
88 static expert_field ei_per_choice_extension_unknown = EI_INIT;
89 static expert_field ei_per_sequence_extension_unknown = EI_INIT;
90 static expert_field ei_per_encoding_error = EI_INIT;
93 #define DEBUG_ENTRY(x) \
94 printf("#%u %s tvb:0x%08x\n",actx->pinfo->fd->num,x,(int)tvb);
96 #define DEBUG_ENTRY(x) \
99 #define BLEN(old_offset, offset) (((offset)>>3)!=((old_offset)>>3)?((offset)>>3)-((old_offset)>>3):1)
101 /* whether the PER helpers should put the internal PER fields into the tree
102 or not.
104 static gboolean display_internal_per_fields = FALSE;
108 static const true_false_string tfs_extension_present_bit = {
112 static const true_false_string tfs_extension_bit = {
113 "Extension bit is set",
114 "Extension bit is clear"
116 static const true_false_string tfs_small_number_bit = {
117 "The number is small, 0-63",
118 "The number is large, >63"
120 static const true_false_string tfs_optional_field_bit = {
126 #define BYTE_ALIGN_OFFSET(offset) if(offset&0x07){offset=(offset&0xfffffff8)+8;}
128 #define SEQ_MAX_COMPONENTS 128
130 static void per_check_value(guint32 value, guint32 min_len, guint32 max_len, asn1_ctx_t *actx, proto_item *item, gboolean is_signed)
132 if ((is_signed == FALSE) && (value > max_len)) {
133 expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_value, "Size constraint: value too big: %u (%u .. %u)", value, min_len, max_len);
134 } else if ((is_signed == TRUE) && ((gint32)value > (gint32)max_len)) {
135 expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_value, "Size constraint: value too big: %d (%d .. %d)", (gint32)value, (gint32)min_len, (gint32)max_len);
139 static void per_check_value64(guint64 value, guint64 min_len, guint64 max_len, asn1_ctx_t *actx, proto_item *item, gboolean is_signed)
141 if ((is_signed == FALSE) && (value > max_len)) {
142 expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_value, "Size constraint: value too big: %" G_GINT64_MODIFIER "u (%" G_GINT64_MODIFIER "u .. %" G_GINT64_MODIFIER "u)", value, min_len, max_len);
143 } else if ((is_signed == TRUE) && ((gint64)value > (gint64)max_len)) {
144 expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_value, "Size constraint: value too big: %" G_GINT64_MODIFIER "d (%" G_GINT64_MODIFIER "d .. %" G_GINT64_MODIFIER "d)", (gint64)value, (gint64)min_len, (gint64)max_len);
148 static void per_check_items(guint32 cnt, int min_len, int max_len, asn1_ctx_t *actx, proto_item *item)
150 if (min_len != NO_BOUND && cnt < (guint32)min_len) {
151 expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_too_few, "Size constraint: too few items: %d (%d .. %d)", cnt, min_len, max_len);
152 } else if (max_len != NO_BOUND && cnt > (guint32)max_len) {
153 expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_too_many, "Size constraint: too many items: %d (%d .. %d)", cnt, min_len, max_len);
157 static tvbuff_t *new_octet_aligned_subset(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, guint32 length)
159 tvbuff_t *sub_tvb = NULL;
160 guint32 boffset = offset >> 3;
161 unsigned int i, shift0, shift1;
162 guint8 octet0, octet1, *buf;
163 guint32 actual_length;
165 /* XXX - why are we doing this? Shouldn't we throw an exception if we've
166 * been asked to decode more octets than exist?
168 actual_length = tvb_length_remaining(tvb,boffset);
169 if (length <= actual_length)
170 actual_length = length;
172 if (offset & 0x07) { /* unaligned */
173 shift1 = offset & 0x07;
174 shift0 = 8 - shift1;
175 buf = (guint8 *)wmem_alloc(actx->pinfo->pool, actual_length);
176 octet0 = tvb_get_guint8(tvb, boffset);
177 for (i=0; i<actual_length; i++) {
178 octet1 = octet0;
179 octet0 = tvb_get_guint8(tvb, boffset + i + 1);
180 buf[i] = (octet1 << shift1) | (octet0 >> shift0);
182 sub_tvb = tvb_new_child_real_data(tvb, buf, actual_length, length);
183 add_new_data_source(actx->pinfo, sub_tvb, "Unaligned OCTET STRING");
184 } else { /* aligned */
185 sub_tvb = tvb_new_subset(tvb, boffset, actual_length, length);
187 return sub_tvb;
190 /* 10 Encoding procedures -------------------------------------------------- */
192 /* 10.2 Open type fields --------------------------------------------------- */
193 static guint32
194 dissect_per_open_type_internal(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, void* type_cb, asn1_cb_variant variant)
196 guint32 type_length, end_offset;
197 tvbuff_t *val_tvb = NULL;
198 header_field_info *hfi;
199 proto_tree *subtree = tree;
201 hfi = (hf_index == -1) ? NULL : proto_registrar_get_nth(hf_index);
203 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &type_length);
204 if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
205 end_offset = offset + type_length * 8;
207 if ((variant==CB_DISSECTOR)||(variant==CB_NEW_DISSECTOR)) {
208 val_tvb = new_octet_aligned_subset(tvb, offset, actx, type_length);
209 if (hfi) {
210 if (IS_FT_UINT(hfi->type)||IS_FT_INT(hfi->type)) {
211 if (IS_FT_UINT(hfi->type))
212 actx->created_item = proto_tree_add_uint(tree, hf_index, val_tvb, 0, type_length, type_length);
213 else
214 actx->created_item = proto_tree_add_int(tree, hf_index, val_tvb, 0, type_length, type_length);
215 proto_item_append_text(actx->created_item, plurality(type_length, " octet", " octets"));
216 } else {
217 actx->created_item = proto_tree_add_item(tree, hf_index, val_tvb, 0, type_length, ENC_BIG_ENDIAN);
219 subtree = proto_item_add_subtree(actx->created_item, ett_per_open_type);
223 if (type_cb) {
224 switch (variant) {
225 case CB_ASN1_ENC:
226 ((per_type_fn)type_cb)(tvb, offset, actx, tree, hf_index);
227 break;
228 case CB_DISSECTOR:
229 ((dissector_t)type_cb)(val_tvb, actx->pinfo, subtree);
230 break;
231 case CB_NEW_DISSECTOR:
232 ((new_dissector_t)type_cb)(val_tvb, actx->pinfo, subtree, NULL);
233 break;
234 case CB_DISSECTOR_HANDLE:
235 break;
237 } else {
238 actx->created_item = proto_tree_add_text(tree, tvb, offset>>3, BLEN(offset, end_offset), "Unknown Open Type");
241 return end_offset;
244 guint32
245 dissect_per_open_type(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, per_type_fn type_cb)
247 return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, (void*)type_cb, CB_ASN1_ENC);
250 guint32
251 dissect_per_open_type_pdu(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, dissector_t type_cb)
253 return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, (void*)type_cb, CB_DISSECTOR);
256 guint32
257 dissect_per_open_type_pdu_new(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, new_dissector_t type_cb)
259 return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, (void*)type_cb, CB_NEW_DISSECTOR);
262 /* 10.9 General rules for encoding a length determinant --------------------
264 NOTE 1 - (Tutorial) The procedures of this subclause are invoked when an explicit length field is needed
265 for some part of the encoding regardless of whether the length count is bounded above
266 (by PER-visible constraints) or not. The part of the encoding to which the length applies may
267 be a bit string (with the length count in bits), an octet string (with the length count in octets),
268 a known-multiplier character string (with the length count in characters), or a list of fields
269 (with the length count in components of a sequence-of or set-of).
271 NOTE 2 - (Tutorial) In the case of the ALIGNED variant if the length count is bounded above by an upper bound
272 that is less than 64K, then the constrained whole number encoding is used for the length.
273 For sufficiently small ranges the result is a bit-field, otherwise the unconstrained length ("n" say)
274 is encoded into an octet-aligned bit-field in one of three ways (in order of increasing size):
275 a) ("n" less than 128) a single octet containing "n" with bit 8 set to zero;
276 b) ("n" less than 16K) two octets containing "n" with bit 8 of the first octet set to 1 and bit 7 set to zero;
277 c) (large "n") a single octet containing a count "m" with bit 8 set to 1 and bit 7 set to 1.
278 The count "m" is one to four, and the length indicates that a fragment of the material follows
279 (a multiple "m" of 16K items). For all values of "m", the fragment is then followed by another length encoding
280 for the remainder of the material.
282 NOTE 3 - (Tutorial) In the UNALIGNED variant, if the length count is bounded above by an upper bound that is less
283 than 64K, then the constrained whole number encoding is used to encode the length in the minimum number of
284 bits necessary to represent the range. Otherwise, the unconstrained length ("n" say) is encoded into a bit
285 field in the manner described above in Note 2.
288 guint32
289 dissect_per_length_determinant(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index, guint32 *length)
291 guint8 byte;
292 guint32 len;
293 proto_item *pi;
294 int num_bits;
295 int i, bit, str_length, str_index;
296 gboolean tmp;
298 if(!length){
299 length=&len;
302 /* byte aligned */
303 if (actx->aligned){
304 BYTE_ALIGN_OFFSET(offset);
305 byte=tvb_get_guint8(tvb, offset>>3);
306 offset+=8;
307 }else{
308 char *str;
309 guint32 val;
311 val = 0;
313 /* prepare the string (max number of bits + quartet separators + prepended space) */
314 str_length = 256+64+1;
315 str=(char *)wmem_alloc(wmem_packet_scope(), str_length+1);
316 str_index = 0;
318 str_length = g_snprintf(str, str_length+1, " ");
319 for(bit=0;bit<((int)(offset&0x07));bit++){
320 if(bit&&(!(bit%4))){
321 if (str_index < str_length) str[str_index++] = ' ';
323 if (str_index < str_length) str[str_index++] = '.';
325 /* read the bits for the int */
326 num_bits = 8;
327 for(i=0;i<num_bits;i++){
328 if(bit&&(!(bit%4))){
329 if (str_index < str_length) str[str_index++] = ' ';
331 if(bit&&(!(bit%8))){
332 if (str_index < str_length) str[str_index++] = ' ';
334 bit++;
335 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &tmp);
336 val<<=1;
337 if(tmp){
338 val|=1;
339 if (str_index < str_length) str[str_index++] = '1';
340 if (i==0) { /* bit 8 is 1, so not a single byte length */
341 num_bits = 16;
343 else if (i==1 && val==3) { /* bits 8 and 7 both 1, so unconstrained */
344 *length = 0;
345 PER_NOT_DECODED_YET("10.9 Unconstrained");
346 return offset;
348 } else {
349 if (str_index < str_length) str[str_index++] = '0';
352 str[str_index] = '\0'; /* Terminate string */
353 if((val&0x80)==0 && num_bits==8){
354 *length = val;
355 if(hf_index!=-1){
356 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
357 if (display_internal_per_fields)
358 proto_item_append_text(pi," %s", str);
359 else
360 PROTO_ITEM_SET_HIDDEN(pi);
363 return offset;
365 else if (num_bits==16) {
366 *length = val&0x3fff;
367 if(hf_index!=-1){
368 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
369 if (display_internal_per_fields)
370 proto_item_append_text(pi," %s", str);
371 else
372 PROTO_ITEM_SET_HIDDEN(pi);
375 return offset;
377 *length = 0;
378 PER_NOT_DECODED_YET("10.9 Unaligned");
379 return offset;
383 /* 10.9.3.6 */
384 if((byte&0x80)==0){
385 *length=byte;
386 if(hf_index!=-1){
387 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
388 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(pi);
390 return offset;
393 /* 10.9.3.7 */
394 if((byte&0xc0)==0x80){
395 *length=(byte&0x3f);
396 *length=((*length)<<8)+tvb_get_guint8(tvb, offset>>3);
397 offset+=8;
398 if(hf_index!=-1){
399 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-2, 2, *length);
400 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(pi);
402 return offset;
404 *length = 0;
405 PER_NOT_DECODED_YET("10.9.3.8.1");
406 return offset;
409 /* 10.6 normally small non-negative whole number */
410 static guint32
411 dissect_per_normally_small_nonnegative_whole_number(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint32 *length)
413 gboolean small_number, length_bit;
414 guint32 len, length_determinant;
415 proto_item *pi;
417 DEBUG_ENTRY("dissect_per_normally_small_nonnegative_whole_number");
418 if(!length){
419 length=&len;
422 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_small_number_bit, &small_number);
423 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
424 if(!small_number){
425 int i;
426 /* 10.6.1 */
427 *length=0;
428 for(i=0;i<6;i++){
429 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &length_bit);
430 *length<<=1;
431 if (length_bit) {
432 *length|=1;
435 if(hf_index!=-1){
436 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset-6)>>3, (offset%8<6)?2:1, *length);
437 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(pi);
439 return offset;
442 /* 10.6.2 */
443 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_normally_small_nonnegative_whole_number_length, &length_determinant);
444 switch (length_determinant) {
445 case 0:
446 *length = 0;
447 break;
448 case 1:
449 *length = tvb_get_bits8(tvb, offset, 8);
450 offset += 8;
451 break;
452 case 2:
453 *length = tvb_get_bits16(tvb, offset, 16, ENC_BIG_ENDIAN);
454 offset += 16;
455 break;
456 case 3:
457 *length = tvb_get_bits32(tvb, offset, 24, ENC_BIG_ENDIAN);
458 offset += 24;
459 break;
460 case 4:
461 *length = tvb_get_bits32(tvb, offset, 32, ENC_BIG_ENDIAN);
462 offset += 32;
463 break;
464 default:
465 PER_NOT_DECODED_YET("too long integer(per_normally_small_nonnegative_whole_number)");
466 offset += 8*length_determinant;
467 *length = 0;
468 return offset;
470 if(hf_index!=-1){
471 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset-(8*length_determinant))>>3, length_determinant, *length);
472 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(pi);
475 return offset;
480 /* this function reads a GeneralString */
481 /* currently based on pure guesswork since RFC2833 didnt tell me much
482 i guess that the PER encoding for this is a normally-small-whole-number
483 followed by a ascii string.
485 based on pure guesswork. it looks ok in the only capture i have where
486 there is a 1 byte general string encoded
488 guint32
489 dissect_per_GeneralString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index)
491 guint32 length;
493 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_GeneralString_length, &length);
495 proto_tree_add_item(tree, hf_index, tvb, offset>>3, length, ENC_BIG_ENDIAN);
497 offset+=length*8;
499 return offset;
502 /* 17 Encoding the null type */
503 guint32
504 dissect_per_null(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) {
505 proto_item *ti_tmp;
507 ti_tmp = proto_tree_add_item(tree, hf_index, tvb, offset>>3, 1, ENC_BIG_ENDIAN);
508 proto_item_append_text(ti_tmp, ": NULL");
510 return offset;
513 /* 19 this function dissects a sequence of */
514 static guint32
515 dissect_per_sequence_of_helper(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, per_type_fn func, int hf_index, guint32 length)
517 guint32 i;
519 DEBUG_ENTRY("dissect_per_sequence_of_helper");
520 for(i=0;i<length;i++){
521 guint32 lold_offset=offset;
522 proto_item *litem;
523 proto_tree *ltree;
525 litem=proto_tree_add_text(tree, tvb, offset>>3, 0, "Item %d", i);
526 ltree=proto_item_add_subtree(litem, ett_per_sequence_of_item);
528 offset=(*func)(tvb, offset, actx, ltree, hf_index);
529 proto_item_set_len(litem, (offset>>3)!=(lold_offset>>3)?(offset>>3)-(lold_offset>>3):1);
532 return offset;
534 guint32
535 dissect_per_sequence_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq)
537 proto_item *item;
538 proto_tree *tree;
539 guint32 old_offset=offset;
540 guint32 length;
541 header_field_info *hfi;
543 DEBUG_ENTRY("dissect_per_sequence_of");
545 /* semi-constrained whole number for number of elements */
546 /* each element encoded as 10.9 */
548 offset=dissect_per_length_determinant(tvb, offset, actx, parent_tree, hf_per_sequence_of_length, &length);
550 hfi = proto_registrar_get_nth(hf_index);
551 if (IS_FT_UINT(hfi->type)) {
552 item = proto_tree_add_uint(parent_tree, hf_index, tvb, old_offset>>3, 0, length);
553 proto_item_append_text(item, (length==1)?" item":" items");
554 } else {
555 item=proto_tree_add_item(parent_tree, hf_index, tvb, old_offset>>3, 0, ENC_BIG_ENDIAN);
557 tree=proto_item_add_subtree(item, ett_index);
559 offset=dissect_per_sequence_of_helper(tvb, offset, actx, tree, seq->func, *seq->p_id, length);
562 proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
563 return offset;
567 /* XXX we don't do >64k length strings yet */
568 static guint32
569 dissect_per_restricted_character_string_sorted(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension _U_,const char *alphabet, int alphabet_length, tvbuff_t **value_tvb)
571 guint32 length;
572 gboolean byte_aligned;
573 guint8 *buf;
574 guint char_pos;
575 int bits_per_char;
576 guint32 old_offset;
578 DEBUG_ENTRY("dissect_per_restricted_character_string");
580 /* xx.x if the length is 0 bytes there will be no encoding */
581 if(max_len==0){
582 if (value_tvb) {
583 *value_tvb = tvb_new_child_real_data(tvb, NULL, 0, 0);
585 return offset;
589 if (min_len == NO_BOUND) {
590 min_len=0;
594 /* 27.5.2 depending of the alphabet length, find how many bits
595 are used to encode each character */
596 /* unaligned PER */
597 if (actx->aligned){
599 if(alphabet_length<=2){
600 bits_per_char=1;
601 } else if(alphabet_length<=4){
602 bits_per_char=2;
603 } else if(alphabet_length<=16){
604 bits_per_char=4;
605 } else {
606 bits_per_char=8;
608 }else{
609 if(alphabet_length<=2){
610 bits_per_char=1;
611 } else if(alphabet_length<=4){
612 bits_per_char=2;
613 } else if(alphabet_length<=8){
614 bits_per_char=3;
615 } else if(alphabet_length<=16){
616 bits_per_char=4;
617 } else if(alphabet_length<=32){
618 bits_per_char=5;
619 } else if(alphabet_length<=64){
620 bits_per_char=6;
621 } else if(alphabet_length<=128){
622 bits_per_char=7;
623 } else {
624 bits_per_char=8;
627 /* 27.4 If the type is extensible for PER encodings (see 9.3.16),
628 * then a bit-field consisting of a single bit shall be added to the field-list.
629 * The single bit shall be set to zero if the value is within the range of the extension root,
630 * and to one otherwise. If the value is outside the range of the extension root,
631 * then the following encoding shall be as if there was no effective size constraint,
632 * and shall have an effective permitted-alphabet constraint that consists of the set of characters
633 * of the unconstrained type.
634 * NOTE - Only the known-multiplier character string types can be extensible for PER encodings.
635 * Extensibility markers on other character string types do not affect the PER encoding.
638 if (has_extension) {
639 gboolean extension_present;
640 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
641 if(extension_present){
642 min_len = NO_BOUND;
643 max_len = NO_BOUND;
647 byte_aligned=TRUE;
648 if((min_len==max_len)&&(max_len<=2)){
649 byte_aligned=FALSE;
651 if ((max_len != NO_BOUND) && (max_len < 2)) {
652 byte_aligned=FALSE;
655 /* xx.x */
656 length=max_len;
657 if (max_len == NO_BOUND) {
658 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_octet_string_length, &length);
659 /* the unconstrained strings are always byte aligned (27.6.3)*/
660 byte_aligned=TRUE;
661 } else if(min_len!=max_len){
662 offset=dissect_per_constrained_integer(tvb, offset, actx,
663 tree, hf_per_octet_string_length, min_len, max_len,
664 &length, FALSE);
665 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
668 if(!length){
669 /* there is no string at all, so don't do any byte alignment */
670 /* byte_aligned=FALSE; */
671 /* Advance offset to next 'element' */
672 offset = offset + 1; }
674 if((byte_aligned)&&(actx->aligned)){
675 BYTE_ALIGN_OFFSET(offset);
679 buf = (guint8 *)wmem_alloc(actx->pinfo->pool, length+1);
680 old_offset=offset;
681 for(char_pos=0;char_pos<length;char_pos++){
682 guchar val;
683 int i;
684 gboolean bit;
686 val=0;
687 for(i=0;i<bits_per_char;i++){
688 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
689 val=(val<<1)|bit;
691 /* ALIGNED PER does not do any remapping of chars if
692 bitsperchar is 8
694 /* If alphabet is not provided, do not do any remapping either */
695 if((bits_per_char==8) || (alphabet==NULL)){
696 buf[char_pos]=val;
697 } else {
698 if (val < alphabet_length){
699 buf[char_pos]=alphabet[val];
700 } else {
701 buf[char_pos] = '?'; /* XXX - how to mark this? */
705 buf[char_pos]=0;
706 proto_tree_add_string(tree, hf_index, tvb, (old_offset>>3), (offset>>3)-(old_offset>>3), (char*)buf);
707 if (value_tvb) {
708 *value_tvb = tvb_new_child_real_data(tvb, buf, length, length);
710 return offset;
713 static const char*
714 sort_alphabet(char *sorted_alphabet, const char *alphabet, int alphabet_length)
716 int i, j;
717 char c, c_max, c_min;
718 char tmp_buf[256];
720 if (!alphabet_length) return sorted_alphabet;
721 memset(tmp_buf, 0, 256);
722 c_min = c_max = alphabet[0];
723 for (i=0; i<alphabet_length; i++) {
724 c = alphabet[i];
725 tmp_buf[(int)c] = 1;
726 if (c > c_max) c_max = c;
727 else if (c < c_min) c_min = c;
729 for (i=c_min,j=0; i<=c_max; i++) {
730 if (tmp_buf[i]) sorted_alphabet[j++] = i;
732 return sorted_alphabet;
735 guint32
736 dissect_per_restricted_character_string(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, const char *alphabet, int alphabet_length, tvbuff_t **value_tvb)
738 const char *alphabet_ptr;
739 char sorted_alphabet[128];
741 if (alphabet_length > 127) {
742 alphabet_ptr = alphabet;
743 } else {
744 alphabet_ptr = sort_alphabet(sorted_alphabet, alphabet, alphabet_length);
746 return dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, alphabet_ptr, alphabet_length, value_tvb);
749 /* dissect a constrained IA5String that consists of the full ASCII set,
750 i.e. no FROM stuff limiting the alphabet
752 guint32
753 dissect_per_IA5String(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension)
755 offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension,
756 NULL, 128, NULL);
758 return offset;
761 guint32
762 dissect_per_NumericString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension)
764 offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension,
765 " 0123456789", 11, NULL);
767 return offset;
769 guint32
770 dissect_per_PrintableString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension)
772 offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension,
773 " '()+,-.*0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 74, NULL);
774 return offset;
776 guint32
777 dissect_per_VisibleString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension)
779 offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension,
780 " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", 95, NULL);
781 return offset;
783 guint32
784 dissect_per_BMPString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension _U_)
786 guint32 length;
787 static char *str;
789 /* xx.x if the length is 0 bytes there will be no encoding */
790 if(max_len==0){
791 return offset;
795 if (min_len == NO_BOUND) {
796 min_len = 0;
800 /* xx.x */
801 length=max_len;
802 if(min_len!=max_len){
803 offset=dissect_per_constrained_integer(tvb, offset, actx,
804 tree, hf_per_octet_string_length, min_len, max_len,
805 &length, FALSE);
806 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
810 /* align to byte boundary */
811 BYTE_ALIGN_OFFSET(offset);
813 if(length>=1024){
814 PER_NOT_DECODED_YET("BMPString too long");
815 length=1024;
818 str = tvb_get_unicode_string(wmem_packet_scope(), tvb, offset>>3, length*2, ENC_BIG_ENDIAN);
820 proto_tree_add_string(tree, hf_index, tvb, offset>>3, length*2, str);
822 offset+=(length<<3)*2;
824 return offset;
826 guint32
827 dissect_per_UTF8String(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension _U_)
829 offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree,
830 hf_index, min_len, max_len, has_extension, NULL, 256, NULL);
831 return offset;
834 guint32
835 dissect_per_object_descriptor(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, tvbuff_t **value_tvb)
837 offset=dissect_per_octet_string(tvb, offset, actx, tree, hf_index, -1, -1, FALSE, value_tvb);
839 return offset;
843 /* this function dissects a constrained sequence of */
844 guint32
845 dissect_per_constrained_sequence_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq, int min_len, int max_len, gboolean has_extension _U_)
847 proto_item *item;
848 proto_tree *tree;
849 guint32 old_offset=offset;
850 guint32 length;
851 header_field_info *hfi;
853 DEBUG_ENTRY("dissect_per_constrained_sequence_of");
855 /* 19.4 If there is a PER-visible constraint and an extension marker is present in it,
856 * a single bit shall be added to the field-list in a bit-field of length one
858 if(has_extension){
859 gboolean extension_present;
860 offset=dissect_per_boolean(tvb, offset, actx, parent_tree, hf_per_extension_present_bit, &extension_present);
861 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
862 if(extension_present){
863 /* 10.9 shall be invoked to add the length determinant as a semi-constrained whole number to the field-list,
864 * followed by the component values
865 * TODO: Handle extension
867 proto_tree_add_text(parent_tree, tvb, (offset>>3), 1, "dissect_per_constrained_sequence_of with extension is not handled");
871 /* 19.5 if min==max and min,max<64k ==> no length determinant */
872 if((min_len==max_len) && (min_len<65536)){
873 length=min_len;
874 goto call_sohelper;
877 /* 19.6 ub>=64k or unset */
878 if ((max_len >= 65536) || (max_len == NO_BOUND)) {
879 /* no constraint, see 10.9.4.2 */
880 offset=dissect_per_length_determinant(tvb, offset, actx, parent_tree, hf_per_sequence_of_length, &length);
881 goto call_sohelper;
884 /* constrained whole number for number of elements */
885 offset=dissect_per_constrained_integer(tvb, offset, actx,
886 parent_tree, hf_per_sequence_of_length, min_len, max_len,
887 &length, FALSE);
888 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
890 call_sohelper:
891 hfi = proto_registrar_get_nth(hf_index);
892 if (IS_FT_UINT(hfi->type)) {
893 item = proto_tree_add_uint(parent_tree, hf_index, tvb, offset>>3, 0, length);
894 proto_item_append_text(item, (length==1)?" item":" items");
895 } else {
896 item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, ENC_BIG_ENDIAN);
898 tree=proto_item_add_subtree(item, ett_index);
899 per_check_items(length, min_len, max_len, actx, item);
901 old_offset = offset;
902 offset=dissect_per_sequence_of_helper(tvb, offset, actx, tree, seq->func, *seq->p_id, length);
904 if (offset == old_offset)
905 length = 0;
906 else if (offset >> 3 == old_offset >> 3)
907 length = 1;
908 else
909 length = (offset >> 3) - (old_offset >> 3);
911 proto_item_set_len(item, length);
912 return offset;
915 /* this function dissects a constrained set of */
916 guint32
917 dissect_per_constrained_set_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq, int min_len, int max_len, gboolean has_extension)
919 /* for basic-per a set-of is encoded in the same way as a sequence-of */
920 DEBUG_ENTRY("dissect_per_constrained_set_of");
921 offset=dissect_per_constrained_sequence_of(tvb, offset, actx, parent_tree, hf_index, ett_index, seq, min_len, max_len, has_extension);
922 return offset;
930 /* this function dissects a set of */
931 guint32
932 dissect_per_set_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq)
934 /* for basic-per a set-of is encoded in the same way as a sequence-of */
935 DEBUG_ENTRY("dissect_per_set_of");
936 offset=dissect_per_sequence_of(tvb, offset, actx, parent_tree, hf_index, ett_index, seq);
937 return offset;
943 /* 23 Encoding the object identifier type */
944 guint32
945 dissect_per_any_oid(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, tvbuff_t **value_tvb,
946 gboolean is_absolute)
948 guint length;
949 const char *str;
950 tvbuff_t *val_tvb = NULL;
951 header_field_info *hfi;
953 DEBUG_ENTRY("dissect_per_any_oid");
955 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_object_identifier_length, &length);
956 if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
957 val_tvb = new_octet_aligned_subset(tvb, offset, actx, length);
959 hfi = proto_registrar_get_nth(hf_index);
960 if ((is_absolute && hfi->type == FT_OID) || (is_absolute && hfi->type == FT_REL_OID)) {
961 actx->created_item = proto_tree_add_item(tree, hf_index, val_tvb, 0, length, ENC_BIG_ENDIAN);
962 } else if (IS_FT_STRING(hfi->type)) {
963 str = oid_encoded2string(tvb_get_ptr(val_tvb, 0, length), length);
964 actx->created_item = proto_tree_add_string(tree, hf_index, val_tvb, 0, length, str);
965 } else {
966 DISSECTOR_ASSERT_NOT_REACHED();
969 if (value_tvb) *value_tvb = val_tvb;
971 offset += 8 * length;
973 return offset;
976 guint32
977 dissect_per_object_identifier(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, tvbuff_t **value_tvb)
979 return dissect_per_any_oid(tvb, offset, actx, tree, hf_index, value_tvb, TRUE);
982 guint32
983 dissect_per_relative_oid(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, tvbuff_t **value_tvb)
985 return dissect_per_any_oid(tvb, offset, actx, tree, hf_index, value_tvb, FALSE);
988 guint32
989 dissect_per_any_oid_str(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, const char **value_stringx,
990 gboolean is_absolute)
992 tvbuff_t *value_tvb = NULL;
993 guint length;
995 offset = dissect_per_any_oid(tvb, offset, actx, tree, hf_index, (value_stringx) ? &value_tvb : NULL, is_absolute);
997 if (value_stringx) {
998 if (value_tvb && (length = tvb_length(value_tvb))) {
999 *value_stringx = oid_encoded2string(tvb_get_ptr(value_tvb, 0, length), length);
1000 } else {
1001 *value_stringx = "";
1005 return offset;
1008 guint32
1009 dissect_per_object_identifier_str(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, const char **value_stringx)
1011 return dissect_per_any_oid_str(tvb, offset, actx, tree, hf_index, value_stringx, TRUE);
1014 guint32
1015 dissect_per_relative_oid_str(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, const char **value_stringx)
1017 return dissect_per_any_oid_str(tvb, offset, actx, tree, hf_index, value_stringx, FALSE);
1021 /* this function reads a single bit */
1022 guint32
1023 dissect_per_boolean(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gboolean *bool_val)
1025 guint8 ch, mask;
1026 gboolean value;
1027 header_field_info *hfi;
1029 DEBUG_ENTRY("dissect_per_boolean");
1031 ch=tvb_get_guint8(tvb, offset>>3);
1032 mask=1<<(7-(offset&0x07));
1033 if(ch&mask){
1034 value=1;
1035 } else {
1036 value=0;
1038 if(hf_index!=-1){
1039 char bits[10];
1040 bits[0] = mask&0x80?'0'+value:'.';
1041 bits[1] = mask&0x40?'0'+value:'.';
1042 bits[2] = mask&0x20?'0'+value:'.';
1043 bits[3] = mask&0x10?'0'+value:'.';
1044 bits[4] = ' ';
1045 bits[5] = mask&0x08?'0'+value:'.';
1046 bits[6] = mask&0x04?'0'+value:'.';
1047 bits[7] = mask&0x02?'0'+value:'.';
1048 bits[8] = mask&0x01?'0'+value:'.';
1049 bits[9] = '\0';
1051 hfi = proto_registrar_get_nth(hf_index);
1052 actx->created_item = proto_tree_add_boolean_format(tree, hf_index, tvb, offset>>3, 1, value,
1053 "%s %s: %s", bits, hfi->name,
1054 value?"True":"False");
1055 } else {
1056 actx->created_item = NULL;
1059 if(bool_val){
1060 *bool_val=value;
1062 return offset+1;
1068 /* we currently only handle integers up to 32 bits in length. */
1069 guint32
1070 dissect_per_integer(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gint32 *value)
1072 guint32 i, length;
1073 gint32 val;
1074 proto_item *it=NULL;
1075 header_field_info *hfi;
1077 /* 12.2.6 b */
1078 offset=dissect_per_length_determinant(tvb, offset, actx, tree,hf_per_integer_length, &length);
1079 /* gassert here? */
1080 if(length>4){
1081 PER_NOT_DECODED_YET("too long integer(per_integer)");
1082 length=4;
1085 val=0;
1086 for(i=0;i<length;i++){
1087 if(i==0){
1088 if(tvb_get_guint8(tvb, offset>>3)&0x80){
1089 /* negative number */
1090 val=0xffffffff;
1091 } else {
1092 /* positive number */
1093 val=0;
1096 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1097 offset+=8;
1100 hfi = proto_registrar_get_nth(hf_index);
1101 if (! hfi)
1102 THROW(ReportedBoundsError);
1103 if (IS_FT_INT(hfi->type)) {
1104 it=proto_tree_add_int(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1105 } else if (IS_FT_UINT(hfi->type)) {
1106 it=proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1107 } else {
1108 proto_tree_add_text(tree, tvb, (offset>>3)-(length+1), length+1, "Field is not an integer: %s", hfi->abbrev);
1109 REPORT_DISSECTOR_BUG("PER integer field that's not an FT_INT* or FT_UINT*");
1113 actx->created_item = it;
1115 if(value){
1116 *value=val;
1119 return offset;
1121 /* 64 bits experimental version, internal for now */
1122 static guint32
1123 dissect_per_integer64b(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gint64 *value)
1125 guint32 i, length;
1126 gint64 val;
1127 proto_item *it=NULL;
1128 header_field_info *hfi;
1130 /* 12.2.6 b */
1131 offset=dissect_per_length_determinant(tvb, offset, actx, tree, -1, &length);
1132 /* gassert here? */
1133 if(length>8){
1134 PER_NOT_DECODED_YET("too long integer (64b)");
1135 length=8;
1138 val=0;
1139 for(i=0;i<length;i++){
1140 if(i==0){
1141 if(tvb_get_guint8(tvb, offset>>3)&0x80){
1142 /* negative number */
1143 val=G_GINT64_CONSTANT(0xffffffffffffffff);
1144 } else {
1145 /* positive number */
1146 val=0;
1149 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1150 offset+=8;
1153 hfi = proto_registrar_get_nth(hf_index);
1154 if (! hfi)
1155 THROW(ReportedBoundsError);
1156 if (IS_FT_INT(hfi->type)) {
1157 it=proto_tree_add_int64(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1158 } else if (IS_FT_UINT(hfi->type)) {
1159 it=proto_tree_add_uint64(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1160 } else {
1161 proto_tree_add_text(tree, tvb, (offset>>3)-(length+1), length+1, "Field is not an integer: %s", hfi->abbrev);
1162 REPORT_DISSECTOR_BUG("PER integer field that's not an FT_INT* or FT_UINT*");
1166 actx->created_item = it;
1168 if(value){
1169 *value=val;
1172 return offset;
1174 /* this function reads a constrained integer with or without a
1175 PER visible extension marker present
1177 has_extension==TRUE would map to asn constructs such as:
1178 rfc-number INTEGER (1..32768, ...)
1179 while has_extension==FALSE would map to:
1180 t35CountryCode INTEGER (0..255)
1182 it only handles integers that fit inside a 32 bit integer
1183 10.5.1 info only
1184 10.5.2 info only
1185 10.5.3 range=ub-lb+1
1186 10.5.4 empty range
1187 10.5.5 info only
1188 10.5.6 unaligned version
1189 10.5.7 aligned version
1190 10.5.7.1 decoding of 0-255 1-8 bits
1191 10.5.7.2 decoding og 0-256 8 bits
1192 10.5.7.3 decoding of 0-65535 16 bits
1193 10.5.7.4
1195 guint32
1196 dissect_per_constrained_integer(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint32 min, guint32 max, guint32 *value, gboolean has_extension)
1198 proto_item *it=NULL;
1199 guint32 range, val;
1200 gint val_start, val_length;
1201 nstime_t timeval;
1202 header_field_info *hfi;
1203 int num_bits;
1205 DEBUG_ENTRY("dissect_per_constrained_integer");
1206 if(has_extension){
1207 gboolean extension_present;
1208 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
1209 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1210 if(extension_present){
1211 offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, (gint32*)value);
1212 return offset;
1216 hfi = proto_registrar_get_nth(hf_index);
1218 /* 10.5.3 Let "range" be defined as the integer value ("ub" - "lb" 1), and let the value to be encoded be "n".
1219 * 10.5.7 In the case of the ALIGNED variant the encoding depends on whether
1220 * d) "range" is greater than 64K (the indefinite length case).
1222 if(((max-min)>65536)&&(actx->aligned)){
1223 /* just set range really big so it will fall through
1224 to the bottom of the encoding */
1225 range=1000000;
1226 } else {
1227 /* Really ugly hack.
1228 * We should really use guint64 as parameters for min/max.
1229 * This is to prevent range from being 0 if
1230 * the range for a signed integer spans the entire 32 bit range.
1231 * Special case the 2 common cases when this can happen until
1232 * a real fix is implemented.
1234 if( (max==0x7fffffff && min==0x80000000)
1235 || (max==0xffffffff && min==0x00000000) ){
1236 range=0xffffffff;
1237 } else {
1238 range=max-min+1;
1242 val=0;
1243 timeval.secs=val; timeval.nsecs=0;
1244 /* 10.5.4 If "range" has the value 1, then the result of the encoding shall be an empty bit-field (no bits).*/
1246 /* something is really wrong if range is 0 */
1247 DISSECTOR_ASSERT(range!=0);
1249 if(range==1){
1250 val_start = offset>>3; val_length = 0;
1251 val = min;
1252 } else if((range<=255)||(!actx->aligned)) {
1253 /* 10.5.7.1
1254 * 10.5.6 In the case of the UNALIGNED variant the value ("n" - "lb") shall be encoded
1255 * as a non-negative binary integer in a bit field as specified in 10.3 with the minimum
1256 * number of bits necessary to represent the range.
1258 char *str;
1259 int i, length;
1260 guint32 mask,mask2;
1261 /* We only handle 32 bit integers */
1262 mask = 0x80000000;
1263 mask2 = 0x7fffffff;
1264 i = 32;
1265 while ((range & mask)== 0){
1266 i = i - 1;
1267 mask = mask>>1;
1268 mask2 = mask2>>1;
1270 if ((range & mask2) == 0)
1271 i = i-1;
1273 num_bits = i;
1274 length=1;
1275 if(range<=2){
1276 num_bits=1;
1279 val_start = (offset)>>3;
1280 val_length = length;
1281 val = (guint32)tvb_get_bits64(tvb,offset,num_bits, ENC_BIG_ENDIAN);
1283 if (display_internal_per_fields){
1284 str = decode_bits_in_field((offset&0x07),num_bits,val);
1285 proto_tree_add_text(tree, tvb, val_start,val_length,"MIN %u Range = %u Bitfield length %u, %s: %s value: %u",min, range, num_bits, hfi->name, str, val+min);
1287 /* The actual value */
1288 val+=min;
1289 offset = offset+num_bits;
1290 } else if(range==256){
1291 /* 10.5.7.2 */
1293 /* in the aligned case, align to byte boundary */
1294 BYTE_ALIGN_OFFSET(offset);
1295 val=tvb_get_guint8(tvb, offset>>3);
1296 offset+=8;
1298 val_start = (offset>>3)-1; val_length = 1;
1299 val+=min;
1300 } else if(range<=65536){
1301 /* 10.5.7.3 */
1303 /* in the aligned case, align to byte boundary */
1304 BYTE_ALIGN_OFFSET(offset);
1305 val=tvb_get_guint8(tvb, offset>>3);
1306 val<<=8;
1307 offset+=8;
1308 val|=tvb_get_guint8(tvb, offset>>3);
1309 offset+=8;
1311 val_start = (offset>>3)-2; val_length = 2;
1312 val+=min;
1313 } else {
1314 int i,num_bytes;
1315 gboolean bit;
1317 /* 10.5.7.4 */
1318 /* 12.2.6 */
1319 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
1320 num_bytes=bit;
1321 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
1322 num_bytes=(num_bytes<<1)|bit;
1324 num_bytes++; /* lower bound for length determinant is 1 */
1325 if (display_internal_per_fields)
1326 proto_tree_add_uint(tree, hf_per_const_int_len, tvb, (offset>>3), 1, num_bytes);
1328 /* byte aligned */
1329 BYTE_ALIGN_OFFSET(offset);
1330 val=0;
1331 for(i=0;i<num_bytes;i++){
1332 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1333 offset+=8;
1335 val_start = (offset>>3)-(num_bytes+1); val_length = num_bytes+1;
1336 val+=min;
1339 timeval.secs = val;
1340 if (IS_FT_UINT(hfi->type)) {
1341 it = proto_tree_add_uint(tree, hf_index, tvb, val_start, val_length, val);
1342 per_check_value(val, min, max, actx, it, FALSE);
1343 } else if (IS_FT_INT(hfi->type)) {
1344 it = proto_tree_add_int(tree, hf_index, tvb, val_start, val_length, val);
1345 per_check_value(val, min, max, actx, it, TRUE);
1346 } else if (IS_FT_TIME(hfi->type)) {
1347 it = proto_tree_add_time(tree, hf_index, tvb, val_start, val_length, &timeval);
1348 } else {
1349 THROW(ReportedBoundsError);
1351 actx->created_item = it;
1352 if (value) *value = val;
1353 return offset;
1356 guint32
1357 dissect_per_constrained_integer_64b(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint64 min, guint64 max, guint64 *value, gboolean has_extension)
1359 proto_item *it=NULL, *int_item=NULL;
1360 guint64 range, val;
1361 gint val_start, val_length;
1362 nstime_t timeval;
1363 header_field_info *hfi;
1364 int num_bits;
1365 gboolean tmp;
1367 DEBUG_ENTRY("dissect_per_constrained_integer_64b");
1368 if(has_extension){
1369 gboolean extension_present;
1370 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
1371 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1372 if(extension_present){
1373 offset = dissect_per_integer64b(tvb, offset, actx, tree, hf_index, (gint64*)value);
1374 return offset;
1378 hfi = proto_registrar_get_nth(hf_index);
1380 /* 10.5.3 Let "range" be defined as the integer value ("ub" - "lb" 1), and let the value to be encoded be "n".
1381 * 10.5.7 In the case of the ALIGNED variant the encoding depends on whether
1382 * d) "range" is greater than 64K (the indefinite length case).
1384 if(((max-min)>65536)&&(actx->aligned)){
1385 /* just set range really big so it will fall through
1386 to the bottom of the encoding */
1387 /* range=1000000; */
1388 range = max-min;
1389 if (range==65536)
1390 range++; /* make it fall trough? */
1391 } else {
1392 /* Copied from the 32 bit version, assuming the same problem occurs
1393 * at 64 bit boundary.
1394 * Really ugly hack.
1395 * We should really use guint64 as parameters for min/max.
1396 * This is to prevent range from being 0 if
1397 * the range for a signed integer spans the entire 32 bit range.
1398 * Special case the 2 common cases when this can happen until
1399 * a real fix is implemented.
1401 if( (max==G_GINT64_CONSTANT(0x7fffffffffffffff) && min==G_GINT64_CONSTANT(0x8000000000000000))
1402 || (max==G_GINT64_CONSTANT(0xffffffffffffffff) && min==0) ){
1403 range=G_GINT64_CONSTANT(0xffffffffffffffff);
1404 } else {
1405 range=max-min+1;
1409 val=0;
1410 timeval.secs=0; timeval.nsecs=0;
1411 /* 10.5.4 If "range" has the value 1, then the result of the encoding shall be an empty bit-field (no bits).*/
1413 /* something is really wrong if range is 0 */
1414 DISSECTOR_ASSERT(range!=0);
1416 if(range==1){
1417 val_start = offset>>3; val_length = 0;
1418 val = min;
1419 } else if((range<=255)||(!actx->aligned)) {
1420 /* 10.5.7.1
1421 * 10.5.6 In the case of the UNALIGNED variant the value ("n" - "lb") shall be encoded
1422 * as a non-negative binary integer in a bit field as specified in 10.3 with the minimum
1423 * number of bits necessary to represent the range.
1425 char *str;
1426 int i, bit, length, str_length, str_index;
1427 guint64 mask,mask2;
1428 /* We only handle 64 bit integers */
1429 mask = G_GINT64_CONSTANT(0x8000000000000000);
1430 mask2 = G_GINT64_CONSTANT(0x7fffffffffffffff);
1431 i = 64;
1432 while ((range & mask)== 0){
1433 i = i - 1;
1434 mask = mask>>1;
1435 mask2 = mask2>>1;
1437 if ((range & mask2) == 0)
1438 i = i-1;
1440 num_bits = i;
1441 length=1;
1442 if(range<=2){
1443 num_bits=1;
1446 /* prepare the string (max number of bits + quartet separators + field name + ": ") */
1447 str_length = 512+128+(int)strlen(hfi->name)+2;
1448 str = (char *)wmem_alloc(wmem_packet_scope(), str_length+1);
1449 str_index = g_snprintf(str, str_length+1, "%s: ", hfi->name);
1450 for(bit=0;bit<((int)(offset&0x07));bit++){
1451 if(bit&&(!(bit%4))){
1452 if (str_index < str_length) str[str_index++] = ' ';
1454 if (str_index < str_length) str[str_index++] = '.';
1456 /* read the bits for the int */
1457 for(i=0;i<num_bits;i++){
1458 if(bit&&(!(bit%4))){
1459 if (str_index < str_length) str[str_index++] = ' ';
1461 if(bit&&(!(bit%8))){
1462 length+=1;
1463 if (str_index < str_length) str[str_index++] = ' ';
1465 bit++;
1466 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &tmp);
1467 val<<=1;
1468 if(tmp){
1469 val|=1;
1470 if (str_index < str_length) str[str_index++] = '1';
1471 } else {
1472 if (str_index < str_length) str[str_index++] = '0';
1475 for(;bit%8;bit++){
1476 if(bit&&(!(bit%4))){
1477 if (str_index < str_length) str[str_index++] = ' ';
1479 if (str_index < str_length) str[str_index++] = '.';
1481 str[str_index] = '\0'; /* Terminate string */
1482 val_start = (offset-num_bits)>>3; val_length = length;
1483 val+=min;
1484 if (display_internal_per_fields)
1485 proto_tree_add_text(tree, tvb, val_start,val_length,"Range = (%" G_GINT64_MODIFIER "u) Bitfield length %u, %s",range, num_bits, str);
1486 } else if(range==256){
1487 /* 10.5.7.2 */
1489 /* in the aligned case, align to byte boundary */
1490 BYTE_ALIGN_OFFSET(offset);
1491 val=tvb_get_guint8(tvb, offset>>3);
1492 offset+=8;
1494 val_start = (offset>>3)-1; val_length = 1;
1495 val+=min;
1496 } else if(range<=65536){
1497 /* 10.5.7.3 */
1499 /* in the aligned case, align to byte boundary */
1500 BYTE_ALIGN_OFFSET(offset);
1501 val=tvb_get_guint8(tvb, offset>>3);
1502 val<<=8;
1503 offset+=8;
1504 val|=tvb_get_guint8(tvb, offset>>3);
1505 offset+=8;
1507 val_start = (offset>>3)-2; val_length = 2;
1508 val+=min;
1509 } else {
1510 int i,num_bytes,n_bits;
1512 /* 10.5.7.4 */
1513 /* 12.2.6 */
1514 /* calculate the number of bits to hold the length */
1515 if ((range & G_GINT64_CONSTANT(0xffffffff0000000)) != 0){
1516 n_bits=3;
1517 }else{
1518 n_bits=2;
1520 num_bytes =tvb_get_bits8(tvb, offset, n_bits);
1521 num_bytes++; /* lower bound for length determinant is 1 */
1522 if (display_internal_per_fields){
1523 int_item = proto_tree_add_bits_item(tree, hf_per_const_int_len, tvb, offset,n_bits, ENC_BIG_ENDIAN);
1524 proto_item_append_text(int_item,"+1=%u bytes, Range = (%" G_GINT64_MODIFIER "u)",num_bytes, range);
1526 offset = offset+n_bits;
1527 /* byte aligned */
1528 BYTE_ALIGN_OFFSET(offset);
1529 val=0;
1530 for(i=0;i<num_bytes;i++){
1531 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1532 offset+=8;
1534 val_start = (offset>>3)-(num_bytes+1); val_length = num_bytes+1;
1535 val+=min;
1539 if (IS_FT_UINT(hfi->type)) {
1540 it = proto_tree_add_uint64(tree, hf_index, tvb, val_start, val_length, val);
1541 per_check_value64(val, min, max, actx, it, FALSE);
1542 } else if (IS_FT_INT(hfi->type)) {
1543 it = proto_tree_add_int64(tree, hf_index, tvb, val_start, val_length, val);
1544 per_check_value64(val, min, max, actx, it, TRUE);
1545 } else if (IS_FT_TIME(hfi->type)) {
1546 timeval.secs = (guint32)val;
1547 it = proto_tree_add_time(tree, hf_index, tvb, val_start, val_length, &timeval);
1548 } else {
1549 THROW(ReportedBoundsError);
1551 actx->created_item = it;
1552 if (value) *value = val;
1553 return offset;
1556 /* 13 Encoding the enumerated type */
1557 guint32
1558 dissect_per_enumerated(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint32 root_num, guint32 *value, gboolean has_extension, guint32 ext_num, guint32 *value_map)
1561 proto_item *it=NULL;
1562 guint32 enum_index, val;
1563 guint32 start_offset = offset;
1564 gboolean extension_present = FALSE;
1565 header_field_info *hfi;
1567 if (has_extension) {
1568 /* Extension bit */
1569 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
1570 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1573 if (!extension_present) {
1574 /* 13.2 */
1575 offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_per_enum_index, 0, root_num - 1, &enum_index, FALSE);
1576 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1577 } else {
1578 /* 13.3 */
1579 if (ext_num == 1) {
1580 /* 10.5.4 If "range" has the value 1,
1581 * then the result of the encoding shall be
1582 * an empty bit-field (no bits).
1584 enum_index = 0;
1585 } else {
1586 /* 13.3 ".. and the value shall be added to the field-list as a
1587 * normally small non-negative whole number whose value is the
1588 * enumeration index of the additional enumeration and with "lb" set to 0.."
1590 offset = dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_enum_extension_index, &enum_index);
1592 enum_index += root_num;
1594 val = (value_map && (enum_index<(root_num+ext_num))) ? value_map[enum_index] : enum_index;
1595 hfi = proto_registrar_get_nth(hf_index);
1596 if (IS_FT_UINT(hfi->type)) {
1597 it = proto_tree_add_uint(tree, hf_index, tvb, start_offset>>3, BLEN(start_offset, offset), val);
1598 } else {
1599 THROW(ReportedBoundsError);
1601 actx->created_item = it;
1602 if (value) *value = val;
1603 return offset;
1606 /* 14 Encoding the real type */
1607 guint32
1608 dissect_per_real(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, double *value)
1610 guint32 val_length, end_offset;
1611 tvbuff_t *val_tvb;
1612 double val = 0;
1614 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_real_length, &val_length);
1615 if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
1616 val_tvb = new_octet_aligned_subset(tvb, offset, actx, val_length);
1617 end_offset = offset + val_length * 8;
1619 val = asn1_get_real(tvb_get_ptr(val_tvb, 0, val_length), val_length);
1620 actx->created_item = proto_tree_add_double(tree, hf_index, val_tvb, 0, val_length, val);
1622 if (value) *value = val;
1624 return end_offset;
1627 /* 22 Encoding the choice type */
1628 guint32
1629 dissect_per_choice(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gint ett_index, const per_choice_t *choice, gint *value)
1631 gboolean /*extension_present,*/ extension_flag;
1632 int extension_root_entries;
1633 int extension_addition_entries;
1634 guint32 choice_index;
1635 int i, idx, cidx;
1636 guint32 ext_length;
1637 guint32 old_offset = offset;
1638 proto_item *choice_item = NULL;
1639 proto_tree *choice_tree = NULL;
1641 DEBUG_ENTRY("dissect_per_choice");
1643 if (value) *value = -1;
1645 /* 22.5 */
1646 if (choice[0].extension == ASN1_NO_EXTENSIONS){
1647 /*extension_present = FALSE; ?? */
1648 extension_flag = FALSE;
1649 } else {
1650 /*extension_present = TRUE; ?? */
1651 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_bit, &extension_flag);
1652 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1655 /* count the number of entries in the extension root and extension addition */
1656 extension_root_entries = 0;
1657 extension_addition_entries = 0;
1658 for (i=0; choice[i].p_id; i++) {
1659 switch(choice[i].extension){
1660 case ASN1_NO_EXTENSIONS:
1661 case ASN1_EXTENSION_ROOT:
1662 extension_root_entries++;
1663 break;
1664 case ASN1_NOT_EXTENSION_ROOT:
1665 extension_addition_entries++;
1666 break;
1670 if (!extension_flag) { /* 22.6, 22.7 */
1671 if (extension_root_entries == 1) { /* 22.5 */
1672 choice_index = 0;
1673 } else {
1674 offset = dissect_per_constrained_integer(tvb, offset, actx,
1675 tree, hf_per_choice_index, 0, extension_root_entries - 1,
1676 &choice_index, FALSE);
1677 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1680 idx = -1; cidx = choice_index;
1681 for (i=0; choice[i].p_id; i++) {
1682 if(choice[i].extension != ASN1_NOT_EXTENSION_ROOT){
1683 if (!cidx) { idx = i; break; }
1684 cidx--;
1687 } else { /* 22.8 */
1688 offset = dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_choice_extension_index, &choice_index);
1689 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &ext_length);
1691 idx = -1; cidx = choice_index;
1692 for (i=0; choice[i].p_id; i++) {
1693 if(choice[i].extension == ASN1_NOT_EXTENSION_ROOT){
1694 if (!cidx) { idx = i; break; }
1695 cidx--;
1700 if (idx != -1) {
1701 choice_item = proto_tree_add_uint(tree, hf_index, tvb, old_offset>>3, 0, choice[idx].value);
1702 choice_tree = proto_item_add_subtree(choice_item, ett_index);
1703 if (!extension_flag) {
1704 offset = choice[idx].func(tvb, offset, actx, choice_tree, *choice[idx].p_id);
1705 } else {
1706 choice[idx].func(tvb, offset, actx, choice_tree, *choice[idx].p_id);
1707 offset += ext_length * 8;
1709 proto_item_set_len(choice_item, BLEN(old_offset, offset));
1710 } else {
1711 if (!extension_flag) {
1712 PER_NOT_DECODED_YET("unknown extension root index in choice");
1713 } else {
1714 offset += ext_length * 8;
1715 proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_choice_extension_unknown,
1716 tvb, old_offset>>3, BLEN(old_offset, offset),
1717 "Choice no. %d in extension", choice_index);
1721 if (value && (idx != -1))
1722 *value = choice[idx].value;
1724 return offset;
1728 static const char *
1729 index_get_optional_name(const per_sequence_t *sequence, int idx)
1731 int i;
1732 header_field_info *hfi;
1734 for(i=0;sequence[i].p_id;i++){
1735 if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1736 if (idx == 0) {
1737 hfi = proto_registrar_get_nth(*sequence[i].p_id);
1738 return (hfi) ? hfi->name : "<unknown filed>";
1740 idx--;
1743 return "<unknown type>";
1746 static const char *
1747 index_get_extension_name(const per_sequence_t *sequence, int idx)
1749 int i;
1750 header_field_info *hfi;
1752 for(i=0;sequence[i].p_id;i++){
1753 if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
1754 if (idx == 0) {
1755 if (*sequence[i].p_id == -1) return "extension addition group";
1756 hfi = proto_registrar_get_nth(*sequence[i].p_id);
1757 return (hfi) ? hfi->name : "<unknown filed>";
1759 idx--;
1762 return "<unknown type>";
1765 static const char *
1766 index_get_field_name(const per_sequence_t *sequence, int idx)
1768 header_field_info *hfi;
1770 hfi = proto_registrar_get_nth(*sequence[idx].p_id);
1771 return (hfi) ? hfi->name : "<unknown filed>";
1774 /* this functions decodes a SEQUENCE
1775 it can only handle SEQUENCES with at most 32 DEFAULT or OPTIONAL fields
1776 18.1 extension bit
1777 18.2 optinal/default items in root
1778 18.3 we ignore the case where n>64K
1779 18.4 the root sequence
1780 18.5
1781 18.6
1782 18.7
1783 18.8
1784 18.9
1786 guint32
1787 dissect_per_sequence(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *sequence)
1789 gboolean /*extension_present,*/ extension_flag, optional_field_flag;
1790 proto_item *item;
1791 proto_tree *tree;
1792 guint32 old_offset=offset;
1793 guint32 i, j, num_opts;
1794 guint32 optional_mask[SEQ_MAX_COMPONENTS>>5];
1796 DEBUG_ENTRY("dissect_per_sequence");
1798 item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, ENC_BIG_ENDIAN);
1799 tree=proto_item_add_subtree(item, ett_index);
1802 /* first check if there should be an extension bit for this CHOICE.
1803 we do this by just checking the first choice arm
1805 /* 18.1 */
1806 extension_flag=0;
1807 if(sequence[0].extension==ASN1_NO_EXTENSIONS){
1808 /*extension_present=0; ?? */
1809 } else {
1810 /*extension_present=1; ?? */
1811 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_bit, &extension_flag);
1812 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1814 /* 18.2 */
1815 num_opts=0;
1816 for(i=0;sequence[i].p_id;i++){
1817 if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1818 num_opts++;
1821 if (num_opts > SEQ_MAX_COMPONENTS) {
1822 PER_NOT_DECODED_YET("too many optional/default components");
1825 memset(optional_mask, 0, sizeof(optional_mask));
1826 for(i=0;i<num_opts;i++){
1827 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_optional_field_bit, &optional_field_flag);
1828 if (tree) {
1829 proto_item_append_text(actx->created_item, " (%s %s present)",
1830 index_get_optional_name(sequence, i), optional_field_flag?"is":"is NOT");
1832 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1833 if(optional_field_flag){
1834 optional_mask[i>>5]|=0x80000000>>(i&0x1f);
1839 /* 18.4 */
1840 for(i=0,j=0;sequence[i].p_id;i++){
1841 if( (sequence[i].extension==ASN1_NO_EXTENSIONS)
1842 || (sequence[i].extension==ASN1_EXTENSION_ROOT) ){
1843 if(sequence[i].optional==ASN1_OPTIONAL){
1844 gboolean is_present;
1845 if (num_opts == 0){
1846 continue;
1848 is_present=(0x80000000>>(j&0x1f))&optional_mask[j>>5];
1849 num_opts--;
1850 j++;
1851 if(!is_present){
1852 continue;
1855 if(sequence[i].func){
1856 offset=sequence[i].func(tvb, offset, actx, tree, *sequence[i].p_id);
1857 } else {
1858 PER_NOT_DECODED_YET(index_get_field_name(sequence, i));
1864 if(extension_flag){
1865 gboolean extension_bit;
1866 guint32 num_known_extensions;
1867 guint32 num_extensions;
1868 guint32 extension_mask;
1870 offset=dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_num_sequence_extensions, &num_extensions);
1871 /* the X.691 standard is VERY unclear here.
1872 there is no mention that the lower bound lb for this
1873 (apparently) semiconstrained value is 1,
1874 apart from the NOTE: comment in 18.8 that this value can
1875 not be 0.
1876 In my book, there is a semantic difference between having
1877 a comment that says that the value can not be zero
1878 and stating that the lb is 1.
1879 I don't know if this is right or not but it makes
1880 some of the very few captures I have decode properly.
1882 It could also be that the captures I have are generated by
1883 a broken implementation.
1884 If this is wrong and you don't report it as a bug
1885 then it won't get fixed!
1887 num_extensions+=1;
1888 if (num_extensions > 32) {
1889 PER_NOT_DECODED_YET("too many extensions");
1892 extension_mask=0;
1893 for(i=0;i<num_extensions;i++){
1894 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_bit);
1895 if (tree) {
1896 proto_item_append_text(actx->created_item, " (%s %s present)",
1897 index_get_extension_name(sequence, i), extension_bit?"is":"is NOT");
1899 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1901 extension_mask=(extension_mask<<1)|extension_bit;
1904 /* find how many extensions we know about */
1905 num_known_extensions=0;
1906 for(i=0;sequence[i].p_id;i++){
1907 if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
1908 num_known_extensions++;
1912 /* decode the extensions one by one */
1913 for(i=0;i<num_extensions;i++){
1914 guint32 length;
1915 guint32 new_offset;
1916 guint32 difference;
1917 guint32 extension_index;
1918 guint32 k;
1920 if(!((1L<<(num_extensions-1-i))&extension_mask)){
1921 /* this extension is not encoded in this PDU */
1922 continue;
1925 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &length);
1927 if(i>=num_known_extensions){
1928 /* we don't know how to decode this extension */
1929 offset+=length*8;
1930 expert_add_info(actx->pinfo, item, &ei_per_sequence_extension_unknown);
1931 continue;
1934 extension_index=0;
1935 for(j=0,k=0;sequence[j].p_id;j++){
1936 if(sequence[j].extension==ASN1_NOT_EXTENSION_ROOT){
1937 if(k==i){
1938 extension_index=j;
1939 break;
1941 k++;
1945 if(sequence[extension_index].func){
1946 new_offset=sequence[extension_index].func(tvb, offset, actx, tree, *sequence[extension_index].p_id);
1947 offset+=length*8;
1948 difference = offset - new_offset;
1949 /* A difference of 7 or less might be byte aligning */
1950 /* Difference could be 8 if open type has no bits and the length is 1 */
1951 if ((length > 1) && (difference > 7)) {
1952 proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_encoding_error, tvb, new_offset>>3, (offset-new_offset)>>3,
1953 "Possible encoding error full length not decoded. Open type length %u ,decoded %u",length, length - (difference>>3));
1955 } else {
1956 PER_NOT_DECODED_YET(index_get_field_name(sequence, extension_index));
1957 offset+=length*8;
1962 proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
1963 actx->created_item = item;
1964 return offset;
1967 guint32
1968 dissect_per_sequence_eag(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, const per_sequence_t *sequence)
1970 gboolean optional_field_flag;
1971 guint32 i, j, num_opts;
1972 guint32 optional_mask[SEQ_MAX_COMPONENTS>>5];
1974 DEBUG_ENTRY("dissect_per_sequence_eag");
1976 num_opts=0;
1977 for(i=0;sequence[i].p_id;i++){
1978 if(sequence[i].optional==ASN1_OPTIONAL){
1979 num_opts++;
1982 if (num_opts > SEQ_MAX_COMPONENTS) {
1983 PER_NOT_DECODED_YET("too many optional/default components");
1986 memset(optional_mask, 0, sizeof(optional_mask));
1987 for(i=0;i<num_opts;i++){
1988 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_optional_field_bit, &optional_field_flag);
1989 if (tree) {
1990 proto_item_append_text(actx->created_item, " (%s %s present)",
1991 index_get_optional_name(sequence, i), optional_field_flag?"is":"is NOT");
1993 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1994 if(optional_field_flag){
1995 optional_mask[i>>5]|=0x80000000>>(i&0x1f);
1999 for(i=0,j=0;sequence[i].p_id;i++){
2000 if(sequence[i].optional==ASN1_OPTIONAL){
2001 gboolean is_present;
2002 if (num_opts == 0){
2003 continue;
2005 is_present=(0x80000000>>(j&0x1f))&optional_mask[j>>5];
2006 num_opts--;
2007 j++;
2008 if(!is_present){
2009 continue;
2012 if(sequence[i].func){
2013 offset=sequence[i].func(tvb, offset, actx, tree, *sequence[i].p_id);
2014 } else {
2015 PER_NOT_DECODED_YET(index_get_field_name(sequence, i));
2019 return offset;
2023 /* 15 Encoding the bitstring type
2025 max_len or min_len == NO_BOUND means there is no lower/upper constraint
2029 static tvbuff_t *dissect_per_bit_string_display(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, header_field_info *hfi, guint32 length)
2031 tvbuff_t *out_tvb = NULL;
2032 guint32 pad_length=0;
2033 guint64 value;
2035 out_tvb = tvb_new_octet_aligned(tvb, offset, length);
2036 add_new_data_source(actx->pinfo, out_tvb, "Bitstring tvb");
2038 if (hfi) {
2039 actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, -1, ENC_BIG_ENDIAN);
2040 proto_item_append_text(actx->created_item, " [bit length %u", length);
2041 if (length%8) {
2042 pad_length = 8-(length%8);
2043 proto_item_append_text(actx->created_item, ", %u LSB pad bits", pad_length);
2046 if (length<=64) { /* if read into 64 bits also handle length <= 24, 40, 48, 56 bits */
2047 if (length<=8) {
2048 value = tvb_get_bits8(out_tvb, 0, length);
2049 }else if (length<=16) {
2050 value = tvb_get_bits16(out_tvb, 0, length, ENC_BIG_ENDIAN);
2051 }else if (length<=24) { /* first read 16 and then the remaining bits */
2052 value = tvb_get_bits16(out_tvb, 0, 16, ENC_BIG_ENDIAN);
2053 value <<= 8 - pad_length;
2054 value |= tvb_get_bits8(out_tvb, 16, length - 16);
2055 }else if (length<=32) {
2056 value = tvb_get_bits32(out_tvb, 0, length, ENC_BIG_ENDIAN);
2057 }else if (length<=40) { /* first read 32 and then the remaining bits */
2058 value = tvb_get_bits32(out_tvb, 0, 32, ENC_BIG_ENDIAN);
2059 value <<= 8 - pad_length;
2060 value |= tvb_get_bits8(out_tvb, 32, length - 32);
2061 }else if (length<=48) { /* first read 32 and then the remaining bits */
2062 value = tvb_get_bits32(out_tvb, 0, 32, ENC_BIG_ENDIAN);
2063 value <<= 16 - pad_length;
2064 value |= tvb_get_bits16(out_tvb, 32, length - 32, ENC_BIG_ENDIAN);
2065 }else if (length<=56) { /* first read 32 and 16 then the remaining bits */
2066 value = tvb_get_bits32(out_tvb, 0, 32, ENC_BIG_ENDIAN);
2067 value <<= 16;
2068 value |= tvb_get_bits16(out_tvb, 32, 16, ENC_BIG_ENDIAN);
2069 value <<= 8 - pad_length;
2070 value |= tvb_get_bits8(out_tvb, 48, length - 48);
2071 }else {
2072 value = tvb_get_bits64(out_tvb, 0, length, ENC_BIG_ENDIAN);
2074 proto_item_append_text(actx->created_item, ", %s decimal value %" G_GINT64_MODIFIER "u",
2075 decode_bits_in_field(0, length, value), value);
2077 proto_item_append_text(actx->created_item, "]");
2080 return out_tvb;
2082 guint32
2083 dissect_per_bit_string(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, tvbuff_t **value_tvb)
2085 /*gint val_start, val_length;*/
2086 guint32 length;
2087 header_field_info *hfi;
2088 tvbuff_t *out_tvb = NULL;
2090 hfi = (hf_index==-1) ? NULL : proto_registrar_get_nth(hf_index);
2092 DEBUG_ENTRY("dissect_per_bit_string");
2093 /* 15.8 if the length is 0 bytes there will be no encoding */
2094 if(max_len==0) {
2095 if (value_tvb)
2096 *value_tvb = out_tvb;
2097 return offset;
2100 if (min_len == NO_BOUND) {
2101 min_len = 0;
2103 /* 15.6 If an extension marker is present in the size constraint specification of the bitstring type,
2104 * a single bit shall be added to the field-list in a bit-field of length one.
2105 * The bit shall be set to 1 if the length of this encoding is not within the range of the extension root,
2106 * and zero otherwise.
2108 if (has_extension) {
2109 gboolean extension_present;
2110 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
2111 if(extension_present){
2112 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_bit_string_length, &length);
2113 if(length){
2114 /* align to byte */
2115 if (actx->aligned){
2116 BYTE_ALIGN_OFFSET(offset);
2118 out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, length);
2120 /* XXX: ?? */
2121 /*val_start = offset>>3;*/
2122 /*val_length = (length+7)/8;*/
2123 offset+=length;
2125 if (value_tvb)
2126 *value_tvb = out_tvb;
2128 return offset;
2132 /* 15.9 if length is fixed and less than or equal to sixteen bits*/
2133 if ((min_len==max_len) && (max_len<=16)) {
2134 out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, min_len);
2135 offset+=min_len;
2136 if (value_tvb)
2137 *value_tvb = out_tvb;
2138 return offset;
2142 /* 15.10 if length is fixed and less than to 64kbits*/
2143 if((min_len==max_len)&&(min_len<65536)){
2144 /* (octet-aligned in the ALIGNED variant)
2145 * align to byte
2147 if (actx->aligned){
2148 BYTE_ALIGN_OFFSET(offset);
2150 out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, min_len);
2151 offset+=min_len;
2152 if (value_tvb)
2153 *value_tvb = out_tvb;
2154 return offset;
2157 /* 15.11 */
2158 if (max_len != NO_BOUND) {
2159 offset=dissect_per_constrained_integer(tvb, offset, actx,
2160 tree, hf_per_bit_string_length, min_len, max_len,
2161 &length, FALSE);
2162 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
2163 } else {
2164 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_bit_string_length, &length);
2166 if(length){
2167 /* align to byte */
2168 if (actx->aligned){
2169 BYTE_ALIGN_OFFSET(offset);
2171 out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, length);
2173 /* XXX: ?? */
2174 /*val_start = offset>>3;*/
2175 /*val_length = (length+7)/8;*/
2176 offset+=length;
2178 if (value_tvb)
2179 *value_tvb = out_tvb;
2181 return offset;
2184 guint32 dissect_per_bit_string_containing_pdu(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, dissector_t type_cb)
2186 tvbuff_t *val_tvb = NULL;
2187 proto_tree *subtree = tree;
2189 offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, &val_tvb);
2191 if (type_cb && val_tvb) {
2192 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2193 type_cb(val_tvb, actx->pinfo, subtree);
2196 return offset;
2199 guint32 dissect_per_bit_string_containing_pdu_new(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, new_dissector_t type_cb)
2201 tvbuff_t *val_tvb = NULL;
2202 proto_tree *subtree = tree;
2204 offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, &val_tvb);
2206 if (type_cb && val_tvb) {
2207 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2208 type_cb(val_tvb, actx->pinfo, subtree, NULL);
2211 return offset;
2214 /* this fucntion dissects an OCTET STRING
2215 16.1
2216 16.2
2217 16.3
2218 16.4
2219 16.5
2220 16.6
2221 16.7
2222 16.8
2224 max_len or min_len == NO_BOUND means there is no lower/upper constraint
2226 hf_index can either be a FT_BYTES or an FT_STRING
2228 guint32
2229 dissect_per_octet_string(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, tvbuff_t **value_tvb)
2231 gint val_start = 0, val_length;
2232 guint32 length = 0;
2233 header_field_info *hfi;
2234 tvbuff_t *out_tvb = NULL;
2236 hfi = (hf_index==-1) ? NULL : proto_registrar_get_nth(hf_index);
2238 DEBUG_ENTRY("dissect_per_octet_string");
2240 if (has_extension) { /* 16.3 an extension marker is present */
2241 gboolean extension_present;
2242 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
2243 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
2244 if (extension_present) max_len = NO_BOUND; /* skip to 16.8 */
2247 if (min_len == NO_BOUND) {
2248 min_len = 0;
2250 if (max_len==0) { /* 16.5 if the length is 0 bytes there will be no encoding */
2251 val_start = offset>>3;
2252 val_length = 0;
2254 } else if((min_len==max_len)&&(max_len<=2)) {
2255 /* 16.6 if length is fixed and less than or equal to two bytes*/
2256 val_start = offset>>3;
2257 val_length = min_len;
2258 out_tvb = new_octet_aligned_subset(tvb, offset, actx, val_length);
2259 offset+=min_len*8;
2261 } else if ((min_len==max_len)&&(min_len<65536)) {
2262 /* 16.7 if length is fixed and less than to 64k*/
2264 /* align to byte */
2265 if (actx->aligned){
2266 BYTE_ALIGN_OFFSET(offset);
2268 val_start = offset>>3;
2269 val_length = min_len;
2270 out_tvb = new_octet_aligned_subset(tvb, offset, actx, val_length);
2271 offset+=min_len*8;
2273 } else { /* 16.8 */
2274 if(max_len>0) {
2275 offset = dissect_per_constrained_integer(tvb, offset, actx, tree,
2276 hf_per_octet_string_length, min_len, max_len, &length, FALSE);
2278 if (!display_internal_per_fields)
2279 PROTO_ITEM_SET_HIDDEN(actx->created_item);
2280 } else {
2281 offset = dissect_per_length_determinant(tvb, offset, actx, tree,
2282 hf_per_octet_string_length, &length);
2285 if(length){
2286 /* align to byte */
2287 if (actx->aligned){
2288 BYTE_ALIGN_OFFSET(offset);
2290 out_tvb = new_octet_aligned_subset(tvb, offset, actx, length);
2291 } else {
2292 val_start = offset>>3;
2294 val_length = length;
2295 offset+=length*8;
2298 if (hfi) {
2299 if (IS_FT_UINT(hfi->type)||IS_FT_INT(hfi->type)) {
2300 /* If the type has been converted to FT_UINT or FT_INT in the .cnf file
2301 * display the length of this octet string instead of the octetstring itself
2303 if (IS_FT_UINT(hfi->type))
2304 actx->created_item = proto_tree_add_uint(tree, hf_index, out_tvb, 0, val_length, val_length);
2305 else
2306 actx->created_item = proto_tree_add_int(tree, hf_index, out_tvb, 0, val_length, val_length);
2307 proto_item_append_text(actx->created_item, plurality(val_length, " octet", " octets"));
2308 } else {
2309 if(out_tvb){
2310 actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, val_length, ENC_BIG_ENDIAN);
2311 }else{
2312 /* Length = 0 */
2313 actx->created_item = proto_tree_add_item(tree, hf_index, tvb, val_start, val_length, ENC_BIG_ENDIAN);
2318 if (value_tvb)
2319 *value_tvb = (out_tvb) ? out_tvb : tvb_new_subset(tvb, val_start, val_length, val_length);
2321 return offset;
2324 guint32 dissect_per_octet_string_containing_pdu(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, dissector_t type_cb)
2326 tvbuff_t *val_tvb = NULL;
2327 proto_tree *subtree = tree;
2329 offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, &val_tvb);
2331 if (type_cb && val_tvb) {
2332 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2333 type_cb(val_tvb, actx->pinfo, subtree);
2336 return offset;
2339 guint32 dissect_per_octet_string_containing_pdu_new(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, new_dissector_t type_cb)
2341 tvbuff_t *val_tvb = NULL;
2342 proto_tree *subtree = tree;
2344 offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, &val_tvb);
2346 if (type_cb && val_tvb) {
2347 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2348 type_cb(val_tvb, actx->pinfo, subtree, NULL);
2351 return offset;
2354 guint32 dissect_per_size_constrained_type(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, per_type_fn type_cb, const gchar *name, int min_len, int max_len, gboolean has_extension)
2356 asn1_stack_frame_push(actx, name);
2357 asn1_param_push_integer(actx, min_len);
2358 asn1_param_push_integer(actx, max_len);
2359 asn1_param_push_boolean(actx, has_extension);
2361 offset = type_cb(tvb, offset, actx, tree, hf_index);
2363 asn1_stack_frame_pop(actx, name);
2365 return offset;
2368 gboolean get_size_constraint_from_stack(asn1_ctx_t *actx, const gchar *name, int *pmin_len, int *pmax_len, gboolean *phas_extension)
2370 asn1_par_t *par;
2372 if (pmin_len) *pmin_len = NO_BOUND;
2373 if (pmax_len) *pmax_len = NO_BOUND;
2374 if (phas_extension) *phas_extension = FALSE;
2376 if (!actx->stack) return FALSE;
2377 if (strcmp(actx->stack->name, name)) return FALSE;
2379 par = actx->stack->par;
2380 if (!par || (par->ptype != ASN1_PAR_INTEGER)) return FALSE;
2381 if (pmin_len) *pmin_len = par->value.v_integer;
2382 par = par->next;
2383 if (!par || (par->ptype != ASN1_PAR_INTEGER)) return FALSE;
2384 if (pmax_len) *pmax_len = par->value.v_integer;
2385 par = par->next;
2386 if (!par || (par->ptype != ASN1_PAR_BOOLEAN)) return FALSE;
2387 if (phas_extension) *phas_extension = par->value.v_boolean;
2389 return TRUE;
2393 /* 26 Encoding of a value of the external type */
2395 /* code generated from definition in 26.1 */
2397 [UNIVERSAL 8] IMPLICIT SEQUENCE {
2398 direct-reference OBJECT IDENTIFIER OPTIONAL,
2399 indirect-reference INTEGER OPTIONAL,
2400 data-value-descriptor ObjectDescriptor OPTIONAL,
2401 encoding CHOICE {
2402 single-ASN1-type [0] ABSTRACT-SYNTAX.&Type,
2403 octet-aligned [1] IMPLICIT OCTET STRING,
2404 arbitrary [2] IMPLICIT BIT STRING
2408 /* NOTE: This sequence type differs from that in ITU-T Rec. X.680 | ISO/IEC 8824-1 for historical reasons. */
2410 static int
2411 dissect_per_T_direct_reference(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2412 offset = dissect_per_object_identifier_str(tvb, offset, actx, tree, hf_index, &actx->external.direct_reference);
2414 actx->external.direct_ref_present = TRUE;
2415 return offset;
2420 static int
2421 dissect_per_T_indirect_reference(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2422 offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, &actx->external.indirect_reference);
2424 actx->external.indirect_ref_present = TRUE;
2425 return offset;
2430 static int
2431 dissect_per_T_data_value_descriptor(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2432 offset = dissect_per_object_descriptor(tvb, offset, actx, tree, hf_index, &actx->external.data_value_descriptor);
2434 actx->external.data_value_descr_present = TRUE;
2435 return offset;
2440 static int
2441 dissect_per_T_single_ASN1_type(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2442 offset = dissect_per_open_type(tvb, offset, actx, tree, actx->external.hf_index, actx->external.u.per.type_cb);
2444 return offset;
2449 static int
2450 dissect_per_T_octet_aligned(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2451 offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index,
2452 NO_BOUND, NO_BOUND, FALSE, &actx->external.octet_aligned);
2454 if (actx->external.octet_aligned) {
2455 if (actx->external.u.per.type_cb) {
2456 actx->external.u.per.type_cb(actx->external.octet_aligned, 0, actx, tree, actx->external.hf_index);
2457 } else {
2458 actx->created_item = proto_tree_add_text(tree, actx->external.octet_aligned, 0, -1, "Unknown EXTERNAL Type");
2461 return offset;
2466 static int
2467 dissect_per_T_arbitrary(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2468 offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index,
2469 NO_BOUND, NO_BOUND, FALSE, &actx->external.arbitrary);
2471 if (actx->external.arbitrary) {
2472 if (actx->external.u.per.type_cb) {
2473 actx->external.u.per.type_cb(actx->external.arbitrary, 0, actx, tree, actx->external.hf_index);
2474 } else {
2475 actx->created_item = proto_tree_add_text(tree, actx->external.arbitrary, 0, -1, "Unknown EXTERNAL Type");
2478 return offset;
2482 static const value_string per_External_encoding_vals[] = {
2483 { 0, "single-ASN1-type" },
2484 { 1, "octet-aligned" },
2485 { 2, "arbitrary" },
2486 { 0, NULL }
2489 static const per_choice_t External_encoding_choice[] = {
2490 { 0, &hf_per_single_ASN1_type, ASN1_NO_EXTENSIONS , dissect_per_T_single_ASN1_type },
2491 { 1, &hf_per_octet_aligned , ASN1_NO_EXTENSIONS , dissect_per_T_octet_aligned },
2492 { 2, &hf_per_arbitrary , ASN1_NO_EXTENSIONS , dissect_per_T_arbitrary },
2493 { 0, NULL, 0, NULL }
2496 static int
2497 dissect_per_External_encoding(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2498 offset = dissect_per_choice(tvb, offset, actx, tree, hf_index,
2499 ett_per_External_encoding, External_encoding_choice,
2500 &actx->external.encoding);
2502 return offset;
2506 static const per_sequence_t External_sequence[] = {
2507 { &hf_per_direct_reference, ASN1_NO_EXTENSIONS , ASN1_OPTIONAL , dissect_per_T_direct_reference },
2508 { &hf_per_indirect_reference, ASN1_NO_EXTENSIONS , ASN1_OPTIONAL , dissect_per_T_indirect_reference },
2509 { &hf_per_data_value_descriptor, ASN1_NO_EXTENSIONS , ASN1_OPTIONAL , dissect_per_T_data_value_descriptor },
2510 { &hf_per_encoding , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_per_External_encoding },
2511 { NULL, 0, 0, NULL }
2514 static int
2515 dissect_per_External(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2516 offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
2517 ett_per_External, External_sequence);
2519 return offset;
2522 guint32
2523 dissect_per_external_type(tvbuff_t *tvb _U_, guint32 offset, asn1_ctx_t *actx, proto_tree *tree _U_, int hf_index _U_, per_type_fn type_cb)
2525 asn1_ctx_clean_external(actx);
2526 actx->external.u.per.type_cb = type_cb;
2527 offset = dissect_per_External(tvb, offset, actx, tree, hf_index);
2529 asn1_ctx_clean_external(actx);
2530 return offset;
2534 void
2535 proto_register_per(void)
2537 static hf_register_info hf[] =
2539 { &hf_per_num_sequence_extensions,
2540 { "Number of Sequence Extensions", "per.num_sequence_extensions", FT_UINT32, BASE_DEC,
2541 NULL, 0, "Number of extensions encoded in this sequence", HFILL }},
2542 { &hf_per_choice_index,
2543 { "Choice Index", "per.choice_index", FT_UINT32, BASE_DEC,
2544 NULL, 0, "Which index of the Choice within extension root is encoded", HFILL }},
2545 { &hf_per_choice_extension_index,
2546 { "Choice Extension Index", "per.choice_extension_index", FT_UINT32, BASE_DEC,
2547 NULL, 0, "Which index of the Choice within extension addition is encoded", HFILL }},
2548 { &hf_per_enum_index,
2549 { "Enumerated Index", "per.enum_index", FT_UINT32, BASE_DEC,
2550 NULL, 0, "Which index of the Enumerated within extension root is encoded", HFILL }},
2551 { &hf_per_enum_extension_index,
2552 { "Enumerated Extension Index", "per.enum_extension_index", FT_UINT32, BASE_DEC,
2553 NULL, 0, "Which index of the Enumerated within extension addition is encoded", HFILL }},
2554 { &hf_per_GeneralString_length,
2555 { "GeneralString Length", "per.generalstring_length", FT_UINT32, BASE_DEC,
2556 NULL, 0, "Length of the GeneralString", HFILL }},
2557 { &hf_per_extension_bit,
2558 { "Extension Bit", "per.extension_bit", FT_BOOLEAN, 8,
2559 TFS(&tfs_extension_bit), 0x01, "The extension bit of an aggregate", HFILL }},
2560 { &hf_per_extension_present_bit,
2561 { "Extension Present Bit", "per.extension_present_bit", FT_BOOLEAN, 8,
2562 TFS(&tfs_extension_present_bit), 0x01, "Whether this optional extension is present or not", HFILL }},
2563 { &hf_per_small_number_bit,
2564 { "Small Number Bit", "per.small_number_bit", FT_BOOLEAN, 8,
2565 TFS(&tfs_small_number_bit), 0x01, "The small number bit for a section 10.6 integer", HFILL }},
2566 { &hf_per_optional_field_bit,
2567 { "Optional Field Bit", "per.optional_field_bit", FT_BOOLEAN, 8,
2568 TFS(&tfs_optional_field_bit), 0x01, "This bit specifies the presence/absence of an optional field", HFILL }},
2569 { &hf_per_sequence_of_length,
2570 { "Sequence-Of Length", "per.sequence_of_length", FT_UINT32, BASE_DEC,
2571 NULL, 0, "Number of items in the Sequence Of", HFILL }},
2572 { &hf_per_object_identifier_length,
2573 { "Object Identifier Length", "per.object_length", FT_UINT32, BASE_DEC,
2574 NULL, 0, "Length of the object identifier", HFILL }},
2575 { &hf_per_open_type_length,
2576 { "Open Type Length", "per.open_type_length", FT_UINT32, BASE_DEC,
2577 NULL, 0, "Length of an open type encoding", HFILL }},
2578 { &hf_per_real_length,
2579 { "Real Length", "per.real_length", FT_UINT32, BASE_DEC,
2580 NULL, 0, "Length of an real encoding", HFILL }},
2581 { &hf_per_octet_string_length,
2582 { "Octet String Length", "per.octet_string_length", FT_UINT32, BASE_DEC,
2583 NULL, 0, "Number of bytes in the Octet String", HFILL }},
2584 { &hf_per_bit_string_length,
2585 { "Bit String Length", "per.bit_string_length", FT_UINT32, BASE_DEC,
2586 NULL, 0, "Number of bits in the Bit String", HFILL }},
2587 { &hf_per_normally_small_nonnegative_whole_number_length,
2588 { "Normally Small Non-negative Whole Number Length", "per.normally_small_nonnegative_whole_number_length", FT_UINT32, BASE_DEC,
2589 NULL, 0, "Number of bytes in the Normally Small Non-negative Whole Number", HFILL }},
2590 { &hf_per_const_int_len,
2591 { "Constrained Integer Length", "per.const_int_len", FT_UINT32, BASE_DEC,
2592 NULL, 0, "Number of bytes in the Constrained Integer", HFILL }},
2593 { &hf_per_direct_reference,
2594 { "direct-reference", "per.direct_reference",
2595 FT_OID, BASE_NONE, NULL, 0,
2596 "per.T_direct_reference", HFILL }},
2597 { &hf_per_indirect_reference,
2598 { "indirect-reference", "per.indirect_reference",
2599 FT_INT32, BASE_DEC, NULL, 0,
2600 "per.T_indirect_reference", HFILL }},
2601 { &hf_per_data_value_descriptor,
2602 { "data-value-descriptor", "per.data_value_descriptor",
2603 FT_STRING, BASE_NONE, NULL, 0,
2604 "per.T_data_value_descriptor", HFILL }},
2605 { &hf_per_encoding,
2606 { "encoding", "per.encoding",
2607 FT_UINT32, BASE_DEC, VALS(per_External_encoding_vals), 0,
2608 "per.External_encoding", HFILL }},
2609 { &hf_per_single_ASN1_type,
2610 { "single-ASN1-type", "per.single_ASN1_type",
2611 FT_NONE, BASE_NONE, NULL, 0,
2612 "per.T_single_ASN1_type", HFILL }},
2613 { &hf_per_octet_aligned,
2614 { "octet-aligned", "per.octet_aligned",
2615 FT_BYTES, BASE_NONE, NULL, 0,
2616 "per.T_octet_aligned", HFILL }},
2617 { &hf_per_arbitrary,
2618 { "arbitrary", "per.arbitrary",
2619 FT_BYTES, BASE_NONE, NULL, 0,
2620 "per.T_arbitrary", HFILL }},
2621 { &hf_per_integer_length,
2622 { "integer length", "per.integer_length",
2623 FT_UINT32, BASE_DEC, NULL, 0,
2624 NULL, HFILL }},
2625 #if 0
2626 { &hf_per_debug_pos,
2627 { "Current bit offset", "per.debug_pos",
2628 FT_UINT32, BASE_DEC, NULL, 0,
2629 NULL, HFILL }},
2630 #endif
2632 static gint *ett[] =
2634 &ett_per_open_type,
2635 &ett_per_containing,
2636 &ett_per_sequence_of_item,
2637 &ett_per_External,
2638 &ett_per_External_encoding,
2640 static ei_register_info ei[] = {
2641 { &ei_per_size_constraint_value, { "per.size_constraint.value", PI_PROTOCOL, PI_WARN, "Size constraint: value too big", EXPFILL }},
2642 { &ei_per_size_constraint_too_few, { "per.size_constraint.too_few", PI_PROTOCOL, PI_WARN, "Size constraint: too few items", EXPFILL }},
2643 { &ei_per_size_constraint_too_many, { "per.size_constraint.too_many", PI_PROTOCOL, PI_WARN, "Size constraint: too many items", EXPFILL }},
2644 { &ei_per_choice_extension_unknown, { "per.choice_extension_unknown", PI_UNDECODED, PI_NOTE, "unknown choice extension", EXPFILL }},
2645 { &ei_per_sequence_extension_unknown, { "per.sequence_extension_unknown", PI_UNDECODED, PI_NOTE, "unknown sequence extension", EXPFILL }},
2646 { &ei_per_encoding_error, { "per.encoding_error", PI_MALFORMED, PI_WARN, "Encoding error", EXPFILL }},
2649 module_t *per_module;
2650 expert_module_t* expert_per;
2652 proto_per = proto_register_protocol("Packed Encoding Rules (ASN.1 X.691)", "PER", "per");
2653 proto_register_field_array(proto_per, hf, array_length(hf));
2654 proto_register_subtree_array(ett, array_length(ett));
2655 expert_per = expert_register_protocol(proto_per);
2656 expert_register_field_array(expert_per, ei, array_length(ei));
2658 proto_set_cant_toggle(proto_per);
2660 per_module = prefs_register_protocol(proto_per, NULL);
2661 prefs_register_bool_preference(per_module, "display_internal_per_fields",
2662 "Display the internal PER fields in the tree",
2663 "Whether the dissector should put the internal PER data in the tree or if it should hide it",
2664 &display_internal_per_fields);
2668 void
2669 proto_reg_handoff_per(void)
2674 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2676 * Local variables:
2677 * c-basic-offset: 8
2678 * tab-width: 8
2679 * indent-tabs-mode: t
2680 * End:
2682 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2683 * :indentSize=8:tabSize=8:noTabs=false: