Add packet-ansi_map.h to the distribution.
[obnox/wireshark/wip.git] / 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: packet-per.c,v 1.23 2003/10/27 22:28:48 guy Exp $
11  *
12  * Ethereal - Network traffic analyzer
13  * By Gerald Combs <gerald@ethereal.com>
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 <string.h>
40
41 #include "prefs.h"
42 #include "packet-per.h"
43
44
45 static int proto_per = -1;
46 static int hf_per_GeneralString_length = -1;
47 static int hf_per_extension_bit = -1;
48 static int hf_per_extension_present_bit = -1;
49 static int hf_per_choice_extension = -1;
50 static int hf_per_num_sequence_extensions = -1;
51 static int hf_per_small_number_bit = -1;
52 static int hf_per_optional_field_bit = -1;
53 static int hf_per_sequence_of_length = -1;
54 static int hf_per_object_identifier_length = -1;
55 static int hf_per_open_type_length = -1;
56 static int hf_per_octet_string_length = -1;
57
58
59 static gint ett_per_sequence_of_item = -1;
60
61
62 /*
63 #define DEBUG_ENTRY(x) \
64 printf("#%d  %s   tvb:0x%08x\n",pinfo->fd->num,x,(int)tvb);
65 */
66 #define DEBUG_ENTRY(x) \
67         ;
68
69
70
71 /* whether the PER helpers should put the internal PER fields into the tree
72    or not.
73 */
74 static guint display_internal_per_fields = FALSE;
75
76
77
78 static const true_false_string tfs_extension_present_bit = {
79         "",
80         ""
81 };
82 static const true_false_string tfs_extension_bit = {
83         "Extension bit is set",
84         "Extension bit is clear"
85 };
86 static const true_false_string tfs_small_number_bit = {
87         "The number is small, 0-63",
88         "The number is large, >63"
89 };
90 static const true_false_string tfs_optional_field_bit = {
91         "",
92         ""
93 };
94
95
96
97
98 /* 10.9 */
99 /* this decodes and returns a length determinant according to 10.9 */
100 guint32
101 dissect_per_length_determinant(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index, guint32 *length)
102 {
103         guint8 byte;
104         guint32 len;
105
106         if(!length){
107                 length=&len;
108         }
109
110         /* byte aligned */
111         if(offset&0x07){
112                 offset=(offset&0xfffffff8)+8;
113         }
114         byte=tvb_get_guint8(tvb, offset>>3);
115         offset+=8;
116
117         if((byte&0x80)==0){
118                 *length=byte;
119                 if(hf_index!=-1){
120                         proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
121                 }
122                 return offset;
123         }
124         if((byte&0xc0)==0x80){
125                 *length=(byte&0x3f);
126                 *length=((*length)<<8)+tvb_get_guint8(tvb, offset>>3);
127                 offset+=8;
128                 if(hf_index!=-1){
129                         proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-2, 2, *length);
130                 }
131                 return offset;
132         }
133         NOT_DECODED_YET("10.9.3.8.1");
134         return offset;
135 }
136
137 /* 10.6   normally small non-negative whole number */
138 guint32
139 dissect_per_normally_small_nonnegative_whole_number(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, guint32 *length)
140 {
141         gboolean small_number;
142         guint32 len;
143
144 DEBUG_ENTRY("dissect_per_normally_small_nonnegative_whole_number");
145         if(!length){
146                 length=&len;
147         }
148
149         offset=dissect_per_boolean(tvb, offset, pinfo, tree, hf_per_small_number_bit, &small_number, NULL);
150         if(!small_number){
151                 int i;
152                 /* 10.6.1 */
153                 *length=0;
154                 for(i=0;i<6;i++){
155                         offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &small_number, NULL);
156                         *length<<=1;
157                         if(small_number){
158                                 *length|=1;
159                         }
160                 }
161                 if(hf_index!=-1){
162                         if((offset&0x07)<7){
163                                 proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
164                         } else {
165                                 proto_tree_add_uint(tree, hf_index, tvb, (offset>>3), 1, *length);
166                         }
167                 }
168                 return offset;
169         }
170
171         /* 10.6.2 */
172         offset=dissect_per_length_determinant(tvb, offset, pinfo, tree, hf_index, length);
173
174         return offset;
175 }
176
177
178
179 /* this function reads a GeneralString */
180 /* currently based on pure guesswork since RFC2833 didnt tell me much
181    i guess that the PER encoding for this is a normally-small-whole-number
182    followed by a ascii string.
183
184    based on pure guesswork.  it looks ok in the only capture i have where
185    there is a 1 byte general string encoded
186 */
187 guint32
188 dissect_per_GeneralString(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index)
189 {
190         proto_tree *etr=NULL;
191         guint32 length;
192
193         if(display_internal_per_fields){
194                 etr=tree;
195         }
196
197         offset=dissect_per_length_determinant(tvb, offset, pinfo, etr, hf_per_GeneralString_length, &length);
198
199
200         proto_tree_add_item(tree, hf_index, tvb, offset>>3, length, FALSE);
201
202         offset+=length*8;
203
204         return offset;
205 }
206
207 /* 19 this function dissects a sequence of */
208 static guint32
209 dissect_per_sequence_of_helper(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int (*func)(tvbuff_t *, int , packet_info *, proto_tree *), guint32 length)
210 {
211         guint32 i;
212
213 DEBUG_ENTRY("dissect_per_sequence_of_helper");
214         for(i=0;i<length;i++){
215                 guint32 lold_offset=offset;
216                 proto_item *litem;
217                 proto_tree *ltree;
218
219                 litem=proto_tree_add_text(tree, tvb, offset>>3, 0, "Item %d", i);
220                 ltree=proto_item_add_subtree(litem, ett_per_sequence_of_item);
221
222                 offset=(*func)(tvb, offset, pinfo, ltree);
223                 proto_item_set_len(litem, (offset>>3)!=(lold_offset>>3)?(offset>>3)-(lold_offset>>3):1);
224         }
225
226         return offset;
227 }
228 guint32
229 dissect_per_sequence_of(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *parent_tree, int hf_index, gint ett_index, int (*func)(tvbuff_t *, int , packet_info *, proto_tree *))
230 {
231         proto_item *item;
232         proto_tree *tree;
233         guint32 old_offset=offset;
234         guint32 length;
235         proto_tree *etr = NULL;
236
237 DEBUG_ENTRY("dissect_per_sequence_of");
238
239         item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, FALSE);
240         tree=proto_item_add_subtree(item, ett_index);
241
242         /* semi-constrained whole number for number of elements */
243         /* each element encoded as 10.9 */
244
245         if(display_internal_per_fields){
246                 etr=tree;
247         }
248         offset=dissect_per_length_determinant(tvb, offset, pinfo, etr, hf_per_sequence_of_length, &length);
249
250         offset=dissect_per_sequence_of_helper(tvb, offset, pinfo, tree, func, length);
251
252
253         proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
254         return offset;
255 }
256
257
258 /* dissect a constrained IA5String that consists of the full ASCII set,
259    i.e. no FROM stuff limiting the alphabet
260 */
261 guint32
262 dissect_per_IA5String(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, int min_len, int max_len)
263 {
264         offset=dissect_per_octet_string(tvb, offset, pinfo, tree, hf_index, min_len, max_len, NULL, NULL);
265
266         return offset;
267 }
268
269 /* XXX we dont do >64k length strings   yet */
270 guint32
271 dissect_per_restricted_character_string(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, int min_len, int max_len, char *alphabet, int alphabet_length)
272 {
273         guint32 length;
274         gboolean byte_aligned;
275         static char str[1024];
276         guint char_pos;
277         int bits_per_char;
278         guint32 old_offset;
279
280 DEBUG_ENTRY("dissect_per_restricted_character_string");
281         /* xx.x if the length is 0 bytes there will be no encoding */
282         if(max_len==0){
283                 return offset;
284         }
285
286
287         if(min_len==-1){
288                 min_len=0;
289         }
290
291
292         /* xx.x */
293         length=max_len;
294         if(min_len!=max_len){
295                 proto_tree *etr = NULL;
296
297                 if(display_internal_per_fields){
298                         etr=tree;
299                 }
300                 offset=dissect_per_constrained_integer(tvb, offset, pinfo,
301                         etr, hf_per_octet_string_length, min_len, max_len,
302                         &length, NULL, FALSE);
303         }
304
305
306
307         /* xx.x if length is fixed or constrained to be less than or equal to
308            two bytes, then it will not be byte aligned. */
309         byte_aligned=TRUE;
310         if((min_len==max_len)&&(max_len<=2)){
311                 byte_aligned=FALSE;
312         }
313         if(max_len<2){
314                 byte_aligned=FALSE;
315         }
316
317         if(byte_aligned){
318                 if(offset&0x07){
319                         offset=(offset&0xfffffff8)+8;
320                 }
321         }
322
323
324         if(length>=1024){
325                 NOT_DECODED_YET("restricted char string too long");
326                 length=1024;
327         }
328
329         /* 27.5.2 depending of the alphabet length, find how many bits
330            are used to encode each character */
331 /* unaligned PER
332         if(alphabet_length<=2){
333                 bits_per_char=1;
334         } else if(alphabet_length<=4){
335                 bits_per_char=2;
336         } else if(alphabet_length<=8){
337                 bits_per_char=3;
338         } else if(alphabet_length<=16){
339                 bits_per_char=4;
340         } else if(alphabet_length<=32){
341                 bits_per_char=5;
342         } else if(alphabet_length<=64){
343                 bits_per_char=6;
344         } else if(alphabet_length<=128){
345                 bits_per_char=7;
346         } else {
347                 bits_per_char=8;
348         }
349 */
350         if(alphabet_length<=2){
351                 bits_per_char=1;
352         } else if(alphabet_length<=4){
353                 bits_per_char=2;
354         } else if(alphabet_length<=16){
355                 bits_per_char=4;
356         } else {
357                 bits_per_char=8;
358         }
359
360         old_offset=offset;
361         for(char_pos=0;char_pos<length;char_pos++){
362                 guchar val;
363                 int i;
364                 gboolean bit;
365
366                 val=0;
367                 for(i=0;i<bits_per_char;i++){
368                         offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &bit, NULL);
369                         val=(val<<1)|bit;
370                 }
371                 if (val >= alphabet_length)
372                         str[char_pos] = '?';    /* XXX - how to mark this? */
373                 else
374                         str[char_pos]=alphabet[val];
375         }
376         str[char_pos]=0;
377         proto_tree_add_string(tree, hf_index, tvb, (old_offset>>3), (offset>>3)-(old_offset>>3), str);
378
379         return offset;
380 }
381 guint32
382 dissect_per_NumericString(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, int min_len, int max_len)
383 {
384         offset=dissect_per_restricted_character_string(tvb, offset, pinfo, tree, hf_index, min_len, max_len, " 0123456789", 11);
385
386         return offset;
387 }
388 guint32
389 dissect_per_PrintableString(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, int min_len, int max_len)
390 {
391         offset=dissect_per_restricted_character_string(tvb, offset, pinfo, tree, hf_index, min_len, max_len, " '()+,-.*0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 74);
392         return offset;
393 }
394 guint32
395 dissect_per_BMPString(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, int min_len, int max_len)
396 {
397         guint32 length;
398         static char *str;
399
400         /* xx.x if the length is 0 bytes there will be no encoding */
401         if(max_len==0){
402                 return offset;
403         }
404
405
406         if(min_len==-1){
407                 min_len=0;
408         }
409
410
411         /* xx.x */
412         length=max_len;
413         if(min_len!=max_len){
414                 proto_tree *etr = NULL;
415
416                 if(display_internal_per_fields){
417                         etr=tree;
418                 }
419                 offset=dissect_per_constrained_integer(tvb, offset, pinfo,
420                         etr, hf_per_octet_string_length, min_len, max_len,
421                         &length, NULL, FALSE);
422         }
423
424
425         /* align to byte boundary */
426         if(offset&0x07){
427                 offset=(offset&0xfffffff8)+8;
428         }
429
430         if(length>=1024){
431                 NOT_DECODED_YET("BMPString too long");
432                 length=1024;
433         }
434
435         str = tvb_fake_unicode(tvb, offset>>3, length, FALSE);
436
437         proto_tree_add_string(tree, hf_index, tvb, offset>>3, length*2, str);
438
439         offset+=(length<<3)*2;
440
441         return offset;
442 }
443
444
445 /* this function dissects a constrained sequence of */
446 guint32
447 dissect_per_constrained_sequence_of(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *parent_tree, int hf_index, gint ett_index, int (*func)(tvbuff_t *, int , packet_info *, proto_tree *), int min_len, int max_len)
448 {
449         proto_item *item;
450         proto_tree *tree;
451         guint32 old_offset=offset;
452         guint32 length;
453
454
455 DEBUG_ENTRY("dissect_per_constrained_sequence_of");
456         item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, FALSE);
457         tree=proto_item_add_subtree(item, ett_index);
458
459         /* 19.5 if min==max and min,max<64k ==> no length determinant */
460         if((min_len==max_len) && (min_len<65536)){
461                 length=min_len;
462                 goto call_sohelper;
463         }
464
465         /* 19.6 ub>=64k or unset */
466         if(max_len>=65536){
467                 guint32 old_offset=offset;
468                 /* semi-constrained whole number for number of elements */
469                 /* each element encoded as 10.9 */
470                 offset=dissect_per_length_determinant(tvb, offset, pinfo, tree, -1, &length);
471                 length+=min_len;
472                 proto_tree_add_uint(tree, hf_per_sequence_of_length, tvb, old_offset>>3, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1, length);
473                 goto call_sohelper;
474         }
475
476         /* constrained whole number for number of elements */
477         offset=dissect_per_constrained_integer(tvb, offset, pinfo,
478                 tree, hf_per_sequence_of_length, min_len, max_len,
479                 &length, NULL, FALSE);
480
481
482
483 call_sohelper:
484         offset=dissect_per_sequence_of_helper(tvb, offset, pinfo, tree, func, length);
485
486
487         proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
488         return offset;
489 }
490
491 /* this function dissects a constrained set of */
492 guint32
493 dissect_per_constrained_set_of(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *parent_tree, int hf_index, gint ett_index, int (*func)(tvbuff_t *, int , packet_info *, proto_tree *), int min_len, int max_len)
494 {
495         /* for basic-per  a set-of is encoded in the same way as a sequence-of */
496 DEBUG_ENTRY("dissect_per_constrained_set_of");
497         offset=dissect_per_constrained_sequence_of(tvb, offset, pinfo, parent_tree, hf_index, ett_index, func, min_len, max_len);
498         return offset;
499 }
500
501
502
503
504
505
506 /* this function dissects a set of */
507 guint32
508 dissect_per_set_of(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *parent_tree, int hf_index, gint ett_index, int (*func)(tvbuff_t *, int , packet_info *, proto_tree *))
509 {
510         /* for basic-per  a set-of is encoded in the same way as a sequence-of */
511 DEBUG_ENTRY("dissect_per_set_of");
512         offset=dissect_per_sequence_of(tvb, offset, pinfo, parent_tree, hf_index, ett_index, func);
513         return offset;
514 }
515
516
517
518
519 /* this function reads a OBJECT IDENTIFIER */
520 guint32
521 dissect_per_object_identifier(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index, char *value_string)
522 {
523         int i,count;
524         char str[256],*strp;
525         guint8 byte;
526         guint32 value;
527         proto_tree *etr=NULL;
528
529 DEBUG_ENTRY("dissect_per_object_identifier");
530
531         if(display_internal_per_fields){
532                 etr=tree;
533         }
534
535         /* first byte is the count and it is byte aligned */
536         if(offset&0x07){
537                 offset=(offset&0xfffffff8)+8;
538         }
539         count=tvb_get_guint8(tvb, offset>>3);
540
541
542         proto_tree_add_uint(etr, hf_per_object_identifier_length, tvb, offset>>3, 1, count);
543         offset+=8;
544
545         value=0;
546         for(i=0,strp=str;i<count;i++){
547                 byte=tvb_get_guint8(tvb,offset>>3);
548                 offset+=8;
549
550                 if((strp-str)>200){
551 NOT_DECODED_YET("too long octet_string");
552                         /*XXX assert here */
553                         return offset;
554                 }
555
556                 if(i==0){
557                         /* the first byte contains the first two object identifier components */
558                         if(byte<40){
559                                 strp+=sprintf(strp,"0.%d",byte);
560                         } else if (byte<80){
561                                 strp+=sprintf(strp,"1.%d",byte-40);
562                         } else {
563                                 strp+=sprintf(strp,"2.%d",byte-80);
564                         }
565                         continue;
566                 }
567
568                 value=(value<<7)|(byte&0x7f);
569                 if(byte&0x80){
570                         continue;
571                 }
572
573                 strp+=sprintf(strp,".%d",value);
574                 value=0;
575         }
576         *strp=0;
577
578         proto_tree_add_string(tree, hf_index, tvb, (offset>>3)-count, count, str);
579
580         if (value_string) {
581                 strcpy(value_string, str);
582         }
583
584         return offset;
585 }
586
587
588
589
590 /* this function reads a single bit */
591 guint32
592 dissect_per_boolean(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index, gboolean *bool, proto_item **item)
593 {
594         guint8 ch, mask;
595         gboolean value;
596         header_field_info *hfi;
597         proto_item *it;
598
599 DEBUG_ENTRY("dissect_per_boolean");
600
601         ch=tvb_get_guint8(tvb, offset>>3);
602         mask=1<<(7-(offset&0x07));
603         if(ch&mask){
604                 value=1;
605         } else {
606                 value=0;
607         }
608         if(hf_index!=-1){
609                 char str[256];
610                 hfi = proto_registrar_get_nth(hf_index);
611                 sprintf(str,"%s: %c%c%c%c %c%c%c%c %s",
612                         hfi->name,
613                         mask&0x80?'0'+value:'.',
614                         mask&0x40?'0'+value:'.',
615                         mask&0x20?'0'+value:'.',
616                         mask&0x10?'0'+value:'.',
617                         mask&0x08?'0'+value:'.',
618                         mask&0x04?'0'+value:'.',
619                         mask&0x02?'0'+value:'.',
620                         mask&0x01?'0'+value:'.',
621                         value?"True":"False"
622                 );
623                 it=proto_tree_add_boolean_format(tree, hf_index, tvb, offset>>3, 1, value, str);
624                 if(item){
625                         *item=it;
626                 }
627         }
628
629         if(bool){
630                 *bool=value;
631         }
632         return offset+1;
633 }
634
635
636
637
638 /* we currently only handle integers up to 32 bits in length. */
639 guint32
640 dissect_per_integer(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, gint32 *value, proto_item **item)
641 {
642         guint32 i, length;
643         gint32 val;
644         proto_item *it=NULL;
645
646         /* 12.2.6 b */
647         offset=dissect_per_length_determinant(tvb, offset, pinfo, tree, -1, &length);
648         /* gassert here? */
649         if(length>4){
650 NOT_DECODED_YET("too long integer");
651                 length=4;
652         }
653
654         val=0;
655         for(i=0;i<length;i++){
656                 if(i==0){
657                         if(tvb_get_guint8(tvb, offset>>3)&0x80){
658                                 /* negative number */
659                                 val=0xffffffff;
660                         } else {
661                                 /* positive number */
662                                 val=0;
663                         }
664                 }
665                 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
666                 offset+=8;
667         }
668         it=proto_tree_add_int(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
669
670         if(item){
671                 *item=it;
672         }
673         if(value){
674                 *value=val;
675         }
676
677         return offset;
678 }
679
680
681 /* this function reads a constrained integer  with or without a
682    PER visible extension marker present
683
684    has_extension==TRUE  would map to asn constructs such as:
685                 rfc-number      INTEGER (1..32768, ...)
686    while has_extension==FALSE would map to:
687                 t35CountryCode  INTEGER (0..255)
688
689    it only handles integers that fit inside a 32 bit integer
690 10.5.1 info only
691 10.5.2 info only
692 10.5.3 range=ub-lb+1
693 10.5.4 empty range
694 10.5.5 info only
695         10.5.6 unaligned version
696 10.5.7 aligned version
697 10.5.7.1 decoding of 0-255 1-8 bits
698 10.5.7.2 decoding og 0-256 8 bits
699 10.5.7.3 decoding of 0-65535 16 bits
700         10.5.7.4
701 */
702 guint32
703 dissect_per_constrained_integer(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, guint32 min, guint32 max, guint32 *value, proto_item **item, gboolean has_extension)
704 {
705         proto_item *it=NULL;
706         guint32 range, val;
707         header_field_info *hfi;
708         int num_bits;
709         int pad;
710         guint32 tmp;
711
712 DEBUG_ENTRY("dissect_per_constrained_integer");
713         if(has_extension){
714                 gboolean extension_present;
715                 offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &extension_present, NULL);
716                 if(extension_present){
717                         offset=dissect_per_integer(tvb, offset, pinfo, tree,
718                                 hf_index,
719                                 NULL, NULL);
720                         return offset;
721                 }
722         }
723
724         hfi = proto_registrar_get_nth(hf_index);
725
726         /* 10.5.3 */
727         if((max-min)>65536){
728                 /* just set range really big so it will fall through
729                    to the bottom of the encoding */
730                 range=1000000;
731         } else {
732                 range=max-min+1;
733         }
734
735         num_bits=0;
736         pad=0;
737         val=0;
738         /* 10.5.4 */
739         if(range==1){
740                 it=proto_tree_add_uint_format(tree, hf_index, tvb, offset>>3, 0, min, "%s: %d", hfi->name, min);
741                 if(item){
742                         *item=it;
743                 }
744                 if(value){
745                         *value=val;
746                 }
747                 return offset;
748         }
749
750         /* 10.5.7 */
751         if(range<=255){
752                 /* 10.5.7.1 */
753                 char str[256];
754                 int i, bit, length;
755
756                 length=1;
757                 if(range<=2){
758                         num_bits=1;
759                 } else if(range<=4){
760                         num_bits=2;
761                 } else if(range<=8){
762                         num_bits=3;
763                 } else if(range<=16){
764                         num_bits=4;
765                 } else if(range<=32){
766                         num_bits=5;
767                 } else if(range<=64){
768                         num_bits=6;
769                 } else if(range<=128){
770                         num_bits=7;
771                 } else if(range<=256){
772                         num_bits=8;
773                 }
774                 /* prepare the string */
775                 sprintf(str, "%s: ", hfi->name);
776                 for(bit=0;bit<((int)(offset&0x07));bit++){
777                         if(bit&&(!(bit%4))){
778                                 strcat(str, " ");
779                         }
780                         strcat(str,".");
781                 }
782                 /* read the bits for the int */
783                 for(i=0;i<num_bits;i++){
784                         if(bit&&(!(bit%4))){
785                                 strcat(str, " ");
786                         }
787                         if(bit&&(!(bit%8))){
788                                 length+=1;
789                                 strcat(str, " ");
790                         }
791                         bit++;
792                         offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &tmp, NULL);
793                         val<<=1;
794                         if(tmp){
795                                 val|=tmp;
796                                 strcat(str, "1");
797                         } else {
798                                 strcat(str, "0");
799                         }
800                 }
801                 for(;bit%8;bit++){
802                         if(bit&&(!(bit%4))){
803                                 strcat(str, " ");
804                         }
805                         strcat(str,".");
806                 }
807                 val+=min;
808                 if(hfi->strings){
809                         it=proto_tree_add_uint_format(tree, hf_index, tvb, (offset-num_bits)>>3, length, val, "%s : %s (%d)", str, val_to_str(val, hfi->strings, "Unknown(%d)"),val);
810                 } else {
811                         it=proto_tree_add_uint(tree, hf_index, tvb, (offset-num_bits)>>3, length, val);
812                 }
813                 if(item){
814                         *item=it;
815                 }
816                 if(value){
817                         *value=val;
818                 }
819                 return offset;
820         } else if(range==256){
821                 /* 10.5.7.2 */
822                 num_bits=8;
823                 pad=7-(offset&0x07);
824
825                 /* in the aligned case, align to byte boundary */
826                 if(offset&0x07){
827                         offset=(offset&0xfffffff8)+8;
828                 }
829                 val=tvb_get_guint8(tvb, offset>>3);
830                 offset+=8;
831
832                 val+=min;
833                 it=proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, val);
834                 if(item){
835                         *item=it;
836                 }
837                 if(value){
838                         *value=val;
839                 }
840                 return offset;
841         } else if(range<=65536){
842                 /* 10.5.7.3 */
843                 num_bits=16;
844                 pad=7-(offset&0x07);
845
846                 /* in the aligned case, align to byte boundary */
847                 if(offset&0x07){
848                         offset=(offset&0xfffffff8)+8;
849                 }
850                 val=tvb_get_guint8(tvb, offset>>3);
851                 val<<=8;
852                 offset+=8;
853                 val|=tvb_get_guint8(tvb, offset>>3);
854                 offset+=8;
855
856                 val+=min;
857                 it=proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-2, 2, val);
858                 if(item){
859                         *item=it;
860                 }
861                 if(value){
862                         *value=val;
863                 }
864                 return offset;
865         } else {
866                 int i,num_bytes;
867                 gboolean bit;
868
869                 /* 10.5.7.4 */
870                 /* 12.2.6 */
871                 offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &bit, NULL);
872                 num_bytes=bit;
873                 offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &bit, NULL);
874                 num_bytes=(num_bytes<<1)|bit;
875
876                 num_bytes++;  /* lower bound for length determinant is 1 */
877
878                 /* byte aligned */
879                 if(offset&0x07){
880                         offset=(offset&0xfffffff8)+8;
881                 }
882                 val=0;
883                 for(i=0;i<num_bytes;i++){
884                         val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
885                         offset+=8;
886                 }
887                 val+=min;
888                 it=proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-(num_bytes+1), num_bytes+1, val);
889                 if(item){
890                         *item=it;
891                 }
892                 if(value){
893                         *value=val;
894                 }
895                 return offset;
896         }
897
898         NOT_DECODED_YET("10.5");
899         return offset;
900 }
901
902 /* this functions decodes a CHOICE
903    it can only handle CHOICE INDEX values that fits inside a 32 bit integer.
904            22.1
905            22.2
906            22.3
907            22.4
908            22.5
909 22.6 no extensions
910 22.7 extension marker == 0
911            22.8 extension marker == 1
912 */
913 guint32
914 dissect_per_choice(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, gint ett_index, per_choice_t *choice, char *name, guint32 *value)
915 {
916         gboolean extension_present, extension_flag;
917         int extension_root_entries;
918         guint32 choice_index;
919         int i;
920         proto_item *it=NULL;
921         proto_tree *tr=NULL;
922         guint32 old_offset=offset;
923    int min_choice=INT_MAX;
924    int max_choice=-1;
925
926 DEBUG_ENTRY("dissect_per_choice");
927
928         it=proto_tree_add_text(tree, tvb, offset>>3, 0, name);
929         tr=proto_item_add_subtree(it, ett_index);
930
931
932         /* first check if there should be an extension bit for this CHOICE.
933            we do this by just checking the first choice arm
934          */
935         if(choice[0].extension==ASN1_NO_EXTENSIONS){
936                 extension_present=0;
937         } else {
938                 proto_tree *etr=NULL;
939
940                 if(display_internal_per_fields){
941                         etr=tr;
942                 }
943                 extension_present=1;
944                 /* will be placed called again below to place it in the tree */
945                 offset=dissect_per_boolean(tvb, offset, pinfo, etr, hf_per_extension_bit, &extension_flag, NULL);
946         }
947
948         /* count the number of entries in the extension_root */
949         extension_root_entries=0;
950         for(i=0;choice[i].name;i++){
951                 switch(choice[i].extension){
952                 case ASN1_NO_EXTENSIONS:
953                 case ASN1_EXTENSION_ROOT:
954          if(choice[i].value<min_choice){
955             min_choice=choice[i].value;
956          }
957          if(choice[i].value>max_choice){
958             max_choice=choice[i].value;
959          }
960                         extension_root_entries++;
961                         break;
962                 }
963         }
964
965         if( (!extension_present)
966         ||  (extension_present && (extension_flag==0)) ){
967                 guint32 choice_offset=offset;
968                 proto_tree *choicetree;
969                 proto_item *choiceitem;
970                 proto_tree *etr=NULL;
971
972                 /* 22.6 */
973                 /* 22.7 */
974 /*qqq  make it similar to the section below instead */
975                 offset=dissect_per_constrained_integer(tvb, offset, pinfo,
976                         tr, hf_index, min_choice, max_choice,
977                         &choice_index, &choiceitem, FALSE);
978                 if(value){
979                         *value=choice_index;
980                 }
981
982                 choicetree=proto_item_add_subtree(choiceitem, ett_index);
983
984                 if(display_internal_per_fields){
985                         etr=choicetree;
986                 }
987
988                 /* find and call the appropriate callback */
989                 for(i=0;choice[i].name;i++){
990                         if(choice[i].value==(int)choice_index){
991                                 if(choice[i].func){
992                                         offset=choice[i].func(tvb, offset, pinfo, choicetree);
993                                         break;
994                                 } else {
995                                         NOT_DECODED_YET(choice[i].name);
996                                         break;
997                                 }
998                         }
999                 }
1000                 proto_item_set_len(choiceitem, (offset>>3)!=(choice_offset>>3)?(offset>>3)-(choice_offset>>3):1);
1001         } else {
1002                 guint32 length;
1003                 int i, index;
1004                 guint32 choice_offset;
1005                 proto_tree *choicetree;
1006                 proto_item *choiceitem;
1007                 proto_tree *etr=NULL;
1008
1009                 if(display_internal_per_fields){
1010                         etr=tr;
1011                 }
1012
1013                 /* 22.8 */
1014                 offset=dissect_per_normally_small_nonnegative_whole_number(tvb, offset, pinfo, etr, hf_per_choice_extension, &choice_index);
1015                 offset=dissect_per_length_determinant(tvb, offset, pinfo, etr, hf_per_open_type_length, &length);
1016
1017
1018                 choice_offset=offset;
1019                 choiceitem=proto_tree_add_text(tr, tvb, offset>>3, 0, "Choice");
1020                 choicetree=proto_item_add_subtree(choiceitem, ett_index);
1021
1022                 index=-1;
1023                 for(i=0;choice[i].name;i++){
1024                         if(choice[i].extension==ASN1_NOT_EXTENSION_ROOT){
1025                                 if(!choice_index){
1026                                         index=i;
1027                                         break;
1028                                 }
1029                                 choice_index--;
1030                         }
1031                 }
1032
1033                 if(index!=-1){
1034                         if(value){
1035                                 *value=index;
1036                         }
1037                 }
1038
1039                 if(index==-1){
1040                         /* if we dont know how to decode this one, just step offset to the next structure */
1041                         offset+=length*8;
1042                         NOT_DECODED_YET("unknown choice extension");
1043                 } else {
1044                         guint32 new_offset;
1045
1046                         proto_item_set_text(choiceitem, choice[index].name);
1047                         new_offset=choice[index].func(tvb, offset, pinfo, choicetree);
1048
1049                         if((new_offset>(offset+(length*8)))||((new_offset+8)<(offset+length*8))){
1050 printf("new_offset:%d  offset:%d  length*8:%d\n",new_offset,offset,length*8);
1051 /*                              g_assert_not_reached();*/
1052                         }
1053
1054                         offset+=length*8;
1055                 }
1056                 proto_item_set_len(choiceitem, (offset>>3)!=(choice_offset>>3)?(offset>>3)-(choice_offset>>3):1);
1057         }
1058
1059         proto_item_set_len(it, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
1060         return offset;
1061 }
1062
1063
1064 static char *
1065 index_get_optional_name(per_sequence_t *sequence, int index)
1066 {
1067         int i;
1068
1069         for(i=0;sequence[i].name;i++){
1070                 if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1071                         if(index==0){
1072                                 return sequence[i].name;
1073                         }
1074                         index--;
1075                 }
1076         }
1077         return "<unknown type>";
1078 }
1079
1080 static char *
1081 index_get_extension_name(per_sequence_t *sequence, int index)
1082 {
1083         int i;
1084
1085         for(i=0;sequence[i].name;i++){
1086                 if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
1087                         if(index==0){
1088                                 return sequence[i].name;
1089                         }
1090                         index--;
1091                 }
1092         }
1093         return "<unknown type>";
1094 }
1095
1096 /* this functions decodes a SEQUENCE
1097    it can only handle SEQUENCES with at most 32 DEFAULT or OPTIONAL fields
1098 18.1 extension bit
1099 18.2 optinal/default items in root
1100 18.3 we ignore the case where n>64K
1101 18.4 the root sequence
1102            18.5
1103            18.6
1104            18.7
1105            18.8
1106            18.9
1107 */
1108 guint32
1109 dissect_per_sequence(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *parent_tree, int hf_index, gint ett_index, per_sequence_t *sequence)
1110 {
1111         gboolean extension_present, extension_flag, optional_field_flag;
1112         proto_item *item;
1113         proto_tree *tree;
1114         guint32 old_offset=offset;
1115         guint32 i, num_opts;
1116         guint32 optional_mask;
1117
1118
1119 DEBUG_ENTRY("dissect_per_sequence");
1120
1121         item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, FALSE);
1122         tree=proto_item_add_subtree(item, ett_index);
1123
1124
1125         /* first check if there should be an extension bit for this CHOICE.
1126            we do this by just checking the first choice arm
1127          */
1128         /* 18.1 */
1129         extension_flag=0;
1130         if(sequence[0].extension==ASN1_NO_EXTENSIONS){
1131                 extension_present=0;
1132         } else {
1133                 proto_tree *etr=NULL;
1134
1135                 if(display_internal_per_fields){
1136                         etr=tree;
1137                 }
1138                 extension_present=1;
1139                 offset=dissect_per_boolean(tvb, offset, pinfo, etr, hf_per_extension_bit, &extension_flag, NULL);
1140         }
1141         /* 18.2 */
1142         num_opts=0;
1143         for(i=0;sequence[i].name;i++){
1144                 if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1145                         num_opts++;
1146                 }
1147         }
1148
1149         optional_mask=0;
1150         for(i=0;i<num_opts;i++){
1151                 proto_item *it=NULL;
1152                 proto_tree *etr=NULL;
1153                 if(display_internal_per_fields){
1154                         etr=tree;
1155                 }
1156                 offset=dissect_per_boolean(tvb, offset, pinfo, etr, hf_per_optional_field_bit, &optional_field_flag, &it);
1157                 optional_mask<<=1;
1158                 if(optional_field_flag){
1159                         optional_mask|=0x01;
1160                 }
1161                 if(it){
1162                         proto_item_append_text(it, " (%s %s present)",
1163                                 index_get_optional_name(sequence, i),
1164                                 optional_field_flag?"is":"is NOT"
1165                                 );
1166                 }
1167         }
1168
1169
1170         /* 18.4 */
1171         for(i=0;sequence[i].name;i++){
1172                 if( (sequence[i].extension==ASN1_NO_EXTENSIONS)
1173                 ||  (sequence[i].extension==ASN1_EXTENSION_ROOT) ){
1174                         if(sequence[i].optional==ASN1_OPTIONAL){
1175                                 gboolean is_present;
1176                                 is_present=(1<<(num_opts-1))&optional_mask;
1177                                 num_opts--;
1178                                 if(!is_present){
1179                                         continue;
1180                                 }
1181                         }
1182                         if(sequence[i].func){
1183                                 offset=sequence[i].func(tvb, offset, pinfo, tree);
1184                         } else {
1185                                 NOT_DECODED_YET(sequence[i].name);
1186                         }
1187                 }
1188         }
1189
1190
1191         if(extension_flag){
1192                 gboolean extension_bit;
1193                 guint32 num_known_extensions;
1194                 guint32 num_extensions;
1195                 guint32 extension_mask;
1196                 proto_tree *etr=NULL;
1197                 proto_item *it=NULL;
1198
1199                 if(display_internal_per_fields){
1200                         etr=tree;
1201                 }
1202
1203                 offset=dissect_per_normally_small_nonnegative_whole_number(tvb, offset, pinfo, etr, hf_per_num_sequence_extensions, &num_extensions);
1204                 /* the X.691 standard is VERY unclear here.
1205                    there is no mention that the lower bound lb for this
1206                    (apparently) semiconstrained value is 1,
1207                    apart from the NOTE: comment in 18.8 that this value can
1208                    not be 0.
1209                    In my book, there is a semantic difference between having
1210                    a comment that says that the value can not be zero
1211                    and stating that the lb is 1.
1212                    I dont know if this is right or not but it makes
1213                    some of the very few captures I have decode properly.
1214
1215                    It could also be that the captures I have are generated by
1216                    a broken implementation.
1217                    If this is wrong and you dont report it as a bug
1218                    then it wont get fixed!
1219                 */
1220                 num_extensions+=1;
1221
1222                 extension_mask=0;
1223                 for(i=0;i<num_extensions;i++){
1224                         offset=dissect_per_boolean(tvb, offset, pinfo, etr, hf_per_extension_present_bit, &extension_bit, &it);
1225                         extension_mask=(extension_mask<<1)|extension_bit;
1226                         if(it){
1227                                 proto_item_append_text(it, " (%s %s present)",
1228                                         index_get_extension_name(sequence, i),
1229                                         extension_bit?"is":"is NOT"
1230                                         );
1231                         }
1232
1233                 }
1234
1235                 /* find how many extensions we know about */
1236                 num_known_extensions=0;
1237                 for(i=0;sequence[i].name;i++){
1238                         if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
1239                                 num_known_extensions++;
1240                         }
1241                 }
1242
1243                 /* decode the extensions one by one */
1244                 for(i=0;i<num_extensions;i++){
1245                         guint32 length;
1246                         guint32 new_offset;
1247                         guint32 extension_index;
1248                         guint32 j,k;
1249
1250                         if(!((1L<<(num_extensions-1-i))&extension_mask)){
1251                                 /* this extension is not encoded in this PDU */
1252                                 continue;
1253                         }
1254
1255                         offset=dissect_per_length_determinant(tvb, offset, pinfo, etr, hf_per_open_type_length, &length);
1256
1257                         if(i>=num_known_extensions){
1258                                 /* we dont know how to decode this extension */
1259                                 offset+=length*8;
1260                                 NOT_DECODED_YET("unknown sequence extension");
1261                                 continue;
1262                         }
1263
1264                         extension_index=0;
1265                         for(j=0,k=0;sequence[j].name;j++){
1266                                 if(sequence[j].extension==ASN1_NOT_EXTENSION_ROOT){
1267                                         if(k==i){
1268                                                 extension_index=j;
1269                                                 break;
1270                                         }
1271                                         k++;
1272                                 }
1273                         }
1274
1275                         if(sequence[extension_index].func){
1276                                 new_offset=sequence[extension_index].func(tvb, offset, pinfo, tree);
1277                         } else {
1278                                 NOT_DECODED_YET(sequence[extension_index].name);
1279                         }
1280                         offset+=length*8;
1281
1282                 }
1283         }
1284
1285
1286         proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
1287         return offset;
1288 }
1289
1290
1291
1292
1293
1294 /* this fucntion dissects an OCTET STRING
1295         16.1
1296         16.2
1297         16.3
1298         16.4
1299         16.5
1300         16.6
1301         16.7
1302         16.8
1303
1304    max_len or min_len == -1 means there is no lower/upper constraint
1305
1306    hf_index can either be a FT_BYTES or an FT_STRING
1307 */
1308 guint32
1309 dissect_per_octet_string(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, int min_len, int max_len, guint32 *value_offset, guint32 *value_len)
1310 {
1311         guint32 length;
1312         header_field_info *hfi;
1313
1314         hfi = (hf_index==-1) ? NULL : proto_registrar_get_nth(hf_index);
1315
1316 DEBUG_ENTRY("dissect_per_octet_string");
1317         /* 16.5 if the length is 0 bytes there will be no encoding */
1318         if(max_len==0){
1319                 return offset;
1320         }
1321
1322
1323         if(min_len==-1){
1324                 min_len=0;
1325         }
1326
1327         /* 16.6 if length is fixed and less than or equal to two bytes*/
1328         if((min_len==max_len)&&(max_len<=2)){
1329                 static char bytes[4];
1330                 guint32 i, old_offset=offset;
1331                 gboolean bit;
1332
1333                 for(i=0;i<8;i++){
1334                         offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &bit, NULL);
1335                         bytes[0]=(bytes[0]<<1)|bit;
1336                 }
1337                 if(min_len==2){
1338                         for(i=0;i<8;i++){
1339                                 offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &bit, NULL);
1340                                 bytes[1]=(bytes[1]<<1)|bit;
1341                         }
1342                 }
1343                 bytes[min_len]=0;
1344                 if (hfi) {
1345                         if(hfi->type==FT_STRING){
1346                                 proto_tree_add_string(tree, hf_index, tvb, old_offset>>3, min_len+(offset&0x07)?1:0, bytes);
1347                         } else {
1348                                 proto_tree_add_bytes(tree, hf_index, tvb, old_offset>>3, min_len+(offset&0x07)?1:0, bytes);
1349                         }
1350                 }
1351                 if (value_offset) {
1352                         *value_offset = old_offset>>3;
1353                 }
1354                 if (value_len) {
1355                         *value_len = min_len+(offset&0x07)?1:0;
1356                 }
1357                 return offset;
1358         }
1359
1360
1361         /* 16.7 if length is fixed and less than to 64k*/
1362         if((min_len==max_len)&&(min_len<65536)){
1363                 /* align to byte */
1364                 if(offset&0x07){
1365                         offset=(offset&0xfffffff8)+8;
1366                 }
1367                 if (hfi) {
1368                         proto_tree_add_item(tree, hf_index, tvb, offset>>3, min_len, FALSE);
1369                 }
1370                 if (value_offset) {
1371                         *value_offset = offset>>3;
1372                 }
1373                 if (value_len) {
1374                         *value_len = min_len;
1375                 }
1376                 offset+=min_len*8;
1377                 return offset;
1378         }
1379
1380         /* 16.8 */
1381         if(max_len>0){
1382                 proto_tree *etr = NULL;
1383
1384                 if(display_internal_per_fields){
1385                         etr=tree;
1386                 }
1387                 offset=dissect_per_constrained_integer(tvb, offset, pinfo,
1388                         etr, hf_per_octet_string_length, min_len, max_len,
1389                         &length, NULL, FALSE);
1390         } else {
1391                 offset=dissect_per_length_determinant(tvb, offset, pinfo, tree, hf_per_octet_string_length, &length);
1392         }
1393         if(length){
1394                 /* align to byte */
1395                 if(offset&0x07){
1396                         offset=(offset&0xfffffff8)+8;
1397                 }
1398                 if (hfi) {
1399                         proto_tree_add_item(tree, hf_index, tvb, offset>>3, length, FALSE);
1400                 }
1401         }
1402         if (value_offset) {
1403                 *value_offset = offset>>3;
1404         }
1405         if (value_len) {
1406                 *value_len = length;
1407         }
1408         offset+=length*8;
1409
1410         return offset;
1411 }
1412
1413
1414
1415 void
1416 proto_register_per(void)
1417 {
1418         static hf_register_info hf[] =
1419         {
1420         { &hf_per_num_sequence_extensions,
1421                 { "Number of Sequence Extensions", "per.num_sequence_extensions", FT_UINT32, BASE_DEC,
1422                 NULL, 0, "Number of extensions encoded in this sequence", HFILL }},
1423         { &hf_per_choice_extension,
1424                 { "Choice Extension", "per.choice_extension", FT_UINT32, BASE_DEC,
1425                 NULL, 0, "Which extension of the Choice is encoded", HFILL }},
1426         { &hf_per_GeneralString_length,
1427                 { "GeneralString Length", "per.generalstring_length", FT_UINT32, BASE_DEC,
1428                 NULL, 0, "Length of the GeneralString", HFILL }},
1429         { &hf_per_extension_bit,
1430                 { "Extension Bit", "per.extension_bit", FT_BOOLEAN, 8,
1431                 TFS(&tfs_extension_bit), 0x01, "The extension bit of an aggregate", HFILL }},
1432         { &hf_per_extension_present_bit,
1433                 { "Extension Present Bit", "per.extension_present_bit", FT_BOOLEAN, 8,
1434                 TFS(&tfs_extension_present_bit), 0x01, "Whether this optional extension is present or not", HFILL }},
1435         { &hf_per_small_number_bit,
1436                 { "Small Number Bit", "per.small_number_bit", FT_BOOLEAN, 8,
1437                 TFS(&tfs_small_number_bit), 0x01, "The small number bit for a section 10.6 integer", HFILL }},
1438         { &hf_per_optional_field_bit,
1439                 { "Optional Field Bit", "per.optional_field_bit", FT_BOOLEAN, 8,
1440                 TFS(&tfs_optional_field_bit), 0x01, "This bit specifies the presence/absence of an optional field", HFILL }},
1441         { &hf_per_sequence_of_length,
1442                 { "Sequence-Of Length", "per.sequence_of_length", FT_UINT32, BASE_DEC,
1443                 NULL, 0, "Number of items in the Sequence Of", HFILL }},
1444         { &hf_per_object_identifier_length,
1445                 { "Object Length", "per.object_length", FT_UINT32, BASE_DEC,
1446                 NULL, 0, "Length of the object identifier", HFILL }},
1447         { &hf_per_open_type_length,
1448                 { "Open Type Length", "per.open_type_length", FT_UINT32, BASE_DEC,
1449                 NULL, 0, "Length of an open type encoding", HFILL }},
1450         { &hf_per_octet_string_length,
1451                 { "Octet String Length", "per.octet_string_length", FT_UINT32, BASE_DEC,
1452                 NULL, 0, "Number of bytes in the Octet String", HFILL }},
1453         };
1454
1455         static gint *ett[] =
1456         {
1457                 &ett_per_sequence_of_item
1458         };
1459         module_t *per_module;
1460
1461         proto_per = proto_register_protocol("Packed Encoding Rules (ASN.1 X.691)", "PER", "per");
1462         proto_register_field_array(proto_per, hf, array_length(hf));
1463         proto_register_subtree_array(ett, array_length(ett));
1464
1465         per_module = prefs_register_protocol(proto_per, NULL);
1466         prefs_register_bool_preference(per_module, "display_internal_per_fields",
1467                 "Display the internal PER fields in the tree",
1468                 "Whether the dissector should put the internal PER data in the tree or if it should hide it",
1469                 &display_internal_per_fields);
1470
1471 }
1472
1473 void
1474 proto_reg_handoff_per(void)
1475 {
1476 }
1477