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
7 * Routines for dissection of ASN.1 Aligned PER
10 * $Id: packet-per.c,v 1.28 2004/05/17 20:03:36 sahlberg Exp $
12 * Ethereal - Network traffic analyzer
13 * By Gerald Combs <gerald@ethereal.com>
14 * Copyright 1998 Gerald Combs
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
36 #include <epan/packet.h>
42 #include "packet-per.h"
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;
59 static gint ett_per_sequence_of_item = -1;
63 #define DEBUG_ENTRY(x) \
64 printf("#%d %s tvb:0x%08x\n",pinfo->fd->num,x,(int)tvb);
66 #define DEBUG_ENTRY(x) \
71 /* whether the PER helpers should put the internal PER fields into the tree
74 static guint display_internal_per_fields = FALSE;
78 static const true_false_string tfs_extension_present_bit = {
82 static const true_false_string tfs_extension_bit = {
83 "Extension bit is set",
84 "Extension bit is clear"
86 static const true_false_string tfs_small_number_bit = {
87 "The number is small, 0-63",
88 "The number is large, >63"
90 static const true_false_string tfs_optional_field_bit = {
99 /* this decodes and returns a length determinant according to 10.9 */
101 dissect_per_length_determinant(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index, guint32 *length)
112 offset=(offset&0xfffffff8)+8;
114 byte=tvb_get_guint8(tvb, offset>>3);
120 proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
124 if((byte&0xc0)==0x80){
126 *length=((*length)<<8)+tvb_get_guint8(tvb, offset>>3);
129 proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-2, 2, *length);
133 PER_NOT_DECODED_YET("10.9.3.8.1");
137 /* 10.6 normally small non-negative whole number */
139 dissect_per_normally_small_nonnegative_whole_number(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, guint32 *length)
141 gboolean small_number;
144 DEBUG_ENTRY("dissect_per_normally_small_nonnegative_whole_number");
149 offset=dissect_per_boolean(tvb, offset, pinfo, tree, hf_per_small_number_bit, &small_number, NULL);
155 offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &small_number, NULL);
163 proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
165 proto_tree_add_uint(tree, hf_index, tvb, (offset>>3), 1, *length);
172 offset=dissect_per_length_determinant(tvb, offset, pinfo, tree, hf_index, length);
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.
184 based on pure guesswork. it looks ok in the only capture i have where
185 there is a 1 byte general string encoded
188 dissect_per_GeneralString(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index)
190 proto_tree *etr=NULL;
193 if(display_internal_per_fields){
197 offset=dissect_per_length_determinant(tvb, offset, pinfo, etr, hf_per_GeneralString_length, &length);
200 proto_tree_add_item(tree, hf_index, tvb, offset>>3, length, FALSE);
207 /* 19 this function dissects a sequence of */
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)
213 DEBUG_ENTRY("dissect_per_sequence_of_helper");
214 for(i=0;i<length;i++){
215 guint32 lold_offset=offset;
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);
222 offset=(*func)(tvb, offset, pinfo, ltree);
223 proto_item_set_len(litem, (offset>>3)!=(lold_offset>>3)?(offset>>3)-(lold_offset>>3):1);
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 *))
233 guint32 old_offset=offset;
235 proto_tree *etr = NULL;
237 DEBUG_ENTRY("dissect_per_sequence_of");
239 item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, FALSE);
240 tree=proto_item_add_subtree(item, ett_index);
242 /* semi-constrained whole number for number of elements */
243 /* each element encoded as 10.9 */
245 if(display_internal_per_fields){
248 offset=dissect_per_length_determinant(tvb, offset, pinfo, etr, hf_per_sequence_of_length, &length);
250 offset=dissect_per_sequence_of_helper(tvb, offset, pinfo, tree, func, length);
253 proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
258 /* dissect a constrained IA5String that consists of the full ASCII set,
259 i.e. no FROM stuff limiting the alphabet
262 dissect_per_IA5String(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, int min_len, int max_len)
264 offset=dissect_per_octet_string(tvb, offset, pinfo, tree, hf_index, min_len, max_len, NULL, NULL);
269 /* XXX we dont do >64k length strings yet */
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)
274 gboolean byte_aligned;
275 static char str[1024];
280 DEBUG_ENTRY("dissect_per_restricted_character_string");
281 /* xx.x if the length is 0 bytes there will be no encoding */
294 if(min_len!=max_len){
295 proto_tree *etr = NULL;
297 if(display_internal_per_fields){
300 offset=dissect_per_constrained_integer(tvb, offset, pinfo,
301 etr, hf_per_octet_string_length, min_len, max_len,
302 &length, NULL, FALSE);
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. */
309 if((min_len==max_len)&&(max_len<=2)){
316 /* there is no string at all, so dont do any byte alignment */
322 offset=(offset&0xfffffff8)+8;
328 PER_NOT_DECODED_YET("restricted char string too long");
332 /* 27.5.2 depending of the alphabet length, find how many bits
333 are used to encode each character */
335 if(alphabet_length<=2){
337 } else if(alphabet_length<=4){
339 } else if(alphabet_length<=8){
341 } else if(alphabet_length<=16){
343 } else if(alphabet_length<=32){
345 } else if(alphabet_length<=64){
347 } else if(alphabet_length<=128){
353 if(alphabet_length<=2){
355 } else if(alphabet_length<=4){
357 } else if(alphabet_length<=16){
364 for(char_pos=0;char_pos<length;char_pos++){
370 for(i=0;i<bits_per_char;i++){
371 offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &bit, NULL);
374 if (val >= alphabet_length)
375 str[char_pos] = '?'; /* XXX - how to mark this? */
377 str[char_pos]=alphabet[val];
380 proto_tree_add_string(tree, hf_index, tvb, (old_offset>>3), (offset>>3)-(old_offset>>3), str);
385 dissect_per_NumericString(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, int min_len, int max_len)
387 offset=dissect_per_restricted_character_string(tvb, offset, pinfo, tree, hf_index, min_len, max_len, " 0123456789", 11);
392 dissect_per_PrintableString(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, int min_len, int max_len)
394 offset=dissect_per_restricted_character_string(tvb, offset, pinfo, tree, hf_index, min_len, max_len, " '()+,-.*0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 74);
398 dissect_per_BMPString(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, int min_len, int max_len)
403 /* xx.x if the length is 0 bytes there will be no encoding */
416 if(min_len!=max_len){
417 proto_tree *etr = NULL;
419 if(display_internal_per_fields){
422 offset=dissect_per_constrained_integer(tvb, offset, pinfo,
423 etr, hf_per_octet_string_length, min_len, max_len,
424 &length, NULL, FALSE);
428 /* align to byte boundary */
430 offset=(offset&0xfffffff8)+8;
434 PER_NOT_DECODED_YET("BMPString too long");
438 str = tvb_fake_unicode(tvb, offset>>3, length, FALSE);
440 proto_tree_add_string(tree, hf_index, tvb, offset>>3, length*2, str);
442 offset+=(length<<3)*2;
448 /* this function dissects a constrained sequence of */
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)
454 guint32 old_offset=offset;
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);
462 /* 19.5 if min==max and min,max<64k ==> no length determinant */
463 if((min_len==max_len) && (min_len<65536)){
468 /* 19.6 ub>=64k or unset */
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);
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);
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);
487 offset=dissect_per_sequence_of_helper(tvb, offset, pinfo, tree, func, length);
490 proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
494 /* this function dissects a constrained set of */
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)
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);
509 /* this function dissects a set of */
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 *))
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);
522 /* this function reads a OBJECT IDENTIFIER */
524 dissect_per_object_identifier(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index, char *value_string)
530 proto_tree *etr=NULL;
532 DEBUG_ENTRY("dissect_per_object_identifier");
534 if(display_internal_per_fields){
538 /* first byte is the count and it is byte aligned */
540 offset=(offset&0xfffffff8)+8;
542 count=tvb_get_guint8(tvb, offset>>3);
545 proto_tree_add_uint(etr, hf_per_object_identifier_length, tvb, offset>>3, 1, count);
549 for(i=0,strp=str;i<count;i++){
550 byte=tvb_get_guint8(tvb,offset>>3);
554 PER_NOT_DECODED_YET("too long octet_string");
560 /* the first byte contains the first two object identifier components */
562 strp+=sprintf(strp,"0.%d",byte);
564 strp+=sprintf(strp,"1.%d",byte-40);
566 strp+=sprintf(strp,"2.%d",byte-80);
571 value=(value<<7)|(byte&0x7f);
576 strp+=sprintf(strp,".%d",value);
581 proto_tree_add_string(tree, hf_index, tvb, (offset>>3)-count, count, str);
584 strcpy(value_string, str);
593 /* this function reads a single bit */
595 dissect_per_boolean(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index, gboolean *bool, proto_item **item)
599 header_field_info *hfi;
602 DEBUG_ENTRY("dissect_per_boolean");
604 ch=tvb_get_guint8(tvb, offset>>3);
605 mask=1<<(7-(offset&0x07));
613 hfi = proto_registrar_get_nth(hf_index);
614 sprintf(str,"%s: %c%c%c%c %c%c%c%c %s",
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:'.',
626 it=proto_tree_add_boolean_format(tree, hf_index, tvb, offset>>3, 1, value, str);
641 /* we currently only handle integers up to 32 bits in length. */
643 dissect_per_integer(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, proto_tree *tree, int hf_index, gint32 *value, proto_item **item)
650 offset=dissect_per_length_determinant(tvb, offset, pinfo, tree, -1, &length);
653 PER_NOT_DECODED_YET("too long integer");
658 for(i=0;i<length;i++){
660 if(tvb_get_guint8(tvb, offset>>3)&0x80){
661 /* negative number */
664 /* positive number */
668 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
671 it=proto_tree_add_int(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
684 /* this function reads a constrained integer with or without a
685 PER visible extension marker present
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)
692 it only handles integers that fit inside a 32 bit integer
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
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)
710 header_field_info *hfi;
715 DEBUG_ENTRY("dissect_per_constrained_integer");
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,
727 hfi = proto_registrar_get_nth(hf_index);
731 /* just set range really big so it will fall through
732 to the bottom of the encoding */
743 it=proto_tree_add_uint_format(tree, hf_index, tvb, offset>>3, 0, min, "%s: %d", hfi->name, min);
766 } else if(range<=16){
768 } else if(range<=32){
770 } else if(range<=64){
772 } else if(range<=128){
774 } else if(range<=256){
777 /* prepare the string */
778 sprintf(str, "%s: ", hfi->name);
779 for(bit=0;bit<((int)(offset&0x07));bit++){
785 /* read the bits for the int */
786 for(i=0;i<num_bits;i++){
795 offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &tmp, NULL);
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);
814 it=proto_tree_add_uint(tree, hf_index, tvb, (offset-num_bits)>>3, length, val);
823 } else if(range==256){
828 /* in the aligned case, align to byte boundary */
830 offset=(offset&0xfffffff8)+8;
832 val=tvb_get_guint8(tvb, offset>>3);
836 it=proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, val);
844 } else if(range<=65536){
849 /* in the aligned case, align to byte boundary */
851 offset=(offset&0xfffffff8)+8;
853 val=tvb_get_guint8(tvb, offset>>3);
856 val|=tvb_get_guint8(tvb, offset>>3);
860 it=proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-2, 2, val);
874 offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &bit, NULL);
876 offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &bit, NULL);
877 num_bytes=(num_bytes<<1)|bit;
879 num_bytes++; /* lower bound for length determinant is 1 */
883 offset=(offset&0xfffffff8)+8;
886 for(i=0;i<num_bytes;i++){
887 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
891 it=proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-(num_bytes+1), num_bytes+1, val);
901 PER_NOT_DECODED_YET("10.5");
905 /* this functions decodes a CHOICE
906 it can only handle CHOICE INDEX values that fits inside a 32 bit integer.
913 22.7 extension marker == 0
914 22.8 extension marker == 1
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)
919 gboolean extension_present, extension_flag;
920 int extension_root_entries;
921 guint32 choice_index;
925 guint32 old_offset=offset;
926 int min_choice=INT_MAX;
929 DEBUG_ENTRY("dissect_per_choice");
931 it=proto_tree_add_text(tree, tvb, offset>>3, 0, name);
932 tr=proto_item_add_subtree(it, ett_index);
935 /* first check if there should be an extension bit for this CHOICE.
936 we do this by just checking the first choice arm
938 if(choice[0].extension==ASN1_NO_EXTENSIONS){
941 proto_tree *etr=NULL;
943 if(display_internal_per_fields){
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);
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;
960 if(choice[i].value>max_choice){
961 max_choice=choice[i].value;
963 extension_root_entries++;
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;
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);
985 choicetree=proto_item_add_subtree(choiceitem, ett_index);
987 if(display_internal_per_fields){
991 /* find and call the appropriate callback */
992 for(i=0;choice[i].name;i++){
993 if(choice[i].value==(int)choice_index){
995 offset=choice[i].func(tvb, offset, pinfo, choicetree);
998 PER_NOT_DECODED_YET(choice[i].name);
1003 proto_item_set_len(choiceitem, (offset>>3)!=(choice_offset>>3)?(offset>>3)-(choice_offset>>3):1);
1007 guint32 choice_offset;
1008 proto_tree *choicetree;
1009 proto_item *choiceitem;
1010 proto_tree *etr=NULL;
1012 if(display_internal_per_fields){
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);
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);
1026 for(i=0;choice[i].name;i++){
1027 if(choice[i].extension==ASN1_NOT_EXTENSION_ROOT){
1043 /* if we dont know how to decode this one, just step offset to the next structure */
1045 PER_NOT_DECODED_YET("unknown choice extension");
1049 proto_item_set_text(choiceitem, choice[index].name);
1050 new_offset=choice[index].func(tvb, offset, pinfo, choicetree);
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();*/
1059 proto_item_set_len(choiceitem, (offset>>3)!=(choice_offset>>3)?(offset>>3)-(choice_offset>>3):1);
1062 proto_item_set_len(it, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
1068 index_get_optional_name(per_sequence_t *sequence, int index)
1072 for(i=0;sequence[i].name;i++){
1073 if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1075 return sequence[i].name;
1080 return "<unknown type>";
1084 index_get_extension_name(per_sequence_t *sequence, int index)
1088 for(i=0;sequence[i].name;i++){
1089 if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
1091 return sequence[i].name;
1096 return "<unknown type>";
1099 /* this functions decodes a SEQUENCE
1100 it can only handle SEQUENCES with at most 32 DEFAULT or OPTIONAL fields
1102 18.2 optinal/default items in root
1103 18.3 we ignore the case where n>64K
1104 18.4 the root sequence
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)
1114 gboolean extension_present, extension_flag, optional_field_flag;
1117 guint32 old_offset=offset;
1118 guint32 i, num_opts;
1119 guint32 optional_mask;
1122 DEBUG_ENTRY("dissect_per_sequence");
1124 item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, FALSE);
1125 tree=proto_item_add_subtree(item, ett_index);
1128 /* first check if there should be an extension bit for this CHOICE.
1129 we do this by just checking the first choice arm
1133 if(sequence[0].extension==ASN1_NO_EXTENSIONS){
1134 extension_present=0;
1136 proto_tree *etr=NULL;
1138 if(display_internal_per_fields){
1141 extension_present=1;
1142 offset=dissect_per_boolean(tvb, offset, pinfo, etr, hf_per_extension_bit, &extension_flag, NULL);
1146 for(i=0;sequence[i].name;i++){
1147 if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1153 for(i=0;i<num_opts;i++){
1154 proto_item *it=NULL;
1155 proto_tree *etr=NULL;
1156 if(display_internal_per_fields){
1159 offset=dissect_per_boolean(tvb, offset, pinfo, etr, hf_per_optional_field_bit, &optional_field_flag, &it);
1161 if(optional_field_flag){
1162 optional_mask|=0x01;
1165 proto_item_append_text(it, " (%s %s present)",
1166 index_get_optional_name(sequence, i),
1167 optional_field_flag?"is":"is NOT"
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;
1185 if(sequence[i].func){
1186 offset=sequence[i].func(tvb, offset, pinfo, tree);
1188 PER_NOT_DECODED_YET(sequence[i].name);
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;
1202 if(display_internal_per_fields){
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
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.
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!
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;
1230 proto_item_append_text(it, " (%s %s present)",
1231 index_get_extension_name(sequence, i),
1232 extension_bit?"is":"is NOT"
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++;
1246 /* decode the extensions one by one */
1247 for(i=0;i<num_extensions;i++){
1250 guint32 extension_index;
1253 if(!((1L<<(num_extensions-1-i))&extension_mask)){
1254 /* this extension is not encoded in this PDU */
1258 offset=dissect_per_length_determinant(tvb, offset, pinfo, etr, hf_per_open_type_length, &length);
1260 if(i>=num_known_extensions){
1261 /* we dont know how to decode this extension */
1263 PER_NOT_DECODED_YET("unknown sequence extension");
1268 for(j=0,k=0;sequence[j].name;j++){
1269 if(sequence[j].extension==ASN1_NOT_EXTENSION_ROOT){
1278 if(sequence[extension_index].func){
1279 new_offset=sequence[extension_index].func(tvb, offset, pinfo, tree);
1281 PER_NOT_DECODED_YET(sequence[extension_index].name);
1289 proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
1295 /* 15 Encoding the bitstring type
1297 max_len or min_len == -1 means there is no lower/upper constraint
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)
1304 header_field_info *hfi;
1306 hfi = (hf_index==-1) ? NULL : proto_registrar_get_nth(hf_index);
1308 DEBUG_ENTRY("dissect_per_bit_string");
1309 /* 15.8 if the length is 0 bytes there will be no encoding */
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];
1322 guint32 old_offset=offset;
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;
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;
1336 bytes[1]|=bytes[0]<<(min_len-8);
1337 bytes[0]>>=16-min_len;
1341 proto_tree_add_bytes(tree, hf_index, tvb, old_offset>>3, (min_len+7)/8+(offset&0x07)?1:0, bytes);
1347 /* 15.10 if length is fixed and less than to 64kbits*/
1348 if((min_len==max_len)&&(min_len<65536)){
1351 offset=(offset&0xfffffff8)+8;
1354 proto_tree_add_item(tree, hf_index, tvb, offset>>3, (min_len+7)/8, FALSE);
1362 proto_tree *etr = NULL;
1364 if(display_internal_per_fields){
1367 offset=dissect_per_constrained_integer(tvb, offset, pinfo,
1368 etr, hf_per_bit_string_length, min_len, max_len,
1369 &length, NULL, FALSE);
1371 offset=dissect_per_length_determinant(tvb, offset, pinfo, tree, hf_per_bit_string_length, &length);
1376 offset=(offset&0xfffffff8)+8;
1379 proto_tree_add_item(tree, hf_index, tvb, offset>>3, (length+7)/8, FALSE);
1388 /* this fucntion dissects an OCTET STRING
1398 max_len or min_len == -1 means there is no lower/upper constraint
1400 hf_index can either be a FT_BYTES or an FT_STRING
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)
1406 header_field_info *hfi;
1408 hfi = (hf_index==-1) ? NULL : proto_registrar_get_nth(hf_index);
1410 DEBUG_ENTRY("dissect_per_octet_string");
1411 /* 16.5 if the length is 0 bytes there will be no encoding */
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;
1428 offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &bit, NULL);
1429 bytes[0]=(bytes[0]<<1)|bit;
1433 offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &bit, NULL);
1434 bytes[1]=(bytes[1]<<1)|bit;
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);
1442 proto_tree_add_bytes(tree, hf_index, tvb, old_offset>>3, min_len+(offset&0x07)?1:0, bytes);
1446 *value_offset = old_offset>>3;
1449 *value_len = min_len+(offset&0x07)?1:0;
1455 /* 16.7 if length is fixed and less than to 64k*/
1456 if((min_len==max_len)&&(min_len<65536)){
1459 offset=(offset&0xfffffff8)+8;
1462 proto_tree_add_item(tree, hf_index, tvb, offset>>3, min_len, FALSE);
1465 *value_offset = offset>>3;
1468 *value_len = min_len;
1476 proto_tree *etr = NULL;
1478 if(display_internal_per_fields){
1481 offset=dissect_per_constrained_integer(tvb, offset, pinfo,
1482 etr, hf_per_octet_string_length, min_len, max_len,
1483 &length, NULL, FALSE);
1485 offset=dissect_per_length_determinant(tvb, offset, pinfo, tree, hf_per_octet_string_length, &length);
1490 offset=(offset&0xfffffff8)+8;
1493 proto_tree_add_item(tree, hf_index, tvb, offset>>3, length, FALSE);
1497 *value_offset = offset>>3;
1500 *value_len = length;
1510 proto_register_per(void)
1512 static hf_register_info hf[] =
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 }},
1552 static gint *ett[] =
1554 &ett_per_sequence_of_item
1556 module_t *per_module;
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));
1562 proto_set_cant_toggle(proto_per);
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);
1573 proto_reg_handoff_per(void)