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