Enable Lua tcp tap userdata.
[obnox/wireshark/wip.git] / epan / dissectors / packet-per.c
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
9  *
10  * $Id$
11  *
12  * Wireshark - Network traffic analyzer
13  * By Gerald Combs <gerald@wireshark.org>
14  * Copyright 1998 Gerald Combs
15  *
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.
20  *
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.
25  *
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
29  */
30
31 #ifdef HAVE_CONFIG_H
32 # include "config.h"
33 #endif
34
35 #include <glib.h>
36 #include <epan/packet.h>
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <math.h>
42
43 #include <epan/oids.h>
44 #include <epan/to_str.h>
45 #include <epan/prefs.h>
46 #include <epan/emem.h>
47 #include <epan/asn1.h>
48 #include <epan/strutil.h>
49 #include <epan/expert.h>
50 #include "packet-per.h"
51
52
53 static int proto_per = -1;
54 static int hf_per_GeneralString_length = -1;
55 static int hf_per_extension_bit = -1;
56 static int hf_per_extension_present_bit = -1;
57 static int hf_per_choice_index = -1;
58 static int hf_per_choice_extension_index = -1;
59 static int hf_per_enum_index = -1;
60 static int hf_per_enum_extension_index = -1;
61 static int hf_per_num_sequence_extensions = -1;
62 static int hf_per_small_number_bit = -1;
63 static int hf_per_optional_field_bit = -1;
64 static int hf_per_sequence_of_length = -1;
65 static int hf_per_object_identifier_length = -1;
66 static int hf_per_open_type_length = -1;
67 static int hf_per_real_length = -1;
68 static int hf_per_octet_string_length = -1;
69 static int hf_per_bit_string_length = -1;
70 static int hf_per_const_int_len = -1;
71 static int hf_per_direct_reference = -1;          /* T_direct_reference */
72 static int hf_per_indirect_reference = -1;        /* T_indirect_reference */
73 static int hf_per_data_value_descriptor = -1;     /* T_data_value_descriptor */
74 static int hf_per_encoding = -1;                  /* External_encoding */
75 static int hf_per_single_ASN1_type = -1;          /* T_single_ASN1_type */
76 static int hf_per_octet_aligned = -1;             /* T_octet_aligned */
77 static int hf_per_arbitrary = -1;                 /* T_arbitrary */
78 static int hf_per_integer_length = -1;                    /* Show integer length if "show internal per fields" */
79
80 static gint ett_per_open_type = -1;
81 static gint ett_per_containing = -1;
82 static gint ett_per_sequence_of_item = -1;
83 static gint ett_per_External = -1;
84 static gint ett_per_External_encoding = -1;
85
86 /*
87 #define DEBUG_ENTRY(x) \
88 printf("#%u  %s   tvb:0x%08x\n",actx->pinfo->fd->num,x,(int)tvb);
89 */
90 #define DEBUG_ENTRY(x) \
91         ;
92
93 #define BLEN(old_offset, offset) (((offset)>>3)!=((old_offset)>>3)?((offset)>>3)-((old_offset)>>3):1)
94
95 /* whether the PER helpers should put the internal PER fields into the tree
96    or not.
97 */
98 static gboolean display_internal_per_fields = FALSE;
99
100
101
102 static const true_false_string tfs_extension_present_bit = {
103         "",
104         ""
105 };
106 static const true_false_string tfs_extension_bit = {
107         "Extension bit is set",
108         "Extension bit is clear"
109 };
110 static const true_false_string tfs_small_number_bit = {
111         "The number is small, 0-63",
112         "The number is large, >63"
113 };
114 static const true_false_string tfs_optional_field_bit = {
115         "",
116         ""
117 };
118
119
120 #define BYTE_ALIGN_OFFSET(offset) if(offset&0x07){offset=(offset&0xfffffff8)+8;}
121
122 static tvbuff_t *new_octet_aligned_subset(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, guint32 length)
123 {
124   tvbuff_t *sub_tvb = NULL;
125   guint32 boffset = offset >> 3;
126   unsigned int i, shift0, shift1;
127   guint8 octet0, octet1, *buf;
128   guint32 actual_length;
129
130   actual_length = tvb_length_remaining(tvb,boffset);
131   if (length <= actual_length)
132           actual_length = length;
133
134   if (offset & 0x07) {  /* unaligned */
135     shift1 = offset & 0x07;
136     shift0 = 8 - shift1;
137     buf = ep_alloc(actual_length);
138     octet0 = tvb_get_guint8(tvb, boffset);
139     for (i=0; i<actual_length; i++) {
140       octet1 = octet0;
141       octet0 = tvb_get_guint8(tvb, boffset + i + 1);
142       buf[i] = (octet1 << shift1) | (octet0 >> shift0);
143     }
144     sub_tvb = tvb_new_child_real_data(tvb, buf, actual_length, length);
145     add_new_data_source(actx->pinfo, sub_tvb, "Unaligned OCTET STRING");
146   } else {  /* aligned */
147     sub_tvb = tvb_new_subset(tvb, boffset, actual_length, length);
148   }
149   return sub_tvb;
150 }
151
152 static const guint16 bit_mask16[] = {
153     0xffff,
154     0x7fff,
155     0x3fff,
156     0x1fff,
157     0x0fff,
158     0x07ff,
159     0x03ff,
160     0x01ff
161 };
162
163 /* Fetch a number of bits to a new tvb right adjusted to the nearest number of bytes.
164  * (add proceeding zeros in case of aligned PER)
165  */
166 tvbuff_t *new_octet_aligned_subset_bits(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, guint32 no_of_bits)
167 {
168   tvbuff_t *sub_tvb = NULL;
169   guint32 boffset = offset >> 3;
170   unsigned int i, shift0, shift1;
171   guint8 octet0, octet1, *buf;
172   guint16       word;
173
174   guint32       length;
175   guint32       remainder;
176
177   /* Calculate the size reqired */
178
179   length = no_of_bits/8;
180   remainder = no_of_bits % 8;
181   if(remainder){
182           length++;
183   }else{
184           /* Number of bits = even number of octets */
185         return new_octet_aligned_subset(tvb, offset, actx, length);
186   }
187   buf = ep_alloc(length);
188
189   if (actx->aligned)
190   {
191     /* get the 'odd' bits */
192     shift1 = offset & 0x07;
193     word = tvb_get_ntohs(tvb,boffset) & bit_mask16[offset & 0x07];
194     word = word >> (16-(shift1+remainder));
195     buf[0] = word & 0x00ff;
196
197     offset = offset + remainder;
198     boffset = offset >> 3;
199     if (length >1){
200       shift1 = offset & 0x07;
201       shift0 = 8 - shift1;
202       octet0 = tvb_get_guint8(tvb, boffset);
203       for (i=1; i<length; i++) {
204         octet1 = octet0;
205         octet0 = tvb_get_guint8(tvb, boffset + i);
206         buf[i] = (octet1 << shift1) | (octet0 >> shift0);
207       }
208     }
209   }
210   else
211   {
212     /* Do not preceed with zeros in case of PER unaligned */
213     i = 0;
214     shift1 = offset & 0x07;
215     shift0 = 8 - shift1;
216
217     if (length > 1){
218       octet0 = tvb_get_guint8(tvb, boffset);
219       for (; i < length-1; i++) {
220         octet1 = octet0;
221         octet0 = tvb_get_guint8(tvb, boffset + i + 1);
222         buf[i] = (octet1 << shift1) | (octet0 >> shift0);
223       }
224     }
225     /* get the 'odd' bits */
226     word = tvb_get_ntohs(tvb,boffset+i) << shift1;
227     word = word & ~bit_mask16[remainder];
228     word = word >> 8;
229     buf[i] = (guint8) (word & 0x00ff);
230   }
231   sub_tvb = tvb_new_child_real_data(tvb, buf, length, length);
232   add_new_data_source(actx->pinfo, sub_tvb, "Unaligned OCTET STRING");
233   
234   return sub_tvb;
235 }
236
237
238 /* 10 Encoding procedures -------------------------------------------------- */
239
240 /* 10.2 Open type fields --------------------------------------------------- */
241 static guint32 
242 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)
243 {
244         guint32 type_length, end_offset;
245         tvbuff_t *val_tvb = NULL;
246         header_field_info *hfi;
247         proto_tree *subtree = tree;
248
249         hfi = (hf_index == -1) ? NULL : proto_registrar_get_nth(hf_index);
250
251         offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &type_length);
252         if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
253         end_offset = offset + type_length * 8;
254
255     if ((variant==CB_DISSECTOR)||(variant==CB_NEW_DISSECTOR)) {
256                 val_tvb = new_octet_aligned_subset(tvb, offset, actx, type_length);
257                 if (hfi) {
258                         if (IS_FT_UINT(hfi->type)||IS_FT_INT(hfi->type)) {
259                                 if (IS_FT_UINT(hfi->type))
260                                         actx->created_item = proto_tree_add_uint(tree, hf_index, val_tvb, 0, type_length, type_length);
261                                 else
262                                         actx->created_item = proto_tree_add_int(tree, hf_index, val_tvb, 0, type_length, type_length);
263                                 proto_item_append_text(actx->created_item, plurality(type_length, " octet", " octets"));
264                         } else {
265                                 actx->created_item = proto_tree_add_item(tree, hf_index, val_tvb, 0, type_length, FALSE);
266                         }
267                         subtree = proto_item_add_subtree(actx->created_item, ett_per_open_type);
268                 }
269         }
270
271         if (type_cb) {
272                 switch (variant) {
273                         case CB_ASN1_ENC:
274                                 ((per_type_fn)type_cb)(tvb, offset, actx, tree, hf_index);
275                                 break;
276                         case CB_DISSECTOR:
277                                 ((dissector_t)type_cb)(val_tvb, actx->pinfo, subtree);
278                                 break;
279                         case CB_NEW_DISSECTOR:
280                                 ((new_dissector_t)type_cb)(val_tvb, actx->pinfo, subtree);
281                                 break;
282                         case CB_DISSECTOR_HANDLE:
283                                 break;
284                 }
285         } else {
286                 actx->created_item = proto_tree_add_text(tree, tvb, offset>>3, BLEN(offset, end_offset), "Unknown Open Type");
287         }
288
289         return end_offset;
290 }
291
292 guint32 
293 dissect_per_open_type(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, per_type_fn type_cb)
294 {
295         return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, (void*)type_cb, CB_ASN1_ENC);
296 }
297
298 guint32 
299 dissect_per_open_type_pdu(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, dissector_t type_cb)
300 {
301         return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, (void*)type_cb, CB_DISSECTOR);
302 }
303
304 guint32 
305 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)
306 {
307         return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, (void*)type_cb, CB_NEW_DISSECTOR);
308 }
309
310 /* 10.9 General rules for encoding a length determinant -------------------- 
311         
312           NOTE 1 - (Tutorial) The procedures of this subclause are invoked when an explicit length field is needed 
313                                 for some part of the encoding regardless of whether the length count is bounded above 
314                                 (by PER-visible constraints) or not. The part of the encoding to which the length applies may 
315                                 be a bit string (with the length count in bits), an octet string (with the length count in octets), 
316                                 a known-multiplier character string (with the length count in characters), or a list of fields 
317                                 (with the length count in components of a sequence-of or set-of).
318         
319           NOTE 2 - (Tutorial) In the case of the ALIGNED variant if the length count is bounded above by an upper bound 
320                                 that is less than 64K, then the constrained whole number encoding is used for the length. 
321                                 For sufficiently small ranges the result is a bit-field, otherwise the unconstrained length ("n" say) 
322                                 is encoded into an octet-aligned bit-field in one of three ways (in order of increasing size):
323                 a)      ("n" less than 128) a single octet containing "n" with bit 8 set to zero;
324                 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;
325                 c)      (large "n") a single octet containing a count "m" with bit 8 set to 1 and bit 7 set to 1. 
326                         The count "m" is one to four, and the length indicates that a fragment of the material follows 
327                         (a multiple "m" of 16K items). For all values of "m", the fragment is then followed by another length encoding
328                         for the remainder of the material.
329         
330           NOTE 3 - (Tutorial) In the UNALIGNED variant, if the length count is bounded above by an upper bound that is less
331                         than 64K, then the constrained whole number encoding is used to encode the length in the minimum number of 
332                         bits necessary to represent the range. Otherwise, the unconstrained length ("n" say) is encoded into a bit 
333                         field in the manner described above in Note 2.
334
335  */
336 guint32
337 dissect_per_length_determinant(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index, guint32 *length)
338 {
339         guint8 byte;
340         guint32 len;
341         proto_item *pi;
342         int num_bits;
343         int i, bit;
344         gboolean tmp;
345
346         if(!length){
347                 length=&len;
348         }
349
350         /* byte aligned */
351         if (actx->aligned){
352                 BYTE_ALIGN_OFFSET(offset);
353                 byte=tvb_get_guint8(tvb, offset>>3);
354                 offset+=8;
355         }else{
356                 char *str;
357                 guint32 val;
358                 gint val_start;
359                 
360                 val_start = offset>>3;
361                 val = 0;
362                 str=ep_alloc(256);
363
364                 g_snprintf(str, 256, " ");
365                 for(bit=0;bit<((int)(offset&0x07));bit++){
366                         if(bit&&(!(bit%4))){
367                                 g_strlcat(str, " ", 256);
368                         }
369                         g_strlcat(str,".", 256);
370                 }
371                 /* read the bits for the int */
372                 num_bits = 8;
373                 for(i=0;i<num_bits;i++){
374                         if(bit&&(!(bit%4))){
375                                 g_strlcat(str, " ", 256);
376                         }
377                         if(bit&&(!(bit%8))){
378                                 g_strlcat(str, " ", 256);
379                         }
380                         bit++;
381                         offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &tmp);
382                         val<<=1;
383                         if(tmp){
384                                 val|=1;
385                                 g_strlcat(str, "1", 256);
386                                 if (i==0) { /* bit 8 is 1, so not a single byte length */
387                                         num_bits = 16;
388                                 }
389                                 else if (i==1 && val==3) { /* bits 8 and 7 both 1, so unconstrained */
390                                         PER_NOT_DECODED_YET("10.9 Unconstrained");
391                                         return offset;
392                                 }
393                         } else {
394                                 g_strlcat(str, "0", 256);
395                         }
396                 }
397                 if((val&0x80)==0 && num_bits==8){
398                         *length = val;
399                         if(hf_index!=-1){
400                                 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
401                                 if (display_internal_per_fields)
402                                         proto_item_append_text(pi," %s", str);
403                                 else
404                                         PROTO_ITEM_SET_HIDDEN(pi);
405                         }
406                 
407                         return offset;
408                 }
409                 else if (num_bits==16) {
410                         *length = val&0x3fff;
411                         if(hf_index!=-1){
412                                 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
413                                 if (display_internal_per_fields)
414                                         proto_item_append_text(pi," %s", str);
415                                 else
416                                         PROTO_ITEM_SET_HIDDEN(pi);
417                         }
418         
419                         return offset;
420                 }
421                 PER_NOT_DECODED_YET("10.9 Unaligned");
422                 return offset;
423
424         }
425
426         /* 10.9.3.6 */
427         if((byte&0x80)==0){
428                 *length=byte;
429                 if(hf_index!=-1){
430                         pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
431                         if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(pi);
432                 }
433                 return offset;
434         }
435
436         /* 10.9.3.7 */
437         if((byte&0xc0)==0x80){
438                 *length=(byte&0x3f);
439                 *length=((*length)<<8)+tvb_get_guint8(tvb, offset>>3);
440                 offset+=8;
441                 if(hf_index!=-1){
442                         pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-2, 2, *length);
443                         if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(pi);
444                 }
445                 return offset;
446         }
447         PER_NOT_DECODED_YET("10.9.3.8.1");
448         return offset;
449 }
450
451 /* 10.6   normally small non-negative whole number */
452 static guint32
453 dissect_per_normally_small_nonnegative_whole_number(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint32 *length)
454 {
455         gboolean small_number, length_bit;
456         guint32 len;
457         proto_item *pi;
458
459 DEBUG_ENTRY("dissect_per_normally_small_nonnegative_whole_number");
460         if(!length){
461                 length=&len;
462         }
463
464         offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_small_number_bit, &small_number);
465         if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
466         if(!small_number){
467                 int i;
468                 /* 10.6.1 */
469                 *length=0;
470                 for(i=0;i<6;i++){
471                         offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &length_bit);
472                         *length<<=1;
473                         if (length_bit) {
474                                 *length|=1;
475                         }
476                 }
477                 if(hf_index!=-1){
478                         pi = proto_tree_add_uint(tree, hf_index, tvb, (offset-6)>>3, (offset%8<6)?2:1, *length);
479                         if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(pi);
480                 }
481                 return offset;
482         }
483
484         /* 10.6.2 */
485         offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_index, length);
486
487         return offset;
488 }
489
490
491
492 /* this function reads a GeneralString */
493 /* currently based on pure guesswork since RFC2833 didnt tell me much
494    i guess that the PER encoding for this is a normally-small-whole-number
495    followed by a ascii string.
496
497    based on pure guesswork.  it looks ok in the only capture i have where
498    there is a 1 byte general string encoded
499 */
500 guint32
501 dissect_per_GeneralString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index)
502 {
503         guint32 length;
504
505         offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_GeneralString_length, &length);
506
507         proto_tree_add_item(tree, hf_index, tvb, offset>>3, length, FALSE);
508
509         offset+=length*8;
510
511         return offset;
512 }
513
514 /* 17 Encoding the null type */
515 guint32
516 dissect_per_null(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) {
517   proto_item *ti_tmp;
518
519   ti_tmp = proto_tree_add_item(tree, hf_index, tvb, offset>>3, 1, FALSE);
520   proto_item_append_text(ti_tmp, ": NULL");
521
522   return offset;
523 }
524
525 /* 19 this function dissects a sequence of */
526 static guint32
527 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)
528 {
529         guint32 i;
530
531 DEBUG_ENTRY("dissect_per_sequence_of_helper");
532         for(i=0;i<length;i++){
533                 guint32 lold_offset=offset;
534                 proto_item *litem;
535                 proto_tree *ltree;
536
537                 litem=proto_tree_add_text(tree, tvb, offset>>3, 0, "Item %d", i);
538                 ltree=proto_item_add_subtree(litem, ett_per_sequence_of_item);
539
540                 offset=(*func)(tvb, offset, actx, ltree, hf_index);
541                 proto_item_set_len(litem, (offset>>3)!=(lold_offset>>3)?(offset>>3)-(lold_offset>>3):1);
542         }
543
544         return offset;
545 }
546 guint32
547 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)
548 {
549         proto_item *item;
550         proto_tree *tree;
551         guint32 old_offset=offset;
552         guint32 length;
553         header_field_info *hfi;
554
555 DEBUG_ENTRY("dissect_per_sequence_of");
556
557         /* semi-constrained whole number for number of elements */
558         /* each element encoded as 10.9 */
559
560         offset=dissect_per_length_determinant(tvb, offset, actx, parent_tree, hf_per_sequence_of_length, &length);
561
562         hfi = proto_registrar_get_nth(hf_index);
563         if (IS_FT_UINT(hfi->type)) {
564                 item = proto_tree_add_uint(parent_tree, hf_index, tvb, offset>>3, 0, length);
565                 proto_item_append_text(item, (length==1)?" item":" items");
566         } else {
567                 item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, FALSE);
568         }
569         tree=proto_item_add_subtree(item, ett_index);
570
571         offset=dissect_per_sequence_of_helper(tvb, offset, actx, tree, seq->func, *seq->p_id, length);
572
573
574         proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
575         return offset;
576 }
577
578
579 /* dissect a constrained IA5String that consists of the full ASCII set,
580    i.e. no FROM stuff limiting the alphabet
581 */
582 guint32
583 dissect_per_IA5String(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len)
584 {
585         offset=dissect_per_octet_string(tvb, offset, actx, tree, hf_index, min_len, max_len, FALSE, NULL);
586
587         return offset;
588 }
589
590 /* XXX we dont do >64k length strings   yet */
591 static guint32
592 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, const char *alphabet, int alphabet_length, tvbuff_t **value_tvb)
593 {
594         guint32 length;
595         gboolean byte_aligned;
596         guint8 *buf;
597         guint char_pos;
598         int bits_per_char;
599         guint32 old_offset;
600
601 DEBUG_ENTRY("dissect_per_restricted_character_string");
602
603         /* xx.x if the length is 0 bytes there will be no encoding */
604         if(max_len==0){
605                 if (value_tvb) {
606                         *value_tvb = tvb_new_child_real_data(tvb, NULL, 0, 0); 
607                 }
608                 return offset;
609         }
610
611
612         if (min_len == NO_BOUND) {
613                 min_len=0;
614         }
615
616
617         /* 27.5.2 depending of the alphabet length, find how many bits
618            are used to encode each character */
619 /* unaligned PER */
620         if (actx->aligned){
621
622                 if(alphabet_length<=2){
623                         bits_per_char=1;
624                 } else if(alphabet_length<=4){
625                         bits_per_char=2;
626                 } else if(alphabet_length<=16){
627                         bits_per_char=4;
628                 } else {
629                         bits_per_char=8;
630                 }
631         }else{
632                 if(alphabet_length<=2){
633                         bits_per_char=1;
634                 } else if(alphabet_length<=4){
635                         bits_per_char=2;
636                 } else if(alphabet_length<=8){
637                         bits_per_char=3;
638                 } else if(alphabet_length<=16){
639                         bits_per_char=4;
640                 } else if(alphabet_length<=32){
641                         bits_per_char=5;
642                 } else if(alphabet_length<=64){
643                         bits_per_char=6;
644                 } else if(alphabet_length<=128){
645                         bits_per_char=7;
646                 } else {
647                         bits_per_char=8;
648                 }
649         }
650
651         byte_aligned=TRUE;
652         if((min_len==max_len)&&(max_len<=2)){
653                 byte_aligned=FALSE;
654         }
655         if ((max_len != NO_BOUND) && (max_len < 2)) {
656                 byte_aligned=FALSE;
657         }
658
659         /* xx.x */
660         length=max_len;
661         if (max_len == NO_BOUND) {
662                 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_octet_string_length, &length);
663                 /* the unconstrained strings are always byte aligned (27.6.3)*/
664                 byte_aligned=TRUE;
665         } else if(min_len!=max_len){
666                 offset=dissect_per_constrained_integer(tvb, offset, actx,
667                         tree, hf_per_octet_string_length, min_len, max_len,
668                         &length, FALSE);
669                         if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
670         }
671
672         if(!length){
673                 /* there is no string at all, so dont do any byte alignment */
674                 /* byte_aligned=FALSE; */
675                 /* Advance offset to next 'element' */
676                 offset = offset + 1;    }
677
678         if((byte_aligned)&&(actx->aligned)){
679                 BYTE_ALIGN_OFFSET(offset);
680         }
681
682
683         buf = g_malloc(length+1);
684         old_offset=offset;
685         for(char_pos=0;char_pos<length;char_pos++){
686                 guchar val;
687                 int i;
688                 gboolean bit;
689
690                 val=0;
691                 for(i=0;i<bits_per_char;i++){
692                         offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
693                         val=(val<<1)|bit;
694                 }
695                 /* ALIGNED PER does not do any remapping of chars if 
696                    bitsperchar is 8 
697                 */
698                 if(bits_per_char==8){
699                         buf[char_pos]=val;
700                 } else {
701                         if (val < alphabet_length){
702                                 buf[char_pos]=alphabet[val];
703                         } else {
704                                 buf[char_pos] = '?';    /* XXX - how to mark this? */
705                         }
706                 }
707         }
708         buf[char_pos]=0;
709         proto_tree_add_string(tree, hf_index, tvb, (old_offset>>3), (offset>>3)-(old_offset>>3), (char*)buf);
710         if (value_tvb) {
711                 *value_tvb = tvb_new_child_real_data(tvb, buf, length, length); 
712                 tvb_set_free_cb(*value_tvb, g_free);
713         } else {
714                 g_free(buf);
715         }
716         return offset;
717 }
718
719 static const char*
720 sort_alphabet(char *sorted_alphabet, const char *alphabet, int alphabet_length)
721 {
722   int i, j;
723   char c, c_max, c_min;
724   char tmp_buf[256];
725
726   if (!alphabet_length) return sorted_alphabet;
727   memset(tmp_buf, 0, 256);
728   c_min = c_max = alphabet[0];
729   for (i=0; i<alphabet_length; i++) {
730     c = alphabet[i];
731     tmp_buf[(int)c] = 1;
732     if (c > c_max) c_max = c;
733     else if (c < c_min) c_min = c;
734   }
735   for (i=c_min,j=0; i<=c_max; i++) {
736     if (tmp_buf[i]) sorted_alphabet[j++] = i;
737   }
738   return sorted_alphabet;
739 }
740
741 guint32
742 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, const char *alphabet, int alphabet_length, tvbuff_t **value_tvb)
743 {
744   const char *alphabet_ptr;
745   char sorted_alphabet[128];
746
747   if (alphabet_length > 127) {
748     alphabet_ptr = alphabet;
749   } else {
750     alphabet_ptr = sort_alphabet(sorted_alphabet, alphabet, alphabet_length);
751   }
752   return dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, alphabet_ptr, alphabet_length, value_tvb);
753 }
754
755 guint32
756 dissect_per_NumericString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len)
757 {
758         offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, 
759                 " 0123456789", 11, NULL);
760
761         return offset;
762 }
763 guint32
764 dissect_per_PrintableString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len)
765 {
766         offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, 
767                 " '()+,-.*0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 74, NULL);
768         return offset;
769 }
770 guint32
771 dissect_per_VisibleString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len)
772 {
773         offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len,
774                 " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", 95, NULL);
775         return offset;
776 }
777 guint32
778 dissect_per_BMPString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len)
779 {
780         guint32 length;
781         static char *str;
782
783         /* xx.x if the length is 0 bytes there will be no encoding */
784         if(max_len==0){
785                 return offset;
786         }
787
788
789         if (min_len == NO_BOUND) {
790                 min_len = 0;
791         }
792
793
794         /* xx.x */
795         length=max_len;
796         if(min_len!=max_len){
797                 offset=dissect_per_constrained_integer(tvb, offset, actx,
798                         tree, hf_per_octet_string_length, min_len, max_len,
799                         &length, FALSE);
800                 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
801         }
802
803
804         /* align to byte boundary */
805         BYTE_ALIGN_OFFSET(offset);
806
807         if(length>=1024){
808                 PER_NOT_DECODED_YET("BMPString too long");
809                 length=1024;
810         }
811
812         str = tvb_get_ephemeral_faked_unicode(tvb, offset>>3, length, FALSE);
813
814         proto_tree_add_string(tree, hf_index, tvb, offset>>3, length*2, str);
815
816         offset+=(length<<3)*2;
817
818         return offset;
819 }
820
821 guint32 
822 dissect_per_object_descriptor(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, tvbuff_t **value_tvb)
823 {
824         offset=dissect_per_octet_string(tvb, offset, actx, tree, hf_index, -1, -1, FALSE, value_tvb);
825
826         return offset;
827 }
828
829
830 /* this function dissects a constrained sequence of */
831 guint32
832 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_)
833 {
834         proto_item *item;
835         proto_tree *tree;
836         guint32 old_offset=offset;
837         guint32 length;
838         header_field_info *hfi;
839
840 DEBUG_ENTRY("dissect_per_constrained_sequence_of");
841
842         /* 19.4 If there is a PER-visible constraint and an extension marker is present in it, 
843          * a single bit shall be added to the field-list in a bit-field of length one
844          */
845         if(has_extension){
846                 gboolean extension_present;
847                 offset=dissect_per_boolean(tvb, offset, actx, parent_tree, hf_per_extension_present_bit, &extension_present);
848                 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
849                 if(extension_present){
850                         /* 10.9 shall be invoked to add the length determinant as a semi-constrained whole number to the field-list, 
851                          * followed by the component values
852                          * TODO: Handle extension
853                          */
854                         proto_tree_add_text(parent_tree, tvb, (offset>>3), 1, "dissect_per_constrained_sequence_of with extension is not handled");
855                 }
856         }
857
858         /* 19.5 if min==max and min,max<64k ==> no length determinant */
859         if((min_len==max_len) && (min_len<65536)){
860                 length=min_len;
861                 goto call_sohelper;
862         }
863
864         /* 19.6 ub>=64k or unset */
865         if ((max_len >= 65536) || (max_len == NO_BOUND)) {
866                 /* no constraint, see 10.9.4.2 */
867                 offset=dissect_per_length_determinant(tvb, offset, actx, parent_tree, hf_per_sequence_of_length, &length);
868                 goto call_sohelper;
869         }
870
871         /* constrained whole number for number of elements */
872         offset=dissect_per_constrained_integer(tvb, offset, actx,
873                 parent_tree, hf_per_sequence_of_length, min_len, max_len,
874                 &length, FALSE);
875         if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
876
877 call_sohelper:
878         hfi = proto_registrar_get_nth(hf_index);
879         if (IS_FT_UINT(hfi->type)) {
880                 item = proto_tree_add_uint(parent_tree, hf_index, tvb, offset>>3, 0, length);
881                 proto_item_append_text(item, (length==1)?" item":" items");
882         } else {
883                 item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, FALSE);
884         }
885         tree=proto_item_add_subtree(item, ett_index);
886
887         offset=dissect_per_sequence_of_helper(tvb, offset, actx, tree, seq->func, *seq->p_id, length);
888
889
890         proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
891         return offset;
892 }
893
894 /* this function dissects a constrained set of */
895 guint32
896 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)
897 {
898         /* for basic-per  a set-of is encoded in the same way as a sequence-of */
899 DEBUG_ENTRY("dissect_per_constrained_set_of");
900         offset=dissect_per_constrained_sequence_of(tvb, offset, actx, parent_tree, hf_index, ett_index, seq, min_len, max_len, has_extension);
901         return offset;
902 }
903
904
905
906
907
908
909 /* this function dissects a set of */
910 guint32
911 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)
912 {
913         /* for basic-per  a set-of is encoded in the same way as a sequence-of */
914 DEBUG_ENTRY("dissect_per_set_of");
915         offset=dissect_per_sequence_of(tvb, offset, actx, parent_tree, hf_index, ett_index, seq);
916         return offset;
917 }
918
919
920
921
922 /* 23 Encoding the object identifier type */
923 guint32
924 dissect_per_object_identifier(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index, tvbuff_t **value_tvb)
925 {
926   guint length;
927   const char *str;
928   tvbuff_t *val_tvb = NULL;
929   header_field_info *hfi;
930
931 DEBUG_ENTRY("dissect_per_object_identifier");
932
933   offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_object_identifier_length, &length);
934   if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
935   val_tvb = new_octet_aligned_subset(tvb, offset, actx, length);
936         
937   hfi = proto_registrar_get_nth(hf_index);
938   if (hfi->type == FT_OID) {
939     actx->created_item = proto_tree_add_item(tree, hf_index, val_tvb, 0, length, FALSE);
940   } else if (IS_FT_STRING(hfi->type)) {
941     str = oid_encoded2string(tvb_get_ptr(val_tvb, 0, length), length);
942     actx->created_item = proto_tree_add_string(tree, hf_index, val_tvb, 0, length, str);
943   } else {
944     DISSECTOR_ASSERT_NOT_REACHED();
945   }
946
947   if (value_tvb) *value_tvb = val_tvb;
948
949   offset += 8 * length;
950
951   return offset;
952 }
953
954 guint32
955 dissect_per_object_identifier_str(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, const char **value_stringx)
956 {
957   tvbuff_t *value_tvb = NULL;
958   guint length;
959
960   offset = dissect_per_object_identifier(tvb, offset, actx, tree, hf_index, (value_stringx) ? &value_tvb : NULL);
961
962   if (value_stringx) {
963     if (value_tvb && (length = tvb_length(value_tvb))) {
964       *value_stringx = oid_encoded2string(tvb_get_ptr(value_tvb, 0, length), length);
965     } else {
966       *value_stringx = "";
967     }
968   }
969
970   return offset;
971 }
972
973
974
975 /* this function reads a single bit */
976 guint32
977 dissect_per_boolean(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index, gboolean *bool)
978 {
979         guint8 ch, mask;
980         gboolean value;
981         header_field_info *hfi;
982
983 DEBUG_ENTRY("dissect_per_boolean");
984
985         ch=tvb_get_guint8(tvb, offset>>3);
986         mask=1<<(7-(offset&0x07));
987         if(ch&mask){
988                 value=1;
989         } else {
990                 value=0;
991         }
992         if(hf_index!=-1){
993                 char *str;
994                 hfi = proto_registrar_get_nth(hf_index);
995                 str=ep_alloc(256);
996                 g_snprintf(str, 256, "%c%c%c%c %c%c%c%c %s: %s",
997                         mask&0x80?'0'+value:'.',
998                         mask&0x40?'0'+value:'.',
999                         mask&0x20?'0'+value:'.',
1000                         mask&0x10?'0'+value:'.',
1001                         mask&0x08?'0'+value:'.',
1002                         mask&0x04?'0'+value:'.',
1003                         mask&0x02?'0'+value:'.',
1004                         mask&0x01?'0'+value:'.',
1005                         hfi->name,
1006                         value?"True":"False"
1007                 );
1008                 actx->created_item = proto_tree_add_boolean_format(tree, hf_index, tvb, offset>>3, 1, value, "%s", str);
1009         } else {
1010                 actx->created_item = NULL;
1011         }
1012
1013         if(bool){
1014                 *bool=value;
1015         }
1016         return offset+1;
1017 }
1018
1019
1020
1021
1022 /* we currently only handle integers up to 32 bits in length. */
1023 guint32
1024 dissect_per_integer(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gint32 *value)
1025 {
1026         guint32 i, length;
1027         gint32 val;
1028         proto_item *it=NULL;
1029         header_field_info *hfi;
1030
1031         /* 12.2.6 b */
1032         offset=dissect_per_length_determinant(tvb, offset, actx, tree,hf_per_integer_length, &length);
1033         /* gassert here? */
1034         if(length>4){
1035 PER_NOT_DECODED_YET("too long integer(per_integer)");
1036                 length=4;
1037         }
1038
1039         val=0;
1040         for(i=0;i<length;i++){
1041                 if(i==0){
1042                         if(tvb_get_guint8(tvb, offset>>3)&0x80){
1043                                 /* negative number */
1044                                 val=0xffffffff;
1045                         } else {
1046                                 /* positive number */
1047                                 val=0;
1048                         }
1049                 }
1050                 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1051                 offset+=8;
1052         }
1053
1054         hfi = proto_registrar_get_nth(hf_index);
1055         if (! hfi)
1056                 THROW(ReportedBoundsError);
1057         if (IS_FT_INT(hfi->type)) {
1058                 it=proto_tree_add_int(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1059         } else if (IS_FT_UINT(hfi->type)) {
1060                 it=proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1061         } else {
1062                 proto_tree_add_text(tree, tvb, (offset>>3)-(length+1), length+1, "Field is not an integer: %s", hfi->abbrev);
1063                 REPORT_DISSECTOR_BUG("PER integer field that's not an FT_INT* or FT_UINT*");
1064         }
1065
1066
1067         actx->created_item = it;
1068
1069         if(value){
1070                 *value=val;
1071         }
1072
1073         return offset;
1074 }
1075 /* 64 bits experimental version, internal for now */
1076 static guint32
1077 dissect_per_integer64b(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gint64 *value)
1078 {
1079         guint32 i, length;
1080         gint64 val;
1081         proto_item *it=NULL;
1082         header_field_info *hfi;
1083
1084         /* 12.2.6 b */
1085         offset=dissect_per_length_determinant(tvb, offset, actx, tree, -1, &length);
1086         /* gassert here? */
1087         if(length>8){
1088 PER_NOT_DECODED_YET("too long integer (64b)");
1089                 length=4;
1090         }
1091
1092         val=0;
1093         for(i=0;i<length;i++){
1094                 if(i==0){
1095                         if(tvb_get_guint8(tvb, offset>>3)&0x80){
1096                                 /* negative number */
1097                                 val=G_GINT64_CONSTANT(0xffffffffffffffff);
1098                         } else {
1099                                 /* positive number */
1100                                 val=0;
1101                         }
1102                 }
1103                 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1104                 offset+=8;
1105         }
1106
1107         hfi = proto_registrar_get_nth(hf_index);
1108         if (! hfi)
1109                 THROW(ReportedBoundsError);
1110         if (IS_FT_INT(hfi->type)) {
1111                 it=proto_tree_add_int64(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1112         } else if (IS_FT_UINT(hfi->type)) {
1113                 it=proto_tree_add_uint64(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1114         } else {
1115                 proto_tree_add_text(tree, tvb, (offset>>3)-(length+1), length+1, "Field is not an integer: %s", hfi->abbrev);
1116                 REPORT_DISSECTOR_BUG("PER integer field that's not an FT_INT* or FT_UINT*");
1117         }
1118
1119
1120         actx->created_item = it;
1121
1122         if(value){
1123                 *value=val;
1124         }
1125
1126         return offset;
1127 }
1128 /* this function reads a constrained integer  with or without a
1129    PER visible extension marker present
1130
1131    has_extension==TRUE  would map to asn constructs such as:
1132                 rfc-number      INTEGER (1..32768, ...)
1133    while has_extension==FALSE would map to:
1134                 t35CountryCode  INTEGER (0..255)
1135
1136    it only handles integers that fit inside a 32 bit integer
1137 10.5.1 info only
1138 10.5.2 info only
1139 10.5.3 range=ub-lb+1
1140 10.5.4 empty range
1141 10.5.5 info only
1142         10.5.6 unaligned version
1143 10.5.7 aligned version
1144 10.5.7.1 decoding of 0-255 1-8 bits
1145 10.5.7.2 decoding og 0-256 8 bits
1146 10.5.7.3 decoding of 0-65535 16 bits
1147         10.5.7.4
1148 */
1149 guint32
1150 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)
1151 {
1152         proto_item *it=NULL;
1153         guint32 range, val;
1154         gint val_start, val_length;
1155         nstime_t timeval;
1156         header_field_info *hfi;
1157         int num_bits;
1158         int pad;
1159         gboolean tmp;
1160
1161 DEBUG_ENTRY("dissect_per_constrained_integer");
1162         if(has_extension){
1163                 gboolean extension_present;
1164                 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
1165                 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1166                 if(extension_present){
1167                         offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, (gint32*)value);
1168                         return offset;
1169                 }
1170         }
1171
1172         hfi = proto_registrar_get_nth(hf_index);
1173
1174         /* 10.5.3 Let "range" be defined as the integer value ("ub" - "lb"   1), and let the value to be encoded be "n". 
1175          * 10.5.7       In the case of the ALIGNED variant the encoding depends on whether
1176          *                      d)      "range" is greater than 64K (the indefinite length case).
1177          */
1178         if(((max-min)>65536)&&(actx->aligned)){
1179                 /* just set range really big so it will fall through
1180                    to the bottom of the encoding */
1181                 range=1000000;
1182         } else {
1183                 /* Really ugly hack.
1184                  * We should really use guint64 as parameters for min/max.
1185                  * This is to prevent range from being 0 if
1186                  * the range for a signed integer spans the entire 32 bit range.
1187                  * Special case the 2 common cases when this can happen until
1188                  * a real fix is implemented.
1189                  */
1190                 if( (max==0x7fffffff && min==0x80000000)
1191                 ||  (max==0xffffffff && min==0x00000000) ){
1192                         range=0xffffffff;
1193                 } else {
1194                         range=max-min+1;
1195                 }
1196         }
1197
1198         num_bits=0;
1199         pad=0;
1200         val=0;
1201         timeval.secs=val; timeval.nsecs=0;
1202         /* 10.5.4 If "range" has the value 1, then the result of the encoding shall be an empty bit-field (no bits).*/
1203
1204         /* something is really wrong if range is 0 */
1205         DISSECTOR_ASSERT(range!=0);
1206
1207         if(range==1){
1208                 val_start = offset>>3; val_length = 0;
1209                 val = min; 
1210         } else if((range<=255)||(!actx->aligned)) {
1211                 /* 10.5.7.1 
1212                  * 10.5.6       In the case of the UNALIGNED variant the value ("n" - "lb") shall be encoded
1213                  * as a non-negative  binary integer in a bit field as specified in 10.3 with the minimum
1214                  * number of bits necessary to represent the range.
1215                  */
1216                 char *str;
1217                 int i, bit, length;
1218                 guint32 mask,mask2;
1219                 /* We only handle 32 bit integers */
1220                 mask  = 0x80000000;
1221                 mask2 = 0x7fffffff;
1222                 i = 32;
1223                 while ((range & mask)== 0){
1224                         i = i - 1;
1225                         mask = mask>>1;
1226                         mask2 = mask2>>1;
1227                 }
1228                 if ((range & mask2) == 0)
1229                         i = i-1;
1230
1231                 num_bits = i;
1232                 length=1;
1233                 if(range<=2){
1234                         num_bits=1;
1235                 }
1236
1237                 /* prepare the string */
1238                 str=ep_alloc(256);
1239                 g_snprintf(str, 256, "%s: ", hfi->name);
1240                 for(bit=0;bit<((int)(offset&0x07));bit++){
1241                         if(bit&&(!(bit%4))){
1242                                 g_strlcat(str, " ", 256);
1243                         }
1244                         g_strlcat(str,".", 256);
1245                 }
1246                 /* read the bits for the int */
1247                 for(i=0;i<num_bits;i++){
1248                         if(bit&&(!(bit%4))){
1249                                 g_strlcat(str, " ", 256);
1250                         }
1251                         if(bit&&(!(bit%8))){
1252                                 length+=1;
1253                                 g_strlcat(str, " ", 256);
1254                         }
1255                         bit++;
1256                         offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &tmp);
1257                         val<<=1;
1258                         if(tmp){
1259                                 val|=1;
1260                                 g_strlcat(str, "1", 256);
1261                         } else {
1262                                 g_strlcat(str, "0", 256);
1263                         }
1264                 }
1265                 for(;bit%8;bit++){
1266                         if(bit&&(!(bit%4))){
1267                                 g_strlcat(str, " ", 256);
1268                         }
1269                         g_strlcat(str,".", 256);
1270                 }
1271                 val_start = (offset-num_bits)>>3; val_length = length;
1272                 val+=min;
1273                 if (display_internal_per_fields)
1274                         proto_tree_add_text(tree, tvb, val_start,val_length,"Range = %u Bitfield length %u, %s",range, num_bits, str);
1275         } else if(range==256){
1276                 /* 10.5.7.2 */
1277                 num_bits=8;
1278                 pad=7-(offset&0x07);
1279
1280                 /* in the aligned case, align to byte boundary */
1281                 BYTE_ALIGN_OFFSET(offset);
1282                 val=tvb_get_guint8(tvb, offset>>3);
1283                 offset+=8;
1284
1285                 val_start = (offset>>3)-1; val_length = 1;
1286                 val+=min;
1287         } else if(range<=65536){
1288                 /* 10.5.7.3 */
1289                 num_bits=16;
1290                 pad=7-(offset&0x07);
1291
1292                 /* in the aligned case, align to byte boundary */
1293                 BYTE_ALIGN_OFFSET(offset);
1294                 val=tvb_get_guint8(tvb, offset>>3);
1295                 val<<=8;
1296                 offset+=8;
1297                 val|=tvb_get_guint8(tvb, offset>>3);
1298                 offset+=8;
1299
1300                 val_start = (offset>>3)-2; val_length = 2;
1301                 val+=min;
1302         } else {
1303                 int i,num_bytes;
1304                 gboolean bit;
1305
1306                 /* 10.5.7.4 */
1307                 /* 12.2.6 */
1308                 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
1309                 num_bytes=bit;
1310                 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
1311                 num_bytes=(num_bytes<<1)|bit;
1312
1313                 num_bytes++;  /* lower bound for length determinant is 1 */
1314                 if (display_internal_per_fields)
1315                         proto_tree_add_uint(tree, hf_per_const_int_len, tvb, (offset>>3), 1, num_bytes);
1316
1317                 /* byte aligned */
1318                 BYTE_ALIGN_OFFSET(offset);
1319                 val=0;
1320                 for(i=0;i<num_bytes;i++){
1321                         val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1322                         offset+=8;
1323                 }
1324                 val_start = (offset>>3)-(num_bytes+1); val_length = num_bytes+1;
1325                 val+=min;
1326         }
1327
1328         timeval.secs = val;
1329         if (IS_FT_UINT(hfi->type)) {
1330                 it = proto_tree_add_uint(tree, hf_index, tvb, val_start, val_length, val);
1331         } else if (IS_FT_INT(hfi->type)) {
1332                 it = proto_tree_add_int(tree, hf_index, tvb, val_start, val_length, val);
1333         } else if (IS_FT_TIME(hfi->type)) {
1334                 it = proto_tree_add_time(tree, hf_index, tvb, val_start, val_length, &timeval);
1335         } else {
1336                 THROW(ReportedBoundsError);
1337         }
1338         actx->created_item = it;
1339         if (value) *value = val;
1340         return offset;}
1341
1342 guint32
1343 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)
1344 {
1345         proto_item *it=NULL, *int_item=NULL;
1346         guint64 range, val;
1347         gint val_start, val_length;
1348         nstime_t timeval;
1349         header_field_info *hfi;
1350         int num_bits;
1351         int pad;
1352         gboolean tmp;
1353
1354 DEBUG_ENTRY("dissect_per_constrained_integer_64b");
1355         if(has_extension){
1356                 gboolean extension_present;
1357                 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
1358                 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1359                 if(extension_present){
1360                         offset = dissect_per_integer64b(tvb, offset, actx, tree, hf_index, (gint64*)value);
1361                         return offset;
1362                 }
1363         }
1364
1365         hfi = proto_registrar_get_nth(hf_index);
1366
1367         /* 10.5.3 Let "range" be defined as the integer value ("ub" - "lb"   1), and let the value to be encoded be "n". 
1368          * 10.5.7       In the case of the ALIGNED variant the encoding depends on whether
1369          *                      d)      "range" is greater than 64K (the indefinite length case).
1370          */
1371         if(((max-min)>65536)&&(actx->aligned)){
1372                /* just set range really big so it will fall through
1373                   to the bottom of the encoding */
1374                /* range=1000000; */             
1375                            range = max-min;
1376                            if (range==65536)
1377                                    range++; /* make it fall trough? */
1378         } else {
1379                 /* Copied from the 32 bit version, asuming the same problem occures
1380                  * at 64 bit boundary.
1381                  * Really ugly hack.
1382                  * We should really use guint64 as parameters for min/max.
1383                  * This is to prevent range from being 0 if
1384                  * the range for a signed integer spans the entire 32 bit range.
1385                  * Special case the 2 common cases when this can happen until
1386                  * a real fix is implemented.
1387                  */
1388                 if( (max==G_GINT64_CONSTANT(0x7fffffffffffffff) && min==G_GINT64_CONSTANT(0x8000000000000000))
1389                 ||  (max==G_GINT64_CONSTANT(0xffffffffffffffff) && min==0) ){
1390                         range=G_GINT64_CONSTANT(0xffffffffffffffff);
1391                 } else {
1392                         range=max-min+1;
1393                 }
1394         }
1395
1396         num_bits=0;
1397         pad=0;
1398         val=0;
1399         timeval.secs=0; timeval.nsecs=0;
1400         /* 10.5.4 If "range" has the value 1, then the result of the encoding shall be an empty bit-field (no bits).*/
1401
1402         /* something is really wrong if range is 0 */
1403         DISSECTOR_ASSERT(range!=0);
1404
1405         if(range==1){
1406                 val_start = offset>>3; val_length = 0;
1407                 val = min; 
1408         } else if((range<=255)||(!actx->aligned)) {
1409                 /* 10.5.7.1 
1410                  * 10.5.6       In the case of the UNALIGNED variant the value ("n" - "lb") shall be encoded
1411                  * as a non-negative  binary integer in a bit field as specified in 10.3 with the minimum
1412                  * number of bits necessary to represent the range.
1413                  */
1414                 char *str;
1415                 int i, bit, length;
1416                 guint32 mask,mask2;
1417                 /* We only handle 32 bit integers */
1418                 mask  = 0x80000000;
1419                 mask2 = 0x7fffffff;
1420                 i = 32;
1421                 while ((range & mask)== 0){
1422                         i = i - 1;
1423                         mask = mask>>1;
1424                         mask2 = mask2>>1;
1425                 }
1426                 if ((range & mask2) == 0)
1427                         i = i-1;
1428
1429                 num_bits = i;
1430                 length=1;
1431                 if(range<=2){
1432                         num_bits=1;
1433                 }
1434
1435                 /* prepare the string */
1436                 str=ep_alloc(256);
1437                 g_snprintf(str, 256, "%s: ", hfi->name);
1438                 for(bit=0;bit<((int)(offset&0x07));bit++){
1439                         if(bit&&(!(bit%4))){
1440                                 g_strlcat(str, " ", 256);
1441                         }
1442                         g_strlcat(str,".", 256);
1443                 }
1444                 /* read the bits for the int */
1445                 for(i=0;i<num_bits;i++){
1446                         if(bit&&(!(bit%4))){
1447                                 g_strlcat(str, " ", 256);
1448                         }
1449                         if(bit&&(!(bit%8))){
1450                                 length+=1;
1451                                 g_strlcat(str, " ", 256);
1452                         }
1453                         bit++;
1454                         offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &tmp);
1455                         val<<=1;
1456                         if(tmp){
1457                                 val|=1;
1458                                 g_strlcat(str, "1", 256);
1459                         } else {
1460                                 g_strlcat(str, "0", 256);
1461                         }
1462                 }
1463                 for(;bit%8;bit++){
1464                         if(bit&&(!(bit%4))){
1465                                 g_strlcat(str, " ", 256);
1466                         }
1467                         g_strlcat(str,".", 256);
1468                 }
1469                 val_start = (offset-num_bits)>>3; val_length = length;
1470                 val+=min;
1471                 if (display_internal_per_fields)
1472                         proto_tree_add_text(tree, tvb, val_start,val_length,"Range = (%" G_GINT64_MODIFIER "u) Bitfield length %u, %s",range, num_bits, str);
1473         } else if(range==256){
1474                 /* 10.5.7.2 */
1475                 num_bits=8;
1476                 pad=7-(offset&0x07);
1477
1478                 /* in the aligned case, align to byte boundary */
1479                 BYTE_ALIGN_OFFSET(offset);
1480                 val=tvb_get_guint8(tvb, offset>>3);
1481                 offset+=8;
1482
1483                 val_start = (offset>>3)-1; val_length = 1;
1484                 val+=min;
1485         } else if(range<=65536){
1486                 /* 10.5.7.3 */
1487                 num_bits=16;
1488                 pad=7-(offset&0x07);
1489
1490                 /* in the aligned case, align to byte boundary */
1491                 BYTE_ALIGN_OFFSET(offset);
1492                 val=tvb_get_guint8(tvb, offset>>3);
1493                 val<<=8;
1494                 offset+=8;
1495                 val|=tvb_get_guint8(tvb, offset>>3);
1496                 offset+=8;
1497
1498                 val_start = (offset>>3)-2; val_length = 2;
1499                 val+=min;
1500         } else {
1501                 int i,num_bytes,num_bits;
1502
1503                 /* 10.5.7.4 */
1504                 /* 12.2.6 */
1505                 /* calculate the number of bits to hold the length */
1506                 if ((range & G_GINT64_CONSTANT(0xffffffff0000000)) != 0){
1507                         num_bits=3;
1508                 }else{
1509                         num_bits=2;
1510                 }
1511                 num_bytes =tvb_get_bits8(tvb, offset, num_bits);
1512                 num_bytes++;  /* lower bound for length determinant is 1 */
1513                 if (display_internal_per_fields){
1514                         int_item = proto_tree_add_bits_item(tree, hf_per_const_int_len, tvb, offset,num_bits, FALSE);
1515                         proto_item_append_text(int_item,"+1=%u bytes, Range = (%" G_GINT64_MODIFIER "u)",num_bytes, range);
1516                 }
1517                 offset = offset+num_bits;
1518                 /* byte aligned */
1519                 BYTE_ALIGN_OFFSET(offset);
1520                 val=0;
1521                 for(i=0;i<num_bytes;i++){
1522                         val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1523                         offset+=8;
1524                 }
1525                 val_start = (offset>>3)-(num_bytes+1); val_length = num_bytes+1;
1526                 val+=min;
1527         }
1528
1529         
1530         if (IS_FT_UINT(hfi->type)) {
1531                 it = proto_tree_add_uint64(tree, hf_index, tvb, val_start, val_length, val);
1532         } else if (IS_FT_INT(hfi->type)) {
1533                 it = proto_tree_add_int64(tree, hf_index, tvb, val_start, val_length, val);
1534         } else if (IS_FT_TIME(hfi->type)) {
1535                 timeval.secs = (guint32)val;
1536                 it = proto_tree_add_time(tree, hf_index, tvb, val_start, val_length, &timeval);
1537         } else {
1538                 THROW(ReportedBoundsError);
1539         }
1540         actx->created_item = it;
1541         if (value) *value = val;
1542         return offset;}
1543
1544 /* 13 Encoding the enumerated type */
1545 guint32
1546 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)
1547 {
1548
1549         proto_item *it=NULL;
1550         guint32 enum_index, val;
1551         guint32 start_offset = offset;
1552         gboolean extension_present = FALSE;
1553         header_field_info *hfi;
1554
1555         if (has_extension) {
1556                 /* Extension bit */
1557                 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
1558                 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1559         }
1560
1561         if (!extension_present) {
1562                 /* 13.2  */
1563                 offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_per_enum_index, 0, root_num - 1, &enum_index, FALSE);
1564                 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1565         } else {
1566                 /* 13.3  */
1567                 if (ext_num == 1) {
1568                         /* 10.5.4       If "range" has the value 1,
1569                          * then the result of the encoding shall be
1570                          * an empty bit-field (no bits).
1571                          */
1572                         enum_index = 0;
1573                 } else {
1574                         /* 13.3 ".. and the value shall be added to the field-list as a
1575                          * normally small non-negative whole number whose value is the 
1576                          * enumeration index of the additional enumeration and with "lb" set to 0.."
1577                          */
1578                         offset = dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_enum_extension_index, &enum_index);
1579                 }
1580                 enum_index += root_num;
1581         }
1582     val = (value_map && (enum_index<(root_num+ext_num))) ? value_map[enum_index] : enum_index;
1583         hfi = proto_registrar_get_nth(hf_index);
1584         if (IS_FT_UINT(hfi->type)) {
1585                 it = proto_tree_add_uint(tree, hf_index, tvb, start_offset>>3, BLEN(start_offset, offset), val);
1586         } else {
1587                 THROW(ReportedBoundsError);
1588         }
1589         actx->created_item = it;
1590         if (value) *value = val;
1591         return offset;
1592 }
1593
1594 /* 14 Encoding the real type */
1595 guint32 
1596 dissect_per_real(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, double *value)
1597 {
1598         guint32 val_length, end_offset;
1599         tvbuff_t *val_tvb;
1600         double val = 0;
1601
1602         offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_real_length, &val_length);
1603         if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
1604         val_tvb = new_octet_aligned_subset(tvb, offset, actx, val_length);
1605         end_offset = offset + val_length * 8;
1606
1607         val = asn1_get_real(tvb_get_ptr(val_tvb, 0, val_length), val_length);
1608         actx->created_item = proto_tree_add_double(tree, hf_index, val_tvb, 0, val_length, val);
1609
1610         if (value) *value = val;
1611
1612         return end_offset;
1613 }
1614
1615 /* 22 Encoding the choice type */
1616 guint32
1617 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)
1618 {
1619         gboolean extension_present, extension_flag;
1620         int extension_root_entries;
1621         int extension_addition_entries;
1622         guint32 choice_index;
1623         int i, index, cidx;
1624         guint32 ext_length;
1625         guint32 old_offset = offset;
1626         proto_item *choice_item = NULL;
1627         proto_tree *choice_tree = NULL;
1628
1629 DEBUG_ENTRY("dissect_per_choice");
1630
1631         if (value) *value = -1;
1632
1633         /* 22.5 */
1634         if (choice[0].extension == ASN1_NO_EXTENSIONS){
1635                 extension_present = FALSE;
1636                 extension_flag = FALSE;
1637         } else {
1638                 extension_present = TRUE;
1639                 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_bit, &extension_flag);
1640                 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1641         }
1642
1643         /* count the number of entries in the extension root and extension addition */
1644         extension_root_entries = 0;
1645         extension_addition_entries = 0;
1646         for (i=0; choice[i].p_id; i++) {
1647                 switch(choice[i].extension){
1648                         case ASN1_NO_EXTENSIONS:
1649                         case ASN1_EXTENSION_ROOT:
1650                                 extension_root_entries++;
1651                                 break;
1652                         case ASN1_NOT_EXTENSION_ROOT:
1653                                 extension_addition_entries++;
1654                                 break;
1655                 }
1656         }
1657
1658         if (!extension_flag) {  /* 22.6, 22.7 */
1659                 if (extension_root_entries == 1) {  /* 22.5 */
1660                         choice_index = 0;
1661                 } else {
1662                         offset = dissect_per_constrained_integer(tvb, offset, actx,
1663                                 tree, hf_per_choice_index, 0, extension_root_entries - 1,
1664                                 &choice_index, FALSE);
1665                         if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1666                 }
1667
1668                 index = -1; cidx = choice_index;
1669                 for (i=0; choice[i].p_id; i++) {
1670                         if(choice[i].extension != ASN1_NOT_EXTENSION_ROOT){
1671                                 if (!cidx) { index = i; break; }
1672                                 cidx--;
1673                         }
1674                 }
1675         } else {  /* 22.8 */
1676                 offset = dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_choice_extension_index, &choice_index);
1677                 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &ext_length);
1678
1679                 index = -1; cidx = choice_index;
1680                 for (i=0; choice[i].p_id; i++) {
1681                         if(choice[i].extension == ASN1_NOT_EXTENSION_ROOT){
1682                                 if (!cidx) { index = i; break; }
1683                                 cidx--;
1684                         }
1685                 }
1686         }
1687
1688         if (index != -1) {
1689                 choice_item = proto_tree_add_uint(tree, hf_index, tvb, old_offset>>3, 0, choice[index].value);
1690                 choice_tree = proto_item_add_subtree(choice_item, ett_index);
1691                 if (!extension_flag) {
1692                         offset = choice[index].func(tvb, offset, actx, choice_tree, *choice[index].p_id);
1693                 } else {
1694                         choice[index].func(tvb, offset, actx, choice_tree, *choice[index].p_id);
1695                         offset += ext_length * 8;
1696                 }
1697                 proto_item_set_len(choice_item, BLEN(old_offset, offset));
1698         } else {
1699                 if (!extension_flag) {
1700                         PER_NOT_DECODED_YET("unknown extension root index in choice");
1701                 } else {
1702                         offset += ext_length * 8;
1703                         proto_tree_add_text(tree, tvb, old_offset>>3, BLEN(old_offset, offset), "Choice no. %d in extension", choice_index);
1704                         PER_NOT_DECODED_YET("unknown choice extension");
1705                 }
1706         }
1707
1708         if (value && (index != -1)) 
1709                 *value = choice[index].value;
1710
1711         return offset;
1712 }
1713
1714
1715 static const char *
1716 index_get_optional_name(const per_sequence_t *sequence, int index)
1717 {
1718         int i;
1719         header_field_info *hfi;
1720
1721         for(i=0;sequence[i].p_id;i++){
1722                 if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1723                         if (index == 0) {
1724                                 hfi = proto_registrar_get_nth(*sequence[i].p_id);
1725                                 return (hfi) ? hfi->name : "<unknown filed>";
1726                         }
1727                         index--;
1728                 }
1729         }
1730         return "<unknown type>";
1731 }
1732
1733 static const char *
1734 index_get_extension_name(const per_sequence_t *sequence, int index)
1735 {
1736         int i;
1737         header_field_info *hfi;
1738
1739         for(i=0;sequence[i].p_id;i++){
1740                 if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
1741                         if (index == 0) {
1742                                 hfi = proto_registrar_get_nth(*sequence[i].p_id);
1743                                 return (hfi) ? hfi->name : "<unknown filed>";
1744                         }
1745                         index--;
1746                 }
1747         }
1748         return "<unknown type>";
1749 }
1750
1751 static const char *
1752 index_get_field_name(const per_sequence_t *sequence, int index)
1753 {
1754         header_field_info *hfi;
1755
1756         hfi = proto_registrar_get_nth(*sequence[index].p_id);
1757         return (hfi) ? hfi->name : "<unknown filed>";
1758 }
1759
1760 /* this functions decodes a SEQUENCE
1761    it can only handle SEQUENCES with at most 32 DEFAULT or OPTIONAL fields
1762 18.1 extension bit
1763 18.2 optinal/default items in root
1764 18.3 we ignore the case where n>64K
1765 18.4 the root sequence
1766            18.5
1767            18.6
1768            18.7
1769            18.8
1770            18.9
1771 */
1772 guint32
1773 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)
1774 {
1775         gboolean extension_present, extension_flag, optional_field_flag;
1776         proto_item *item;
1777         proto_tree *tree;
1778         guint32 old_offset=offset;
1779         guint32 i, num_opts;
1780         guint32 optional_mask;
1781
1782 DEBUG_ENTRY("dissect_per_sequence");
1783
1784         item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, FALSE);
1785         tree=proto_item_add_subtree(item, ett_index);
1786
1787
1788         /* first check if there should be an extension bit for this CHOICE.
1789            we do this by just checking the first choice arm
1790          */
1791         /* 18.1 */
1792         extension_flag=0;
1793         if(sequence[0].extension==ASN1_NO_EXTENSIONS){
1794                 extension_present=0;
1795         } else {
1796                 extension_present=1;
1797                 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_bit, &extension_flag);
1798                 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1799         }
1800         /* 18.2 */
1801         num_opts=0;
1802         for(i=0;sequence[i].p_id;i++){
1803                 if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1804                         num_opts++;
1805                 }
1806         }
1807
1808         optional_mask=0;
1809         for(i=0;i<num_opts;i++){
1810                 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_optional_field_bit, &optional_field_flag);
1811                 if (tree) {
1812                         proto_item_append_text(actx->created_item, " (%s %s present)",
1813                                 index_get_optional_name(sequence, i), optional_field_flag?"is":"is NOT");
1814                 }
1815                 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1816                 optional_mask<<=1;
1817                 if(optional_field_flag){
1818                         optional_mask|=0x01;
1819                 }
1820         }
1821
1822
1823         /* 18.4 */
1824         for(i=0;sequence[i].p_id;i++){
1825                 if( (sequence[i].extension==ASN1_NO_EXTENSIONS)
1826                 ||  (sequence[i].extension==ASN1_EXTENSION_ROOT) ){
1827                         if(sequence[i].optional==ASN1_OPTIONAL){
1828                                 gboolean is_present;
1829                                 is_present=(1<<(num_opts-1))&optional_mask;
1830                                 num_opts--;
1831                                 if(!is_present){
1832                                         continue;
1833                                 }
1834                         }
1835                         if(sequence[i].func){
1836                                 offset=sequence[i].func(tvb, offset, actx, tree, *sequence[i].p_id);
1837                         } else {
1838                                 PER_NOT_DECODED_YET(index_get_field_name(sequence, i));
1839                         }
1840                 }
1841         }
1842
1843
1844         if(extension_flag){
1845                 gboolean extension_bit;
1846                 guint32 num_known_extensions;
1847                 guint32 num_extensions;
1848                 guint32 extension_mask;
1849
1850                 offset=dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_num_sequence_extensions, &num_extensions);
1851                 /* the X.691 standard is VERY unclear here.
1852                    there is no mention that the lower bound lb for this
1853                    (apparently) semiconstrained value is 1,
1854                    apart from the NOTE: comment in 18.8 that this value can
1855                    not be 0.
1856                    In my book, there is a semantic difference between having
1857                    a comment that says that the value can not be zero
1858                    and stating that the lb is 1.
1859                    I dont know if this is right or not but it makes
1860                    some of the very few captures I have decode properly.
1861
1862                    It could also be that the captures I have are generated by
1863                    a broken implementation.
1864                    If this is wrong and you dont report it as a bug
1865                    then it wont get fixed!
1866                 */
1867                 num_extensions+=1;
1868
1869                 extension_mask=0;
1870                 for(i=0;i<num_extensions;i++){
1871                         offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_bit);
1872                         if (tree) {
1873                                 proto_item_append_text(actx->created_item, " (%s %s present)",
1874                                         index_get_extension_name(sequence, i), extension_bit?"is":"is NOT");
1875                         }
1876                         if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
1877
1878                         extension_mask=(extension_mask<<1)|extension_bit;
1879                 }
1880
1881                 /* find how many extensions we know about */
1882                 num_known_extensions=0;
1883                 for(i=0;sequence[i].p_id;i++){
1884                         if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
1885                                 num_known_extensions++;
1886                         }
1887                 }
1888
1889                 /* decode the extensions one by one */
1890                 for(i=0;i<num_extensions;i++){
1891                         proto_item *cause;
1892                         guint32 length;
1893                         guint32 new_offset;
1894                         guint32 difference;
1895                         guint32 extension_index;
1896                         guint32 j,k;
1897
1898                         if(!((1L<<(num_extensions-1-i))&extension_mask)){
1899                                 /* this extension is not encoded in this PDU */
1900                                 continue;
1901                         }
1902
1903                         offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &length);
1904
1905                         if(i>=num_known_extensions){
1906                                 /* we dont know how to decode this extension */
1907                                 offset+=length*8;
1908                                 PER_NOT_DECODED_YET("unknown sequence extension");
1909                                 continue;
1910                         }
1911
1912                         extension_index=0;
1913                         for(j=0,k=0;sequence[j].p_id;j++){
1914                                 if(sequence[j].extension==ASN1_NOT_EXTENSION_ROOT){
1915                                         if(k==i){
1916                                                 extension_index=j;
1917                                                 break;
1918                                         }
1919                                         k++;
1920                                 }
1921                         }
1922
1923                         if(sequence[extension_index].func){
1924                                 new_offset=sequence[extension_index].func(tvb, offset, actx, tree, *sequence[extension_index].p_id);
1925                                 if (new_offset == offset) new_offset += 8;  /* OpenType has at least 1 octet */
1926                                 offset+=length*8;
1927                                 difference = offset - new_offset;
1928                                 /* A difference of 7 or less might be byte aligning */
1929                                 if(difference > 7){
1930                                         cause=proto_tree_add_text(tree, tvb, new_offset>>3, (offset-new_offset)>>3, 
1931                                                 "[Possible encoding error full length not decoded. Open type length %u ,decoded %u]",length, length - (difference>>3));
1932                                         proto_item_set_expert_flags(cause, PI_MALFORMED, PI_WARN);
1933                                         expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, 
1934                                                 "Possible encoding error full length not decoded. Open type length %u ,decoded %u",length, length - (difference>>3));
1935                                 }
1936                         } else {
1937                                 PER_NOT_DECODED_YET(index_get_field_name(sequence, extension_index));
1938                                 offset+=length*8;
1939                         }
1940                 }
1941         }
1942
1943         proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
1944         actx->created_item = item;
1945         return offset;
1946 }
1947
1948
1949
1950 /* 15 Encoding the bitstring type
1951
1952    max_len or min_len == NO_BOUND means there is no lower/upper constraint
1953
1954 */
1955 guint32
1956 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)
1957 {
1958         gint val_start, val_length;
1959         guint32 length;
1960         header_field_info *hfi;
1961         tvbuff_t *out_tvb = NULL;
1962
1963         hfi = (hf_index==-1) ? NULL : proto_registrar_get_nth(hf_index);
1964
1965 DEBUG_ENTRY("dissect_per_bit_string");
1966         /* 15.8 if the length is 0 bytes there will be no encoding */
1967         if(max_len==0) {
1968                 return offset;
1969         }
1970
1971         if (min_len == NO_BOUND) {
1972                 min_len = 0;
1973         }
1974
1975         /* 15.9 if length is fixed and less than or equal to sixteen bits*/
1976         if ((min_len==max_len) && (max_len<=16)) {
1977                 out_tvb = new_octet_aligned_subset_bits(tvb, offset, actx, min_len);
1978                 if (hfi) {
1979                         actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, -1, FALSE);
1980                         proto_item_append_text(actx->created_item, " [bit length %u]", max_len);
1981                 }
1982                 offset+=min_len;
1983                 if (value_tvb)
1984                         *value_tvb = out_tvb;
1985                 return offset;
1986         }
1987
1988
1989         /* 15.10 if length is fixed and less than to 64kbits*/
1990         if((min_len==max_len)&&(min_len<65536)){
1991                 /* (octet-aligned in the ALIGNED variant) 
1992                  * align to byte 
1993                  */
1994                 if (actx->aligned){
1995                         /* TODO the displayed value will be wrong for the unaligned variant */
1996                         BYTE_ALIGN_OFFSET(offset);
1997                 }
1998                 out_tvb = new_octet_aligned_subset_bits(tvb, offset, actx, min_len);
1999                 if (hfi) {
2000                         actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, -1, FALSE);
2001                         proto_item_append_text(actx->created_item, " [bit length %u]", max_len);
2002                 }
2003                 offset+=min_len;
2004                 if (value_tvb)
2005                         *value_tvb = out_tvb;
2006                 return offset;
2007         }
2008
2009         /* 15.11 */
2010         if (max_len != NO_BOUND) {
2011                 offset=dissect_per_constrained_integer(tvb, offset, actx,
2012                         tree, hf_per_bit_string_length, min_len, max_len,
2013                         &length, has_extension);
2014                         if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
2015         } else {
2016                 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_bit_string_length, &length);
2017         }
2018         if(length){
2019                 /* align to byte */
2020                 if (actx->aligned){
2021                         BYTE_ALIGN_OFFSET(offset);
2022                 }
2023                 out_tvb = new_octet_aligned_subset_bits(tvb, offset, actx, length);
2024
2025                 if (hfi) {
2026                         actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, -1, FALSE);
2027                         proto_item_append_text(actx->created_item, " [bit length %u]", length);
2028                 }
2029         }
2030         val_start = offset>>3;
2031         val_length = (length+7)/8;
2032         offset+=length;
2033
2034         if (value_tvb)
2035                 *value_tvb = out_tvb;
2036
2037         return offset;
2038 }
2039
2040 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)
2041 {
2042         tvbuff_t *val_tvb = NULL;
2043         proto_tree *subtree = tree;
2044
2045         offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, &val_tvb);
2046
2047         if (type_cb && val_tvb) {
2048                 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2049                 type_cb(val_tvb, actx->pinfo, subtree);
2050         }
2051
2052         return offset;
2053 }
2054
2055 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)
2056 {
2057         tvbuff_t *val_tvb = NULL;
2058         proto_tree *subtree = tree;
2059
2060         offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, &val_tvb);
2061
2062         if (type_cb && val_tvb) {
2063                 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2064                 type_cb(val_tvb, actx->pinfo, subtree);
2065         }
2066
2067         return offset;
2068 }
2069
2070 /* this fucntion dissects an OCTET STRING
2071         16.1
2072         16.2
2073         16.3
2074         16.4
2075         16.5
2076         16.6
2077         16.7
2078         16.8
2079
2080    max_len or min_len == NO_BOUND means there is no lower/upper constraint
2081
2082    hf_index can either be a FT_BYTES or an FT_STRING
2083 */
2084 guint32
2085 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)
2086 {
2087         gint val_start = 0, val_length;
2088         guint32 length;
2089         header_field_info *hfi;
2090         tvbuff_t *out_tvb = NULL;
2091
2092         hfi = (hf_index==-1) ? NULL : proto_registrar_get_nth(hf_index);
2093
2094 DEBUG_ENTRY("dissect_per_octet_string");
2095
2096         if (has_extension) {  /* 16.3 an extension marker is present */
2097                 gboolean extension_present;
2098                 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
2099                 if (!display_internal_per_fields) PROTO_ITEM_SET_HIDDEN(actx->created_item);
2100                 if (extension_present) max_len = NO_BOUND;  /* skip to 16.8 */
2101         }
2102
2103         if (min_len == NO_BOUND) {
2104                 min_len = 0;
2105         }
2106         if (max_len==0) {  /* 16.5 if the length is 0 bytes there will be no encoding */
2107                 val_start = offset>>3; 
2108                 val_length = 0;
2109
2110         } else if((min_len==max_len)&&(max_len<=2)) {  
2111                 /* 16.6 if length is fixed and less than or equal to two bytes*/
2112                 val_start = offset>>3; 
2113                 val_length = min_len;
2114                 out_tvb = new_octet_aligned_subset(tvb, offset, actx, val_length);
2115                 offset+=min_len*8;
2116
2117         } else if ((min_len==max_len)&&(min_len<65536)) {  
2118                 /* 16.7 if length is fixed and less than to 64k*/
2119
2120                 /* align to byte */
2121                 if (actx->aligned){
2122                         BYTE_ALIGN_OFFSET(offset);
2123                 }
2124                 val_start = offset>>3;
2125                 val_length = min_len;
2126                 out_tvb = new_octet_aligned_subset(tvb, offset, actx, val_length);
2127                 offset+=min_len*8;
2128
2129         } else {  /* 16.8 */
2130                 if(max_len>0) {  
2131                         offset = dissect_per_constrained_integer(tvb, offset, actx, tree,
2132                                 hf_per_octet_string_length, min_len, max_len, &length, FALSE);
2133
2134                                 if (!display_internal_per_fields) 
2135                                         PROTO_ITEM_SET_HIDDEN(actx->created_item);
2136                 } else {
2137                         offset = dissect_per_length_determinant(tvb, offset, actx, tree, 
2138                                 hf_per_octet_string_length, &length);
2139                 }
2140
2141                 if(length){
2142                         /* align to byte */
2143                         if (actx->aligned){
2144                                 BYTE_ALIGN_OFFSET(offset);
2145                         }
2146                         out_tvb = new_octet_aligned_subset(tvb, offset, actx, length);
2147                 } else {
2148                         val_start = offset>>3; 
2149                 }
2150                 val_length = length;
2151                 offset+=length*8;
2152         }
2153
2154         if (hfi) {
2155                 if (IS_FT_UINT(hfi->type)||IS_FT_INT(hfi->type)) {
2156                         /* If the type has been converted to FT_UINT or FT_INT in the .cnf file
2157                          * display the length of this octet string instead of the octetstring itself
2158                          */
2159                         if (IS_FT_UINT(hfi->type))
2160                                 actx->created_item = proto_tree_add_uint(tree, hf_index, out_tvb, 0, val_length, val_length);
2161                         else
2162                                 actx->created_item = proto_tree_add_int(tree, hf_index, out_tvb, 0, val_length, val_length);
2163                         proto_item_append_text(actx->created_item, plurality(val_length, " octet", " octets"));
2164                 } else {
2165                         if(out_tvb){
2166                                 actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, val_length, FALSE);
2167                         }else{
2168                                 /* Length = 0 */
2169                                 actx->created_item = proto_tree_add_item(tree, hf_index, tvb, val_start, val_length, FALSE);
2170                         }
2171                 }
2172         }
2173
2174         if (value_tvb)
2175                 *value_tvb = (out_tvb) ? out_tvb : tvb_new_subset(tvb, val_start, val_length, val_length);
2176
2177         return offset;
2178 }
2179
2180 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)
2181 {
2182         tvbuff_t *val_tvb = NULL;
2183         proto_tree *subtree = tree;
2184
2185         offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, &val_tvb);
2186
2187         if (type_cb && val_tvb) {
2188                 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2189                 type_cb(val_tvb, actx->pinfo, subtree);
2190         }
2191
2192         return offset;
2193 }
2194
2195 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)
2196 {
2197         tvbuff_t *val_tvb = NULL;
2198         proto_tree *subtree = tree;
2199
2200         offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, &val_tvb);
2201
2202         if (type_cb && val_tvb) {
2203                 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2204                 type_cb(val_tvb, actx->pinfo, subtree);
2205         }
2206
2207         return offset;
2208 }
2209
2210 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)
2211 {
2212   asn1_stack_frame_push(actx, name);
2213   asn1_param_push_integer(actx, min_len);
2214   asn1_param_push_integer(actx, max_len);
2215   asn1_param_push_boolean(actx, has_extension);
2216
2217   offset = type_cb(tvb, offset, actx, tree, hf_index);
2218
2219   asn1_stack_frame_pop(actx, name);
2220
2221   return offset;
2222 }
2223
2224 gboolean get_size_constraint_from_stack(asn1_ctx_t *actx, const gchar *name, int *pmin_len, int *pmax_len, gboolean *phas_extension)
2225 {
2226   asn1_par_t *par;
2227
2228   if (pmin_len) *pmin_len = NO_BOUND;
2229   if (pmax_len) *pmax_len = NO_BOUND;
2230   if (phas_extension) *phas_extension = FALSE;
2231
2232   if (!actx->stack) return FALSE;
2233   if (strcmp(actx->stack->name, name)) return FALSE;
2234
2235   par = actx->stack->par;
2236   if (!par || (par->ptype != ASN1_PAR_INTEGER)) return FALSE;
2237   if (pmin_len) *pmin_len = par->value.v_integer;
2238   par = par->next;
2239   if (!par || (par->ptype != ASN1_PAR_INTEGER)) return FALSE;
2240   if (pmax_len) *pmax_len = par->value.v_integer;
2241   par = par->next;
2242   if (!par || (par->ptype != ASN1_PAR_BOOLEAN)) return FALSE;
2243   if (phas_extension) *phas_extension = par->value.v_boolean;
2244
2245   return TRUE;
2246 }
2247
2248
2249 /* 26 Encoding of a value of the external type */
2250
2251 /* code generated from definition in 26.1 */
2252 /*
2253 [UNIVERSAL 8] IMPLICIT SEQUENCE {
2254   direct-reference OBJECT IDENTIFIER OPTIONAL,
2255   indirect-reference INTEGER OPTIONAL,
2256   data-value-descriptor ObjectDescriptor OPTIONAL,
2257     encoding CHOICE {
2258     single-ASN1-type [0] ABSTRACT-SYNTAX.&Type,
2259     octet-aligned [1] IMPLICIT OCTET STRING,
2260     arbitrary [2] IMPLICIT BIT STRING 
2261   } 
2262 }
2263 */
2264 /* NOTE: This sequence type differs from that in ITU-T Rec. X.680 | ISO/IEC 8824-1 for historical reasons. */
2265
2266 static int
2267 dissect_per_T_direct_reference(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2268   offset = dissect_per_object_identifier_str(tvb, offset, actx, tree, hf_index, &actx->external.direct_reference);
2269
2270   actx->external.direct_ref_present = TRUE;
2271   return offset;
2272 }
2273
2274
2275
2276 static int
2277 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_) {
2278   offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, &actx->external.indirect_reference);
2279
2280   actx->external.indirect_ref_present = TRUE;
2281   return offset;
2282 }
2283
2284
2285
2286 static int
2287 dissect_per_T_data_value_descriptor(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2288   offset = dissect_per_object_descriptor(tvb, offset, actx, tree, hf_index, &actx->external.data_value_descriptor);
2289
2290   actx->external.data_value_descr_present = TRUE;
2291   return offset;
2292 }
2293
2294
2295
2296 static int
2297 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_) {
2298   offset = dissect_per_open_type(tvb, offset, actx, tree, actx->external.hf_index, actx->external.u.per.type_cb);
2299
2300   return offset;
2301 }
2302
2303
2304
2305 static int
2306 dissect_per_T_octet_aligned(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2307   offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index,
2308                                        NO_BOUND, NO_BOUND, FALSE, &actx->external.octet_aligned);
2309
2310   if (actx->external.u.per.type_cb) {
2311     actx->external.u.per.type_cb(actx->external.octet_aligned, 0, actx, tree, actx->external.hf_index);
2312     } else {
2313         actx->created_item = proto_tree_add_text(tree, actx->external.octet_aligned, 0, -1, "Unknown EXTERNAL Type");
2314     }
2315   return offset;
2316 }
2317
2318
2319
2320 static int
2321 dissect_per_T_arbitrary(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2322   offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index,
2323                                      NO_BOUND, NO_BOUND, FALSE, &actx->external.arbitrary);
2324
2325   if (actx->external.u.per.type_cb) {
2326     actx->external.u.per.type_cb(actx->external.arbitrary, 0, actx, tree, actx->external.hf_index);
2327     } else {
2328         actx->created_item = proto_tree_add_text(tree, actx->external.arbitrary, 0, -1, "Unknown EXTERNAL Type");
2329     }
2330   return offset;
2331 }
2332
2333
2334 static const value_string per_External_encoding_vals[] = {
2335   {   0, "single-ASN1-type" },
2336   {   1, "octet-aligned" },
2337   {   2, "arbitrary" },
2338   { 0, NULL }
2339 };
2340
2341 static const per_choice_t External_encoding_choice[] = {
2342   {   0, &hf_per_single_ASN1_type, ASN1_NO_EXTENSIONS     , dissect_per_T_single_ASN1_type },
2343   {   1, &hf_per_octet_aligned   , ASN1_NO_EXTENSIONS     , dissect_per_T_octet_aligned },
2344   {   2, &hf_per_arbitrary       , ASN1_NO_EXTENSIONS     , dissect_per_T_arbitrary },
2345   { 0, NULL, 0, NULL }
2346 };
2347
2348 static int
2349 dissect_per_External_encoding(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2350   offset = dissect_per_choice(tvb, offset, actx, tree, hf_index,
2351                                  ett_per_External_encoding, External_encoding_choice,
2352                                  &actx->external.encoding);
2353
2354   return offset;
2355 }
2356
2357
2358 static const per_sequence_t External_sequence[] = {
2359   { &hf_per_direct_reference, ASN1_NO_EXTENSIONS     , ASN1_OPTIONAL    , dissect_per_T_direct_reference },
2360   { &hf_per_indirect_reference, ASN1_NO_EXTENSIONS     , ASN1_OPTIONAL    , dissect_per_T_indirect_reference },
2361   { &hf_per_data_value_descriptor, ASN1_NO_EXTENSIONS     , ASN1_OPTIONAL    , dissect_per_T_data_value_descriptor },
2362   { &hf_per_encoding        , ASN1_NO_EXTENSIONS     , ASN1_NOT_OPTIONAL, dissect_per_External_encoding },
2363   { NULL, 0, 0, NULL }
2364 };
2365
2366 static int
2367 dissect_per_External(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2368   offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
2369                                    ett_per_External, External_sequence);
2370
2371   return offset;
2372 }
2373
2374 guint32 
2375 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)
2376 {
2377   asn1_ctx_clean_external(actx);
2378   actx->external.u.per.type_cb = type_cb;
2379   offset = dissect_per_External(tvb, offset, actx, tree, hf_index);
2380
2381   asn1_ctx_clean_external(actx);
2382   return offset;
2383 }
2384
2385
2386 void
2387 proto_register_per(void)
2388 {
2389         static hf_register_info hf[] =
2390         {
2391         { &hf_per_num_sequence_extensions,
2392                 { "Number of Sequence Extensions", "per.num_sequence_extensions", FT_UINT32, BASE_DEC,
2393                 NULL, 0, "Number of extensions encoded in this sequence", HFILL }},
2394         { &hf_per_choice_index,
2395                 { "Choice Index", "per.choice_index", FT_UINT32, BASE_DEC,
2396                 NULL, 0, "Which index of the Choice within extension root is encoded", HFILL }},
2397         { &hf_per_choice_extension_index,
2398                 { "Choice Extension Index", "per.choice_extension_index", FT_UINT32, BASE_DEC,
2399                 NULL, 0, "Which index of the Choice within extension addition is encoded", HFILL }},
2400         { &hf_per_enum_index,
2401                 { "Enumerated Index", "per.enum_index", FT_UINT32, BASE_DEC,
2402                 NULL, 0, "Which index of the Enumerated within extension root is encoded", HFILL }},
2403         { &hf_per_enum_extension_index,
2404                 { "Enumerated Extension Index", "per.enum_extension_index", FT_UINT32, BASE_DEC,
2405                 NULL, 0, "Which index of the Enumerated within extension addition is encoded", HFILL }},
2406         { &hf_per_GeneralString_length,
2407                 { "GeneralString Length", "per.generalstring_length", FT_UINT32, BASE_DEC,
2408                 NULL, 0, "Length of the GeneralString", HFILL }},
2409         { &hf_per_extension_bit,
2410                 { "Extension Bit", "per.extension_bit", FT_BOOLEAN, 8,
2411                 TFS(&tfs_extension_bit), 0x01, "The extension bit of an aggregate", HFILL }},
2412         { &hf_per_extension_present_bit,
2413                 { "Extension Present Bit", "per.extension_present_bit", FT_BOOLEAN, 8,
2414                 TFS(&tfs_extension_present_bit), 0x01, "Whether this optional extension is present or not", HFILL }},
2415         { &hf_per_small_number_bit,
2416                 { "Small Number Bit", "per.small_number_bit", FT_BOOLEAN, 8,
2417                 TFS(&tfs_small_number_bit), 0x01, "The small number bit for a section 10.6 integer", HFILL }},
2418         { &hf_per_optional_field_bit,
2419                 { "Optional Field Bit", "per.optional_field_bit", FT_BOOLEAN, 8,
2420                 TFS(&tfs_optional_field_bit), 0x01, "This bit specifies the presence/absence of an optional field", HFILL }},
2421         { &hf_per_sequence_of_length,
2422                 { "Sequence-Of Length", "per.sequence_of_length", FT_UINT32, BASE_DEC,
2423                 NULL, 0, "Number of items in the Sequence Of", HFILL }},
2424         { &hf_per_object_identifier_length,
2425                 { "Object Identifier Length", "per.object_length", FT_UINT32, BASE_DEC,
2426                 NULL, 0, "Length of the object identifier", HFILL }},
2427         { &hf_per_open_type_length,
2428                 { "Open Type Length", "per.open_type_length", FT_UINT32, BASE_DEC,
2429                 NULL, 0, "Length of an open type encoding", HFILL }},
2430         { &hf_per_real_length,
2431                 { "Real Length", "per.real_length", FT_UINT32, BASE_DEC,
2432                 NULL, 0, "Length of an real encoding", HFILL }},
2433         { &hf_per_octet_string_length,
2434                 { "Octet String Length", "per.octet_string_length", FT_UINT32, BASE_DEC,
2435                 NULL, 0, "Number of bytes in the Octet String", HFILL }},
2436         { &hf_per_bit_string_length,
2437                 { "Bit String Length", "per.bit_string_length", FT_UINT32, BASE_DEC,
2438                 NULL, 0, "Number of bits in the Bit String", HFILL }},
2439         { &hf_per_const_int_len,
2440                 { "Constrained Integer Length", "per._const_int_len", FT_UINT32, BASE_DEC,
2441                 NULL, 0, "Number of bytes in the Constrained Integer", HFILL }},
2442     { &hf_per_direct_reference,
2443       { "direct-reference", "per.direct_reference",
2444         FT_OID, BASE_NONE, NULL, 0,
2445         "per.T_direct_reference", HFILL }},
2446     { &hf_per_indirect_reference,
2447       { "indirect-reference", "per.indirect_reference",
2448         FT_INT32, BASE_DEC, NULL, 0,
2449         "per.T_indirect_reference", HFILL }},
2450     { &hf_per_data_value_descriptor,
2451       { "data-value-descriptor", "per.data_value_descriptor",
2452         FT_STRING, BASE_NONE, NULL, 0,
2453         "per.T_data_value_descriptor", HFILL }},
2454     { &hf_per_encoding,
2455       { "encoding", "per.encoding",
2456         FT_UINT32, BASE_DEC, VALS(per_External_encoding_vals), 0,
2457         "per.External_encoding", HFILL }},
2458     { &hf_per_single_ASN1_type,
2459       { "single-ASN1-type", "per.single_ASN1_type",
2460         FT_NONE, BASE_NONE, NULL, 0,
2461         "per.T_single_ASN1_type", HFILL }},
2462     { &hf_per_octet_aligned,
2463       { "octet-aligned", "per.octet_aligned",
2464         FT_BYTES, BASE_HEX, NULL, 0,
2465         "per.T_octet_aligned", HFILL }},
2466     { &hf_per_arbitrary,
2467       { "arbitrary", "per.arbitrary",
2468         FT_BYTES, BASE_HEX, NULL, 0,
2469         "per.T_arbitrary", HFILL }},
2470     { &hf_per_integer_length,
2471       { "integer length", "per.integer_length",
2472         FT_UINT32, BASE_DEC, NULL, 0,
2473         NULL, HFILL }},
2474         };
2475         static gint *ett[] =
2476         {
2477                 &ett_per_open_type,
2478                 &ett_per_containing,
2479                 &ett_per_sequence_of_item,
2480                 &ett_per_External,
2481                 &ett_per_External_encoding,
2482         };
2483         module_t *per_module;
2484
2485         proto_per = proto_register_protocol("Packed Encoding Rules (ASN.1 X.691)", "PER", "per");
2486         proto_register_field_array(proto_per, hf, array_length(hf));
2487         proto_register_subtree_array(ett, array_length(ett));
2488
2489         proto_set_cant_toggle(proto_per);
2490
2491         per_module = prefs_register_protocol(proto_per, NULL);
2492         prefs_register_bool_preference(per_module, "display_internal_per_fields",
2493                 "Display the internal PER fields in the tree",
2494                 "Whether the dissector should put the internal PER data in the tree or if it should hide it",
2495                 &display_internal_per_fields);
2496
2497 }
2498
2499 void
2500 proto_reg_handoff_per(void)
2501 {
2502 }
2503