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