diff options
author | Bill Meier <wmeier@newsguy.com> | 2012-04-23 17:43:56 +0000 |
---|---|---|
committer | Bill Meier <wmeier@newsguy.com> | 2012-04-23 17:43:56 +0000 |
commit | 159901cd1596b29a113272e1765a9c400fa62ad6 (patch) | |
tree | 18b8d628e1e91426f1d4aeeda5c6ded057e6c90a /epan | |
parent | 8819fa284ce875978a92d2f9cbc879dd9e2db130 (diff) | |
download | wireshark-159901cd1596b29a113272e1765a9c400fa62ad6.tar.gz |
Use consistent indentation;
Use #if 0/#endif to comment out some code (rather than /* ... */
svn path=/trunk/; revision=42212
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-ber.c | 7371 |
1 files changed, 3690 insertions, 3681 deletions
diff --git a/epan/dissectors/packet-ber.c b/epan/dissectors/packet-ber.c index 4607d38a30..7b9cf043cd 100644 --- a/epan/dissectors/packet-ber.c +++ b/epan/dissectors/packet-ber.c @@ -172,84 +172,84 @@ static guint32 last_length; static gboolean last_ind; static const value_string ber_class_codes[] = { - { BER_CLASS_UNI, "UNIVERSAL" }, - { BER_CLASS_APP, "APPLICATION" }, - { BER_CLASS_CON, "CONTEXT" }, - { BER_CLASS_PRI, "PRIVATE" }, - { 0, NULL } + { BER_CLASS_UNI, "UNIVERSAL" }, + { BER_CLASS_APP, "APPLICATION" }, + { BER_CLASS_CON, "CONTEXT" }, + { BER_CLASS_PRI, "PRIVATE" }, + { 0, NULL } }; static const true_false_string ber_pc_codes = { - "Constructed Encoding", - "Primitive Encoding" + "Constructed Encoding", + "Primitive Encoding" }; static const true_false_string ber_pc_codes_short = { - "constructed", - "primitive" + "constructed", + "primitive" }; static const value_string ber_uni_tag_codes[] = { - { BER_UNI_TAG_EOC, "'end-of-content'" }, - { BER_UNI_TAG_BOOLEAN, "BOOLEAN" }, - { BER_UNI_TAG_INTEGER, "INTEGER" }, - { BER_UNI_TAG_BITSTRING, "BIT STRING" }, - { BER_UNI_TAG_OCTETSTRING, "OCTET STRING" }, - { BER_UNI_TAG_NULL, "NULL" }, - { BER_UNI_TAG_OID, "OBJECT IDENTIFIER" }, - { BER_UNI_TAG_ObjectDescriptor, "ObjectDescriptor" }, - { BER_UNI_TAG_EXTERNAL, "EXTERNAL" }, - { BER_UNI_TAG_REAL, "REAL" }, - { BER_UNI_TAG_ENUMERATED, "ENUMERATED" }, - { BER_UNI_TAG_EMBEDDED_PDV, "EMBEDDED PDV" }, - { BER_UNI_TAG_UTF8String, "UTF8String" }, - { BER_UNI_TAG_RELATIVE_OID, "RELATIVE-OID" }, - /* UNIVERSAL 14-15 - * Reserved for future editions of this - * Recommendation | International Standard - */ - { 14, "Reserved for future editions" }, - { 15 , "Reserved for future editions" }, - - { BER_UNI_TAG_SEQUENCE, "SEQUENCE" }, - { BER_UNI_TAG_SET, "SET" }, - { BER_UNI_TAG_NumericString, "NumericString" }, - { BER_UNI_TAG_PrintableString, "PrintableString" }, - { BER_UNI_TAG_TeletexString, "TeletexString, T61String" }, - { BER_UNI_TAG_VideotexString, "VideotexString" }, - { BER_UNI_TAG_IA5String, "IA5String" }, - { BER_UNI_TAG_UTCTime, "UTCTime" }, - { BER_UNI_TAG_GeneralizedTime, "GeneralizedTime" }, - { BER_UNI_TAG_GraphicString, "GraphicString" }, - { BER_UNI_TAG_VisibleString, "VisibleString, ISO64String" }, - { BER_UNI_TAG_GeneralString, "GeneralString" }, - { BER_UNI_TAG_UniversalString, "UniversalString" }, - { BER_UNI_TAG_CHARACTERSTRING, "CHARACTER STRING" }, - { BER_UNI_TAG_BMPString, "BMPString" }, - { 31, "Continued" }, - { 0, NULL } + { BER_UNI_TAG_EOC, "'end-of-content'" }, + { BER_UNI_TAG_BOOLEAN, "BOOLEAN" }, + { BER_UNI_TAG_INTEGER, "INTEGER" }, + { BER_UNI_TAG_BITSTRING, "BIT STRING" }, + { BER_UNI_TAG_OCTETSTRING, "OCTET STRING" }, + { BER_UNI_TAG_NULL, "NULL" }, + { BER_UNI_TAG_OID, "OBJECT IDENTIFIER" }, + { BER_UNI_TAG_ObjectDescriptor, "ObjectDescriptor" }, + { BER_UNI_TAG_EXTERNAL, "EXTERNAL" }, + { BER_UNI_TAG_REAL, "REAL" }, + { BER_UNI_TAG_ENUMERATED, "ENUMERATED" }, + { BER_UNI_TAG_EMBEDDED_PDV, "EMBEDDED PDV" }, + { BER_UNI_TAG_UTF8String, "UTF8String" }, + { BER_UNI_TAG_RELATIVE_OID, "RELATIVE-OID" }, + /* UNIVERSAL 14-15 + * Reserved for future editions of this + * Recommendation | International Standard + */ + { 14, "Reserved for future editions" }, + { 15 , "Reserved for future editions" }, + + { BER_UNI_TAG_SEQUENCE, "SEQUENCE" }, + { BER_UNI_TAG_SET, "SET" }, + { BER_UNI_TAG_NumericString, "NumericString" }, + { BER_UNI_TAG_PrintableString, "PrintableString" }, + { BER_UNI_TAG_TeletexString, "TeletexString, T61String" }, + { BER_UNI_TAG_VideotexString, "VideotexString" }, + { BER_UNI_TAG_IA5String, "IA5String" }, + { BER_UNI_TAG_UTCTime, "UTCTime" }, + { BER_UNI_TAG_GeneralizedTime, "GeneralizedTime" }, + { BER_UNI_TAG_GraphicString, "GraphicString" }, + { BER_UNI_TAG_VisibleString, "VisibleString, ISO64String" }, + { BER_UNI_TAG_GeneralString, "GeneralString" }, + { BER_UNI_TAG_UniversalString, "UniversalString" }, + { BER_UNI_TAG_CHARACTERSTRING, "CHARACTER STRING" }, + { BER_UNI_TAG_BMPString, "BMPString" }, + { 31, "Continued" }, + { 0, NULL } }; static value_string_ext ber_uni_tag_codes_ext = VALUE_STRING_EXT_INIT(ber_uni_tag_codes); static const true_false_string ber_real_binary_vals = { - "Binary encoding", - "Decimal encoding" + "Binary encoding", + "Decimal encoding" }; static const true_false_string ber_real_decimal_vals = { - "SpecialRealValue", - "Decimal encoding " + "SpecialRealValue", + "Decimal encoding " }; typedef struct _da_data { - GHFunc func; - gpointer user_data; + GHFunc func; + gpointer user_data; } da_data; typedef struct _oid_user_t { - char *oid; - char *name; - char *syntax; + char *oid; + char *name; + char *syntax; } oid_user_t; UAT_CSTRING_CB_DEF(oid_users, oid, oid_user_t) @@ -263,100 +263,100 @@ static guint num_oid_users; /* Define non_const_value_string as a hack to prevent chackAPIs.pl from complaining */ #define non_const_value_string value_string static non_const_value_string syntax_names[MAX_SYNTAX_NAMES+1] = { - {0, ""}, - {0, NULL} + {0, ""}, + {0, NULL} }; static const fragment_items octet_string_frag_items = { - /* Fragment subtrees */ - &ett_ber_fragment, - &ett_ber_fragments, - /* Fragment fields */ - &hf_ber_fragments, - &hf_ber_fragment, - &hf_ber_fragment_overlap, - &hf_ber_fragment_overlap_conflicts, - &hf_ber_fragment_multiple_tails, - &hf_ber_fragment_too_long_fragment, - &hf_ber_fragment_error, - &hf_ber_fragment_count, - /* Reassembled in field */ - &hf_ber_reassembled_in, - /* Reassembled length field */ - &hf_ber_reassembled_length, - /* Tag */ - "OCTET STRING fragments" + /* Fragment subtrees */ + &ett_ber_fragment, + &ett_ber_fragments, + /* Fragment fields */ + &hf_ber_fragments, + &hf_ber_fragment, + &hf_ber_fragment_overlap, + &hf_ber_fragment_overlap_conflicts, + &hf_ber_fragment_multiple_tails, + &hf_ber_fragment_too_long_fragment, + &hf_ber_fragment_error, + &hf_ber_fragment_count, + /* Reassembled in field */ + &hf_ber_reassembled_in, + /* Reassembled length field */ + &hf_ber_reassembled_length, + /* Tag */ + "OCTET STRING fragments" }; static void * oid_copy_cb(void *dest, const void *orig, size_t len _U_) { - oid_user_t *u = dest; - const oid_user_t *o = orig; + oid_user_t *u = dest; + const oid_user_t *o = orig; - u->oid = g_strdup(o->oid); - u->name = g_strdup(o->name); - u->syntax = o->syntax; + u->oid = g_strdup(o->oid); + u->name = g_strdup(o->name); + u->syntax = o->syntax; - return dest; + return dest; } static void oid_free_cb(void *r) { - oid_user_t *u = r; + oid_user_t *u = r; - g_free(u->oid); - g_free(u->name); + g_free(u->oid); + g_free(u->name); } static int cmp_value_string(const void *v1, const void *v2) { - value_string *vs1 = (value_string *)v1; - value_string *vs2 = (value_string *)v2; + value_string *vs1 = (value_string *)v1; + value_string *vs2 = (value_string *)v2; - return strcmp(vs1->strptr, vs2->strptr); + return strcmp(vs1->strptr, vs2->strptr); } static uat_field_t users_flds[] = { - UAT_FLD_OID(oid_users, oid, "OID", "Object Identifier"), - UAT_FLD_CSTRING(oid_users, name, "Name", "Human readable name for the OID"), - UAT_FLD_VS(oid_users, syntax, "Syntax", syntax_names, "Syntax of values associated with the OID"), - UAT_END_FIELDS + UAT_FLD_OID(oid_users, oid, "OID", "Object Identifier"), + UAT_FLD_CSTRING(oid_users, name, "Name", "Human readable name for the OID"), + UAT_FLD_VS(oid_users, syntax, "Syntax", syntax_names, "Syntax of values associated with the OID"), + UAT_END_FIELDS }; void dissect_ber_oid_NULL_callback(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) { - return; + return; } void register_ber_oid_dissector_handle(const char *oid, dissector_handle_t dissector, int proto _U_, const char *name) { - dissector_add_string("ber.oid", oid, dissector); - oid_add_from_string(name, oid); + dissector_add_string("ber.oid", oid, dissector); + oid_add_from_string(name, oid); } void register_ber_oid_dissector(const char *oid, dissector_t dissector, int proto, const char *name) { - dissector_handle_t dissector_handle; + dissector_handle_t dissector_handle; - dissector_handle=create_dissector_handle(dissector, proto); - dissector_add_string("ber.oid", oid, dissector_handle); - oid_add_from_string(name, oid); + dissector_handle=create_dissector_handle(dissector, proto); + dissector_add_string("ber.oid", oid, dissector_handle); + oid_add_from_string(name, oid); } void register_ber_syntax_dissector(const char *syntax, int proto, dissector_t dissector) { - dissector_handle_t dissector_handle; + dissector_handle_t dissector_handle; - dissector_handle=create_dissector_handle(dissector, proto); - dissector_add_string("ber.syntax", syntax, dissector_handle); + dissector_handle=create_dissector_handle(dissector, proto); + dissector_add_string("ber.syntax", syntax, dissector_handle); } @@ -364,195 +364,195 @@ void register_ber_oid_syntax(const char *oid, const char *name, const char *syntax) { - if(syntax && *syntax) - g_hash_table_insert(syntax_table, (gpointer)g_strdup(oid), (gpointer)g_strdup(syntax)); + if(syntax && *syntax) + g_hash_table_insert(syntax_table, (gpointer)g_strdup(oid), (gpointer)g_strdup(syntax)); - if(name && *name) - register_ber_oid_name(oid, name); + if(name && *name) + register_ber_oid_name(oid, name); } /* Register the oid name to get translation in proto dissection */ void register_ber_oid_name(const char *oid, const char *name) { - oid_add_from_string(name, oid); + oid_add_from_string(name, oid); } static void ber_add_syntax_name(gpointer key, gpointer value _U_, gpointer user_data) { - guint *i = (guint*)user_data; + guint *i = (guint*)user_data; - if(*i < MAX_SYNTAX_NAMES) { - syntax_names[*i].value = *i; - syntax_names[*i].strptr = (const gchar*)key; + if(*i < MAX_SYNTAX_NAMES) { + syntax_names[*i].value = *i; + syntax_names[*i].strptr = (const gchar*)key; - (*i)++; - } + (*i)++; + } } static void ber_decode_as_dt(const gchar *table_name _U_, ftenum_t selector_type _U_, gpointer key, gpointer value, gpointer user_data) { - da_data *decode_as_data; + da_data *decode_as_data; - decode_as_data = (da_data *)user_data; + decode_as_data = (da_data *)user_data; - decode_as_data->func(key, value, decode_as_data->user_data); + decode_as_data->func(key, value, decode_as_data->user_data); } void ber_decode_as_foreach(GHFunc func, gpointer user_data) { - da_data decode_as_data; + da_data decode_as_data; - decode_as_data.func = func; - decode_as_data.user_data = user_data; + decode_as_data.func = func; + decode_as_data.user_data = user_data; - dissector_table_foreach("ber.syntax", ber_decode_as_dt, &decode_as_data); + dissector_table_foreach("ber.syntax", ber_decode_as_dt, &decode_as_data); } void ber_decode_as(const gchar *syntax) { - if(decode_as_syntax) { - g_free(decode_as_syntax); - decode_as_syntax = NULL; - } + if(decode_as_syntax) { + g_free(decode_as_syntax); + decode_as_syntax = NULL; + } - if(syntax) - decode_as_syntax = g_strdup(syntax); + if(syntax) + decode_as_syntax = g_strdup(syntax); } /* Get oid syntax from hash table to get translation in proto dissection(packet-per.c) */ static const gchar * get_ber_oid_syntax(const char *oid) { - return g_hash_table_lookup(syntax_table, oid); + return g_hash_table_lookup(syntax_table, oid); } void ber_set_filename(gchar *filename) { - gchar *ptr; + gchar *ptr; - if(ber_filename) { - g_free(ber_filename); - ber_filename = NULL; - } + if(ber_filename) { + g_free(ber_filename); + ber_filename = NULL; + } - if(filename) { + if(filename) { - ber_filename = g_strdup(filename); + ber_filename = g_strdup(filename); - if((ptr = strrchr(ber_filename, '.')) != NULL) { + if((ptr = strrchr(ber_filename, '.')) != NULL) { - ber_decode_as(get_ber_oid_syntax(ptr)); + ber_decode_as(get_ber_oid_syntax(ptr)); + } } - } } static void ber_update_oids(void) { - guint i; + guint i; - for(i = 0; i < num_oid_users; i++) - register_ber_oid_syntax(oid_users[i].oid, oid_users[i].name, oid_users[i].syntax); + for(i = 0; i < num_oid_users; i++) + register_ber_oid_syntax(oid_users[i].oid, oid_users[i].name, oid_users[i].syntax); } static void ber_check_length (guint32 length, gint32 min_len, gint32 max_len, asn1_ctx_t *actx, proto_item *item, gboolean bit) { - if (min_len != -1 && length < (guint32)min_len) { - expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: %sstring too short: %d (%d .. %d)", bit ? "bit " : "", length, min_len, max_len); - } else if (max_len != -1 && length > (guint32)max_len) { - expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: %sstring too long: %d (%d .. %d)", bit ? "bit " : "", length, min_len, max_len); - } + if (min_len != -1 && length < (guint32)min_len) { + expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: %sstring too short: %d (%d .. %d)", bit ? "bit " : "", length, min_len, max_len); + } else if (max_len != -1 && length > (guint32)max_len) { + expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: %sstring too long: %d (%d .. %d)", bit ? "bit " : "", length, min_len, max_len); + } } static void ber_check_value64 (gint64 value, gint64 min_len, gint64 max_len, asn1_ctx_t *actx, proto_item *item) { - if (min_len != -1 && value < min_len) { - expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: value too small: %" G_GINT64_MODIFIER "d (%" G_GINT64_MODIFIER "d .. %" G_GINT64_MODIFIER "d)", value, min_len, max_len); - } else if (max_len != -1 && value > max_len) { - expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: value too big: %" G_GINT64_MODIFIER "d (%" G_GINT64_MODIFIER "d .. %" G_GINT64_MODIFIER "d)", value, min_len, max_len); - } + if (min_len != -1 && value < min_len) { + expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: value too small: %" G_GINT64_MODIFIER "d (%" G_GINT64_MODIFIER "d .. %" G_GINT64_MODIFIER "d)", value, min_len, max_len); + } else if (max_len != -1 && value > max_len) { + expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: value too big: %" G_GINT64_MODIFIER "d (%" G_GINT64_MODIFIER "d .. %" G_GINT64_MODIFIER "d)", value, min_len, max_len); + } } static void ber_check_value (guint32 value, gint32 min_len, gint32 max_len, asn1_ctx_t *actx, proto_item *item) { - if (min_len != -1 && value < (guint32)min_len) { - expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: value too small: %d (%d .. %d)", value, min_len, max_len); - } else if (max_len != -1 && value > (guint32)max_len) { - expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: value too big: %d (%d .. %d)", value, min_len, max_len); - } + if (min_len != -1 && value < (guint32)min_len) { + expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: value too small: %d (%d .. %d)", value, min_len, max_len); + } else if (max_len != -1 && value > (guint32)max_len) { + expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: value too big: %d (%d .. %d)", value, min_len, max_len); + } } static void ber_check_items (int cnt, gint32 min_len, gint32 max_len, asn1_ctx_t *actx, proto_item *item) { - if (min_len != -1 && cnt < min_len) { - expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: too few items: %d (%d .. %d)", cnt, min_len, max_len); - } else if (max_len != -1 && cnt > max_len) { - expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: too many items: %d (%d .. %d)", cnt, min_len, max_len); - } + if (min_len != -1 && cnt < min_len) { + expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: too few items: %d (%d .. %d)", cnt, min_len, max_len); + } else if (max_len != -1 && cnt > max_len) { + expert_add_info_format(actx->pinfo, item, PI_PROTOCOL, PI_WARN, "Size constraint: too many items: %d (%d .. %d)", cnt, min_len, max_len); + } } int dissect_ber_tagged_type(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, gint8 tag_cls, gint32 tag_tag, gboolean tag_impl, ber_type_fn type) { - gint8 tmp_cls; - gint32 tmp_tag; - guint32 tmp_len; - tvbuff_t *next_tvb = tvb; - proto_item *cause; + gint8 tmp_cls; + gint32 tmp_tag; + guint32 tmp_len; + tvbuff_t *next_tvb = tvb; + proto_item *cause; #ifdef DEBUG_BER -{ -const char *name; -header_field_info *hfinfo; -if(hf_id>=0){ -hfinfo = proto_registrar_get_nth(hf_id); -name=hfinfo->name; -} else { -name="unnamed"; -} -if(tvb_length_remaining(tvb,offset)>3){ -printf("dissect_ber_tagged_type(%s) entered implicit_tag:%d offset:%d len:%d %02x:%02x:%02x\n",name,implicit_tag,offset,tvb_length_remaining(tvb,offset),tvb_get_guint8(tvb,offset),tvb_get_guint8(tvb,offset+1),tvb_get_guint8(tvb,offset+2)); -}else{ -printf("dissect_ber_tagged_type(%s) entered\n",name); -} -} + { + const char *name; + header_field_info *hfinfo; + if(hf_id>=0){ + hfinfo = proto_registrar_get_nth(hf_id); + name=hfinfo->name; + } else { + name="unnamed"; + } + if(tvb_length_remaining(tvb,offset)>3){ + printf("dissect_ber_tagged_type(%s) entered implicit_tag:%d offset:%d len:%d %02x:%02x:%02x\n",name,implicit_tag,offset,tvb_length_remaining(tvb,offset),tvb_get_guint8(tvb,offset),tvb_get_guint8(tvb,offset+1),tvb_get_guint8(tvb,offset+2)); + }else{ + printf("dissect_ber_tagged_type(%s) entered\n",name); + } + } #endif - if (implicit_tag) { - offset = type(tag_impl, tvb, offset, actx, tree, hf_id); - return offset; - } + if (implicit_tag) { + offset = type(tag_impl, tvb, offset, actx, tree, hf_id); + return offset; + } - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &tmp_cls, NULL, &tmp_tag); - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &tmp_len, NULL); + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &tmp_cls, NULL, &tmp_tag); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &tmp_len, NULL); - if ((tmp_cls != tag_cls) || (tmp_tag != tag_tag)) { - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, tmp_len, "wrong_tag", - "BER Error: Wrong tag in tagged type - expected class:%s(%d) tag:%d (%s) but found class:%s(%d) tag:%d", - val_to_str(tag_cls, ber_class_codes, "Unknown"), tag_cls, tag_tag, val_to_str_ext(tag_tag, &ber_uni_tag_codes_ext,"Unknown"), - val_to_str(tmp_cls, ber_class_codes, "Unknown"), tmp_cls, tmp_tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong tag in tagged type"); - } + if ((tmp_cls != tag_cls) || (tmp_tag != tag_tag)) { + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, tmp_len, "wrong_tag", + "BER Error: Wrong tag in tagged type - expected class:%s(%d) tag:%d (%s) but found class:%s(%d) tag:%d", + val_to_str(tag_cls, ber_class_codes, "Unknown"), tag_cls, tag_tag, val_to_str_ext(tag_tag, &ber_uni_tag_codes_ext,"Unknown"), + val_to_str(tmp_cls, ber_class_codes, "Unknown"), tmp_cls, tmp_tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong tag in tagged type"); + } - if (tag_impl) { - next_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), tmp_len); - type(tag_impl, next_tvb, 0, actx, tree, hf_id); - offset += tmp_len; - } else { - offset = type(tag_impl, tvb, offset, actx, tree, hf_id); - } + if (tag_impl) { + next_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), tmp_len); + type(tag_impl, next_tvb, 0, actx, tree, hf_id); + offset += tmp_len; + } else { + offset = type(tag_impl, tvb, offset, actx, tree, hf_id); + } - return offset; + return offset; } /* @@ -563,13 +563,13 @@ ber_add_bad_length_error(packet_info *pinfo, proto_tree *tree, const char *name, tvbuff_t *tvb, const gint start, gint length) { - proto_item *ti; + proto_item *ti; - ti = proto_tree_add_string_format(tree, hf_ber_error, tvb, start, length, "illegal_length", - "%s: length of item (%d) is not valid", name, length); - expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_WARN, - "Length of item (%d) is not valid", length); - return ti; + ti = proto_tree_add_string_format(tree, hf_ber_error, tvb, start, length, "illegal_length", + "%s: length of item (%d) is not valid", name, length); + expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_WARN, + "Length of item (%d) is not valid", length); + return ti; } /* @@ -594,429 +594,429 @@ ber_proto_tree_add_item(packet_info *pinfo, proto_tree *tree, const int hfindex, tvbuff_t *tvb, const gint start, gint length, const guint encoding) { - header_field_info *hfinfo; - - hfinfo = proto_registrar_get_nth((guint)hfindex); - if (hfinfo != NULL) { - switch (hfinfo->type) { - - case FT_BOOLEAN: - case FT_UINT8: - case FT_UINT16: - case FT_UINT24: - case FT_UINT32: - case FT_INT8: - case FT_INT16: - case FT_INT24: - case FT_INT32: - if (length != 1 && length != 2 && length != 3 && - length != 4) - return ber_add_bad_length_error(pinfo, tree, - hfinfo->name, tvb, start, length); - break; - - case FT_IPv4: - if (length != FT_IPv4_LEN) - return ber_add_bad_length_error(pinfo, tree, - hfinfo->name, tvb, start, length); - break; - - case FT_IPXNET: - if (length != FT_IPXNET_LEN) - return ber_add_bad_length_error(pinfo, tree, - hfinfo->name, tvb, start, length); - break; - - case FT_IPv6: - if (length < 0 || length > FT_IPv6_LEN) - return ber_add_bad_length_error(pinfo, tree, - hfinfo->name, tvb, start, length); - break; - - case FT_ETHER: - if (length != FT_ETHER_LEN) - return ber_add_bad_length_error(pinfo, tree, - hfinfo->name, tvb, start, length); - break; - - case FT_GUID: - if (length != FT_GUID_LEN) - return ber_add_bad_length_error(pinfo, tree, - hfinfo->name, tvb, start, length); - break; - - case FT_FLOAT: - if (length != 4) - return ber_add_bad_length_error(pinfo, tree, - hfinfo->name, tvb, start, length); - break; - - case FT_DOUBLE: - if (length != 8) - return ber_add_bad_length_error(pinfo, tree, - hfinfo->name, tvb, start, length); - break; - - case FT_ABSOLUTE_TIME: - case FT_RELATIVE_TIME: - if (length != 4 && length != 8) - return ber_add_bad_length_error(pinfo, tree, - hfinfo->name, tvb, start, length); - break; - - default: - break; - } - } - return proto_tree_add_item(tree, hfindex, tvb, start, length, encoding); + header_field_info *hfinfo; + + hfinfo = proto_registrar_get_nth((guint)hfindex); + if (hfinfo != NULL) { + switch (hfinfo->type) { + + case FT_BOOLEAN: + case FT_UINT8: + case FT_UINT16: + case FT_UINT24: + case FT_UINT32: + case FT_INT8: + case FT_INT16: + case FT_INT24: + case FT_INT32: + if (length != 1 && length != 2 && length != 3 && + length != 4) + return ber_add_bad_length_error(pinfo, tree, + hfinfo->name, tvb, start, length); + break; + + case FT_IPv4: + if (length != FT_IPv4_LEN) + return ber_add_bad_length_error(pinfo, tree, + hfinfo->name, tvb, start, length); + break; + + case FT_IPXNET: + if (length != FT_IPXNET_LEN) + return ber_add_bad_length_error(pinfo, tree, + hfinfo->name, tvb, start, length); + break; + + case FT_IPv6: + if (length < 0 || length > FT_IPv6_LEN) + return ber_add_bad_length_error(pinfo, tree, + hfinfo->name, tvb, start, length); + break; + + case FT_ETHER: + if (length != FT_ETHER_LEN) + return ber_add_bad_length_error(pinfo, tree, + hfinfo->name, tvb, start, length); + break; + + case FT_GUID: + if (length != FT_GUID_LEN) + return ber_add_bad_length_error(pinfo, tree, + hfinfo->name, tvb, start, length); + break; + + case FT_FLOAT: + if (length != 4) + return ber_add_bad_length_error(pinfo, tree, + hfinfo->name, tvb, start, length); + break; + + case FT_DOUBLE: + if (length != 8) + return ber_add_bad_length_error(pinfo, tree, + hfinfo->name, tvb, start, length); + break; + + case FT_ABSOLUTE_TIME: + case FT_RELATIVE_TIME: + if (length != 4 && length != 8) + return ber_add_bad_length_error(pinfo, tree, + hfinfo->name, tvb, start, length); + break; + + default: + break; + } + } + return proto_tree_add_item(tree, hfindex, tvb, start, length, encoding); } static int try_dissect_unknown_ber(packet_info *pinfo, tvbuff_t *tvb, volatile int offset, proto_tree *tree, gint nest_level) { - int start_offset; - gint8 ber_class; - gboolean pc, ind; - gint32 tag; - guint32 len; - int hdr_len; - proto_item *item=NULL; - proto_tree *next_tree=NULL; - guint8 c; - guint32 i; - gboolean is_printable; - volatile gboolean is_decoded_as; - proto_item *pi, *cause; - asn1_ctx_t asn1_ctx; - - if (nest_level > BER_MAX_NESTING) { - /* Assume that we have a malformed packet. */ - THROW(ReportedBoundsError); - } - - start_offset=offset; - asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); - - offset=get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); - offset=get_ber_length(tvb, offset, &len, &ind); - - if(len>(guint32)tvb_length_remaining(tvb, offset)){ - /* hmm maybe something bad happened or the frame is short, - since these are not vital outputs just return instead of - throwing an exception. - */ - - if(show_internal_ber_fields) { - offset=dissect_ber_identifier(pinfo, tree, tvb, start_offset, &ber_class, &pc, &tag); - offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL); - } - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "illegal_length", "BER Error: length:%u longer than tvb_length_remaining:%d",len, tvb_length_remaining(tvb, offset)); - expert_add_info_format(pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error length"); - return tvb_length(tvb); - } + int start_offset; + gint8 ber_class; + gboolean pc, ind; + gint32 tag; + guint32 len; + int hdr_len; + proto_item *item=NULL; + proto_tree *next_tree=NULL; + guint8 c; + guint32 i; + gboolean is_printable; + volatile gboolean is_decoded_as; + proto_item *pi, *cause; + asn1_ctx_t asn1_ctx; + + if (nest_level > BER_MAX_NESTING) { + /* Assume that we have a malformed packet. */ + THROW(ReportedBoundsError); + } + + start_offset=offset; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + + offset=get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); + offset=get_ber_length(tvb, offset, &len, &ind); + + if(len>(guint32)tvb_length_remaining(tvb, offset)){ + /* hmm maybe something bad happened or the frame is short, + since these are not vital outputs just return instead of + throwing an exception. + */ + + if(show_internal_ber_fields) { + offset=dissect_ber_identifier(pinfo, tree, tvb, start_offset, &ber_class, &pc, &tag); + offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL); + } + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "illegal_length", "BER Error: length:%u longer than tvb_length_remaining:%d",len, tvb_length_remaining(tvb, offset)); + expert_add_info_format(pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error length"); + return tvb_length(tvb); + } /* we dont care about the class only on the constructor flag */ - switch(pc){ - - case FALSE: /* this is not constructed */ - - switch(ber_class) { /* we do care about the class */ - case BER_CLASS_UNI: /* it a Universal tag - we can decode it */ - switch(tag){ - case BER_UNI_TAG_EOC: - /* XXX: shouldn't really get here */ - break; - case BER_UNI_TAG_INTEGER: - offset = dissect_ber_integer(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_INTEGER, NULL); - break; - case BER_UNI_TAG_BITSTRING: - offset = dissect_ber_bitstring(FALSE, &asn1_ctx, tree, tvb, start_offset, NULL, hf_ber_unknown_BITSTRING, -1, NULL); - break; - case BER_UNI_TAG_ENUMERATED: - offset = dissect_ber_integer(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_ENUMERATED, NULL); - break; - case BER_UNI_TAG_GraphicString: - offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_GraphicString, NULL); - break; - case BER_UNI_TAG_OCTETSTRING: - is_decoded_as = FALSE; - if (decode_octetstring_as_ber && len >= 2) { - volatile int ber_offset = 0; - guint32 ber_len = 0; - TRY { - ber_offset = get_ber_identifier(tvb, offset, NULL, &pc, NULL); - ber_offset = get_ber_length(tvb, ber_offset, &ber_len, NULL); - } CATCH_ALL { - } - ENDTRY; - if (pc && (ber_len > 0) && (ber_len + (ber_offset - offset) == len)) { - /* Decoded a constructed ASN.1 tag with a length indicating this - * could be BER encoded data. Try dissecting as unknown BER. - */ - is_decoded_as = TRUE; - if (show_internal_ber_fields) { - offset = dissect_ber_identifier(pinfo, tree, tvb, start_offset, NULL, NULL, NULL); - offset = dissect_ber_length(pinfo, tree, tvb, offset, NULL, NULL); - } - item = ber_proto_tree_add_item(pinfo, tree, hf_ber_unknown_BER_OCTETSTRING, tvb, offset, len, ENC_NA); - next_tree = proto_item_add_subtree(item, ett_ber_octet_string); - offset = try_dissect_unknown_ber(pinfo, tvb, offset, next_tree, nest_level+1); - } - } - if (!is_decoded_as) { - offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_OCTETSTRING, NULL); - } - break; - case BER_UNI_TAG_OID: - offset=dissect_ber_object_identifier_str(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_OID, NULL); - break; - case BER_UNI_TAG_NumericString: - offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_NumericString, NULL); - break; - case BER_UNI_TAG_PrintableString: - offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_PrintableString, NULL); - break; - case BER_UNI_TAG_TeletexString: - offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_TeletexString, NULL); - break; - case BER_UNI_TAG_VisibleString: - offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_VisibleString, NULL); - break; - case BER_UNI_TAG_GeneralString: - offset = dissect_ber_GeneralString(&asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_GeneralString, NULL, 0); - break; - case BER_UNI_TAG_BMPString: - offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_BMPString, NULL); - break; - case BER_UNI_TAG_UniversalString: - offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_UniversalString, NULL); - break; - case BER_UNI_TAG_IA5String: - offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_IA5String, NULL); - break; - case BER_UNI_TAG_UTCTime: - offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_UTCTime, NULL); - break; - case BER_UNI_TAG_NULL: - proto_tree_add_text(tree, tvb, offset, len, "NULL tag"); - break; - case BER_UNI_TAG_UTF8String: - offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_UTF8String, NULL); - break; - case BER_UNI_TAG_GeneralizedTime: - offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_GeneralizedTime, NULL); - break; - case BER_UNI_TAG_BOOLEAN: - offset = dissect_ber_boolean(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_BOOLEAN, NULL); - break; - default: - offset=dissect_ber_identifier(pinfo, tree, tvb, start_offset, &ber_class, &pc, &tag); - offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "unknown_universal_tag", "BER Error: can not handle universal tag:%d",tag); - expert_add_info_format(pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: can not handle universal"); - offset += len; - } - break; - case BER_CLASS_APP: - case BER_CLASS_CON: - case BER_CLASS_PRI: - default: - /* we dissect again if show_internal_ber_fields is set */ - if(show_internal_ber_fields) { - offset=dissect_ber_identifier(pinfo, tree, tvb, start_offset, &ber_class, &pc, &tag); - offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL); - } - - /* we can't dissect this directly as it is specific */ - pi = proto_tree_add_none_format(tree, hf_ber_unknown_BER_primitive, tvb, offset, len, - "[%s %d] ", val_to_str(ber_class,ber_class_codes,"Unknown"), tag); - - is_decoded_as = FALSE; - if (decode_primitive_as_ber && len >= 2) { - volatile int ber_offset = 0; - guint32 ber_len = 0; - TRY { - ber_offset = get_ber_identifier(tvb, offset, NULL, &pc, NULL); - ber_offset = get_ber_length(tvb, ber_offset, &ber_len, NULL); - } CATCH_ALL { - } - ENDTRY; - if (pc && (ber_len > 0) && (ber_len + (ber_offset - offset) == len)) { - /* Decoded a constructed ASN.1 tag with a length indicating this - * could be BER encoded data. Try dissecting as unknown BER. - */ - is_decoded_as = TRUE; - proto_item_append_text (pi, "[BER encoded]"); - next_tree = proto_item_add_subtree(pi, ett_ber_primitive); - offset = try_dissect_unknown_ber(pinfo, tvb, offset, next_tree, nest_level+1); - } - } - - if (!is_decoded_as && len) { - /* we may want to do better and show the bytes */ - is_printable = TRUE; - for(i=0;i<len;i++){ - c = tvb_get_guint8(tvb, offset+i); - - if(is_printable && !g_ascii_isprint(c)) - is_printable=FALSE; - - proto_item_append_text(pi,"%02x",c); - } - - if(is_printable) { /* give a nicer representation if it looks like a string */ - proto_item_append_text(pi," ("); - for(i=0;i<len;i++){ - proto_item_append_text(pi,"%c",tvb_get_guint8(tvb, offset+i)); - } - proto_item_append_text(pi,")"); - } - offset += len; - } - - break; - } - break; - - case TRUE: /* this is constructed */ - - /* we dissect again if show_internal_ber_fields is set */ - if(show_internal_ber_fields) { - offset=dissect_ber_identifier(pinfo, tree, tvb, start_offset, &ber_class, &pc, &tag); - offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL); - } - - hdr_len=offset-start_offset; - - switch(ber_class) { - case BER_CLASS_UNI: - item=proto_tree_add_text(tree, tvb, offset, len, "%s", val_to_str_ext(tag,&ber_uni_tag_codes_ext,"Unknown")); - if(item){ - next_tree=proto_item_add_subtree(item, ett_ber_SEQUENCE); - } - while(offset < (int)(start_offset + len + hdr_len)) - offset=try_dissect_unknown_ber(pinfo, tvb, offset, next_tree, nest_level+1); - break; - case BER_CLASS_APP: - case BER_CLASS_CON: - case BER_CLASS_PRI: - default: - item=proto_tree_add_text(tree, tvb, offset, len, "[%s %d]", val_to_str(ber_class,ber_class_codes,"Unknown"), tag); - if(item){ - next_tree=proto_item_add_subtree(item, ett_ber_SEQUENCE); - } - while(offset < (int)(start_offset + len + hdr_len)) - offset=try_dissect_unknown_ber(pinfo, tvb, offset, next_tree, nest_level+1); - break; - - } - break; - - } - - return offset; + switch(pc){ + + case FALSE: /* this is not constructed */ + + switch(ber_class) { /* we do care about the class */ + case BER_CLASS_UNI: /* it a Universal tag - we can decode it */ + switch(tag){ + case BER_UNI_TAG_EOC: + /* XXX: shouldn't really get here */ + break; + case BER_UNI_TAG_INTEGER: + offset = dissect_ber_integer(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_INTEGER, NULL); + break; + case BER_UNI_TAG_BITSTRING: + offset = dissect_ber_bitstring(FALSE, &asn1_ctx, tree, tvb, start_offset, NULL, hf_ber_unknown_BITSTRING, -1, NULL); + break; + case BER_UNI_TAG_ENUMERATED: + offset = dissect_ber_integer(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_ENUMERATED, NULL); + break; + case BER_UNI_TAG_GraphicString: + offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_GraphicString, NULL); + break; + case BER_UNI_TAG_OCTETSTRING: + is_decoded_as = FALSE; + if (decode_octetstring_as_ber && len >= 2) { + volatile int ber_offset = 0; + guint32 ber_len = 0; + TRY { + ber_offset = get_ber_identifier(tvb, offset, NULL, &pc, NULL); + ber_offset = get_ber_length(tvb, ber_offset, &ber_len, NULL); + } CATCH_ALL { + } + ENDTRY; + if (pc && (ber_len > 0) && (ber_len + (ber_offset - offset) == len)) { + /* Decoded a constructed ASN.1 tag with a length indicating this + * could be BER encoded data. Try dissecting as unknown BER. + */ + is_decoded_as = TRUE; + if (show_internal_ber_fields) { + offset = dissect_ber_identifier(pinfo, tree, tvb, start_offset, NULL, NULL, NULL); + offset = dissect_ber_length(pinfo, tree, tvb, offset, NULL, NULL); + } + item = ber_proto_tree_add_item(pinfo, tree, hf_ber_unknown_BER_OCTETSTRING, tvb, offset, len, ENC_NA); + next_tree = proto_item_add_subtree(item, ett_ber_octet_string); + offset = try_dissect_unknown_ber(pinfo, tvb, offset, next_tree, nest_level+1); + } + } + if (!is_decoded_as) { + offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_OCTETSTRING, NULL); + } + break; + case BER_UNI_TAG_OID: + offset=dissect_ber_object_identifier_str(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_OID, NULL); + break; + case BER_UNI_TAG_NumericString: + offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_NumericString, NULL); + break; + case BER_UNI_TAG_PrintableString: + offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_PrintableString, NULL); + break; + case BER_UNI_TAG_TeletexString: + offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_TeletexString, NULL); + break; + case BER_UNI_TAG_VisibleString: + offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_VisibleString, NULL); + break; + case BER_UNI_TAG_GeneralString: + offset = dissect_ber_GeneralString(&asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_GeneralString, NULL, 0); + break; + case BER_UNI_TAG_BMPString: + offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_BMPString, NULL); + break; + case BER_UNI_TAG_UniversalString: + offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_UniversalString, NULL); + break; + case BER_UNI_TAG_IA5String: + offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_IA5String, NULL); + break; + case BER_UNI_TAG_UTCTime: + offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_UTCTime, NULL); + break; + case BER_UNI_TAG_NULL: + proto_tree_add_text(tree, tvb, offset, len, "NULL tag"); + break; + case BER_UNI_TAG_UTF8String: + offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_UTF8String, NULL); + break; + case BER_UNI_TAG_GeneralizedTime: + offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_GeneralizedTime, NULL); + break; + case BER_UNI_TAG_BOOLEAN: + offset = dissect_ber_boolean(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_BOOLEAN, NULL); + break; + default: + offset=dissect_ber_identifier(pinfo, tree, tvb, start_offset, &ber_class, &pc, &tag); + offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "unknown_universal_tag", "BER Error: can not handle universal tag:%d",tag); + expert_add_info_format(pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: can not handle universal"); + offset += len; + } + break; + case BER_CLASS_APP: + case BER_CLASS_CON: + case BER_CLASS_PRI: + default: + /* we dissect again if show_internal_ber_fields is set */ + if(show_internal_ber_fields) { + offset=dissect_ber_identifier(pinfo, tree, tvb, start_offset, &ber_class, &pc, &tag); + offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL); + } + + /* we can't dissect this directly as it is specific */ + pi = proto_tree_add_none_format(tree, hf_ber_unknown_BER_primitive, tvb, offset, len, + "[%s %d] ", val_to_str(ber_class,ber_class_codes,"Unknown"), tag); + + is_decoded_as = FALSE; + if (decode_primitive_as_ber && len >= 2) { + volatile int ber_offset = 0; + guint32 ber_len = 0; + TRY { + ber_offset = get_ber_identifier(tvb, offset, NULL, &pc, NULL); + ber_offset = get_ber_length(tvb, ber_offset, &ber_len, NULL); + } CATCH_ALL { + } + ENDTRY; + if (pc && (ber_len > 0) && (ber_len + (ber_offset - offset) == len)) { + /* Decoded a constructed ASN.1 tag with a length indicating this + * could be BER encoded data. Try dissecting as unknown BER. + */ + is_decoded_as = TRUE; + proto_item_append_text (pi, "[BER encoded]"); + next_tree = proto_item_add_subtree(pi, ett_ber_primitive); + offset = try_dissect_unknown_ber(pinfo, tvb, offset, next_tree, nest_level+1); + } + } + + if (!is_decoded_as && len) { + /* we may want to do better and show the bytes */ + is_printable = TRUE; + for(i=0;i<len;i++){ + c = tvb_get_guint8(tvb, offset+i); + + if(is_printable && !g_ascii_isprint(c)) + is_printable=FALSE; + + proto_item_append_text(pi,"%02x",c); + } + + if(is_printable) { /* give a nicer representation if it looks like a string */ + proto_item_append_text(pi," ("); + for(i=0;i<len;i++){ + proto_item_append_text(pi,"%c",tvb_get_guint8(tvb, offset+i)); + } + proto_item_append_text(pi,")"); + } + offset += len; + } + + break; + } + break; + + case TRUE: /* this is constructed */ + + /* we dissect again if show_internal_ber_fields is set */ + if(show_internal_ber_fields) { + offset=dissect_ber_identifier(pinfo, tree, tvb, start_offset, &ber_class, &pc, &tag); + offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL); + } + + hdr_len=offset-start_offset; + + switch(ber_class) { + case BER_CLASS_UNI: + item=proto_tree_add_text(tree, tvb, offset, len, "%s", val_to_str_ext(tag,&ber_uni_tag_codes_ext,"Unknown")); + if(item){ + next_tree=proto_item_add_subtree(item, ett_ber_SEQUENCE); + } + while(offset < (int)(start_offset + len + hdr_len)) + offset=try_dissect_unknown_ber(pinfo, tvb, offset, next_tree, nest_level+1); + break; + case BER_CLASS_APP: + case BER_CLASS_CON: + case BER_CLASS_PRI: + default: + item=proto_tree_add_text(tree, tvb, offset, len, "[%s %d]", val_to_str(ber_class,ber_class_codes,"Unknown"), tag); + if(item){ + next_tree=proto_item_add_subtree(item, ett_ber_SEQUENCE); + } + while(offset < (int)(start_offset + len + hdr_len)) + offset=try_dissect_unknown_ber(pinfo, tvb, offset, next_tree, nest_level+1); + break; + + } + break; + + } + + return offset; } int dissect_unknown_ber(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree) { - return try_dissect_unknown_ber(pinfo, tvb, offset, tree, 1); + return try_dissect_unknown_ber(pinfo, tvb, offset, tree, 1); } int call_ber_oid_callback(const char *oid, tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { - tvbuff_t *next_tvb; - const char *syntax = NULL; - - if (!tvb) { - return offset; - } - - next_tvb = tvb_new_subset_remaining(tvb, offset); - if(oid == NULL || - ((((syntax = get_ber_oid_syntax(oid)) == NULL) || - /* First see if a syntax has been registered for this oid (user defined) */ - !dissector_try_string(ber_syntax_dissector_table, syntax, next_tvb, pinfo, tree)) && - /* Then try registered oid's */ - (!dissector_try_string(ber_oid_dissector_table, oid, next_tvb, pinfo, tree)))) { - proto_item *item=NULL; - proto_tree *next_tree=NULL; - gint length_remaining; - - length_remaining = tvb_length_remaining(tvb, offset); - - if (oid == NULL) { - item=proto_tree_add_none_format(tree, hf_ber_no_oid, next_tvb, 0, length_remaining, "BER: No OID supplied to call_ber_oid_callback"); - expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN, "BER Error: No OID supplied"); - } else if (tvb_get_ntohs (tvb, offset) != 0x0500) { /* Not NULL tag */ - if(syntax) - item=proto_tree_add_none_format(tree, hf_ber_syntax_not_implemented, next_tvb, 0, length_remaining, "BER: Dissector for syntax:%s not implemented. Contact Wireshark developers if you want this supported", syntax); - else - item=proto_tree_add_none_format(tree, hf_ber_oid_not_implemented, next_tvb, 0, length_remaining, "BER: Dissector for OID:%s not implemented. Contact Wireshark developers if you want this supported", oid); - expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "BER: Dissector for OID %s not implemented", oid); - } else { - next_tree=tree; - } - if (decode_unexpected) { - int ber_offset; - gint32 ber_len; - - if(item){ - next_tree=proto_item_add_subtree(item, ett_ber_unknown); - } - ber_offset = get_ber_identifier(next_tvb, 0, NULL, NULL, NULL); - ber_offset = get_ber_length(next_tvb, ber_offset, &ber_len, NULL); - if ((ber_len + ber_offset) == length_remaining) { - /* Decoded an ASN.1 tag with a length indicating this - * could be BER encoded data. Try dissecting as unknown BER. - */ - dissect_unknown_ber(pinfo, next_tvb, 0, next_tree); - } else { - proto_tree_add_text(next_tree, next_tvb, 0, length_remaining, - "Unknown Data (%d byte%s)", length_remaining, - plurality(length_remaining, "", "s")); - } - } - - } - - /*XXX until we change the #.REGISTER signature for _PDU()s - * into new_dissector_t we have to do this kludge with - * manually step past the content in the ANY type. - */ - offset+=tvb_length_remaining(tvb, offset); - - return offset; + tvbuff_t *next_tvb; + const char *syntax = NULL; + + if (!tvb) { + return offset; + } + + next_tvb = tvb_new_subset_remaining(tvb, offset); + if(oid == NULL || + ((((syntax = get_ber_oid_syntax(oid)) == NULL) || + /* First see if a syntax has been registered for this oid (user defined) */ + !dissector_try_string(ber_syntax_dissector_table, syntax, next_tvb, pinfo, tree)) && + /* Then try registered oid's */ + (!dissector_try_string(ber_oid_dissector_table, oid, next_tvb, pinfo, tree)))) { + proto_item *item=NULL; + proto_tree *next_tree=NULL; + gint length_remaining; + + length_remaining = tvb_length_remaining(tvb, offset); + + if (oid == NULL) { + item=proto_tree_add_none_format(tree, hf_ber_no_oid, next_tvb, 0, length_remaining, "BER: No OID supplied to call_ber_oid_callback"); + expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN, "BER Error: No OID supplied"); + } else if (tvb_get_ntohs (tvb, offset) != 0x0500) { /* Not NULL tag */ + if(syntax) + item=proto_tree_add_none_format(tree, hf_ber_syntax_not_implemented, next_tvb, 0, length_remaining, "BER: Dissector for syntax:%s not implemented. Contact Wireshark developers if you want this supported", syntax); + else + item=proto_tree_add_none_format(tree, hf_ber_oid_not_implemented, next_tvb, 0, length_remaining, "BER: Dissector for OID:%s not implemented. Contact Wireshark developers if you want this supported", oid); + expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "BER: Dissector for OID %s not implemented", oid); + } else { + next_tree=tree; + } + if (decode_unexpected) { + int ber_offset; + gint32 ber_len; + + if(item){ + next_tree=proto_item_add_subtree(item, ett_ber_unknown); + } + ber_offset = get_ber_identifier(next_tvb, 0, NULL, NULL, NULL); + ber_offset = get_ber_length(next_tvb, ber_offset, &ber_len, NULL); + if ((ber_len + ber_offset) == length_remaining) { + /* Decoded an ASN.1 tag with a length indicating this + * could be BER encoded data. Try dissecting as unknown BER. + */ + dissect_unknown_ber(pinfo, next_tvb, 0, next_tree); + } else { + proto_tree_add_text(next_tree, next_tvb, 0, length_remaining, + "Unknown Data (%d byte%s)", length_remaining, + plurality(length_remaining, "", "s")); + } + } + + } + + /*XXX until we change the #.REGISTER signature for _PDU()s + * into new_dissector_t we have to do this kludge with + * manually step past the content in the ANY type. + */ + offset+=tvb_length_remaining(tvb, offset); + + return offset; } static int call_ber_syntax_callback(const char *syntax, tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { - tvbuff_t *next_tvb; - - next_tvb = tvb_new_subset_remaining(tvb, offset); - if(syntax == NULL || - !dissector_try_string(ber_syntax_dissector_table, syntax, next_tvb, pinfo, tree)){ - proto_item *item=NULL; - proto_tree *next_tree=NULL; - - if (syntax == NULL) - item=proto_tree_add_none_format(tree, hf_ber_no_syntax, next_tvb, 0, tvb_length_remaining(tvb, offset), "BER: No syntax supplied to call_ber_syntax_callback"); - else - item=proto_tree_add_none_format(tree, hf_ber_syntax_not_implemented, next_tvb, 0, tvb_length_remaining(tvb, offset), "BER: Dissector for syntax: %s not implemented. Contact Wireshark developers if you want this supported", syntax); - if(item){ - next_tree=proto_item_add_subtree(item, ett_ber_unknown); - } - dissect_unknown_ber(pinfo, next_tvb, 0, next_tree); - } + tvbuff_t *next_tvb; + + next_tvb = tvb_new_subset_remaining(tvb, offset); + if(syntax == NULL || + !dissector_try_string(ber_syntax_dissector_table, syntax, next_tvb, pinfo, tree)){ + proto_item *item=NULL; + proto_tree *next_tree=NULL; + + if (syntax == NULL) + item=proto_tree_add_none_format(tree, hf_ber_no_syntax, next_tvb, 0, tvb_length_remaining(tvb, offset), "BER: No syntax supplied to call_ber_syntax_callback"); + else + item=proto_tree_add_none_format(tree, hf_ber_syntax_not_implemented, next_tvb, 0, tvb_length_remaining(tvb, offset), "BER: Dissector for syntax: %s not implemented. Contact Wireshark developers if you want this supported", syntax); + if(item){ + next_tree=proto_item_add_subtree(item, ett_ber_unknown); + } + dissect_unknown_ber(pinfo, next_tvb, 0, next_tree); + } - /*XXX until we change the #.REGISTER signature for _PDU()s - * into new_dissector_t we have to do this kludge with - * manually step past the content in the ANY type. - */ - offset+=tvb_length_remaining(tvb, offset); + /*XXX until we change the #.REGISTER signature for _PDU()s + * into new_dissector_t we have to do this kludge with + * manually step past the content in the ANY type. + */ + offset+=tvb_length_remaining(tvb, offset); - return offset; + return offset; } @@ -1024,98 +1024,99 @@ call_ber_syntax_callback(const char *syntax, tvbuff_t *tvb, int offset, packet_i /* 8.1.2 Identifier octets */ int get_ber_identifier(tvbuff_t *tvb, int offset, gint8 *ber_class, gboolean *pc, gint32 *tag) { - guint8 id, t; - gint8 tmp_class; - gboolean tmp_pc; - gint32 tmp_tag; + guint8 id, t; + gint8 tmp_class; + gboolean tmp_pc; + gint32 tmp_tag; - id = tvb_get_guint8(tvb, offset); - offset += 1; + id = tvb_get_guint8(tvb, offset); + offset += 1; #ifdef DEBUG_BER printf ("BER ID=%02x", id); #endif - /* 8.1.2.2 */ - tmp_class = (id>>6) & 0x03; - tmp_pc = (id>>5) & 0x01; - tmp_tag = id&0x1F; - /* 8.1.2.4 */ - if (tmp_tag == 0x1F) { - tmp_tag = 0; - while (tvb_length_remaining(tvb, offset) > 0) { - t = tvb_get_guint8(tvb, offset); + /* 8.1.2.2 */ + tmp_class = (id>>6) & 0x03; + tmp_pc = (id>>5) & 0x01; + tmp_tag = id&0x1F; + /* 8.1.2.4 */ + if (tmp_tag == 0x1F) { + tmp_tag = 0; + while (tvb_length_remaining(tvb, offset) > 0) { + t = tvb_get_guint8(tvb, offset); #ifdef DEBUG_BER printf (" %02x", t); #endif - offset += 1; - tmp_tag <<= 7; - tmp_tag |= t & 0x7F; - if (!(t & 0x80)) break; - } - } + offset += 1; + tmp_tag <<= 7; + tmp_tag |= t & 0x7F; + if (!(t & 0x80)) + break; + } + } #ifdef DEBUG_BER printf ("\n"); #endif - if (ber_class) - *ber_class = tmp_class; - if (pc) - *pc = tmp_pc; - if (tag) - *tag = tmp_tag; + if (ber_class) + *ber_class = tmp_class; + if (pc) + *pc = tmp_pc; + if (tag) + *tag = tmp_tag; - last_class = tmp_class; - last_pc = tmp_pc; - last_tag = tmp_tag; + last_class = tmp_class; + last_pc = tmp_pc; + last_tag = tmp_tag; - return offset; + return offset; } static void get_last_ber_identifier(gint8 *ber_class, gboolean *pc, gint32 *tag) { - if (ber_class) - *ber_class = last_class; - if (pc) - *pc = last_pc; - if (tag) - *tag = last_tag; + if (ber_class) + *ber_class = last_class; + if (pc) + *pc = last_pc; + if (tag) + *tag = last_tag; } int dissect_ber_identifier(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gint8 *ber_class, gboolean *pc, gint32 *tag) { - int old_offset = offset; - gint8 tmp_class; - gboolean tmp_pc; - gint32 tmp_tag; - - offset = get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag); - - if(show_internal_ber_fields){ - proto_tree_add_uint(tree, hf_ber_id_class, tvb, old_offset, 1, tmp_class<<6); - proto_tree_add_boolean(tree, hf_ber_id_pc, tvb, old_offset, 1, (tmp_pc)?0x20:0x00); - if(tmp_tag>0x1F){ - if(tmp_class==BER_CLASS_UNI){ - proto_tree_add_uint(tree, hf_ber_id_uni_tag_ext, tvb, old_offset + 1, offset - (old_offset + 1), tmp_tag); - } else { - proto_tree_add_uint(tree, hf_ber_id_tag_ext, tvb, old_offset + 1, offset - (old_offset + 1), tmp_tag); - } - } else { - if(tmp_class==BER_CLASS_UNI){ - proto_tree_add_uint(tree, hf_ber_id_uni_tag, tvb, old_offset, 1, tmp_tag); - } else { - proto_tree_add_uint(tree, hf_ber_id_tag, tvb, old_offset, 1, tmp_tag); - } - } - } - - if(ber_class) - *ber_class = tmp_class; - if(pc) - *pc = tmp_pc; - if(tag) - *tag = tmp_tag; - - return offset; + int old_offset = offset; + gint8 tmp_class; + gboolean tmp_pc; + gint32 tmp_tag; + + offset = get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag); + + if(show_internal_ber_fields){ + proto_tree_add_uint(tree, hf_ber_id_class, tvb, old_offset, 1, tmp_class<<6); + proto_tree_add_boolean(tree, hf_ber_id_pc, tvb, old_offset, 1, (tmp_pc)?0x20:0x00); + if(tmp_tag>0x1F){ + if(tmp_class==BER_CLASS_UNI){ + proto_tree_add_uint(tree, hf_ber_id_uni_tag_ext, tvb, old_offset + 1, offset - (old_offset + 1), tmp_tag); + } else { + proto_tree_add_uint(tree, hf_ber_id_tag_ext, tvb, old_offset + 1, offset - (old_offset + 1), tmp_tag); + } + } else { + if(tmp_class==BER_CLASS_UNI){ + proto_tree_add_uint(tree, hf_ber_id_uni_tag, tvb, old_offset, 1, tmp_tag); + } else { + proto_tree_add_uint(tree, hf_ber_id_tag, tvb, old_offset, 1, tmp_tag); + } + } + } + + if(ber_class) + *ber_class = tmp_class; + if(pc) + *pc = tmp_pc; + if(tag) + *tag = tmp_tag; + + return offset; } /** Try to get the length octets of the BER TLV. @@ -1128,85 +1129,85 @@ int dissect_ber_identifier(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *t static int try_get_ber_length(tvbuff_t *tvb, int offset, guint32 *length, gboolean *ind, gint nest_level) { - guint8 oct, len; - guint32 indef_len; - guint32 tmp_length; - gboolean tmp_ind; - int tmp_offset,s_offset; - gint8 tclass; - gboolean tpc; - gint32 ttag; - tmp_length = 0; - tmp_ind = FALSE; - - if (nest_level > BER_MAX_NESTING) { - /* Assume that we have a malformed packet. */ - THROW(ReportedBoundsError); - } - - oct = tvb_get_guint8(tvb, offset); - offset += 1; - - if(!(oct&0x80)) { - /* 8.1.3.4 */ - tmp_length = oct; - } else { - len = oct & 0x7F; - if(len) { - /* 8.1.3.5 */ - while (len--) { - oct = tvb_get_guint8(tvb, offset); - offset++; - tmp_length = (tmp_length<<8) + oct; - } - } else { - /* 8.1.3.6 */ - - tmp_offset = offset; - /* ok in here we can traverse the BER to find the length, this will fix most indefinite length issues */ - /* Assumption here is that indefinite length is always used on constructed types*/ - /* check for EOC */ - while (tvb_get_guint8(tvb, offset) || tvb_get_guint8(tvb, offset+1)) { - /* not an EOC at offset */ - s_offset=offset; - offset= get_ber_identifier(tvb, offset, &tclass, &tpc, &ttag); - offset= try_get_ber_length(tvb,offset, &indef_len, NULL, nest_level+1); - tmp_length += indef_len+(offset-s_offset); /* length + tag and length */ - offset += indef_len; + guint8 oct, len; + guint32 indef_len; + guint32 tmp_length; + gboolean tmp_ind; + int tmp_offset,s_offset; + gint8 tclass; + gboolean tpc; + gint32 ttag; + tmp_length = 0; + tmp_ind = FALSE; + + if (nest_level > BER_MAX_NESTING) { + /* Assume that we have a malformed packet. */ + THROW(ReportedBoundsError); + } + + oct = tvb_get_guint8(tvb, offset); + offset += 1; + + if(!(oct&0x80)) { + /* 8.1.3.4 */ + tmp_length = oct; + } else { + len = oct & 0x7F; + if(len) { + /* 8.1.3.5 */ + while (len--) { + oct = tvb_get_guint8(tvb, offset); + offset++; + tmp_length = (tmp_length<<8) + oct; + } + } else { + /* 8.1.3.6 */ + + tmp_offset = offset; + /* ok in here we can traverse the BER to find the length, this will fix most indefinite length issues */ + /* Assumption here is that indefinite length is always used on constructed types*/ + /* check for EOC */ + while (tvb_get_guint8(tvb, offset) || tvb_get_guint8(tvb, offset+1)) { + /* not an EOC at offset */ + s_offset=offset; + offset= get_ber_identifier(tvb, offset, &tclass, &tpc, &ttag); + offset= try_get_ber_length(tvb,offset, &indef_len, NULL, nest_level+1); + tmp_length += indef_len+(offset-s_offset); /* length + tag and length */ + offset += indef_len; /* Make sure we've moved forward in the packet */ - if (offset <= s_offset) - THROW(ReportedBoundsError); - } - tmp_length += 2; - tmp_ind = TRUE; - offset = tmp_offset; - } - } - - if (length) - *length = tmp_length; - if (ind) - *ind = tmp_ind; + if (offset <= s_offset) + THROW(ReportedBoundsError); + } + tmp_length += 2; + tmp_ind = TRUE; + offset = tmp_offset; + } + } + + if (length) + *length = tmp_length; + if (ind) + *ind = tmp_ind; #ifdef DEBUG_BER printf("get BER length %d, offset %d (remaining %d)\n", tmp_length, offset, tvb_length_remaining(tvb, offset)); #endif - return offset; + return offset; } int get_ber_length(tvbuff_t *tvb, int offset, guint32 *length, gboolean *ind) { - return try_get_ber_length(tvb, offset, length, ind, 1); + return try_get_ber_length(tvb, offset, length, ind, 1); } static void get_last_ber_length(guint32 *length, gboolean *ind) { - if (length) - *length = last_length; - if (ind) - *ind = last_ind; + if (length) + *length = last_length; + if (ind) + *ind = last_ind; } /* this function dissects the length octets of the BER TLV. @@ -1215,152 +1216,152 @@ static void get_last_ber_length(guint32 *length, gboolean *ind) int dissect_ber_length(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, guint32 *length, gboolean *ind) { - int old_offset = offset; - guint32 tmp_length; - gboolean tmp_ind; - - offset = get_ber_length(tvb, offset, &tmp_length, &tmp_ind); - - if(show_internal_ber_fields){ - if(tmp_ind){ - proto_tree_add_text(tree, tvb, old_offset, 1, "Length: Indefinite length %d", tmp_length); - } else { - proto_tree_add_uint(tree, hf_ber_length, tvb, old_offset, offset - old_offset, tmp_length); - } - } - if(length) - *length = tmp_length; - if(ind) - *ind = tmp_ind; + int old_offset = offset; + guint32 tmp_length; + gboolean tmp_ind; + + offset = get_ber_length(tvb, offset, &tmp_length, &tmp_ind); + + if(show_internal_ber_fields){ + if(tmp_ind){ + proto_tree_add_text(tree, tvb, old_offset, 1, "Length: Indefinite length %d", tmp_length); + } else { + proto_tree_add_uint(tree, hf_ber_length, tvb, old_offset, offset - old_offset, tmp_length); + } + } + if(length) + *length = tmp_length; + if(ind) + *ind = tmp_ind; #ifdef DEBUG_BER printf("dissect BER length %d, offset %d (remaining %d)\n", tmp_length, offset, tvb_length_remaining(tvb, offset)); #endif - last_length = tmp_length; - last_ind = tmp_ind; + last_length = tmp_length; + last_ind = tmp_ind; - return offset; + return offset; } static GHashTable *octet_segment_table = NULL; static GHashTable *octet_reassembled_table = NULL; static void ber_defragment_init(void) { - fragment_table_init(&octet_segment_table); - reassembled_table_init(&octet_reassembled_table); + fragment_table_init(&octet_segment_table); + reassembled_table_init(&octet_reassembled_table); } static int reassemble_octet_string(asn1_ctx_t *actx, proto_tree *tree, gint hf_id, tvbuff_t *tvb, int offset, guint32 con_len, gboolean ind, tvbuff_t **out_tvb) { - fragment_data *fd_head = NULL; - tvbuff_t *next_tvb = NULL; - tvbuff_t *reassembled_tvb = NULL; - guint16 dst_ref = 0; - int start_offset = offset; - gboolean fragment = TRUE; - gboolean firstFragment = TRUE; + fragment_data *fd_head = NULL; + tvbuff_t *next_tvb = NULL; + tvbuff_t *reassembled_tvb = NULL; + guint16 dst_ref = 0; + int start_offset = offset; + gboolean fragment = TRUE; + gboolean firstFragment = TRUE; - /* so we need to consume octet strings for the given length */ + /* so we need to consume octet strings for the given length */ - if(out_tvb) - *out_tvb=NULL; + if(out_tvb) + *out_tvb=NULL; - if (con_len == 0) /* Zero encodings (8.7.3) */ - return offset; + if (con_len == 0) /* Zero encodings (8.7.3) */ + return offset; - /* not sure we need this */ - actx->pinfo->fragmented = TRUE; + /* not sure we need this */ + actx->pinfo->fragmented = TRUE; - while(!fd_head) { + while(!fd_head) { - offset = dissect_ber_octet_string(FALSE, actx, NULL, tvb, offset, hf_id, &next_tvb); + offset = dissect_ber_octet_string(FALSE, actx, NULL, tvb, offset, hf_id, &next_tvb); - if (next_tvb == NULL) { - /* Assume that we have a malformed packet. */ - THROW(ReportedBoundsError); - } + if (next_tvb == NULL) { + /* Assume that we have a malformed packet. */ + THROW(ReportedBoundsError); + } - if(ind) { - /* this was indefinite length - so check for EOC */ + if(ind) { + /* this was indefinite length - so check for EOC */ - if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)) { - fragment = FALSE; - /* skip past EOC */ - offset +=2; - } - } else { + if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)) { + fragment = FALSE; + /* skip past EOC */ + offset +=2; + } + } else { - if((guint32)(offset - start_offset) >= con_len) - fragment = FALSE; - } + if((guint32)(offset - start_offset) >= con_len) + fragment = FALSE; + } - if(!fragment && firstFragment) { - /* there is only one fragment (I'm sure there's a reason it was constructed) */ - /* anyway, we can get out of here */ - gboolean pc; - get_ber_identifier(tvb, start_offset, NULL, &pc, NULL); - if (!pc && tree) { - /* Only display here if not constructed */ - dissect_ber_octet_string(FALSE, actx, tree, tvb, start_offset, hf_id, NULL); - } - reassembled_tvb = next_tvb; - break; - } + if(!fragment && firstFragment) { + /* there is only one fragment (I'm sure there's a reason it was constructed) */ + /* anyway, we can get out of here */ + gboolean pc; + get_ber_identifier(tvb, start_offset, NULL, &pc, NULL); + if (!pc && tree) { + /* Only display here if not constructed */ + dissect_ber_octet_string(FALSE, actx, tree, tvb, start_offset, hf_id, NULL); + } + reassembled_tvb = next_tvb; + break; + } - if (tvb_length(next_tvb) < 1) { - /* Don't cause an assertion in the reassembly code. */ - THROW(ReportedBoundsError); - } - fd_head = fragment_add_seq_next(next_tvb, 0, actx->pinfo, dst_ref, - octet_segment_table, - octet_reassembled_table, - tvb_length(next_tvb), - fragment); + if (tvb_length(next_tvb) < 1) { + /* Don't cause an assertion in the reassembly code. */ + THROW(ReportedBoundsError); + } + fd_head = fragment_add_seq_next(next_tvb, 0, actx->pinfo, dst_ref, + octet_segment_table, + octet_reassembled_table, + tvb_length(next_tvb), + fragment); - firstFragment = FALSE; - } + firstFragment = FALSE; + } - if(fd_head) { - if(fd_head->next) { - /* not sure I really want to do this here - should be nearer the application where we can give it a better name*/ - proto_tree *next_tree; - proto_item *frag_tree_item; + if(fd_head) { + if(fd_head->next) { + /* not sure I really want to do this here - should be nearer the application where we can give it a better name*/ + proto_tree *next_tree; + proto_item *frag_tree_item; - reassembled_tvb = tvb_new_child_real_data(next_tvb, fd_head->data, fd_head->len, fd_head->len); + reassembled_tvb = tvb_new_child_real_data(next_tvb, fd_head->data, fd_head->len, fd_head->len); - actx->created_item = proto_tree_add_item(tree, hf_id, reassembled_tvb, 0, -1, ENC_BIG_ENDIAN); - next_tree = proto_item_add_subtree (actx->created_item, ett_ber_reassembled_octet_string); + actx->created_item = proto_tree_add_item(tree, hf_id, reassembled_tvb, 0, -1, ENC_BIG_ENDIAN); + next_tree = proto_item_add_subtree (actx->created_item, ett_ber_reassembled_octet_string); - add_new_data_source(actx->pinfo, reassembled_tvb, "Reassembled OCTET STRING"); - show_fragment_seq_tree(fd_head, &octet_string_frag_items, next_tree, actx->pinfo, reassembled_tvb, &frag_tree_item); + add_new_data_source(actx->pinfo, reassembled_tvb, "Reassembled OCTET STRING"); + show_fragment_seq_tree(fd_head, &octet_string_frag_items, next_tree, actx->pinfo, reassembled_tvb, &frag_tree_item); + } } - } - if(out_tvb) - *out_tvb = reassembled_tvb; + if(out_tvb) + *out_tvb = reassembled_tvb; - /* again - not sure we need this */ - actx->pinfo->fragmented = FALSE; + /* again - not sure we need this */ + actx->pinfo->fragmented = FALSE; - return offset; + return offset; } /* 8.7 Encoding of an octetstring value */ int dissect_ber_constrained_octet_string(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint32 min_len, gint32 max_len, gint hf_id, tvbuff_t **out_tvb) { - gint8 ber_class; - gboolean pc, ind; - gint32 tag; - guint32 len; - int hoffset; - int end_offset; - proto_item *it, *cause; - guint32 i; - guint32 len_remain; + gint8 ber_class; + gboolean pc, ind; + gint32 tag; + guint32 len; + int hoffset; + int end_offset; + proto_item *it, *cause; + guint32 i; + guint32 len_remain; #ifdef DEBUG_BER { @@ -1380,97 +1381,97 @@ printf("OCTET STRING dissect_ber_octet_string(%s) entered\n",name); } #endif - if(out_tvb) - *out_tvb=NULL; - - if (!implicit_tag) { - hoffset = offset; - /* read header and len for the octet string */ - offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); - offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind); - end_offset=offset+len; - - /* sanity check: we only handle Constructed Universal Sequences */ - if ((ber_class!=BER_CLASS_APP)&&(ber_class!=BER_CLASS_PRI)) - - if( (ber_class!=BER_CLASS_UNI) - ||((tag<BER_UNI_TAG_NumericString)&&(tag!=BER_UNI_TAG_OCTETSTRING)&&(tag!=BER_UNI_TAG_UTF8String)) ){ - tvb_ensure_bytes_exist(tvb, hoffset, 2); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "octetstring_expected", "BER Error: OctetString expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: OctetString expected"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - return end_offset; - } - } else { - /* implicit tag so get from last tag/length */ - - get_last_ber_identifier(&ber_class, &pc, &tag); - get_last_ber_length(&len, &ind); - - end_offset=offset+len; - - /* caller may have created new buffer for indefinite length data Verify via length */ - len_remain = (guint32)tvb_length_remaining(tvb, offset); - if((ind) && (len_remain == len - 2)) { - /* new buffer received so adjust length and indefinite flag */ - len -=2; - end_offset -= 2; - ind = FALSE; - } else if (len_remain < len) { - /* - * error - short frame, or this item runs past the - * end of the item containing it - */ - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "illegal_length", "BER Error: length:%u longer than tvb_length_remaining:%d", len, len_remain); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error length"); - return end_offset; - } - - } - - actx->created_item = NULL; - - if (pc) { - /* constructed */ - end_offset = reassemble_octet_string(actx, tree, hf_id, tvb, offset, len, ind, out_tvb); - } else { - /* primitive */ - gint length_remaining; - - length_remaining = tvb_length_remaining(tvb, offset); + if(out_tvb) + *out_tvb=NULL; + + if (!implicit_tag) { + hoffset = offset; + /* read header and len for the octet string */ + offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind); + end_offset=offset+len; + + /* sanity check: we only handle Constructed Universal Sequences */ + if ((ber_class!=BER_CLASS_APP)&&(ber_class!=BER_CLASS_PRI)) + + if( (ber_class!=BER_CLASS_UNI) + ||((tag<BER_UNI_TAG_NumericString)&&(tag!=BER_UNI_TAG_OCTETSTRING)&&(tag!=BER_UNI_TAG_UTF8String)) ){ + tvb_ensure_bytes_exist(tvb, hoffset, 2); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "octetstring_expected", "BER Error: OctetString expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: OctetString expected"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + return end_offset; + } + } else { + /* implicit tag so get from last tag/length */ + + get_last_ber_identifier(&ber_class, &pc, &tag); + get_last_ber_length(&len, &ind); + + end_offset=offset+len; + + /* caller may have created new buffer for indefinite length data Verify via length */ + len_remain = (guint32)tvb_length_remaining(tvb, offset); + if((ind) && (len_remain == len - 2)) { + /* new buffer received so adjust length and indefinite flag */ + len -=2; + end_offset -= 2; + ind = FALSE; + } else if (len_remain < len) { + /* + * error - short frame, or this item runs past the + * end of the item containing it + */ + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "illegal_length", "BER Error: length:%u longer than tvb_length_remaining:%d", len, len_remain); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error length"); + return end_offset; + } + + } + + actx->created_item = NULL; + + if (pc) { + /* constructed */ + end_offset = reassemble_octet_string(actx, tree, hf_id, tvb, offset, len, ind, out_tvb); + } else { + /* primitive */ + gint length_remaining; + + length_remaining = tvb_length_remaining(tvb, offset); #if 0 - if(length_remaining<1){ - return end_offset; - } + if(length_remaining<1){ + return end_offset; + } #endif - if(len<=(guint32)length_remaining){ - length_remaining=len; - } - if(hf_id >= 0) { - it = ber_proto_tree_add_item(actx->pinfo, tree, hf_id, tvb, offset, length_remaining, ENC_BIG_ENDIAN); - actx->created_item = it; - ber_check_length(length_remaining, min_len, max_len, actx, it, ENC_BIG_ENDIAN); - } else { - proto_item *pi; - - pi=proto_tree_add_text(tree, tvb, offset, len, "Unknown OctetString: Length: 0x%02x, Value: 0x", len); - if(pi){ - for(i=0;i<len;i++){ - proto_item_append_text(pi,"%02x",tvb_get_guint8(tvb, offset)); - offset++; - } - } - } - - if(out_tvb) { - *out_tvb = tvb_new_subset(tvb, offset, length_remaining, len); - } - } - return end_offset; + if(len<=(guint32)length_remaining){ + length_remaining=len; + } + if(hf_id >= 0) { + it = ber_proto_tree_add_item(actx->pinfo, tree, hf_id, tvb, offset, length_remaining, ENC_BIG_ENDIAN); + actx->created_item = it; + ber_check_length(length_remaining, min_len, max_len, actx, it, ENC_BIG_ENDIAN); + } else { + proto_item *pi; + + pi=proto_tree_add_text(tree, tvb, offset, len, "Unknown OctetString: Length: 0x%02x, Value: 0x", len); + if(pi){ + for(i=0;i<len;i++){ + proto_item_append_text(pi,"%02x",tvb_get_guint8(tvb, offset)); + offset++; + } + } + } + + if(out_tvb) { + *out_tvb = tvb_new_subset(tvb, offset, length_remaining, len); + } + } + return end_offset; } int @@ -1480,75 +1481,75 @@ dissect_ber_octet_string(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tr int dissect_ber_octet_string_wcb(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, ber_callback func) { - tvbuff_t *out_tvb = NULL; - - offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_id, (func)?&out_tvb:NULL); - if (func && out_tvb && (tvb_length(out_tvb)>0)) { - if (hf_id >= 0) - tree = proto_item_add_subtree(actx->created_item, ett_ber_octet_string); - /* TODO Should hf_id2 be pased as last parameter???*/ - func(FALSE, out_tvb, 0, actx, tree, -1); - } - return offset; + tvbuff_t *out_tvb = NULL; + + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_id, (func)?&out_tvb:NULL); + if (func && out_tvb && (tvb_length(out_tvb)>0)) { + if (hf_id >= 0) + tree = proto_item_add_subtree(actx->created_item, ett_ber_octet_string); + /* TODO Should hf_id2 be pased as last parameter???*/ + func(FALSE, out_tvb, 0, actx, tree, -1); + } + return offset; } int dissect_ber_old_octet_string_wcb(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, ber_old_callback func) { - tvbuff_t *out_tvb = NULL; - - offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_id, (func)?&out_tvb:NULL); - if (func && out_tvb && (tvb_length(out_tvb)>0)) { - if (hf_id >= 0) - tree = proto_item_add_subtree(actx->created_item, ett_ber_octet_string); - /* TODO Should hf_id2 be pased as last parameter???*/ - func(tree, out_tvb, 0, actx); - } - return offset; + tvbuff_t *out_tvb = NULL; + + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_id, (func)?&out_tvb:NULL); + if (func && out_tvb && (tvb_length(out_tvb)>0)) { + if (hf_id >= 0) + tree = proto_item_add_subtree(actx->created_item, ett_ber_octet_string); + /* TODO Should hf_id2 be pased as last parameter???*/ + func(tree, out_tvb, 0, actx); + } + return offset; } /* 8.8 Encoding of a null value */ int dissect_ber_null(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id) { - gint8 ber_class; - gboolean pc; - gint32 tag; - guint32 len; - int offset_old; - proto_item* cause; - -if (!implicit_tag) -{ - offset_old = offset; - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); - if((pc) || - (!implicit_tag && ((ber_class != BER_CLASS_UNI) || (tag != BER_UNI_TAG_NULL)))) { - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset_old, offset - offset_old, "null_expected", "BER Error: NULL expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: NULL expected"); - } - - offset_old = offset; - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL); - if(len) { - proto_tree_add_string_format(tree, hf_ber_error, tvb, offset_old, offset - offset_old, "illegal_length", "BER Error: NULL expect zero length but Length=%d", len); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "unexpected_data", "BER Error: unexpected data in NULL type"); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: NULL expect zero length"); - offset += len; - } -} - if (hf_id >= 0) - proto_tree_add_item(tree, hf_id, tvb, offset, 0, ENC_BIG_ENDIAN); - return offset; + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 len; + int offset_old; + proto_item* cause; + + if (!implicit_tag) + { + offset_old = offset; + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + if((pc) || + (!implicit_tag && ((ber_class != BER_CLASS_UNI) || (tag != BER_UNI_TAG_NULL)))) { + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset_old, offset - offset_old, "null_expected", "BER Error: NULL expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: NULL expected"); + } + + offset_old = offset; + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL); + if(len) { + proto_tree_add_string_format(tree, hf_ber_error, tvb, offset_old, offset - offset_old, "illegal_length", "BER Error: NULL expect zero length but Length=%d", len); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "unexpected_data", "BER Error: unexpected data in NULL type"); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: NULL expect zero length"); + offset += len; + } + } + if (hf_id >= 0) + proto_tree_add_item(tree, hf_id, tvb, offset, 0, ENC_BIG_ENDIAN); + return offset; } int dissect_ber_integer64(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, gint64 *value) { - gint8 ber_class; - gboolean pc; - gint32 tag; - guint32 len; - gint64 val; - guint32 i; - gboolean used_too_many_bytes = FALSE; + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 len; + gint64 val; + guint32 i; + gboolean used_too_many_bytes = FALSE; #ifdef DEBUG_BER { @@ -1569,239 +1570,239 @@ printf("INTEGERnew dissect_ber_integer(%s) entered implicit_tag:%d \n",name,impl #endif - if(value){ - *value=0; - } - - if(!implicit_tag){ - offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); - offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL); - } else { - gint32 remaining=tvb_length_remaining(tvb, offset); - len=remaining>0 ? remaining : 0; - } - - /* we cant handle integers > 64 bits */ - if(len>8){ - header_field_info *hfinfo; - proto_item *pi = NULL; - - if (hf_id >= 0) { - hfinfo = proto_registrar_get_nth(hf_id); - pi=proto_tree_add_text(tree, tvb, offset, len, "%s : 0x", hfinfo->name); - } - if(pi){ - for(i=0;i<len;i++){ - proto_item_append_text(pi,"%02x",tvb_get_guint8(tvb, offset)); - offset++; - } - } else { - offset += len; - } - return offset; - } - - val=0; - if(len > 0) { - /* extend sign bit */ - guint8 first = tvb_get_guint8(tvb, offset); - if(first & 0x80){ - val=-1; - } - if(len > 1) { - guint8 second = tvb_get_guint8(tvb, offset+1); - if((first == 0x00 && (second & 0x80) == 0) || - (first == 0xff && (second & 0x80))) - { - used_too_many_bytes = TRUE; - } - } - for(i=0;i<len;i++){ - val=(val<<8)|tvb_get_guint8(tvb, offset); - offset++; - } - } - - actx->created_item=NULL; - - if(hf_id >= 0){ - /* */ - if(len < 1 || len > 8) { - proto_item *pi = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset-len, len, "invalid length", "BER Error: Can't handle integer length: %u", len); - expert_add_info_format(actx->pinfo, pi, PI_MALFORMED, PI_WARN, "BER Error: Illegal integer length: %u", len); - } else { - header_field_info* hfi; - - hfi = proto_registrar_get_nth(hf_id); - switch(hfi->type){ - case FT_UINT8: - case FT_UINT16: - case FT_UINT24: - case FT_UINT32: - actx->created_item=proto_tree_add_uint(tree, hf_id, tvb, offset-len, len, (guint32)val); - break; - case FT_INT8: - case FT_INT16: - case FT_INT24: - case FT_INT32: - actx->created_item=proto_tree_add_int(tree, hf_id, tvb, offset-len, len, (gint32)val); - break; - case FT_INT64: - actx->created_item=proto_tree_add_int64(tree, hf_id, tvb, offset-len, len, val); - break; - case FT_UINT64: - actx->created_item=proto_tree_add_uint64(tree, hf_id, tvb, offset-len, len, (guint64)val); - break; - default: - DISSECTOR_ASSERT_NOT_REACHED(); - } - - if (used_too_many_bytes) { - expert_add_info_format(actx->pinfo, actx->created_item, PI_PROTOCOL, PI_WARN, - "Value is encoded with too many bytes(9 leading zero or one bits), hf_abbr: %s",hfi->abbrev); - } - } - } - - if(value){ - *value=val; - } - - return offset; + if(value){ + *value=0; + } + + if(!implicit_tag){ + offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL); + } else { + gint32 remaining=tvb_length_remaining(tvb, offset); + len=remaining>0 ? remaining : 0; + } + + /* we cant handle integers > 64 bits */ + if(len>8){ + header_field_info *hfinfo; + proto_item *pi = NULL; + + if (hf_id >= 0) { + hfinfo = proto_registrar_get_nth(hf_id); + pi=proto_tree_add_text(tree, tvb, offset, len, "%s : 0x", hfinfo->name); + } + if(pi){ + for(i=0;i<len;i++){ + proto_item_append_text(pi,"%02x",tvb_get_guint8(tvb, offset)); + offset++; + } + } else { + offset += len; + } + return offset; + } + + val=0; + if(len > 0) { + /* extend sign bit */ + guint8 first = tvb_get_guint8(tvb, offset); + if(first & 0x80){ + val=-1; + } + if(len > 1) { + guint8 second = tvb_get_guint8(tvb, offset+1); + if((first == 0x00 && (second & 0x80) == 0) || + (first == 0xff && (second & 0x80))) + { + used_too_many_bytes = TRUE; + } + } + for(i=0;i<len;i++){ + val=(val<<8)|tvb_get_guint8(tvb, offset); + offset++; + } + } + + actx->created_item=NULL; + + if(hf_id >= 0){ + /* */ + if(len < 1 || len > 8) { + proto_item *pi = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset-len, len, "invalid length", "BER Error: Can't handle integer length: %u", len); + expert_add_info_format(actx->pinfo, pi, PI_MALFORMED, PI_WARN, "BER Error: Illegal integer length: %u", len); + } else { + header_field_info* hfi; + + hfi = proto_registrar_get_nth(hf_id); + switch(hfi->type){ + case FT_UINT8: + case FT_UINT16: + case FT_UINT24: + case FT_UINT32: + actx->created_item=proto_tree_add_uint(tree, hf_id, tvb, offset-len, len, (guint32)val); + break; + case FT_INT8: + case FT_INT16: + case FT_INT24: + case FT_INT32: + actx->created_item=proto_tree_add_int(tree, hf_id, tvb, offset-len, len, (gint32)val); + break; + case FT_INT64: + actx->created_item=proto_tree_add_int64(tree, hf_id, tvb, offset-len, len, val); + break; + case FT_UINT64: + actx->created_item=proto_tree_add_uint64(tree, hf_id, tvb, offset-len, len, (guint64)val); + break; + default: + DISSECTOR_ASSERT_NOT_REACHED(); + } + + if (used_too_many_bytes) { + expert_add_info_format(actx->pinfo, actx->created_item, PI_PROTOCOL, PI_WARN, + "Value is encoded with too many bytes(9 leading zero or one bits), hf_abbr: %s",hfi->abbrev); + } + } + } + + if(value){ + *value=val; + } + + return offset; } int dissect_ber_constrained_integer64(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint64 min_len, gint64 max_len, gint hf_id, gint64 *value) { - gint64 val; + gint64 val; - offset=dissect_ber_integer64(implicit_tag, actx, tree, tvb, offset, hf_id, &val); - if(value){ - *value=val; - } + offset=dissect_ber_integer64(implicit_tag, actx, tree, tvb, offset, hf_id, &val); + if(value){ + *value=val; + } - ber_check_value64 (val, min_len, max_len, actx, actx->created_item); + ber_check_value64 (val, min_len, max_len, actx, actx->created_item); - return offset; + return offset; } int dissect_ber_integer(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, guint32 *value) { - gint64 val; + gint64 val; - offset=dissect_ber_integer64(implicit_tag, actx, tree, tvb, offset, hf_id, &val); - if(value){ - *value=(guint32)val; - } + offset=dissect_ber_integer64(implicit_tag, actx, tree, tvb, offset, hf_id, &val); + if(value){ + *value=(guint32)val; + } - return offset; + return offset; } int dissect_ber_constrained_integer(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint32 min_len, gint32 max_len, gint hf_id, guint32 *value) { - gint64 val; + gint64 val; - offset=dissect_ber_integer64(implicit_tag, actx, tree, tvb, offset, hf_id, &val); - if(value){ - *value=(guint32)val; - } + offset=dissect_ber_integer64(implicit_tag, actx, tree, tvb, offset, hf_id, &val); + if(value){ + *value=(guint32)val; + } - ber_check_value ((guint32)val, min_len, max_len, actx, actx->created_item); + ber_check_value ((guint32)val, min_len, max_len, actx, actx->created_item); - return offset; + return offset; } int dissect_ber_boolean(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, gboolean *value) { - gint8 ber_class; - gboolean pc; - gint32 tag; - guint32 len; - guint8 val; - header_field_info *hfi; - - if(!implicit_tag){ - offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); - offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL); - /*if(ber_class!=BER_CLASS_UNI)*/ - } else { - /* nothing to do here, yet */ - } + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 len; + guint8 val; + header_field_info *hfi; + + if(!implicit_tag){ + offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL); + /*if(ber_class!=BER_CLASS_UNI)*/ + } else { + /* nothing to do here, yet */ + } - val=tvb_get_guint8(tvb, offset); - offset+=1; + val=tvb_get_guint8(tvb, offset); + offset+=1; - actx->created_item=NULL; + actx->created_item=NULL; - if(hf_id >= 0){ - hfi = proto_registrar_get_nth(hf_id); - if(hfi->type == FT_BOOLEAN) - actx->created_item=proto_tree_add_boolean(tree, hf_id, tvb, offset-1, 1, val); - else - actx->created_item=proto_tree_add_uint(tree, hf_id, tvb, offset-1, 1, val?1:0); - } + if(hf_id >= 0){ + hfi = proto_registrar_get_nth(hf_id); + if(hfi->type == FT_BOOLEAN) + actx->created_item=proto_tree_add_boolean(tree, hf_id, tvb, offset-1, 1, val); + else + actx->created_item=proto_tree_add_uint(tree, hf_id, tvb, offset-1, 1, val?1:0); + } - if(value){ - *value=(val?TRUE:ENC_BIG_ENDIAN); - } + if(value){ + *value=(val?TRUE:ENC_BIG_ENDIAN); + } - return offset; + return offset; } -/* 8.5 Encoding of a real value */ +/* 8.5 Encoding of a real value */ /* NOT Tested*/ int dissect_ber_real(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id _U_, double *value) { - gint8 ber_class; - gboolean pc; - gint32 tag; - guint32 val_length = 0, end_offset; - double val = 0; - - if(!implicit_tag){ - offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); - offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &val_length, NULL); - } else { - /* 8.5.1 The encoding of a real value shall be primitive. */ - DISSECTOR_ASSERT_NOT_REACHED(); - } - /* 8.5.2 If the real value is the value zero, - * there shall be no contents octets in the encoding. - */ - if (val_length==0){ - if (value) - *value = 0; - return offset; - } - end_offset = offset + val_length; - - val = asn1_get_real(tvb_get_ptr(tvb, offset, val_length), val_length); - actx->created_item = proto_tree_add_double(tree, hf_id, tvb, offset, val_length, val); - - if (value) *value = val; - - return end_offset; + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 val_length = 0, end_offset; + double val = 0; + + if(!implicit_tag){ + offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &val_length, NULL); + } else { + /* 8.5.1 The encoding of a real value shall be primitive. */ + DISSECTOR_ASSERT_NOT_REACHED(); + } + /* 8.5.2 If the real value is the value zero, + * there shall be no contents octets in the encoding. + */ + if (val_length==0){ + if (value) + *value = 0; + return offset; + } + end_offset = offset + val_length; + + val = asn1_get_real(tvb_get_ptr(tvb, offset, val_length), val_length); + actx->created_item = proto_tree_add_double(tree, hf_id, tvb, offset, val_length, val); + + if (value) *value = val; + + return end_offset; } /* this function dissects a BER sequence */ int dissect_ber_sequence(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const ber_sequence_t *seq, gint hf_id, gint ett_id) { - gint8 classx; - gboolean pcx, ind = 0, ind_field, imp_tag=FALSE; - gint32 tagx; - guint32 lenx; - proto_tree *tree = parent_tree; - proto_item *item = NULL; - proto_item *cause; - int end_offset = 0; - int hoffset; - gint length_remaining; - tvbuff_t *next_tvb; + gint8 classx; + gboolean pcx, ind = 0, ind_field, imp_tag=FALSE; + gint32 tagx; + guint32 lenx; + proto_tree *tree = parent_tree; + proto_item *item = NULL; + proto_item *cause; + int end_offset = 0; + int hoffset; + gint length_remaining; + tvbuff_t *next_tvb; #ifdef DEBUG_BER { @@ -1820,216 +1821,218 @@ printf("SEQUENCE dissect_ber_sequence(%s) entered\n",name); } } #endif - hoffset = offset; - if(!implicit_tag) { - offset = get_ber_identifier(tvb, offset, NULL, NULL, NULL); - offset = get_ber_length(tvb, offset, &lenx, NULL); - } else { - /* was implicit tag so just use the length of the tvb */ - lenx=tvb_length_remaining(tvb,offset); - end_offset=offset+lenx; - } - /* create subtree */ - if(hf_id >= 0) { - if(parent_tree){ - item = proto_tree_add_item(parent_tree, hf_id, tvb, hoffset, lenx + offset - hoffset, ENC_BIG_ENDIAN); - tree = proto_item_add_subtree(item, ett_id); - } - } - offset = hoffset; - - if(!implicit_tag){ - /* first we must read the sequence header */ - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &classx, &pcx, &tagx); - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &lenx, &ind); - if(ind){ - /* Fixed the length is correctly returned from dissect ber_length - end_offset = tvb_length(tvb);*/ - end_offset = offset + lenx -2; - } else { - end_offset = offset + lenx; - } - - /* sanity check: we only handle Constructed Universal Sequences */ - if((classx!=BER_CLASS_APP)&&(classx!=BER_CLASS_PRI)) - if((!pcx) - ||(!implicit_tag&&((classx!=BER_CLASS_UNI) - ||(tagx!=BER_UNI_TAG_SEQUENCE)))) { - tvb_ensure_bytes_exist(tvb, hoffset, 2); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, "sequence_expected", "BER Error: Sequence expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(classx,ber_class_codes,"Unknown"), classx, pcx ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tagx); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Sequence expected"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - return end_offset; - } - } - /* loop over all entries until we reach the end of the sequence */ - while (offset < end_offset){ - gint8 ber_class; - gboolean pc; - gint32 tag; - guint32 len; - int eoffset, count; - - /*if(ind){ this sequence was of indefinite length, if this is implicit indefinite impossible maybe - but ber dissector uses this to eat the tag length then pass into here... EOC still on there...*/ - if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ - /* If the first bytes is 00 00 of a indefenert length field it's a zero length field*/ - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); - dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind); - proto_item_append_text(item," 0 items"); - return end_offset; - /* - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, s_offset, offset+2, "ERROR WRONG SEQ EOC"); - } - return end_offset; - */ - } - /*}*/ - hoffset = offset; - /* read header and len for next field */ - offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); - offset = get_ber_length(tvb, offset, &len, &ind_field); - eoffset = offset + len; + hoffset = offset; + if(!implicit_tag) { + offset = get_ber_identifier(tvb, offset, NULL, NULL, NULL); + offset = get_ber_length(tvb, offset, &lenx, NULL); + } else { + /* was implicit tag so just use the length of the tvb */ + lenx=tvb_length_remaining(tvb,offset); + end_offset=offset+lenx; + } + /* create subtree */ + if(hf_id >= 0) { + if(parent_tree){ + item = proto_tree_add_item(parent_tree, hf_id, tvb, hoffset, lenx + offset - hoffset, ENC_BIG_ENDIAN); + tree = proto_item_add_subtree(item, ett_id); + } + } + offset = hoffset; + + if(!implicit_tag){ + /* first we must read the sequence header */ + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &classx, &pcx, &tagx); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &lenx, &ind); + if(ind){ + /* Fixed the length is correctly returned from dissect ber_length + end_offset = tvb_length(tvb);*/ + end_offset = offset + lenx -2; + } else { + end_offset = offset + lenx; + } + + /* sanity check: we only handle Constructed Universal Sequences */ + if((classx!=BER_CLASS_APP)&&(classx!=BER_CLASS_PRI)) + if((!pcx) + ||(!implicit_tag&&((classx!=BER_CLASS_UNI) + ||(tagx!=BER_UNI_TAG_SEQUENCE)))) { + tvb_ensure_bytes_exist(tvb, hoffset, 2); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, "sequence_expected", "BER Error: Sequence expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(classx,ber_class_codes,"Unknown"), classx, pcx ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tagx); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Sequence expected"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + return end_offset; + } + } + /* loop over all entries until we reach the end of the sequence */ + while (offset < end_offset){ + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 len; + int eoffset, count; + + /*if(ind){ this sequence was of indefinite length, if this is implicit indefinite impossible maybe + but ber dissector uses this to eat the tag length then pass into here... EOC still on there...*/ + if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ + /* If the first bytes is 00 00 of a indefenert length field it's a zero length field*/ + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind); + proto_item_append_text(item," 0 items"); + return end_offset; + /* + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, s_offset, offset+2, "ERROR WRONG SEQ EOC"); + } + return end_offset; + */ + } + /*}*/ + hoffset = offset; + /* read header and len for next field */ + offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); + offset = get_ber_length(tvb, offset, &len, &ind_field); + eoffset = offset + len; /* Make sure we move forward */ - if (eoffset <= hoffset) - THROW(ReportedBoundsError); + if (eoffset <= hoffset) + THROW(ReportedBoundsError); - /*if(ind_field && (len == 2)){ - / disgusting indefinite length zero length field, what are these people doing / - offset = eoffset; - continue; - } - */ + /*if(ind_field && (len == 2)){ + / disgusting indefinite length zero length field, what are these people doing / + offset = eoffset; + continue; + } + */ ber_sequence_try_again: - /* have we run out of known entries in the sequence ?*/ - if(!seq->func) { - /* it was not, move to the next one and try again */ - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, NULL, NULL); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "unknown_field", "BER Error: This field lies beyond the end of the known sequence definition."); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Unknown field in Sequence"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - offset = eoffset; - continue; - } - - /* Verify that this one is the one we want. - * Skip check completely if ber_class==ANY - * of if NOCHKTAG is set - */ + /* have we run out of known entries in the sequence ?*/ + if(!seq->func) { + /* it was not, move to the next one and try again */ + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, NULL, NULL); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "unknown_field", "BER Error: This field lies beyond the end of the known sequence definition."); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Unknown field in Sequence"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + offset = eoffset; + continue; + } + + /* Verify that this one is the one we want. + * Skip check completely if ber_class==ANY + * of if NOCHKTAG is set + */ /* XXX Bug in asn2eth, * for scope [7] Scope OPTIONAL, * it generates * { BER_CLASS_CON, 7, BER_FLAGS_OPTIONAL|BER_FLAGS_NOTCHKTAG, dissect_scope }, * and there should not be a NOTCHKTAG here */ - if( ((seq->ber_class==BER_CLASS_CON)||(seq->ber_class==BER_CLASS_APP)||(seq->ber_class==BER_CLASS_PRI)) && (!(seq->flags&BER_FLAGS_NOOWNTAG)) ){ - if( (seq->ber_class!=BER_CLASS_ANY) - && (seq->tag!=-1) - &&( (seq->ber_class!=ber_class) - ||(seq->tag!=tag) ) ){ - /* it was not, move to the next one and try again */ - if(seq->flags&BER_FLAGS_OPTIONAL){ - /* well this one was optional so just skip to the next one and try again. */ - seq++; - goto ber_sequence_try_again; - } - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, NULL, NULL); - if( seq->ber_class == BER_CLASS_UNI){ - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", - "BER Error: Wrong field in SEQUENCE expected class:%s(%d) tag:%d (%s) but found class:%s(%d) tag:%d", - val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class, - seq->tag,val_to_str_ext(seq->tag,&ber_uni_tag_codes_ext,"Unknown"), - val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in SEQUENCE"); - }else{ - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", - "BER Error: Wrong field in SEQUENCE expected class:%s(%d) tag:%d but found class:%s(%d) tag:%d", - val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class, - seq->tag,val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in SEQUENCE"); - } - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - seq++; - offset=eoffset; - continue; - } - } else if(!(seq->flags & BER_FLAGS_NOTCHKTAG)) { - if( (seq->ber_class!=BER_CLASS_ANY) - && (seq->tag!=-1) - &&( (seq->ber_class!=ber_class) - ||(seq->tag!=tag) ) ){ - /* it was not, move to the next one and try again */ - if(seq->flags&BER_FLAGS_OPTIONAL){ - /* well this one was optional so just skip to the next one and try again. */ - seq++; - goto ber_sequence_try_again; - } - - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, NULL, NULL); - if( seq->ber_class == BER_CLASS_UNI){ - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", "BER Error: Wrong field in sequence expected class:%s(%d) tag:%d(%s) but found class:%s(%d) tag:%d", - val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class,seq->tag,val_to_str_ext(seq->tag,&ber_uni_tag_codes_ext,"Unknown"),val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in sequence"); - }else{ - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", "BER Error: Wrong field in sequence expected class:%s(%d) tag:%d but found class:%s(%d) tag:%d",val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class,seq->tag,val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in sequence"); - } - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - seq++; - offset=eoffset; - continue; - } - } - - if(!(seq->flags & BER_FLAGS_NOOWNTAG) ) { - /* dissect header and len for field */ - if(ind_field && (len == 2)){ - /* This is a Zero length field */ - next_tvb = tvb_new_subset(tvb, offset, len, len); - hoffset = eoffset; - }else{ - hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); - length_remaining=tvb_length_remaining(tvb, hoffset); - if (length_remaining>eoffset-hoffset-(2*ind_field)) - length_remaining=eoffset-hoffset-(2*ind_field); - next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset-(2*ind_field)); - } - } - else { - length_remaining=tvb_length_remaining(tvb, hoffset); - if (length_remaining>eoffset-hoffset) - length_remaining=eoffset-hoffset; - next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset); - } - - /* call the dissector for this field */ - /*if ((eoffset-hoffset)>length_remaining) {*/ - /* If the field is indefinite (i.e. we dont know the - * length) of if the tvb is short, then just - * give it all of the tvb and hope for the best. - */ - /*next_tvb = tvb_new_subset_remaining(tvb, hoffset);*/ - /*} else {*/ - - /*}*/ + if( ((seq->ber_class==BER_CLASS_CON)||(seq->ber_class==BER_CLASS_APP)||(seq->ber_class==BER_CLASS_PRI)) && (!(seq->flags&BER_FLAGS_NOOWNTAG)) ){ + if( (seq->ber_class!=BER_CLASS_ANY) + && (seq->tag!=-1) + &&( (seq->ber_class!=ber_class) + ||(seq->tag!=tag) ) ){ + /* it was not, move to the next one and try again */ + if(seq->flags&BER_FLAGS_OPTIONAL){ + /* well this one was optional so just skip to the next one and try again. */ + seq++; + goto ber_sequence_try_again; + } + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, NULL, NULL); + if( seq->ber_class == BER_CLASS_UNI){ + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", + "BER Error: Wrong field in SEQUENCE expected class:%s(%d) tag:%d (%s) but found class:%s(%d) tag:%d", + val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class, + seq->tag,val_to_str_ext(seq->tag,&ber_uni_tag_codes_ext,"Unknown"), + val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in SEQUENCE"); + }else{ + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", + "BER Error: Wrong field in SEQUENCE expected class:%s(%d) tag:%d but found class:%s(%d) tag:%d", + val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class, + seq->tag,val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in SEQUENCE"); + } + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + seq++; + offset=eoffset; + continue; + } + } else if(!(seq->flags & BER_FLAGS_NOTCHKTAG)) { + if( (seq->ber_class!=BER_CLASS_ANY) + && (seq->tag!=-1) + &&( (seq->ber_class!=ber_class) + ||(seq->tag!=tag) ) ){ + /* it was not, move to the next one and try again */ + if(seq->flags&BER_FLAGS_OPTIONAL){ + /* well this one was optional so just skip to the next one and try again. */ + seq++; + goto ber_sequence_try_again; + } + + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, NULL, NULL); + if( seq->ber_class == BER_CLASS_UNI){ + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", "BER Error: Wrong field in sequence expected class:%s(%d) tag:%d(%s) but found class:%s(%d) tag:%d", + val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class,seq->tag,val_to_str_ext(seq->tag,&ber_uni_tag_codes_ext,"Unknown"),val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in sequence"); + }else{ + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", "BER Error: Wrong field in sequence expected class:%s(%d) tag:%d but found class:%s(%d) tag:%d",val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class,seq->tag,val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in sequence"); + } + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + seq++; + offset=eoffset; + continue; + } + } + + if(!(seq->flags & BER_FLAGS_NOOWNTAG) ) { + /* dissect header and len for field */ + if(ind_field && (len == 2)){ + /* This is a Zero length field */ + next_tvb = tvb_new_subset(tvb, offset, len, len); + hoffset = eoffset; + }else{ + hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); + length_remaining=tvb_length_remaining(tvb, hoffset); + if (length_remaining>eoffset-hoffset-(2*ind_field)) + length_remaining=eoffset-hoffset-(2*ind_field); + next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset-(2*ind_field)); + } + } + else { + length_remaining=tvb_length_remaining(tvb, hoffset); + if (length_remaining>eoffset-hoffset) + length_remaining=eoffset-hoffset; + next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset); + } + +#if 0 + /* call the dissector for this field */ + if ((eoffset-hoffset)>length_remaining) { + /* If the field is indefinite (i.e. we dont know the + * length) of if the tvb is short, then just + * give it all of the tvb and hope for the best. + */ + next_tvb = tvb_new_subset_remaining(tvb, hoffset); + } else { + + } +#endif #ifdef DEBUG_BER { @@ -2048,16 +2051,16 @@ printf("SEQUENCE dissect_ber_sequence(%s) calling subdissector\n",name); } } #endif - if (next_tvb == NULL) { - /* Assume that we have a malformed packet. */ - THROW(ReportedBoundsError); - } - imp_tag=FALSE; - if (seq->flags & BER_FLAGS_IMPLTAG){ - imp_tag = TRUE; - } + if (next_tvb == NULL) { + /* Assume that we have a malformed packet. */ + THROW(ReportedBoundsError); + } + imp_tag=FALSE; + if (seq->flags & BER_FLAGS_IMPLTAG){ + imp_tag = TRUE; + } - count=seq->func(imp_tag, next_tvb, 0, actx, tree, *seq->p_id); + count=seq->func(imp_tag, next_tvb, 0, actx, tree, *seq->p_id); #ifdef DEBUG_BER { @@ -2072,58 +2075,58 @@ name="unnamed"; printf("SEQUENCE dissect_ber_sequence(%s) subdissector ate %d bytes\n",name,count); } #endif - /* if it was optional and no bytes were eaten and it was */ - /* supposed to (len<>0), just try again. */ - if((len!=0)&&(count==0)&&(seq->flags&BER_FLAGS_OPTIONAL)){ - seq++; - goto ber_sequence_try_again; - /* move the offset to the beginning of the next sequenced item */ - } - offset = eoffset; - if(!(seq->flags & BER_FLAGS_NOOWNTAG) ) { - /* if we stripped the tag and length we should also strip the EOC is ind_len - * Unless its a zero length field (len = 2) - */ - if((ind_field == 1)&&(len>2)) - { - /* skip over EOC */ - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, offset, count, "SEQ FIELD EOC"); - } - } - } - seq++; - } - - /* if we didnt end up at exactly offset, then we ate too many bytes */ - if(offset != end_offset) { - tvb_ensure_bytes_exist(tvb, offset-2, 2); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset-2, 2, "illegal_length", "BER Error: Sequence ate %d too many bytes", offset-end_offset); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: too many bytes in Sequence"); - } - if(ind){ - /* need to eat this EOC - end_offset = tvb_length(tvb);*/ - end_offset += 2; - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, end_offset-2,2 , "SEQ EOC"); - } - } - return end_offset; + /* if it was optional and no bytes were eaten and it was */ + /* supposed to (len<>0), just try again. */ + if((len!=0)&&(count==0)&&(seq->flags&BER_FLAGS_OPTIONAL)){ + seq++; + goto ber_sequence_try_again; + /* move the offset to the beginning of the next sequenced item */ + } + offset = eoffset; + if(!(seq->flags & BER_FLAGS_NOOWNTAG) ) { + /* if we stripped the tag and length we should also strip the EOC is ind_len + * Unless its a zero length field (len = 2) + */ + if((ind_field == 1)&&(len>2)) + { + /* skip over EOC */ + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, offset, count, "SEQ FIELD EOC"); + } + } + } + seq++; + } + + /* if we didnt end up at exactly offset, then we ate too many bytes */ + if(offset != end_offset) { + tvb_ensure_bytes_exist(tvb, offset-2, 2); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset-2, 2, "illegal_length", "BER Error: Sequence ate %d too many bytes", offset-end_offset); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: too many bytes in Sequence"); + } + if(ind){ + /* need to eat this EOC + end_offset = tvb_length(tvb);*/ + end_offset += 2; + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, end_offset-2,2 , "SEQ EOC"); + } + } + return end_offset; } int dissect_ber_old_sequence(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const ber_old_sequence_t *seq, gint hf_id, gint ett_id) { - gint8 classx; - gboolean pcx, ind = 0, ind_field; - gint32 tagx; - guint32 lenx; - proto_tree *tree = parent_tree; - proto_item *item = NULL; - proto_item *cause; - int end_offset = 0; - int hoffset; - gint length_remaining; - tvbuff_t *next_tvb; + gint8 classx; + gboolean pcx, ind = 0, ind_field; + gint32 tagx; + guint32 lenx; + proto_tree *tree = parent_tree; + proto_item *item = NULL; + proto_item *cause; + int end_offset = 0; + int hoffset; + gint length_remaining; + tvbuff_t *next_tvb; #ifdef DEBUG_BER { @@ -2142,216 +2145,218 @@ printf("SEQUENCE dissect_ber_old_sequence(%s) entered\n",name); } } #endif - hoffset = offset; - if(!implicit_tag) { - offset = get_ber_identifier(tvb, offset, NULL, NULL, NULL); - offset = get_ber_length(tvb, offset, &lenx, NULL); - } else { - /* was implicit tag so just use the length of the tvb */ - lenx=tvb_length_remaining(tvb,offset); - end_offset=offset+lenx; - } - /* create subtree */ - if(hf_id >= 0) { - if(parent_tree){ - item = proto_tree_add_item(parent_tree, hf_id, tvb, hoffset, lenx + offset - hoffset, ENC_BIG_ENDIAN); - tree = proto_item_add_subtree(item, ett_id); - } - } - offset = hoffset; - - if(!implicit_tag){ - /* first we must read the sequence header */ - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &classx, &pcx, &tagx); - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &lenx, &ind); - if(ind){ - /* Fixed the length is correctly returned from dissect ber_length - end_offset = tvb_length(tvb);*/ - end_offset = offset + lenx -2; - } else { - end_offset = offset + lenx; - } - - /* sanity check: we only handle Constructed Universal Sequences */ - if((classx!=BER_CLASS_APP)&&(classx!=BER_CLASS_PRI)) - if((!pcx) - ||(!implicit_tag&&((classx!=BER_CLASS_UNI) - ||(tagx!=BER_UNI_TAG_SEQUENCE)))) { - tvb_ensure_bytes_exist(tvb, hoffset, 2); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, "sequence_expected", "BER Error: Sequence expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(classx,ber_class_codes,"Unknown"), classx, pcx ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tagx); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Sequence expected"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - return end_offset; - } - } - /* loop over all entries until we reach the end of the sequence */ - while (offset < end_offset){ - gint8 ber_class; - gboolean pc; - gint32 tag; - guint32 len; - int eoffset, count; - - /*if(ind){ this sequence was of indefinite length, if this is implicit indefinite impossible maybe - but ber dissector uses this to eat the tag length then pass into here... EOC still on there...*/ - if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ - /* If the first bytes is 00 00 of a indefenert length field it's a zero length field*/ - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); - dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind); - proto_item_append_text(item," 0 items"); - return end_offset; - /* - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, s_offset, offset+2, "ERROR WRONG SEQ EOC"); - } - return end_offset; - */ - } - /*}*/ - hoffset = offset; - /* read header and len for next field */ - offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); - offset = get_ber_length(tvb, offset, &len, &ind_field); - eoffset = offset + len; + hoffset = offset; + if(!implicit_tag) { + offset = get_ber_identifier(tvb, offset, NULL, NULL, NULL); + offset = get_ber_length(tvb, offset, &lenx, NULL); + } else { + /* was implicit tag so just use the length of the tvb */ + lenx=tvb_length_remaining(tvb,offset); + end_offset=offset+lenx; + } + /* create subtree */ + if(hf_id >= 0) { + if(parent_tree){ + item = proto_tree_add_item(parent_tree, hf_id, tvb, hoffset, lenx + offset - hoffset, ENC_BIG_ENDIAN); + tree = proto_item_add_subtree(item, ett_id); + } + } + offset = hoffset; + + if(!implicit_tag){ + /* first we must read the sequence header */ + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &classx, &pcx, &tagx); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &lenx, &ind); + if(ind){ + /* Fixed the length is correctly returned from dissect ber_length + end_offset = tvb_length(tvb);*/ + end_offset = offset + lenx -2; + } else { + end_offset = offset + lenx; + } + + /* sanity check: we only handle Constructed Universal Sequences */ + if((classx!=BER_CLASS_APP)&&(classx!=BER_CLASS_PRI)) + if((!pcx) + ||(!implicit_tag&&((classx!=BER_CLASS_UNI) + ||(tagx!=BER_UNI_TAG_SEQUENCE)))) { + tvb_ensure_bytes_exist(tvb, hoffset, 2); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, "sequence_expected", "BER Error: Sequence expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(classx,ber_class_codes,"Unknown"), classx, pcx ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tagx); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Sequence expected"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + return end_offset; + } + } + /* loop over all entries until we reach the end of the sequence */ + while (offset < end_offset){ + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 len; + int eoffset, count; + + /*if(ind){ this sequence was of indefinite length, if this is implicit indefinite impossible maybe + but ber dissector uses this to eat the tag length then pass into here... EOC still on there...*/ + if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ + /* If the first bytes is 00 00 of a indefenert length field it's a zero length field*/ + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind); + proto_item_append_text(item," 0 items"); + return end_offset; + /* + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, s_offset, offset+2, "ERROR WRONG SEQ EOC"); + } + return end_offset; + */ + } + /*}*/ + hoffset = offset; + /* read header and len for next field */ + offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); + offset = get_ber_length(tvb, offset, &len, &ind_field); + eoffset = offset + len; /* Make sure we move forward */ - if (eoffset <= hoffset) - THROW(ReportedBoundsError); + if (eoffset <= hoffset) + THROW(ReportedBoundsError); - /*if(ind_field && (len == 2)){ - / disgusting indefinite length zero length field, what are these people doing / - offset = eoffset; - continue; - } - */ + /*if(ind_field && (len == 2)){ + / disgusting indefinite length zero length field, what are these people doing / + offset = eoffset; + continue; + } + */ ber_old_sequence_try_again: - /* have we run out of known entries in the sequence ?*/ - if(!seq->func) { - /* it was not, move to the next one and try again */ - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, NULL, NULL); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "illegal_length", "BER Error: This field lies beyond the end of the known sequence definition."); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Unknown field in Sequence"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - offset = eoffset; - continue; - } - - /* Verify that this one is the one we want. - * Skip check completely if ber_class==ANY - * of if NOCHKTAG is set - */ + /* have we run out of known entries in the sequence ?*/ + if(!seq->func) { + /* it was not, move to the next one and try again */ + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, NULL, NULL); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "illegal_length", "BER Error: This field lies beyond the end of the known sequence definition."); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Unknown field in Sequence"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + offset = eoffset; + continue; + } + + /* Verify that this one is the one we want. + * Skip check completely if ber_class==ANY + * of if NOCHKTAG is set + */ /* XXX Bug in asn2eth, * for scope [7] Scope OPTIONAL, * it generates * { BER_CLASS_CON, 7, BER_FLAGS_OPTIONAL|BER_FLAGS_NOTCHKTAG, dissect_scope }, * and there should not be a NOTCHKTAG here */ - if( ((seq->ber_class==BER_CLASS_CON)||(seq->ber_class==BER_CLASS_APP)||(seq->ber_class==BER_CLASS_PRI)) && (!(seq->flags&BER_FLAGS_NOOWNTAG)) ){ - if( (seq->ber_class!=BER_CLASS_ANY) - && (seq->tag!=-1) - &&( (seq->ber_class!=ber_class) - ||(seq->tag!=tag) ) ){ - /* it was not, move to the next one and try again */ - if(seq->flags&BER_FLAGS_OPTIONAL){ - /* well this one was optional so just skip to the next one and try again. */ - seq++; - goto ber_old_sequence_try_again; - } - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, NULL, NULL); - if( seq->ber_class == BER_CLASS_UNI){ - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", - "BER Error: Wrong field in SEQUENCE expected class:%s(%d) tag:%d (%s) but found class:%s(%d) tag:%d", - val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class, - seq->tag,val_to_str_ext(seq->tag,&ber_uni_tag_codes_ext,"Unknown"), - val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in SEQUENCE"); - }else{ - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field" - "BER Error: Wrong field in SEQUENCE expected class:%s(%d) tag:%d but found class:%s(%d) tag:%d", - val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class, - seq->tag,val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in SEQUENCE"); - } - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - seq++; - offset=eoffset; - continue; - } - } else if(!(seq->flags & BER_FLAGS_NOTCHKTAG)) { - if( (seq->ber_class!=BER_CLASS_ANY) - && (seq->tag!=-1) - &&( (seq->ber_class!=ber_class) - ||(seq->tag!=tag) ) ){ - /* it was not, move to the next one and try again */ - if(seq->flags&BER_FLAGS_OPTIONAL){ - /* well this one was optional so just skip to the next one and try again. */ - seq++; - goto ber_old_sequence_try_again; - } - - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, NULL, NULL); - if( seq->ber_class == BER_CLASS_UNI){ - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", "BER Error: Wrong field in sequence expected class:%s(%d) tag:%d(%s) but found class:%s(%d) tag:%d", - val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class,seq->tag,val_to_str_ext(seq->tag,&ber_uni_tag_codes_ext,"Unknown"),val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in sequence"); - }else{ - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", "BER Error: Wrong field in sequence expected class:%s(%d) tag:%d but found class:%s(%d) tag:%d",val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class,seq->tag,val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in sequence"); - } - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - seq++; - offset=eoffset; - continue; - } - } - - if(!(seq->flags & BER_FLAGS_NOOWNTAG) ) { - /* dissect header and len for field */ - if(ind_field && (len == 2)){ - /* This is a Zero length field */ - next_tvb = tvb_new_subset(tvb, offset, len, len); - hoffset = eoffset; - }else{ - hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); - length_remaining=tvb_length_remaining(tvb, hoffset); - if (length_remaining>eoffset-hoffset-(2*ind_field)) - length_remaining=eoffset-hoffset-(2*ind_field); - next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset-(2*ind_field)); - } - } - else { - length_remaining=tvb_length_remaining(tvb, hoffset); - if (length_remaining>eoffset-hoffset) - length_remaining=eoffset-hoffset; - next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset); - } - - /* call the dissector for this field */ - /*if ((eoffset-hoffset)>length_remaining) {*/ - /* If the field is indefinite (i.e. we dont know the - * length) of if the tvb is short, then just - * give it all of the tvb and hope for the best. - */ - /*next_tvb = tvb_new_subset_remaining(tvb, hoffset);*/ - /*} else {*/ - - /*}*/ + if( ((seq->ber_class==BER_CLASS_CON)||(seq->ber_class==BER_CLASS_APP)||(seq->ber_class==BER_CLASS_PRI)) && (!(seq->flags&BER_FLAGS_NOOWNTAG)) ){ + if( (seq->ber_class!=BER_CLASS_ANY) + && (seq->tag!=-1) + &&( (seq->ber_class!=ber_class) + ||(seq->tag!=tag) ) ){ + /* it was not, move to the next one and try again */ + if(seq->flags&BER_FLAGS_OPTIONAL){ + /* well this one was optional so just skip to the next one and try again. */ + seq++; + goto ber_old_sequence_try_again; + } + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, NULL, NULL); + if( seq->ber_class == BER_CLASS_UNI){ + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", + "BER Error: Wrong field in SEQUENCE expected class:%s(%d) tag:%d (%s) but found class:%s(%d) tag:%d", + val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class, + seq->tag,val_to_str_ext(seq->tag,&ber_uni_tag_codes_ext,"Unknown"), + val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in SEQUENCE"); + }else{ + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field" + "BER Error: Wrong field in SEQUENCE expected class:%s(%d) tag:%d but found class:%s(%d) tag:%d", + val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class, + seq->tag,val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in SEQUENCE"); + } + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + seq++; + offset=eoffset; + continue; + } + } else if(!(seq->flags & BER_FLAGS_NOTCHKTAG)) { + if( (seq->ber_class!=BER_CLASS_ANY) + && (seq->tag!=-1) + &&( (seq->ber_class!=ber_class) + ||(seq->tag!=tag) ) ){ + /* it was not, move to the next one and try again */ + if(seq->flags&BER_FLAGS_OPTIONAL){ + /* well this one was optional so just skip to the next one and try again. */ + seq++; + goto ber_old_sequence_try_again; + } + + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, NULL, NULL); + if( seq->ber_class == BER_CLASS_UNI){ + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", "BER Error: Wrong field in sequence expected class:%s(%d) tag:%d(%s) but found class:%s(%d) tag:%d", + val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class,seq->tag,val_to_str_ext(seq->tag,&ber_uni_tag_codes_ext,"Unknown"),val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in sequence"); + }else{ + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", "BER Error: Wrong field in sequence expected class:%s(%d) tag:%d but found class:%s(%d) tag:%d",val_to_str(seq->ber_class,ber_class_codes,"Unknown"),seq->ber_class,seq->tag,val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in sequence"); + } + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + seq++; + offset=eoffset; + continue; + } + } + + if(!(seq->flags & BER_FLAGS_NOOWNTAG) ) { + /* dissect header and len for field */ + if(ind_field && (len == 2)){ + /* This is a Zero length field */ + next_tvb = tvb_new_subset(tvb, offset, len, len); + hoffset = eoffset; + }else{ + hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); + length_remaining=tvb_length_remaining(tvb, hoffset); + if (length_remaining>eoffset-hoffset-(2*ind_field)) + length_remaining=eoffset-hoffset-(2*ind_field); + next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset-(2*ind_field)); + } + } + else { + length_remaining=tvb_length_remaining(tvb, hoffset); + if (length_remaining>eoffset-hoffset) + length_remaining=eoffset-hoffset; + next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset); + } + +#if 0 + /* call the dissector for this field */ + if ((eoffset-hoffset)>length_remaining) { + /* If the field is indefinite (i.e. we dont know the + * length) of if the tvb is short, then just + * give it all of the tvb and hope for the best. + */ + next_tvb = tvb_new_subset_remaining(tvb, hoffset); + } else { + + } +#endif #ifdef DEBUG_BER { @@ -2370,11 +2375,11 @@ printf("SEQUENCE dissect_ber_old_sequence(%s) calling subdissector\n",name); } } #endif - if (next_tvb == NULL) { - /* Assume that we have a malformed packet. */ - THROW(ReportedBoundsError); - } - count=seq->func(tree, next_tvb, 0, actx); + if (next_tvb == NULL) { + /* Assume that we have a malformed packet. */ + THROW(ReportedBoundsError); + } + count=seq->func(tree, next_tvb, 0, actx); #ifdef DEBUG_BER { @@ -2389,68 +2394,68 @@ name="unnamed"; printf("SEQUENCE dissect_ber_old_sequence(%s) subdissector ate %d bytes\n",name,count); } #endif - /* if it was optional and no bytes were eaten and it was */ - /* supposed to (len<>0), just try again. */ - if((len!=0)&&(count==0)&&(seq->flags&BER_FLAGS_OPTIONAL)){ - seq++; - goto ber_old_sequence_try_again; - /* move the offset to the beginning of the next sequenced item */ - } - offset = eoffset; - seq++; - if(!(seq->flags & BER_FLAGS_NOOWNTAG) ) { - /* if we stripped the tag and length we should also strip the EOC is ind_len - * Unless its a zero length field (len = 2) - */ - if((ind_field == 1)&&(len>2)) - { - /* skip over EOC */ - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, offset, count, "SEQ FIELD EOC"); - } - } - } - } - - /* if we didnt end up at exactly offset, then we ate too many bytes */ - if(offset != end_offset) { - tvb_ensure_bytes_exist(tvb, offset-2, 2); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset-2, 2, "illegal_length", "BER Error: Sequence ate %d too many bytes", offset-end_offset); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: too many bytes in Sequence"); - } - if(ind){ - /* need to eat this EOC - end_offset = tvb_length(tvb);*/ - end_offset += 2; - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, end_offset-2,2 , "SEQ EOC"); - } - } - return end_offset; + /* if it was optional and no bytes were eaten and it was */ + /* supposed to (len<>0), just try again. */ + if((len!=0)&&(count==0)&&(seq->flags&BER_FLAGS_OPTIONAL)){ + seq++; + goto ber_old_sequence_try_again; + /* move the offset to the beginning of the next sequenced item */ + } + offset = eoffset; + seq++; + if(!(seq->flags & BER_FLAGS_NOOWNTAG) ) { + /* if we stripped the tag and length we should also strip the EOC is ind_len + * Unless its a zero length field (len = 2) + */ + if((ind_field == 1)&&(len>2)) + { + /* skip over EOC */ + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, offset, count, "SEQ FIELD EOC"); + } + } + } + } + + /* if we didnt end up at exactly offset, then we ate too many bytes */ + if(offset != end_offset) { + tvb_ensure_bytes_exist(tvb, offset-2, 2); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset-2, 2, "illegal_length", "BER Error: Sequence ate %d too many bytes", offset-end_offset); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: too many bytes in Sequence"); + } + if(ind){ + /* need to eat this EOC + end_offset = tvb_length(tvb);*/ + end_offset += 2; + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, end_offset-2,2 , "SEQ EOC"); + } + } + return end_offset; } /* This function dissects a BER set */ int dissect_ber_set(gboolean implicit_tag,asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const ber_sequence_t *set, gint hf_id, gint ett_id) { - gint8 classx; - gboolean pcx, ind = 0, ind_field, imp_tag = FALSE; - gint32 tagx; - guint32 lenx; - proto_tree *tree = parent_tree; - proto_item *item = NULL; - proto_item *cause; - int end_offset, s_offset; - int hoffset; - gint length_remaining; - tvbuff_t *next_tvb; - const ber_sequence_t *cset = NULL; + gint8 classx; + gboolean pcx, ind = 0, ind_field, imp_tag = FALSE; + gint32 tagx; + guint32 lenx; + proto_tree *tree = parent_tree; + proto_item *item = NULL; + proto_item *cause; + int end_offset, s_offset; + int hoffset; + gint length_remaining; + tvbuff_t *next_tvb; + const ber_sequence_t *cset = NULL; # define MAX_SET_ELEMENTS 32 - guint32 mandatory_fields = 0; - guint8 set_idx; - gboolean first_pass; - s_offset = offset; + guint32 mandatory_fields = 0; + guint8 set_idx; + gboolean first_pass; + s_offset = offset; #ifdef DEBUG_BER - { + { const char *name; header_field_info *hfinfo; if(hf_id>=0){ @@ -2467,128 +2472,130 @@ printf("SET dissect_ber_set(%s) entered\n",name); } #endif - if(!implicit_tag){ - hoffset = offset; - /* first we must read the sequence header */ - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &classx, &pcx, &tagx); - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &lenx, &ind); - if(ind){ - /* Fixed the length is correctly returned from dissect ber_length - end_offset = tvb_length(tvb);*/ - end_offset = offset + lenx -2; - } else { - end_offset = offset + lenx; - } - - /* sanity check: we only handle Constructed Universal Sets */ - if ((classx!=BER_CLASS_APP)&&(classx!=BER_CLASS_PRI)) - if ((!pcx) - ||(!implicit_tag&&((classx!=BER_CLASS_UNI) - ||(tagx!=BER_UNI_TAG_SET)))) { - tvb_ensure_bytes_exist(tvb, hoffset, 2); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, "set_expected", "BER Error: SET expected but class:%s(%d) %s tag:%d was found", val_to_str(classx,ber_class_codes,"Unknown"), classx, pcx ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tagx); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: SET expected"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - return end_offset; - } - } else { - /* was implicit tag so just use the length of the tvb */ - lenx=tvb_length_remaining(tvb,offset); - end_offset=offset+lenx; - } - - /* create subtree */ - if (hf_id >= 0) { - if(parent_tree){ - item = proto_tree_add_item(parent_tree, hf_id, tvb, offset, lenx, ENC_BIG_ENDIAN); - tree = proto_item_add_subtree(item, ett_id); - } - } - - /* record the mandatory elements of the set so we can check we found everything at the end - we can only record 32 elements for now ... */ - for(set_idx = 0; (cset=&set[set_idx])->func && (set_idx < MAX_SET_ELEMENTS); set_idx++) { - - if(!(cset->flags & BER_FLAGS_OPTIONAL)) - mandatory_fields |= 1 << set_idx; - - } - - /* loop over all entries until we reach the end of the set */ - while (offset < end_offset){ - gint8 ber_class; - gboolean pc; - gint32 tag; - guint32 len; - int eoffset, count; - - /*if(ind){ this sequence was of indefinite length, if this is implicit indefinite impossible maybe - but ber dissector uses this to eat the tag length then pass into here... EOC still on there...*/ - - if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, s_offset, offset+2, "SEQ EOC"); - } - return end_offset; - } - /* } */ - hoffset = offset; - /* read header and len for next field */ - offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); - offset = get_ber_length(tvb, offset, &len, &ind_field); - eoffset = offset + len; - - /* Look through the Set to see if this class/id exists and - * hasn't been seen before - * Skip check completely if ber_class==ANY - * of if NOCHKTAG is set - */ - - - for(first_pass=TRUE, cset = set, set_idx = 0; cset->func || first_pass; cset++, set_idx++) { - - /* we reset for a second pass when we will look for choices */ - if(!cset->func) { - first_pass = FALSE; - - cset=set; /* reset to the beginning */ - set_idx = 0; - } - - if((first_pass && ((cset->ber_class==ber_class) && (cset->tag==tag))) || - (!first_pass && ((cset->ber_class== BER_CLASS_ANY) && (cset->tag == -1))) ) /* choices */ - { - - if (!(cset->flags & BER_FLAGS_NOOWNTAG) ) { - /* dissect header and len for field */ - hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); - length_remaining=tvb_length_remaining(tvb, hoffset); - if (length_remaining>eoffset-hoffset-(2*ind_field)) - length_remaining=eoffset-hoffset-(2*ind_field); - next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset-(2*ind_field)); - } - else { - length_remaining=tvb_length_remaining(tvb, hoffset); - if (length_remaining>eoffset-hoffset) - length_remaining=eoffset-hoffset; - next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset); - } - - - /* call the dissector for this field */ - /*if ((eoffset-hoffset)>length_remaining) {*/ - /* If the field is indefinite (i.e. we dont know the - * length) of if the tvb is short, then just - * give it all of the tvb and hope for the best. - */ - /*next_tvb = tvb_new_subset_remaining(tvb, hoffset);*/ - /*} else {*/ - - /*}*/ + if(!implicit_tag){ + hoffset = offset; + /* first we must read the sequence header */ + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &classx, &pcx, &tagx); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &lenx, &ind); + if(ind){ + /* Fixed the length is correctly returned from dissect ber_length + end_offset = tvb_length(tvb);*/ + end_offset = offset + lenx -2; + } else { + end_offset = offset + lenx; + } + + /* sanity check: we only handle Constructed Universal Sets */ + if ((classx!=BER_CLASS_APP)&&(classx!=BER_CLASS_PRI)) + if ((!pcx) + ||(!implicit_tag&&((classx!=BER_CLASS_UNI) + ||(tagx!=BER_UNI_TAG_SET)))) { + tvb_ensure_bytes_exist(tvb, hoffset, 2); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, "set_expected", "BER Error: SET expected but class:%s(%d) %s tag:%d was found", val_to_str(classx,ber_class_codes,"Unknown"), classx, pcx ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tagx); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: SET expected"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + return end_offset; + } + } else { + /* was implicit tag so just use the length of the tvb */ + lenx=tvb_length_remaining(tvb,offset); + end_offset=offset+lenx; + } + + /* create subtree */ + if (hf_id >= 0) { + if(parent_tree){ + item = proto_tree_add_item(parent_tree, hf_id, tvb, offset, lenx, ENC_BIG_ENDIAN); + tree = proto_item_add_subtree(item, ett_id); + } + } + + /* record the mandatory elements of the set so we can check we found everything at the end + we can only record 32 elements for now ... */ + for(set_idx = 0; (cset=&set[set_idx])->func && (set_idx < MAX_SET_ELEMENTS); set_idx++) { + + if(!(cset->flags & BER_FLAGS_OPTIONAL)) + mandatory_fields |= 1 << set_idx; + + } + + /* loop over all entries until we reach the end of the set */ + while (offset < end_offset){ + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 len; + int eoffset, count; + + /*if(ind){ this sequence was of indefinite length, if this is implicit indefinite impossible maybe + but ber dissector uses this to eat the tag length then pass into here... EOC still on there...*/ + + if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, s_offset, offset+2, "SEQ EOC"); + } + return end_offset; + } + /* } */ + hoffset = offset; + /* read header and len for next field */ + offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); + offset = get_ber_length(tvb, offset, &len, &ind_field); + eoffset = offset + len; + + /* Look through the Set to see if this class/id exists and + * hasn't been seen before + * Skip check completely if ber_class==ANY + * of if NOCHKTAG is set + */ + + + for(first_pass=TRUE, cset = set, set_idx = 0; cset->func || first_pass; cset++, set_idx++) { + + /* we reset for a second pass when we will look for choices */ + if(!cset->func) { + first_pass = FALSE; + + cset=set; /* reset to the beginning */ + set_idx = 0; + } + + if((first_pass && ((cset->ber_class==ber_class) && (cset->tag==tag))) || + (!first_pass && ((cset->ber_class== BER_CLASS_ANY) && (cset->tag == -1))) ) /* choices */ + { + + if (!(cset->flags & BER_FLAGS_NOOWNTAG) ) { + /* dissect header and len for field */ + hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); + length_remaining=tvb_length_remaining(tvb, hoffset); + if (length_remaining>eoffset-hoffset-(2*ind_field)) + length_remaining=eoffset-hoffset-(2*ind_field); + next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset-(2*ind_field)); + } + else { + length_remaining=tvb_length_remaining(tvb, hoffset); + if (length_remaining>eoffset-hoffset) + length_remaining=eoffset-hoffset; + next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset); + } + + +#if 0 + /* call the dissector for this field */ + if ((eoffset-hoffset)>length_remaining) { + /* If the field is indefinite (i.e. we dont know the + * length) of if the tvb is short, then just + * give it all of the tvb and hope for the best. + */ + next_tvb = tvb_new_subset_remaining(tvb, hoffset); + } else { + + } +#endif #ifdef DEBUG_BER { @@ -2607,110 +2614,110 @@ printf("SET dissect_ber_set(%s) calling subdissector\n",name); } } #endif - if (next_tvb == NULL) { - /* Assume that we have a malformed packet. */ - THROW(ReportedBoundsError); - } - imp_tag = FALSE; - if ((cset->flags & BER_FLAGS_IMPLTAG)) - imp_tag = TRUE; - count=cset->func(imp_tag, next_tvb, 0, actx, tree, *cset->p_id); - - /* if we consumed some bytes, - or we knew the length was zero (during the first pass only) */ - if(count || (first_pass && (len == 0 || (ind_field == 1 && len == 2)))) { - /* we found it! */ - if(set_idx < MAX_SET_ELEMENTS) - mandatory_fields &= ~(1 << set_idx); - - offset = eoffset; - - if(!(cset->flags & BER_FLAGS_NOOWNTAG) ) { - /* if we stripped the tag and length we should also strip the EOC is ind_len */ - if(ind_field == 1){ - /* skip over EOC */ - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, offset, count, "SET FIELD EOC"); - } - } - } - break; - } - } - } - - if(!cset->func) { - /* we didn't find a match */ - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "unknown_field", "BER Error: Unknown field in SET class:%s(%d) tag:%d",val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Unknown field in SET"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - offset = eoffset; - } - } - - if(mandatory_fields) { - - /* OK - we didn't find some of the elements we expected */ - - for(set_idx = 0; (cset = &set[set_idx])->func && (set_idx < MAX_SET_ELEMENTS); set_idx++) { - - if(mandatory_fields & (1 << set_idx)) { - - /* here is something we should have seen - but didn't! */ - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, "missing_field", - "BER Error: Missing field in SET class:%s(%d) tag:%d expected", - val_to_str(cset->ber_class,ber_class_codes,"Unknown"),cset->ber_class, - cset->tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Missing field in SET"); - - } - - } - } - - /* if we didnt end up at exactly offset, then we ate too many bytes */ - if (offset != end_offset) { - tvb_ensure_bytes_exist(tvb, offset-2, 2); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset-2, 2, "illegal_length", "BER Error: SET ate %d too many bytes", offset-end_offset); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: too many bytes in SET"); - } - - if(ind){ - /* need to eat this EOC - end_offset = tvb_length(tvb);*/ - end_offset += 2; - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, end_offset-2,2 , "SET EOC"); - } - } - - return end_offset; + if (next_tvb == NULL) { + /* Assume that we have a malformed packet. */ + THROW(ReportedBoundsError); + } + imp_tag = FALSE; + if ((cset->flags & BER_FLAGS_IMPLTAG)) + imp_tag = TRUE; + count=cset->func(imp_tag, next_tvb, 0, actx, tree, *cset->p_id); + + /* if we consumed some bytes, + or we knew the length was zero (during the first pass only) */ + if(count || (first_pass && (len == 0 || (ind_field == 1 && len == 2)))) { + /* we found it! */ + if(set_idx < MAX_SET_ELEMENTS) + mandatory_fields &= ~(1 << set_idx); + + offset = eoffset; + + if(!(cset->flags & BER_FLAGS_NOOWNTAG) ) { + /* if we stripped the tag and length we should also strip the EOC is ind_len */ + if(ind_field == 1){ + /* skip over EOC */ + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, offset, count, "SET FIELD EOC"); + } + } + } + break; + } + } + } + + if(!cset->func) { + /* we didn't find a match */ + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "unknown_field", "BER Error: Unknown field in SET class:%s(%d) tag:%d",val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Unknown field in SET"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + offset = eoffset; + } + } + + if(mandatory_fields) { + + /* OK - we didn't find some of the elements we expected */ + + for(set_idx = 0; (cset = &set[set_idx])->func && (set_idx < MAX_SET_ELEMENTS); set_idx++) { + + if(mandatory_fields & (1 << set_idx)) { + + /* here is something we should have seen - but didn't! */ + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, "missing_field", + "BER Error: Missing field in SET class:%s(%d) tag:%d expected", + val_to_str(cset->ber_class,ber_class_codes,"Unknown"),cset->ber_class, + cset->tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Missing field in SET"); + + } + + } + } + + /* if we didnt end up at exactly offset, then we ate too many bytes */ + if (offset != end_offset) { + tvb_ensure_bytes_exist(tvb, offset-2, 2); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset-2, 2, "illegal_length", "BER Error: SET ate %d too many bytes", offset-end_offset); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: too many bytes in SET"); + } + + if(ind){ + /* need to eat this EOC + end_offset = tvb_length(tvb);*/ + end_offset += 2; + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, end_offset-2,2 , "SET EOC"); + } + } + + return end_offset; } int dissect_ber_old_set(gboolean implicit_tag,asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const ber_old_sequence_t *set, gint hf_id, gint ett_id) { - gint8 classx; - gboolean pcx, ind = 0, ind_field; - gint32 tagx; - guint32 lenx; - proto_tree *tree = parent_tree; - proto_item *item = NULL; - proto_item *cause; - int end_offset, s_offset; - int hoffset; - gint length_remaining; - tvbuff_t *next_tvb; - const ber_old_sequence_t *cset = NULL; + gint8 classx; + gboolean pcx, ind = 0, ind_field; + gint32 tagx; + guint32 lenx; + proto_tree *tree = parent_tree; + proto_item *item = NULL; + proto_item *cause; + int end_offset, s_offset; + int hoffset; + gint length_remaining; + tvbuff_t *next_tvb; + const ber_old_sequence_t *cset = NULL; # define MAX_SET_ELEMENTS 32 - guint32 mandatory_fields = 0; - guint8 set_idx; - gboolean first_pass; - s_offset = offset; + guint32 mandatory_fields = 0; + guint8 set_idx; + gboolean first_pass; + s_offset = offset; #ifdef DEBUG_BER - { + { const char *name; header_field_info *hfinfo; if(hf_id>=0){ @@ -2727,128 +2734,130 @@ printf("SET dissect_old_ber_set(%s) entered\n",name); } #endif - if(!implicit_tag){ - hoffset = offset; - /* first we must read the sequence header */ - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &classx, &pcx, &tagx); - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &lenx, &ind); - if(ind){ - /* Fixed the length is correctly returned from dissect ber_length - end_offset = tvb_length(tvb);*/ - end_offset = offset + lenx -2; - } else { - end_offset = offset + lenx; - } - - /* sanity check: we only handle Constructed Universal Sets */ - if ((classx!=BER_CLASS_APP)&&(classx!=BER_CLASS_PRI)) - if ((!pcx) - ||(!implicit_tag&&((classx!=BER_CLASS_UNI) - ||(tagx!=BER_UNI_TAG_SET)))) { - tvb_ensure_bytes_exist(tvb, hoffset, 2); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, "set_expected", "BER Error: SET expected but class:%s(%d) %s tag:%d was found", val_to_str(classx,ber_class_codes,"Unknown"), classx, pcx ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tagx); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: SET expected"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - return end_offset; - } - } else { - /* was implicit tag so just use the length of the tvb */ - lenx=tvb_length_remaining(tvb,offset); - end_offset=offset+lenx; - } - - /* create subtree */ - if (hf_id >= 0) { - if(parent_tree){ - item = proto_tree_add_item(parent_tree, hf_id, tvb, offset, lenx, ENC_BIG_ENDIAN); - tree = proto_item_add_subtree(item, ett_id); - } - } - - /* record the mandatory elements of the set so we can check we found everything at the end - we can only record 32 elements for now ... */ - for(set_idx = 0; (cset=&set[set_idx])->func && (set_idx < MAX_SET_ELEMENTS); set_idx++) { - - if(!(cset->flags & BER_FLAGS_OPTIONAL)) - mandatory_fields |= 1 << set_idx; - - } - - /* loop over all entries until we reach the end of the set */ - while (offset < end_offset){ - gint8 ber_class; - gboolean pc; - gint32 tag; - guint32 len; - int eoffset, count; - - /*if(ind){ this sequence was of indefinite length, if this is implicit indefinite impossible maybe - but ber dissector uses this to eat the tag length then pass into here... EOC still on there...*/ - - if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, s_offset, offset+2, "SEQ EOC"); - } - return end_offset; - } - /* } */ - hoffset = offset; - /* read header and len for next field */ - offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); - offset = get_ber_length(tvb, offset, &len, &ind_field); - eoffset = offset + len; - - /* Look through the Set to see if this class/id exists and - * hasn't been seen before - * Skip check completely if class==ANY - * of if NOCHKTAG is set - */ - - - for(first_pass=TRUE, cset = set, set_idx = 0; cset->func || first_pass; cset++, set_idx++) { - - /* we reset for a second pass when we will look for choices */ - if(!cset->func) { - first_pass = FALSE; - - cset=set; /* reset to the beginning */ - set_idx = 0; - } - - if((first_pass && ((cset->ber_class==ber_class) && (cset->tag==tag))) || - (!first_pass && ((cset->ber_class== BER_CLASS_ANY) && (cset->tag == -1))) ) /* choices */ - { - - if (!(cset->flags & BER_FLAGS_NOOWNTAG) ) { - /* dissect header and len for field */ - hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); - length_remaining=tvb_length_remaining(tvb, hoffset); - if (length_remaining>eoffset-hoffset-(2*ind_field)) - length_remaining=eoffset-hoffset-(2*ind_field); - next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset-(2*ind_field)); - } - else { - length_remaining=tvb_length_remaining(tvb, hoffset); - if (length_remaining>eoffset-hoffset) - length_remaining=eoffset-hoffset; - next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset); - } - - - /* call the dissector for this field */ - /*if ((eoffset-hoffset)>length_remaining) {*/ - /* If the field is indefinite (i.e. we dont know the - * length) of if the tvb is short, then just - * give it all of the tvb and hope for the best. - */ - /*next_tvb = tvb_new_subset_remaining(tvb, hoffset);*/ - /*} else {*/ - - /*}*/ + if(!implicit_tag){ + hoffset = offset; + /* first we must read the sequence header */ + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &classx, &pcx, &tagx); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &lenx, &ind); + if(ind){ + /* Fixed the length is correctly returned from dissect ber_length + end_offset = tvb_length(tvb);*/ + end_offset = offset + lenx -2; + } else { + end_offset = offset + lenx; + } + + /* sanity check: we only handle Constructed Universal Sets */ + if ((classx!=BER_CLASS_APP)&&(classx!=BER_CLASS_PRI)) + if ((!pcx) + ||(!implicit_tag&&((classx!=BER_CLASS_UNI) + ||(tagx!=BER_UNI_TAG_SET)))) { + tvb_ensure_bytes_exist(tvb, hoffset, 2); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, "set_expected", "BER Error: SET expected but class:%s(%d) %s tag:%d was found", val_to_str(classx,ber_class_codes,"Unknown"), classx, pcx ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tagx); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: SET expected"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + return end_offset; + } + } else { + /* was implicit tag so just use the length of the tvb */ + lenx=tvb_length_remaining(tvb,offset); + end_offset=offset+lenx; + } + + /* create subtree */ + if (hf_id >= 0) { + if(parent_tree){ + item = proto_tree_add_item(parent_tree, hf_id, tvb, offset, lenx, ENC_BIG_ENDIAN); + tree = proto_item_add_subtree(item, ett_id); + } + } + + /* record the mandatory elements of the set so we can check we found everything at the end + we can only record 32 elements for now ... */ + for(set_idx = 0; (cset=&set[set_idx])->func && (set_idx < MAX_SET_ELEMENTS); set_idx++) { + + if(!(cset->flags & BER_FLAGS_OPTIONAL)) + mandatory_fields |= 1 << set_idx; + + } + + /* loop over all entries until we reach the end of the set */ + while (offset < end_offset){ + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 len; + int eoffset, count; + + /*if(ind){ this sequence was of indefinite length, if this is implicit indefinite impossible maybe + but ber dissector uses this to eat the tag length then pass into here... EOC still on there...*/ + + if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, s_offset, offset+2, "SEQ EOC"); + } + return end_offset; + } + /* } */ + hoffset = offset; + /* read header and len for next field */ + offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); + offset = get_ber_length(tvb, offset, &len, &ind_field); + eoffset = offset + len; + + /* Look through the Set to see if this class/id exists and + * hasn't been seen before + * Skip check completely if class==ANY + * of if NOCHKTAG is set + */ + + + for(first_pass=TRUE, cset = set, set_idx = 0; cset->func || first_pass; cset++, set_idx++) { + + /* we reset for a second pass when we will look for choices */ + if(!cset->func) { + first_pass = FALSE; + + cset=set; /* reset to the beginning */ + set_idx = 0; + } + + if((first_pass && ((cset->ber_class==ber_class) && (cset->tag==tag))) || + (!first_pass && ((cset->ber_class== BER_CLASS_ANY) && (cset->tag == -1))) ) /* choices */ + { + + if (!(cset->flags & BER_FLAGS_NOOWNTAG) ) { + /* dissect header and len for field */ + hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); + length_remaining=tvb_length_remaining(tvb, hoffset); + if (length_remaining>eoffset-hoffset-(2*ind_field)) + length_remaining=eoffset-hoffset-(2*ind_field); + next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset-(2*ind_field)); + } + else { + length_remaining=tvb_length_remaining(tvb, hoffset); + if (length_remaining>eoffset-hoffset) + length_remaining=eoffset-hoffset; + next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset); + } + + +#if 0 + /* call the dissector for this field */ + if ((eoffset-hoffset)>length_remaining) { + /* If the field is indefinite (i.e. we dont know the + * length) of if the tvb is short, then just + * give it all of the tvb and hope for the best. + */ + next_tvb = tvb_new_subset_remaining(tvb, hoffset); + } else { + + } +#endif #ifdef DEBUG_BER { @@ -2867,84 +2876,84 @@ printf("SET dissect_old_ber_set(%s) calling subdissector\n",name); } } #endif - if (next_tvb == NULL) { - /* Assume that we have a malformed packet. */ - THROW(ReportedBoundsError); - } - count=cset->func(tree, next_tvb, 0, actx); - - /* if we consumed some bytes, - or we knew the length was zero (during the first pass only) */ - if(count || (first_pass && (len == 0 || (ind_field == 1 && len == 2)))) { - /* we found it! */ - if(set_idx < MAX_SET_ELEMENTS) - mandatory_fields &= ~(1 << set_idx); - - offset = eoffset; - - if(!(cset->flags & BER_FLAGS_NOOWNTAG) ) { - /* if we stripped the tag and length we should also strip the EOC is ind_len */ - if(ind_field == 1){ - /* skip over EOC */ - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, offset, count, "SET FIELD EOC"); - } - } - } - break; - } - } - } - - if(!cset->func) { - /* we didn't find a match */ - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "unknown_field", "BER Error: Unknown field in SET class:%s(%d) tag:%d",val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Unknown field in SET"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - offset = eoffset; - } - } - - if(mandatory_fields) { - - /* OK - we didn't find some of the elements we expected */ - - for(set_idx = 0; (cset = &set[set_idx])->func && (set_idx < MAX_SET_ELEMENTS); set_idx++) { - - if(mandatory_fields & (1 << set_idx)) { - - /* here is something we should have seen - but didn't! */ - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, "missing_field", - "BER Error: Missing field in SET class:%s(%d) tag:%d expected", - val_to_str(cset->ber_class,ber_class_codes,"Unknown"),cset->ber_class, - cset->tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Missing field in SET"); - - } - - } - } - - /* if we didnt end up at exactly offset, then we ate too many bytes */ - if (offset != end_offset) { - tvb_ensure_bytes_exist(tvb, offset-2, 2); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset-2, 2, "illegal_length", "BER Error: SET ate %d too many bytes", offset-end_offset); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: too many bytes in SET"); - } - - if(ind){ - /* need to eat this EOC - end_offset = tvb_length(tvb);*/ - end_offset += 2; - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, end_offset-2,2 , "SET EOC"); - } - } - - return end_offset; + if (next_tvb == NULL) { + /* Assume that we have a malformed packet. */ + THROW(ReportedBoundsError); + } + count=cset->func(tree, next_tvb, 0, actx); + + /* if we consumed some bytes, + or we knew the length was zero (during the first pass only) */ + if(count || (first_pass && (len == 0 || (ind_field == 1 && len == 2)))) { + /* we found it! */ + if(set_idx < MAX_SET_ELEMENTS) + mandatory_fields &= ~(1 << set_idx); + + offset = eoffset; + + if(!(cset->flags & BER_FLAGS_NOOWNTAG) ) { + /* if we stripped the tag and length we should also strip the EOC is ind_len */ + if(ind_field == 1){ + /* skip over EOC */ + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, offset, count, "SET FIELD EOC"); + } + } + } + break; + } + } + } + + if(!cset->func) { + /* we didn't find a match */ + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "unknown_field", "BER Error: Unknown field in SET class:%s(%d) tag:%d",val_to_str(ber_class,ber_class_codes,"Unknown"),ber_class,tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Unknown field in SET"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + offset = eoffset; + } + } + + if(mandatory_fields) { + + /* OK - we didn't find some of the elements we expected */ + + for(set_idx = 0; (cset = &set[set_idx])->func && (set_idx < MAX_SET_ELEMENTS); set_idx++) { + + if(mandatory_fields & (1 << set_idx)) { + + /* here is something we should have seen - but didn't! */ + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, "missing_field", + "BER Error: Missing field in SET class:%s(%d) tag:%d expected", + val_to_str(cset->ber_class,ber_class_codes,"Unknown"),cset->ber_class, + cset->tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Missing field in SET"); + + } + + } + } + + /* if we didnt end up at exactly offset, then we ate too many bytes */ + if (offset != end_offset) { + tvb_ensure_bytes_exist(tvb, offset-2, 2); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset-2, 2, "illegal_length", "BER Error: SET ate %d too many bytes", offset-end_offset); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: too many bytes in SET"); + } + + if(ind){ + /* need to eat this EOC + end_offset = tvb_length(tvb);*/ + end_offset += 2; + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, end_offset-2,2 , "SET EOC"); + } + } + + return end_offset; } /* this function dissects a BER choice @@ -2958,19 +2967,19 @@ printf("SET dissect_old_ber_set(%s) calling subdissector\n",name); int dissect_ber_choice(asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const ber_choice_t *choice, gint hf_id, gint ett_id, gint *branch_taken) { - gint8 ber_class; - gboolean pc, ind, imp_tag = FALSE; - gint32 tag; - guint32 len; - const ber_choice_t *ch; - proto_tree *tree=parent_tree; - proto_item *item=NULL; - int end_offset, start_offset, count; - int hoffset = offset; - header_field_info *hfinfo; - gint length, length_remaining; - tvbuff_t *next_tvb; - gboolean first_pass; + gint8 ber_class; + gboolean pc, ind, imp_tag = FALSE; + gint32 tag; + guint32 len; + const ber_choice_t *ch; + proto_tree *tree=parent_tree; + proto_item *item=NULL; + int end_offset, start_offset, count; + int hoffset = offset; + header_field_info *hfinfo; + gint length, length_remaining; + tvbuff_t *next_tvb; + gboolean first_pass; #ifdef DEBUG_BER_CHOICE { @@ -2989,110 +2998,110 @@ printf("CHOICE dissect_ber_choice(%s) entered len:%d\n",name,tvb_length_remainin } } #endif - start_offset=offset; + start_offset=offset; + + if(tvb_length_remaining(tvb,offset) == 0) { + item = proto_tree_add_string_format(parent_tree, hf_ber_error, tvb, offset, 0, "empty_choice", "BER Error: Empty choice was found"); + expert_add_info_format(actx->pinfo, item, PI_MALFORMED, PI_WARN, "BER Error: Empty choice was found"); + return offset; + } - if(tvb_length_remaining(tvb,offset) == 0) { - item = proto_tree_add_string_format(parent_tree, hf_ber_error, tvb, offset, 0, "empty_choice", "BER Error: Empty choice was found"); - expert_add_info_format(actx->pinfo, item, PI_MALFORMED, PI_WARN, "BER Error: Empty choice was found"); - return offset; + /* read header and len for choice field */ + offset=get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); + offset=get_ber_length(tvb, offset, &len, &ind); + end_offset = offset + len ; + + /* Some sanity checks. + * The hf field passed to us MUST be an integer type + */ + if(hf_id >= 0){ + hfinfo=proto_registrar_get_nth(hf_id); + switch(hfinfo->type) { + case FT_UINT8: + case FT_UINT16: + case FT_UINT24: + case FT_UINT32: + break; + default: + proto_tree_add_text(tree, tvb, offset, len,"dissect_ber_choice(): Was passed a HF field that was not integer type : %s",hfinfo->abbrev); + fprintf(stderr,"dissect_ber_choice(): frame:%u offset:%d Was passed a HF field that was not integer type : %s\n",actx->pinfo->fd->num,offset,hfinfo->abbrev); + return end_offset; } + } + + - /* read header and len for choice field */ - offset=get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); - offset=get_ber_length(tvb, offset, &len, &ind); - end_offset = offset + len ; - - /* Some sanity checks. - * The hf field passed to us MUST be an integer type - */ - if(hf_id >= 0){ - hfinfo=proto_registrar_get_nth(hf_id); - switch(hfinfo->type) { - case FT_UINT8: - case FT_UINT16: - case FT_UINT24: - case FT_UINT32: - break; - default: - proto_tree_add_text(tree, tvb, offset, len,"dissect_ber_choice(): Was passed a HF field that was not integer type : %s",hfinfo->abbrev); - fprintf(stderr,"dissect_ber_choice(): frame:%u offset:%d Was passed a HF field that was not integer type : %s\n",actx->pinfo->fd->num,offset,hfinfo->abbrev); - return end_offset; - } - } - - - - /* loop over all entries until we find the right choice or - run out of entries */ - ch = choice; - if(branch_taken){ - *branch_taken=-1; - } - first_pass = TRUE; - while(ch->func || first_pass){ - if(branch_taken){ - (*branch_taken)++; - } - /* we reset for a second pass when we will look for choices */ - if(!ch->func) { - first_pass = FALSE; - ch = choice; /* reset to the beginning */ - if(branch_taken){ - *branch_taken=-1; - } - } + /* loop over all entries until we find the right choice or + run out of entries */ + ch = choice; + if(branch_taken){ + *branch_taken=-1; + } + first_pass = TRUE; + while(ch->func || first_pass){ + if(branch_taken){ + (*branch_taken)++; + } + /* we reset for a second pass when we will look for choices */ + if(!ch->func) { + first_pass = FALSE; + ch = choice; /* reset to the beginning */ + if(branch_taken){ + *branch_taken=-1; + } + } choice_try_again: #ifdef DEBUG_BER_CHOICE printf("CHOICE testing potential subdissector class[%p]:%d:(expected)%d tag:%d:(expected)%d flags:%d\n",ch,ber_class,ch->ber_class,tag,ch->tag,ch->flags); #endif - if( (first_pass && (((ch->ber_class==ber_class)&&(ch->tag==tag)) - || ((ch->ber_class==ber_class)&&(ch->tag==-1)&&(ch->flags&BER_FLAGS_NOOWNTAG)))) || - (!first_pass && (((ch->ber_class == BER_CLASS_ANY) && (ch->tag == -1)))) /* we failed on the first pass so now try any choices */ - ){ - if(!(ch->flags & BER_FLAGS_NOOWNTAG)){ - /* dissect header and len for field */ - hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, start_offset, NULL, NULL, NULL); - hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); - start_offset=hoffset; - if (ind) - { - length = len-2; - } - else - { - length = len; - } - } - else - length = end_offset- hoffset; - /* create subtree */ - if(hf_id >= 0){ - if(parent_tree){ - item = proto_tree_add_uint(parent_tree, hf_id, tvb, hoffset, end_offset - hoffset, ch->value); - tree = proto_item_add_subtree(item, ett_id); - } - } - - length_remaining=tvb_length_remaining(tvb, hoffset); - if(length_remaining>length) - length_remaining=length; + if( (first_pass && (((ch->ber_class==ber_class)&&(ch->tag==tag)) + || ((ch->ber_class==ber_class)&&(ch->tag==-1)&&(ch->flags&BER_FLAGS_NOOWNTAG)))) || + (!first_pass && (((ch->ber_class == BER_CLASS_ANY) && (ch->tag == -1)))) /* we failed on the first pass so now try any choices */ + ){ + if(!(ch->flags & BER_FLAGS_NOOWNTAG)){ + /* dissect header and len for field */ + hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, start_offset, NULL, NULL, NULL); + hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); + start_offset=hoffset; + if (ind) + { + length = len-2; + } + else + { + length = len; + } + } + else + length = end_offset- hoffset; + /* create subtree */ + if(hf_id >= 0){ + if(parent_tree){ + item = proto_tree_add_uint(parent_tree, hf_id, tvb, hoffset, end_offset - hoffset, ch->value); + tree = proto_item_add_subtree(item, ett_id); + } + } + + length_remaining=tvb_length_remaining(tvb, hoffset); + if(length_remaining>length) + length_remaining=length; #ifdef REMOVED - /* This is bogus and makes the OID_1.0.9506.1.1.cap file - * in Steven J Schaeffer's email of 2005-09-12 fail to dissect - * properly. Maybe we should get rid of 'first_pass' - * completely. - * It was added as a qad workaround for some problem CMIP - * traces anyway. - * God, this file is a mess and it is my fault. /ronnie - */ - if(first_pass) - next_tvb=tvb_new_subset(tvb, hoffset, length_remaining, length); - else - next_tvb = tvb; /* we didn't make selection on this class/tag so pass it on */ + /* This is bogus and makes the OID_1.0.9506.1.1.cap file + * in Steven J Schaeffer's email of 2005-09-12 fail to dissect + * properly. Maybe we should get rid of 'first_pass' + * completely. + * It was added as a qad workaround for some problem CMIP + * traces anyway. + * God, this file is a mess and it is my fault. /ronnie + */ + if(first_pass) + next_tvb=tvb_new_subset(tvb, hoffset, length_remaining, length); + else + next_tvb = tvb; /* we didn't make selection on this class/tag so pass it on */ #endif - next_tvb=tvb_new_subset(tvb, hoffset, length_remaining, length); + next_tvb=tvb_new_subset(tvb, hoffset, length_remaining, length); #ifdef DEBUG_BER_CHOICE @@ -3112,14 +3121,14 @@ printf("CHOICE dissect_ber_choice(%s) calling subdissector len:%d\n",name,tvb_le } } #endif - if (next_tvb == NULL) { - /* Assume that we have a malformed packet. */ - THROW(ReportedBoundsError); - } - imp_tag = FALSE; - if ((ch->flags & BER_FLAGS_IMPLTAG)) - imp_tag = TRUE; - count=ch->func(imp_tag, next_tvb, 0, actx, tree, *ch->p_id); + if (next_tvb == NULL) { + /* Assume that we have a malformed packet. */ + THROW(ReportedBoundsError); + } + imp_tag = FALSE; + if ((ch->flags & BER_FLAGS_IMPLTAG)) + imp_tag = TRUE; + count=ch->func(imp_tag, next_tvb, 0, actx, tree, *ch->p_id); #ifdef DEBUG_BER_CHOICE { const char *name; @@ -3133,9 +3142,9 @@ name="unnamed"; printf("CHOICE dissect_ber_choice(%s) subdissector ate %d bytes\n",name,count); } #endif - if((count==0)&&(((ch->ber_class==ber_class)&&(ch->tag==-1)&&(ch->flags&BER_FLAGS_NOOWNTAG)) || !first_pass)){ - /* wrong one, break and try again */ - ch++; + if((count==0)&&(((ch->ber_class==ber_class)&&(ch->tag==-1)&&(ch->flags&BER_FLAGS_NOOWNTAG)) || !first_pass)){ + /* wrong one, break and try again */ + ch++; #ifdef DEBUG_BER_CHOICE { const char *name; @@ -3149,59 +3158,59 @@ name="unnamed"; printf("CHOICE dissect_ber_choice(%s) trying again\n",name); } #endif - goto choice_try_again; - } - if(!(ch->flags & BER_FLAGS_NOOWNTAG)){ - if(ind) - { - /* we are traversing a indfinite length choice where we did not pass the tag length */ - /* we need to eat the EOC */ - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, start_offset, count+2, "CHOICE EOC"); - } - } - } - return end_offset; - } - ch++; - } - if(branch_taken){ - /* none of the branches were taken so set the param - back to -1 */ - *branch_taken=-1; - } + goto choice_try_again; + } + if(!(ch->flags & BER_FLAGS_NOOWNTAG)){ + if(ind) + { + /* we are traversing a indfinite length choice where we did not pass the tag length */ + /* we need to eat the EOC */ + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, start_offset, count+2, "CHOICE EOC"); + } + } + } + return end_offset; + } + ch++; + } + if(branch_taken){ + /* none of the branches were taken so set the param + back to -1 */ + *branch_taken=-1; + } #ifdef REMOVED - /*XXX here we should have another flag to the CHOICE to distinguish - * between the case when we know it is a mandatory or if the CHOICE is optional == no arm matched */ - - /* oops no more entries and we still havent found - * our guy :-( - */ - item = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "missing_choice_field", "BER Error: This choice field was not found."); - expert_add_info_format(actx->pinfo, item, PI_MALFORMED, PI_WARN, "BER Error: This choice field was not found"); - return end_offset; + /*XXX here we should have another flag to the CHOICE to distinguish + * between the case when we know it is a mandatory or if the CHOICE is optional == no arm matched */ + + /* oops no more entries and we still havent found + * our guy :-( + */ + item = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "missing_choice_field", "BER Error: This choice field was not found."); + expert_add_info_format(actx->pinfo, item, PI_MALFORMED, PI_WARN, "BER Error: This choice field was not found"); + return end_offset; #endif - return start_offset; + return start_offset; } int dissect_ber_old_choice(asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const ber_old_choice_t *choice, gint hf_id, gint ett_id, gint *branch_taken) { - gint8 ber_class; - gboolean pc, ind; - gint32 tag; - guint32 len; - const ber_old_choice_t *ch; - proto_tree *tree=parent_tree; - proto_item *item=NULL; - int end_offset, start_offset, count; - int hoffset = offset; - header_field_info *hfinfo; - gint length, length_remaining; - tvbuff_t *next_tvb; - gboolean first_pass; + gint8 ber_class; + gboolean pc, ind; + gint32 tag; + guint32 len; + const ber_old_choice_t *ch; + proto_tree *tree=parent_tree; + proto_item *item=NULL; + int end_offset, start_offset, count; + int hoffset = offset; + header_field_info *hfinfo; + gint length, length_remaining; + tvbuff_t *next_tvb; + gboolean first_pass; #ifdef DEBUG_BER_CHOICE { @@ -3220,110 +3229,110 @@ printf("CHOICE dissect_ber_old_choice(%s) entered len:%d\n",name,tvb_length_rema } } #endif - start_offset=offset; + start_offset=offset; + + if(tvb_length_remaining(tvb,offset) == 0) { + item = proto_tree_add_string_format(parent_tree, hf_ber_error, tvb, offset, 0, "empty_choice", "BER Error: Empty choice was found"); + expert_add_info_format(actx->pinfo, item, PI_MALFORMED, PI_WARN, "BER Error: Empty choice was found"); + return offset; + } - if(tvb_length_remaining(tvb,offset) == 0) { - item = proto_tree_add_string_format(parent_tree, hf_ber_error, tvb, offset, 0, "empty_choice", "BER Error: Empty choice was found"); - expert_add_info_format(actx->pinfo, item, PI_MALFORMED, PI_WARN, "BER Error: Empty choice was found"); - return offset; + /* read header and len for choice field */ + offset=get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); + offset=get_ber_length(tvb, offset, &len, &ind); + end_offset = offset + len ; + + /* Some sanity checks. + * The hf field passed to us MUST be an integer type + */ + if(hf_id >= 0){ + hfinfo=proto_registrar_get_nth(hf_id); + switch(hfinfo->type) { + case FT_UINT8: + case FT_UINT16: + case FT_UINT24: + case FT_UINT32: + break; + default: + proto_tree_add_text(tree, tvb, offset, len,"dissect_ber_old_choice(): Was passed a HF field that was not integer type : %s",hfinfo->abbrev); + fprintf(stderr,"dissect_ber_old_choice(): frame:%u offset:%d Was passed a HF field that was not integer type : %s\n",actx->pinfo->fd->num,offset,hfinfo->abbrev); + return end_offset; } + } + - /* read header and len for choice field */ - offset=get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); - offset=get_ber_length(tvb, offset, &len, &ind); - end_offset = offset + len ; - - /* Some sanity checks. - * The hf field passed to us MUST be an integer type - */ - if(hf_id >= 0){ - hfinfo=proto_registrar_get_nth(hf_id); - switch(hfinfo->type) { - case FT_UINT8: - case FT_UINT16: - case FT_UINT24: - case FT_UINT32: - break; - default: - proto_tree_add_text(tree, tvb, offset, len,"dissect_ber_old_choice(): Was passed a HF field that was not integer type : %s",hfinfo->abbrev); - fprintf(stderr,"dissect_ber_old_choice(): frame:%u offset:%d Was passed a HF field that was not integer type : %s\n",actx->pinfo->fd->num,offset,hfinfo->abbrev); - return end_offset; - } - } - - - - /* loop over all entries until we find the right choice or - run out of entries */ - ch = choice; - if(branch_taken){ - *branch_taken=-1; - } - first_pass = TRUE; - while(ch->func || first_pass){ - if(branch_taken){ - (*branch_taken)++; - } - /* we reset for a second pass when we will look for choices */ - if(!ch->func) { - first_pass = FALSE; - ch = choice; /* reset to the beginning */ - if(branch_taken){ - *branch_taken=-1; - } - } + + /* loop over all entries until we find the right choice or + run out of entries */ + ch = choice; + if(branch_taken){ + *branch_taken=-1; + } + first_pass = TRUE; + while(ch->func || first_pass){ + if(branch_taken){ + (*branch_taken)++; + } + /* we reset for a second pass when we will look for choices */ + if(!ch->func) { + first_pass = FALSE; + ch = choice; /* reset to the beginning */ + if(branch_taken){ + *branch_taken=-1; + } + } choice_try_again: #ifdef DEBUG_BER_CHOICE printf("CHOICE testing potential subdissector class[%p]:%d:(expected)%d tag:%d:(expected)%d flags:%d\n",ch,ber_class,ch->ber_class,tag,ch->tag,ch->flags); #endif - if( (first_pass && (((ch->ber_class==ber_class)&&(ch->tag==tag)) - || ((ch->ber_class==ber_class)&&(ch->tag==-1)&&(ch->flags&BER_FLAGS_NOOWNTAG)))) || - (!first_pass && (((ch->ber_class == BER_CLASS_ANY) && (ch->tag == -1)))) /* we failed on the first pass so now try any choices */ - ){ - if(!(ch->flags & BER_FLAGS_NOOWNTAG)){ - /* dissect header and len for field */ - hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, start_offset, NULL, NULL, NULL); - hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); - start_offset=hoffset; - if (ind) - { - length = len-2; - } - else - { - length = len; - } - } - else - length = end_offset- hoffset; - /* create subtree */ - if(hf_id >= 0){ - if(parent_tree){ - item = proto_tree_add_uint(parent_tree, hf_id, tvb, hoffset, end_offset - hoffset, ch->value); - tree = proto_item_add_subtree(item, ett_id); - } - } - - length_remaining=tvb_length_remaining(tvb, hoffset); - if(length_remaining>length) - length_remaining=length; + if( (first_pass && (((ch->ber_class==ber_class)&&(ch->tag==tag)) + || ((ch->ber_class==ber_class)&&(ch->tag==-1)&&(ch->flags&BER_FLAGS_NOOWNTAG)))) || + (!first_pass && (((ch->ber_class == BER_CLASS_ANY) && (ch->tag == -1)))) /* we failed on the first pass so now try any choices */ + ){ + if(!(ch->flags & BER_FLAGS_NOOWNTAG)){ + /* dissect header and len for field */ + hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, start_offset, NULL, NULL, NULL); + hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); + start_offset=hoffset; + if (ind) + { + length = len-2; + } + else + { + length = len; + } + } + else + length = end_offset- hoffset; + /* create subtree */ + if(hf_id >= 0){ + if(parent_tree){ + item = proto_tree_add_uint(parent_tree, hf_id, tvb, hoffset, end_offset - hoffset, ch->value); + tree = proto_item_add_subtree(item, ett_id); + } + } + + length_remaining=tvb_length_remaining(tvb, hoffset); + if(length_remaining>length) + length_remaining=length; #ifdef REMOVED - /* This is bogus and makes the OID_1.0.9506.1.1.cap file - * in Steven J Schaeffer's email of 2005-09-12 fail to dissect - * properly. Maybe we should get rid of 'first_pass' - * completely. - * It was added as a qad workaround for some problem CMIP - * traces anyway. - * God, this file is a mess and it is my fault. /ronnie - */ - if(first_pass) - next_tvb=tvb_new_subset(tvb, hoffset, length_remaining, length); - else - next_tvb = tvb; /* we didn't make selection on this class/tag so pass it on */ + /* This is bogus and makes the OID_1.0.9506.1.1.cap file + * in Steven J Schaeffer's email of 2005-09-12 fail to dissect + * properly. Maybe we should get rid of 'first_pass' + * completely. + * It was added as a qad workaround for some problem CMIP + * traces anyway. + * God, this file is a mess and it is my fault. /ronnie + */ + if(first_pass) + next_tvb=tvb_new_subset(tvb, hoffset, length_remaining, length); + else + next_tvb = tvb; /* we didn't make selection on this class/tag so pass it on */ #endif - next_tvb=tvb_new_subset(tvb, hoffset, length_remaining, length); + next_tvb=tvb_new_subset(tvb, hoffset, length_remaining, length); #ifdef DEBUG_BER_CHOICE @@ -3343,11 +3352,11 @@ printf("CHOICE dissect_ber_old_choice(%s) calling subdissector len:%d\n",name,tv } } #endif - if (next_tvb == NULL) { - /* Assume that we have a malformed packet. */ - THROW(ReportedBoundsError); - } - count=ch->func(tree, next_tvb, 0, actx); + if (next_tvb == NULL) { + /* Assume that we have a malformed packet. */ + THROW(ReportedBoundsError); + } + count=ch->func(tree, next_tvb, 0, actx); #ifdef DEBUG_BER_CHOICE { const char *name; @@ -3361,9 +3370,9 @@ name="unnamed"; printf("CHOICE dissect_ber_old_choice(%s) subdissector ate %d bytes\n",name,count); } #endif - if((count==0)&&(((ch->ber_class==ber_class)&&(ch->tag==-1)&&(ch->flags&BER_FLAGS_NOOWNTAG)) || !first_pass)){ - /* wrong one, break and try again */ - ch++; + if((count==0)&&(((ch->ber_class==ber_class)&&(ch->tag==-1)&&(ch->flags&BER_FLAGS_NOOWNTAG)) || !first_pass)){ + /* wrong one, break and try again */ + ch++; #ifdef DEBUG_BER_CHOICE { const char *name; @@ -3377,41 +3386,41 @@ name="unnamed"; printf("CHOICE dissect_ber_old_choice(%s) trying again\n",name); } #endif - goto choice_try_again; - } - if(!(ch->flags & BER_FLAGS_NOOWNTAG)){ - if(ind) - { - /* we are traversing a indfinite length choice where we did not pass the tag length */ - /* we need to eat the EOC */ - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, start_offset, count+2, "CHOICE EOC"); - } - } - } - return end_offset; - } - ch++; - } - if(branch_taken){ - /* none of the branches were taken so set the param - back to -1 */ - *branch_taken=-1; - } + goto choice_try_again; + } + if(!(ch->flags & BER_FLAGS_NOOWNTAG)){ + if(ind) + { + /* we are traversing a indfinite length choice where we did not pass the tag length */ + /* we need to eat the EOC */ + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, start_offset, count+2, "CHOICE EOC"); + } + } + } + return end_offset; + } + ch++; + } + if(branch_taken){ + /* none of the branches were taken so set the param + back to -1 */ + *branch_taken=-1; + } #ifdef REMOVED - /*XXX here we should have another flag to the CHOICE to distinguish - * between the case when we know it is a mandatory or if the CHOICE is optional == no arm matched */ - - /* oops no more entries and we still havent found - * our guy :-( - */ - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "missing_choice_field", "BER Error: This choice field was not found."); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: This choice field was not found"); - return end_offset; + /*XXX here we should have another flag to the CHOICE to distinguish + * between the case when we know it is a mandatory or if the CHOICE is optional == no arm matched */ + + /* oops no more entries and we still havent found + * our guy :-( + */ + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "missing_choice_field", "BER Error: This choice field was not found."); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: This choice field was not found"); + return end_offset; #endif - return start_offset; + return start_offset; } #if 0 @@ -3420,66 +3429,66 @@ printf("CHOICE dissect_ber_old_choice(%s) trying again\n",name); int dissect_ber_GeneralString(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, char *name_string, int name_len) { - gint8 ber_class; - gboolean pc; - gint32 tag; - guint32 len; - int end_offset; - int hoffset; - char str_arr[256]; - guint32 max_len; - char *str; - proto_item *cause; - - str=str_arr; - max_len=255; - if(name_string){ - str=name_string; - max_len=name_len; - } - - hoffset = offset; - /* first we must read the GeneralString header */ - offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); - offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL); - end_offset=offset+len; - - /* sanity check: we only handle Universal GeneralString*/ - if( (ber_class!=BER_CLASS_UNI) - ||(tag!=BER_UNI_TAG_GENSTR) ){ - tvb_ensure_bytes_exist(tvb, hoffset, 2); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "generalstring_expected", "BER Error: GeneralString expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: GeneralString expected"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - return end_offset; - } - - if(len>=(max_len-1)){ - len=max_len-1; - } - - tvb_memcpy(tvb, str, offset, len); - str[len]=0; - - if(hf_id >= 0){ - proto_tree_add_string(tree, hf_id, tvb, offset, len, str); - } - - return end_offset; + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 len; + int end_offset; + int hoffset; + char str_arr[256]; + guint32 max_len; + char *str; + proto_item *cause; + + str=str_arr; + max_len=255; + if(name_string){ + str=name_string; + max_len=name_len; + } + + hoffset = offset; + /* first we must read the GeneralString header */ + offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL); + end_offset=offset+len; + + /* sanity check: we only handle Universal GeneralString*/ + if( (ber_class!=BER_CLASS_UNI) + ||(tag!=BER_UNI_TAG_GENSTR) ){ + tvb_ensure_bytes_exist(tvb, hoffset, 2); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "generalstring_expected", "BER Error: GeneralString expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: GeneralString expected"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + return end_offset; + } + + if(len>=(max_len-1)){ + len=max_len-1; + } + + tvb_memcpy(tvb, str, offset, len); + str[len]=0; + + if(hf_id >= 0){ + proto_tree_add_string(tree, hf_id, tvb, offset, len, str); + } + + return end_offset; } #endif int dissect_ber_constrained_restricted_string(gboolean implicit_tag, gint32 type, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint32 min_len, gint32 max_len, gint hf_id, tvbuff_t **out_tvb) { - gint8 ber_class; - gboolean pc; - gint32 tag; - guint32 len; - int eoffset; - int hoffset = offset; - proto_item *cause; + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 len; + int eoffset; + int hoffset = offset; + proto_item *cause; #ifdef DEBUG_BER { @@ -3499,77 +3508,77 @@ printf("RESTRICTED STRING dissect_ber_octet_string(%s) entered\n",name); } #endif - if(!implicit_tag) { - offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); - offset = get_ber_length(tvb, offset, &len, NULL); - eoffset = offset + len; - - /* sanity check */ - if( (ber_class!=BER_CLASS_UNI) - ||(tag != type) ){ - tvb_ensure_bytes_exist(tvb, hoffset, 2); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "string_expected", "BER Error: String with tag=%d expected but class:%s(%d) %s tag:%d was unexpected", type, val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: String expected"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - return eoffset; - } - } - - /* 8.21.3 */ - return dissect_ber_constrained_octet_string(implicit_tag, actx, tree, tvb, hoffset, min_len, max_len, hf_id, out_tvb); + if(!implicit_tag) { + offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); + offset = get_ber_length(tvb, offset, &len, NULL); + eoffset = offset + len; + + /* sanity check */ + if( (ber_class!=BER_CLASS_UNI) + ||(tag != type) ){ + tvb_ensure_bytes_exist(tvb, hoffset, 2); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "string_expected", "BER Error: String with tag=%d expected but class:%s(%d) %s tag:%d was unexpected", type, val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: String expected"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + return eoffset; + } + } + + /* 8.21.3 */ + return dissect_ber_constrained_octet_string(implicit_tag, actx, tree, tvb, hoffset, min_len, max_len, hf_id, out_tvb); } int dissect_ber_restricted_string(gboolean implicit_tag, gint32 type, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, tvbuff_t **out_tvb) { - return dissect_ber_constrained_restricted_string(implicit_tag, type, actx, tree, tvb, offset, NO_BOUND, NO_BOUND, hf_id, out_tvb); + return dissect_ber_constrained_restricted_string(implicit_tag, type, actx, tree, tvb, offset, NO_BOUND, NO_BOUND, hf_id, out_tvb); } int dissect_ber_GeneralString(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, char *name_string, guint name_len) { - tvbuff_t *out_tvb = NULL; - gint tvb_len; - - offset = dissect_ber_restricted_string(FALSE, BER_UNI_TAG_GeneralString, actx, tree, tvb, offset, hf_id, (name_string)?&out_tvb:NULL); - - if(name_string) { - /* - * XXX - do we want to just get what's left in the tvbuff - * if the full length isn't available in the tvbuff, or - * do we want to throw an exception? - */ - if(out_tvb) { - tvb_len = tvb_length(out_tvb); - if((guint)tvb_len >= name_len) { - tvb_memcpy(out_tvb, (guint8*)name_string, 0, name_len-1); - name_string[name_len-1] = '\0'; - } else { - tvb_memcpy(out_tvb, (guint8*)name_string, 0, tvb_len); - name_string[tvb_len] = '\0'; - } - } - } - - return offset; + tvbuff_t *out_tvb = NULL; + gint tvb_len; + + offset = dissect_ber_restricted_string(FALSE, BER_UNI_TAG_GeneralString, actx, tree, tvb, offset, hf_id, (name_string)?&out_tvb:NULL); + + if(name_string) { + /* + * XXX - do we want to just get what's left in the tvbuff + * if the full length isn't available in the tvbuff, or + * do we want to throw an exception? + */ + if(out_tvb) { + tvb_len = tvb_length(out_tvb); + if((guint)tvb_len >= name_len) { + tvb_memcpy(out_tvb, (guint8*)name_string, 0, name_len-1); + name_string[name_len-1] = '\0'; + } else { + tvb_memcpy(out_tvb, (guint8*)name_string, 0, tvb_len); + name_string[tvb_len] = '\0'; + } + } + } + + return offset; } /* 8.19 Encoding of an object identifier value. */ int dissect_ber_object_identifier(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, tvbuff_t **value_tvb) { - gint8 ber_class; - gboolean pc; - gint32 tag; - guint32 len; - int eoffset; - int hoffset; - const char *str; - proto_item *cause; - header_field_info *hfi; - const gchar *name; + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 len; + int eoffset; + int hoffset; + const char *str; + proto_item *cause; + header_field_info *hfi; + const gchar *name; #ifdef DEBUG_BER { @@ -3589,68 +3598,68 @@ printf("OBJECT IDENTIFIER dissect_ber_object_identifier(%s) entered\n",name); } #endif - if(!implicit_tag) { - hoffset = offset; - /* sanity check */ - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL); - eoffset = offset + len; - if( (ber_class!=BER_CLASS_UNI) - ||(tag != BER_UNI_TAG_OID) ){ - tvb_ensure_bytes_exist(tvb, hoffset, 2); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "oid_expected", "BER Error: Object Identifier expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Object Identifier expected"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - return eoffset; - } - } else { - len=tvb_length_remaining(tvb,offset); - eoffset=offset+len; - } - - actx->created_item=NULL; - hfi = proto_registrar_get_nth(hf_id); - if (hfi->type == FT_OID) { - actx->created_item = proto_tree_add_item(tree, hf_id, tvb, offset, len, ENC_BIG_ENDIAN); - } else if (IS_FT_STRING(hfi->type)) { - str = oid_encoded2string(tvb_get_ptr(tvb, offset, len), len); - actx->created_item = proto_tree_add_string(tree, hf_id, tvb, offset, len, str); - if(actx->created_item){ - /* see if we know the name of this oid */ - name = oid_resolved_from_encoded(tvb_get_ptr(tvb, offset, len), len); - if(name){ - proto_item_append_text(actx->created_item, " (%s)", name); - } - } - } else { - DISSECTOR_ASSERT_NOT_REACHED(); - } - - if (value_tvb) - *value_tvb = tvb_new_subset(tvb, offset, len, len); - - return eoffset; + if(!implicit_tag) { + hoffset = offset; + /* sanity check */ + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL); + eoffset = offset + len; + if( (ber_class!=BER_CLASS_UNI) + ||(tag != BER_UNI_TAG_OID) ){ + tvb_ensure_bytes_exist(tvb, hoffset, 2); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "oid_expected", "BER Error: Object Identifier expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Object Identifier expected"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + return eoffset; + } + } else { + len=tvb_length_remaining(tvb,offset); + eoffset=offset+len; + } + + actx->created_item=NULL; + hfi = proto_registrar_get_nth(hf_id); + if (hfi->type == FT_OID) { + actx->created_item = proto_tree_add_item(tree, hf_id, tvb, offset, len, ENC_BIG_ENDIAN); + } else if (IS_FT_STRING(hfi->type)) { + str = oid_encoded2string(tvb_get_ptr(tvb, offset, len), len); + actx->created_item = proto_tree_add_string(tree, hf_id, tvb, offset, len, str); + if(actx->created_item){ + /* see if we know the name of this oid */ + name = oid_resolved_from_encoded(tvb_get_ptr(tvb, offset, len), len); + if(name){ + proto_item_append_text(actx->created_item, " (%s)", name); + } + } + } else { + DISSECTOR_ASSERT_NOT_REACHED(); + } + + if (value_tvb) + *value_tvb = tvb_new_subset(tvb, offset, len, len); + + return eoffset; } int dissect_ber_object_identifier_str(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, const char **value_stringx) { - tvbuff_t *value_tvb = NULL; - guint length; + tvbuff_t *value_tvb = NULL; + guint length; - offset = dissect_ber_object_identifier(implicit_tag, actx, tree, tvb, offset, hf_id, (value_stringx) ? &value_tvb : NULL); + offset = dissect_ber_object_identifier(implicit_tag, actx, tree, tvb, offset, hf_id, (value_stringx) ? &value_tvb : NULL); - if (value_stringx) { - if (value_tvb && (length = tvb_length(value_tvb))) { - *value_stringx = oid_encoded2string(tvb_get_ptr(value_tvb, 0, length), length); - } else { - *value_stringx = ""; + if (value_stringx) { + if (value_tvb && (length = tvb_length(value_tvb))) { + *value_stringx = oid_encoded2string(tvb_get_ptr(value_tvb, 0, length), length); + } else { + *value_stringx = ""; + } } - } - return offset; + return offset; } #ifdef DEBUG_BER @@ -3658,18 +3667,18 @@ int dissect_ber_object_identifier_str(gboolean implicit_tag, asn1_ctx_t *actx, p #endif static int dissect_ber_sq_of(gboolean implicit_tag, gint32 type, asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, gint32 min_len, gint32 max_len, const ber_sequence_t *seq, gint hf_id, gint ett_id) { - gint8 classx; - gboolean pcx, ind = FALSE, ind_field; - gint32 tagx; - guint32 lenx; - - proto_tree *tree = parent_tree; - proto_item *item = NULL; - proto_item *causex; - int cnt, hoffsetx, end_offset; - header_field_info *hfi; - gint length_remaining; - tvbuff_t *next_tvb; + gint8 classx; + gboolean pcx, ind = FALSE, ind_field; + gint32 tagx; + guint32 lenx; + + proto_tree *tree = parent_tree; + proto_item *item = NULL; + proto_item *causex; + int cnt, hoffsetx, end_offset; + header_field_info *hfi; + gint length_remaining; + tvbuff_t *next_tvb; #ifdef DEBUG_BER_SQ_OF { @@ -3689,200 +3698,200 @@ printf("SQ OF dissect_ber_sq_of(%s) entered\n",name); } #endif - if(!implicit_tag){ - hoffsetx = offset; - /* first we must read the sequence header */ - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &classx, &pcx, &tagx); - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &lenx, &ind); - if(ind){ - /* if the length is indefinite we dont really know (yet) where the - * object ends so assume it spans the rest of the tvb for now. - */ - end_offset = offset + lenx; - } else { - end_offset = offset + lenx; - } - - /* sanity check: we only handle Constructed Universal Sequences */ - if((classx!=BER_CLASS_APP)&&(classx!=BER_CLASS_PRI)) - if(!pcx - ||(!implicit_tag&&((classx!=BER_CLASS_UNI) - ||(tagx!=type)))) { - tvb_ensure_bytes_exist(tvb, hoffsetx, 2); - causex = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, (type==BER_UNI_TAG_SEQUENCE)?"set_of_expected":"sequence_of_expected", "BER Error: %s Of expected but class:%s(%d) %s tag:%d was unexpected", - (type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence", val_to_str(classx,ber_class_codes,"Unknown"), classx, pcx ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tagx); - expert_add_info_format(actx->pinfo, causex, PI_MALFORMED, PI_WARN, "BER Error: %s Of expected",(type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(causex, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffsetx, unknown_tree); - } - return end_offset; - } - } else { - /* the tvb length should be correct now nope we could be comming from an implicit choice or sequence, thus we - read the items we match and return the length*/ - lenx=tvb_length_remaining(tvb,offset); - end_offset = offset + lenx; - } - - /* count number of items */ - cnt = 0; - hoffsetx = offset; - /* only count the number of items IFF we have the full blob, - * else this will just generate a [short frame] before we even start - * dissecting a single item. - */ - /* XXX Do we really need to count them at all ? ronnie */ - if(tvb_length_remaining(tvb, offset)==tvb_reported_length_remaining(tvb, offset)){ - while (offset < end_offset){ - guint32 len; - gint s_offset; - - s_offset = offset; - - /*if(ind){ this sequence of was of indefinite length, if this is implicit indefinite impossible maybe - but ber dissector uses this to eat the tag length then pass into here... EOC still on there...*/ - if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ - break; - } - /*}*/ - - /* read header and len for next field */ - offset = get_ber_identifier(tvb, offset, NULL, NULL, NULL); - offset = get_ber_length(tvb, offset, &len, &ind); - /* best place to get real length of implicit sequence of or set of is here... */ - /* adjust end_offset if we find somthing that doesnt match */ - offset += len; - cnt++; - if (offset <= s_offset) - THROW(ReportedBoundsError); - } - } - offset = hoffsetx; - - /* create subtree */ - if(hf_id >= 0) { - hfi = proto_registrar_get_nth(hf_id); - if(parent_tree){ - if(hfi->type == FT_NONE) { - item = proto_tree_add_item(parent_tree, hf_id, tvb, offset, lenx, ENC_BIG_ENDIAN); - proto_item_append_text(item, ":"); - } else { - item = proto_tree_add_uint(parent_tree, hf_id, tvb, offset, lenx, cnt); - proto_item_append_text(item, (cnt==1)?" item":" items"); - } - tree = proto_item_add_subtree(item, ett_id); - ber_check_items (cnt, min_len, max_len, actx, item); - } - } - - /* loop over all entries until we reach the end of the sequence */ - while (offset < end_offset){ - gint8 ber_class; - gboolean pc; - gint32 tag; - guint32 len; - int eoffset; - int hoffset; - proto_item *cause; - gboolean imp_tag; - - hoffset = offset; - /*if(ind){ this sequence was of indefinite length, if this is implicit indefinite impossible maybe - but ber dissector uses this to eat the tag length then pass into here... EOC still on there...*/ - if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, hoffset, end_offset-hoffset, "SEQ OF EOC"); - } - return offset+2; - } - /*}*/ - /* read header and len for next field */ - offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); - offset = get_ber_length(tvb, offset, &len, &ind_field); - eoffset = offset + len; + if(!implicit_tag){ + hoffsetx = offset; + /* first we must read the sequence header */ + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &classx, &pcx, &tagx); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &lenx, &ind); + if(ind){ + /* if the length is indefinite we dont really know (yet) where the + * object ends so assume it spans the rest of the tvb for now. + */ + end_offset = offset + lenx; + } else { + end_offset = offset + lenx; + } + + /* sanity check: we only handle Constructed Universal Sequences */ + if((classx!=BER_CLASS_APP)&&(classx!=BER_CLASS_PRI)) + if(!pcx + ||(!implicit_tag&&((classx!=BER_CLASS_UNI) + ||(tagx!=type)))) { + tvb_ensure_bytes_exist(tvb, hoffsetx, 2); + causex = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, (type==BER_UNI_TAG_SEQUENCE)?"set_of_expected":"sequence_of_expected", "BER Error: %s Of expected but class:%s(%d) %s tag:%d was unexpected", + (type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence", val_to_str(classx,ber_class_codes,"Unknown"), classx, pcx ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tagx); + expert_add_info_format(actx->pinfo, causex, PI_MALFORMED, PI_WARN, "BER Error: %s Of expected",(type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(causex, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffsetx, unknown_tree); + } + return end_offset; + } + } else { + /* the tvb length should be correct now nope we could be comming from an implicit choice or sequence, thus we + read the items we match and return the length*/ + lenx=tvb_length_remaining(tvb,offset); + end_offset = offset + lenx; + } + + /* count number of items */ + cnt = 0; + hoffsetx = offset; + /* only count the number of items IFF we have the full blob, + * else this will just generate a [short frame] before we even start + * dissecting a single item. + */ + /* XXX Do we really need to count them at all ? ronnie */ + if(tvb_length_remaining(tvb, offset)==tvb_reported_length_remaining(tvb, offset)){ + while (offset < end_offset){ + guint32 len; + gint s_offset; + + s_offset = offset; + + /*if(ind){ this sequence of was of indefinite length, if this is implicit indefinite impossible maybe + but ber dissector uses this to eat the tag length then pass into here... EOC still on there...*/ + if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ + break; + } + /*}*/ + + /* read header and len for next field */ + offset = get_ber_identifier(tvb, offset, NULL, NULL, NULL); + offset = get_ber_length(tvb, offset, &len, &ind); + /* best place to get real length of implicit sequence of or set of is here... */ + /* adjust end_offset if we find somthing that doesnt match */ + offset += len; + cnt++; + if (offset <= s_offset) + THROW(ReportedBoundsError); + } + } + offset = hoffsetx; + + /* create subtree */ + if(hf_id >= 0) { + hfi = proto_registrar_get_nth(hf_id); + if(parent_tree){ + if(hfi->type == FT_NONE) { + item = proto_tree_add_item(parent_tree, hf_id, tvb, offset, lenx, ENC_BIG_ENDIAN); + proto_item_append_text(item, ":"); + } else { + item = proto_tree_add_uint(parent_tree, hf_id, tvb, offset, lenx, cnt); + proto_item_append_text(item, (cnt==1)?" item":" items"); + } + tree = proto_item_add_subtree(item, ett_id); + ber_check_items (cnt, min_len, max_len, actx, item); + } + } + + /* loop over all entries until we reach the end of the sequence */ + while (offset < end_offset){ + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 len; + int eoffset; + int hoffset; + proto_item *cause; + gboolean imp_tag; + + hoffset = offset; + /*if(ind){ this sequence was of indefinite length, if this is implicit indefinite impossible maybe + but ber dissector uses this to eat the tag length then pass into here... EOC still on there...*/ + if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, hoffset, end_offset-hoffset, "SEQ OF EOC"); + } + return offset+2; + } + /*}*/ + /* read header and len for next field */ + offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); + offset = get_ber_length(tvb, offset, &len, &ind_field); + eoffset = offset + len; /* Make sure we move forward */ - if (eoffset <= hoffset) - THROW(ReportedBoundsError); - - if((ber_class==BER_CLASS_UNI)&&(tag==BER_UNI_TAG_EOC)){ - /* This is a zero length sequence of*/ - hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); - return eoffset; - } - /* verify that this one is the one we want */ - /* ahup if we are implicit then we return to the uper layer how much we have used */ - if(seq->ber_class!=BER_CLASS_ANY){ - if((seq->ber_class!=ber_class) - ||(seq->tag!=tag) ){ - if(!(seq->flags & BER_FLAGS_NOTCHKTAG)) { - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", "BER Error: Wrong field in SQ OF(tag %u expected %u)",tag,seq->tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in Sequence Of"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - offset = eoffset; - continue; - /* wrong.... */ - } - } - } - - if(!(seq->flags & BER_FLAGS_NOOWNTAG) && !(seq->flags & BER_FLAGS_IMPLTAG)) { - /* dissect header and len for field */ - hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); - } - if((seq->flags == BER_FLAGS_IMPLTAG)&&(seq->ber_class==BER_CLASS_CON)) { - /* Constructed sequence of with a tag */ - /* dissect header and len for field */ - hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); - /* Function has IMPLICIT TAG */ - } - - length_remaining=tvb_length_remaining(tvb, hoffset); - if (length_remaining>eoffset-hoffset) - length_remaining=eoffset-hoffset; - next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset); - - imp_tag = FALSE; - if(seq->flags == BER_FLAGS_IMPLTAG) - imp_tag = TRUE; - /* call the dissector for this field */ - seq->func(imp_tag, next_tvb, 0, actx, tree, *seq->p_id); - /* hold on if we are implicit and the result is zero, i.e. the item in the sequence of - doesnt match the next item, thus this implicit sequence is over, return the number of bytes - we have eaten to allow the possible upper sequence continue... */ - cnt++; /* rubbish*/ - offset = eoffset; - } - - /* if we didnt end up at exactly offset, then we ate too many bytes */ - if(offset != end_offset) { - tvb_ensure_bytes_exist(tvb, offset-2, 2); - causex =proto_tree_add_string_format(tree, hf_ber_error, tvb, offset-2, 2, "illegal_length", "BER Error: %s Of ate %d too many bytes", - (type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence", offset-end_offset); - expert_add_info_format(actx->pinfo, causex, PI_MALFORMED, PI_WARN, "BER Error:too many byte in %s",(type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence"); - } - - return end_offset; + if (eoffset <= hoffset) + THROW(ReportedBoundsError); + + if((ber_class==BER_CLASS_UNI)&&(tag==BER_UNI_TAG_EOC)){ + /* This is a zero length sequence of*/ + hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); + return eoffset; + } + /* verify that this one is the one we want */ + /* ahup if we are implicit then we return to the uper layer how much we have used */ + if(seq->ber_class!=BER_CLASS_ANY){ + if((seq->ber_class!=ber_class) + ||(seq->tag!=tag) ){ + if(!(seq->flags & BER_FLAGS_NOTCHKTAG)) { + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", "BER Error: Wrong field in SQ OF(tag %u expected %u)",tag,seq->tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in Sequence Of"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + offset = eoffset; + continue; + /* wrong.... */ + } + } + } + + if(!(seq->flags & BER_FLAGS_NOOWNTAG) && !(seq->flags & BER_FLAGS_IMPLTAG)) { + /* dissect header and len for field */ + hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); + } + if((seq->flags == BER_FLAGS_IMPLTAG)&&(seq->ber_class==BER_CLASS_CON)) { + /* Constructed sequence of with a tag */ + /* dissect header and len for field */ + hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); + /* Function has IMPLICIT TAG */ + } + + length_remaining=tvb_length_remaining(tvb, hoffset); + if (length_remaining>eoffset-hoffset) + length_remaining=eoffset-hoffset; + next_tvb = tvb_new_subset(tvb, hoffset, length_remaining, eoffset-hoffset); + + imp_tag = FALSE; + if(seq->flags == BER_FLAGS_IMPLTAG) + imp_tag = TRUE; + /* call the dissector for this field */ + seq->func(imp_tag, next_tvb, 0, actx, tree, *seq->p_id); + /* hold on if we are implicit and the result is zero, i.e. the item in the sequence of + doesnt match the next item, thus this implicit sequence is over, return the number of bytes + we have eaten to allow the possible upper sequence continue... */ + cnt++; /* rubbish*/ + offset = eoffset; + } + + /* if we didnt end up at exactly offset, then we ate too many bytes */ + if(offset != end_offset) { + tvb_ensure_bytes_exist(tvb, offset-2, 2); + causex =proto_tree_add_string_format(tree, hf_ber_error, tvb, offset-2, 2, "illegal_length", "BER Error: %s Of ate %d too many bytes", + (type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence", offset-end_offset); + expert_add_info_format(actx->pinfo, causex, PI_MALFORMED, PI_WARN, "BER Error:too many byte in %s",(type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence"); + } + + return end_offset; } static int dissect_ber_old_sq_of(gboolean implicit_tag, gint32 type, asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const ber_old_sequence_t *seq, gint hf_id, gint ett_id) { - gint8 classx; - gboolean pcx, ind = FALSE, ind_field; - gint32 tagx; - guint32 lenx; - - proto_tree *tree = parent_tree; - proto_item *item = NULL; - proto_item *causex; - int cnt, hoffsetx, end_offset; - header_field_info *hfi; - gint length_remaining; + gint8 classx; + gboolean pcx, ind = FALSE, ind_field; + gint32 tagx; + guint32 lenx; + + proto_tree *tree = parent_tree; + proto_item *item = NULL; + proto_item *causex; + int cnt, hoffsetx, end_offset; + header_field_info *hfi; + gint length_remaining; #ifdef DEBUG_BER_SQ_OF { @@ -3902,604 +3911,604 @@ printf("SQ OF dissect_ber_old_sq_of(%s) entered\n",name); } #endif - if(!implicit_tag){ - hoffsetx = offset; - /* first we must read the sequence header */ - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &classx, &pcx, &tagx); - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &lenx, &ind); - if(ind){ - /* if the length is indefinite we dont really know (yet) where the - * object ends so assume it spans the rest of the tvb for now. - */ - end_offset = offset + lenx; - } else { - end_offset = offset + lenx; - } - - /* sanity check: we only handle Constructed Universal Sequences */ - if((classx!=BER_CLASS_APP)&&(classx!=BER_CLASS_PRI)) - if(!pcx - ||(!implicit_tag&&((classx!=BER_CLASS_UNI) - ||(tagx!=type)))) { - tvb_ensure_bytes_exist(tvb, hoffsetx, 2); - causex = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, (type==BER_UNI_TAG_SEQUENCE)?"set_of_expected":"sequence_of_expected", "BER Error: %s Of expected but class:%s(%d) %s tag:%d was unexpected", - (type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence", val_to_str(classx,ber_class_codes,"Unknown"), classx, pcx ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tagx); - expert_add_info_format(actx->pinfo, causex, PI_MALFORMED, PI_WARN, "BER Error: %s Of expected",(type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(causex, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffsetx, unknown_tree); - } - return end_offset; - } - } else { - /* the tvb length should be correct now nope we could be comming from an implicit choice or sequence, thus we - read the items we match and return the length*/ - lenx=tvb_length_remaining(tvb,offset); - end_offset = offset + lenx; - } - - /* count number of items */ - cnt = 0; - hoffsetx = offset; - /* only count the number of items IFF we have the full blob, - * else this will just generate a [short frame] before we even start - * dissecting a single item. - */ - /* XXX Do we really need to count them at all ? ronnie */ - if(tvb_length_remaining(tvb, offset)==tvb_reported_length_remaining(tvb, offset)){ - while (offset < end_offset){ - guint32 len; - gint s_offset; - - s_offset = offset; - - if(ind){ /* this sequence of was of indefinite length, so check for EOC */ - if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ - break; - } - } - - /* read header and len for next field */ - offset = get_ber_identifier(tvb, offset, NULL, NULL, NULL); - offset = get_ber_length(tvb, offset, &len, &ind); - /* best place to get real length of implicit sequence of or set of is here... */ - /* adjust end_offset if we find somthing that doesnt match */ - offset += len; - cnt++; - if (offset <= s_offset) - THROW(ReportedBoundsError); - } - } - offset = hoffsetx; - - /* create subtree */ - if(hf_id >= 0) { - hfi = proto_registrar_get_nth(hf_id); - if(parent_tree){ - if(hfi->type == FT_NONE) { - item = proto_tree_add_item(parent_tree, hf_id, tvb, offset, lenx, ENC_BIG_ENDIAN); - proto_item_append_text(item, ":"); - } else { - item = proto_tree_add_uint(parent_tree, hf_id, tvb, offset, lenx, cnt); - proto_item_append_text(item, (cnt==1)?" item":" items"); - } - tree = proto_item_add_subtree(item, ett_id); - } - } - - /* loop over all entries until we reach the end of the sequence */ - while (offset < end_offset){ - gint8 ber_class; - gboolean pc; - gint32 tag; - guint32 len; - int eoffset; - int hoffset; - proto_item *cause; - - hoffset = offset; - if(ind){ /*this sequence of was of indefinite length, so check for EOC */ - if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ - if(show_internal_ber_fields){ - proto_tree_add_text(tree, tvb, hoffset, end_offset-hoffset, "SEQ OF EOC"); - } - return offset+2; - } - } - /* read header and len for next field */ - offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); - offset = get_ber_length(tvb, offset, &len, &ind_field); - eoffset = offset + len; - /* Make sure we move forward */ - if (eoffset <= hoffset) - THROW(ReportedBoundsError); - - if((ber_class==BER_CLASS_UNI)&&(tag==BER_UNI_TAG_EOC)){ - /* This is a zero length sequence of*/ - hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); - return eoffset; - } - /* verify that this one is the one we want */ - /* ahup if we are implicit then we return to the uper layer how much we have used */ - if(seq->ber_class!=BER_CLASS_ANY){ - if((seq->ber_class!=ber_class) - ||(seq->tag!=tag) ){ - if(!(seq->flags & BER_FLAGS_NOTCHKTAG)) { - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", "BER Error: Wrong field in SQ OF"); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in Sequence Of"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - offset = eoffset; - continue; - /* wrong.... */ - } - } - } - - if(!(seq->flags & BER_FLAGS_NOOWNTAG) && !(seq->flags & BER_FLAGS_IMPLTAG)) { - /* dissect header and len for field */ - hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); - } - if((seq->flags == BER_FLAGS_IMPLTAG)&&(seq->ber_class==BER_CLASS_CON)) { - /* Constructed sequence of with a tag */ - /* dissect header and len for field */ - hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); - hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); - } - - length_remaining=tvb_length_remaining(tvb, hoffset); - if (length_remaining>eoffset-hoffset) - length_remaining=eoffset-hoffset; - - - /* call the dissector for this field */ - seq->func(tree, tvb, hoffset, actx); - /* hold on if we are implicit and the result is zero, i.e. the item in the sequence of - doesnt match the next item, thus this implicit sequence is over, return the number of bytes - we have eaten to allow the possible upper sequence continue... */ - cnt++; /* rubbish*/ - offset = eoffset; - } - - /* if we didnt end up at exactly offset, then we ate too many bytes */ - if(offset != end_offset) { - tvb_ensure_bytes_exist(tvb, offset-2, 2); - causex =proto_tree_add_string_format(tree, hf_ber_error, tvb, offset-2, 2, "illegal_length", "BER Error: %s Of ate %d too many bytes", - (type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence", offset-end_offset); - expert_add_info_format(actx->pinfo, causex, PI_MALFORMED, PI_WARN, "BER Error:too many byte in %s",(type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence"); - } - - return end_offset; + if(!implicit_tag){ + hoffsetx = offset; + /* first we must read the sequence header */ + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &classx, &pcx, &tagx); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &lenx, &ind); + if(ind){ + /* if the length is indefinite we dont really know (yet) where the + * object ends so assume it spans the rest of the tvb for now. + */ + end_offset = offset + lenx; + } else { + end_offset = offset + lenx; + } + + /* sanity check: we only handle Constructed Universal Sequences */ + if((classx!=BER_CLASS_APP)&&(classx!=BER_CLASS_PRI)) + if(!pcx + ||(!implicit_tag&&((classx!=BER_CLASS_UNI) + ||(tagx!=type)))) { + tvb_ensure_bytes_exist(tvb, hoffsetx, 2); + causex = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, lenx, (type==BER_UNI_TAG_SEQUENCE)?"set_of_expected":"sequence_of_expected", "BER Error: %s Of expected but class:%s(%d) %s tag:%d was unexpected", + (type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence", val_to_str(classx,ber_class_codes,"Unknown"), classx, pcx ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tagx); + expert_add_info_format(actx->pinfo, causex, PI_MALFORMED, PI_WARN, "BER Error: %s Of expected",(type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(causex, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffsetx, unknown_tree); + } + return end_offset; + } + } else { + /* the tvb length should be correct now nope we could be comming from an implicit choice or sequence, thus we + read the items we match and return the length*/ + lenx=tvb_length_remaining(tvb,offset); + end_offset = offset + lenx; + } + + /* count number of items */ + cnt = 0; + hoffsetx = offset; + /* only count the number of items IFF we have the full blob, + * else this will just generate a [short frame] before we even start + * dissecting a single item. + */ + /* XXX Do we really need to count them at all ? ronnie */ + if(tvb_length_remaining(tvb, offset)==tvb_reported_length_remaining(tvb, offset)){ + while (offset < end_offset){ + guint32 len; + gint s_offset; + + s_offset = offset; + + if(ind){ /* this sequence of was of indefinite length, so check for EOC */ + if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ + break; + } + } + + /* read header and len for next field */ + offset = get_ber_identifier(tvb, offset, NULL, NULL, NULL); + offset = get_ber_length(tvb, offset, &len, &ind); + /* best place to get real length of implicit sequence of or set of is here... */ + /* adjust end_offset if we find somthing that doesn't match */ + offset += len; + cnt++; + if (offset <= s_offset) + THROW(ReportedBoundsError); + } + } + offset = hoffsetx; + + /* create subtree */ + if(hf_id >= 0) { + hfi = proto_registrar_get_nth(hf_id); + if(parent_tree){ + if(hfi->type == FT_NONE) { + item = proto_tree_add_item(parent_tree, hf_id, tvb, offset, lenx, ENC_BIG_ENDIAN); + proto_item_append_text(item, ":"); + } else { + item = proto_tree_add_uint(parent_tree, hf_id, tvb, offset, lenx, cnt); + proto_item_append_text(item, (cnt==1)?" item":" items"); + } + tree = proto_item_add_subtree(item, ett_id); + } + } + + /* loop over all entries until we reach the end of the sequence */ + while (offset < end_offset){ + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 len; + int eoffset; + int hoffset; + proto_item *cause; + + hoffset = offset; + if(ind){ /*this sequence of was of indefinite length, so check for EOC */ + if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0)){ + if(show_internal_ber_fields){ + proto_tree_add_text(tree, tvb, hoffset, end_offset-hoffset, "SEQ OF EOC"); + } + return offset+2; + } + } + /* read header and len for next field */ + offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); + offset = get_ber_length(tvb, offset, &len, &ind_field); + eoffset = offset + len; + /* Make sure we move forward */ + if (eoffset <= hoffset) + THROW(ReportedBoundsError); + + if((ber_class==BER_CLASS_UNI)&&(tag==BER_UNI_TAG_EOC)){ + /* This is a zero length sequence of*/ + hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); + return eoffset; + } + /* verify that this one is the one we want */ + /* ahup if we are implicit then we return to the uper layer how much we have used */ + if(seq->ber_class!=BER_CLASS_ANY){ + if((seq->ber_class!=ber_class) + ||(seq->tag!=tag) ){ + if(!(seq->flags & BER_FLAGS_NOTCHKTAG)) { + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "wrong_field", "BER Error: Wrong field in SQ OF"); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: Wrong field in Sequence Of"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + offset = eoffset; + continue; + /* wrong.... */ + } + } + } + + if(!(seq->flags & BER_FLAGS_NOOWNTAG) && !(seq->flags & BER_FLAGS_IMPLTAG)) { + /* dissect header and len for field */ + hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); + } + if((seq->flags == BER_FLAGS_IMPLTAG)&&(seq->ber_class==BER_CLASS_CON)) { + /* Constructed sequence of with a tag */ + /* dissect header and len for field */ + hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, hoffset, NULL, NULL, NULL); + hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); + } + + length_remaining=tvb_length_remaining(tvb, hoffset); + if (length_remaining>eoffset-hoffset) + length_remaining=eoffset-hoffset; + + + /* call the dissector for this field */ + seq->func(tree, tvb, hoffset, actx); + /* hold on if we are implicit and the result is zero, i.e. the item in the sequence of + doesnt match the next item, thus this implicit sequence is over, return the number of bytes + we have eaten to allow the possible upper sequence continue... */ + cnt++; /* rubbish*/ + offset = eoffset; + } + + /* if we didnt end up at exactly offset, then we ate too many bytes */ + if(offset != end_offset) { + tvb_ensure_bytes_exist(tvb, offset-2, 2); + causex =proto_tree_add_string_format(tree, hf_ber_error, tvb, offset-2, 2, "illegal_length", "BER Error: %s Of ate %d too many bytes", + (type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence", offset-end_offset); + expert_add_info_format(actx->pinfo, causex, PI_MALFORMED, PI_WARN, "BER Error:too many byte in %s",(type==BER_UNI_TAG_SEQUENCE)?"Set":"Sequence"); + } + + return end_offset; } int dissect_ber_constrained_sequence_of(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, gint32 min_len, gint32 max_len, const ber_sequence_t *seq, gint hf_id, gint ett_id) { - return dissect_ber_sq_of(implicit_tag, BER_UNI_TAG_SEQUENCE, actx, parent_tree, tvb, offset, min_len, max_len, seq, hf_id, ett_id); + return dissect_ber_sq_of(implicit_tag, BER_UNI_TAG_SEQUENCE, actx, parent_tree, tvb, offset, min_len, max_len, seq, hf_id, ett_id); } int dissect_ber_sequence_of(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const ber_sequence_t *seq, gint hf_id, gint ett_id) { - return dissect_ber_sq_of(implicit_tag, BER_UNI_TAG_SEQUENCE, actx, parent_tree, tvb, offset, NO_BOUND, NO_BOUND, seq, hf_id, ett_id); + return dissect_ber_sq_of(implicit_tag, BER_UNI_TAG_SEQUENCE, actx, parent_tree, tvb, offset, NO_BOUND, NO_BOUND, seq, hf_id, ett_id); } int dissect_ber_constrained_set_of(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, gint32 min_len, gint32 max_len, const ber_sequence_t *seq, gint hf_id, gint ett_id) { - return dissect_ber_sq_of(implicit_tag, BER_UNI_TAG_SET, actx, parent_tree, tvb, offset, min_len, max_len, seq, hf_id, ett_id); + return dissect_ber_sq_of(implicit_tag, BER_UNI_TAG_SET, actx, parent_tree, tvb, offset, min_len, max_len, seq, hf_id, ett_id); } int dissect_ber_set_of(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const ber_sequence_t *seq, gint hf_id, gint ett_id) { - return dissect_ber_sq_of(implicit_tag, BER_UNI_TAG_SET, actx, parent_tree, tvb, offset, NO_BOUND, NO_BOUND, seq, hf_id, ett_id); + return dissect_ber_sq_of(implicit_tag, BER_UNI_TAG_SET, actx, parent_tree, tvb, offset, NO_BOUND, NO_BOUND, seq, hf_id, ett_id); } int dissect_ber_old_sequence_of(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const ber_old_sequence_t *seq, gint hf_id, gint ett_id) { - return dissect_ber_old_sq_of(implicit_tag, BER_UNI_TAG_SEQUENCE, actx, parent_tree, tvb, offset, seq, hf_id, ett_id); + return dissect_ber_old_sq_of(implicit_tag, BER_UNI_TAG_SEQUENCE, actx, parent_tree, tvb, offset, seq, hf_id, ett_id); } int dissect_ber_old_set_of(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const ber_old_sequence_t *seq, gint hf_id, gint ett_id) { - return dissect_ber_old_sq_of(implicit_tag, BER_UNI_TAG_SET, actx, parent_tree, tvb, offset, seq, hf_id, ett_id); + return dissect_ber_old_sq_of(implicit_tag, BER_UNI_TAG_SET, actx, parent_tree, tvb, offset, seq, hf_id, ett_id); } int dissect_ber_GeneralizedTime(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id) { - char str[35]; - int tmp_int; - const guint8 *tmpstr; - char *strptr; - char first_delim[2]; - int first_digits; - char second_delim[2]; - int second_digits; - int ret; - gint8 ber_class; - gboolean pc; - gint32 tag; - guint32 len; - int end_offset; - int hoffset; - proto_item *cause; - - if(!implicit_tag){ - hoffset = offset; - offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); - offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL); - end_offset=offset+len; - - /* sanity check. we only handle universal/generalized time */ - if( (ber_class!=BER_CLASS_UNI) - ||(tag!=BER_UNI_TAG_GeneralizedTime)){ - tvb_ensure_bytes_exist(tvb, hoffset, 2); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "generalized_time_expected", "BER Error: GeneralizedTime expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: GeneralizedTime expected"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - return end_offset; - } - } else { - len=tvb_length_remaining(tvb,offset); - end_offset=offset+len; - } - - if (len < 14 || len > 23) { - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "illegal_length", "BER Error: GeneralizedTime invalid length: %u", len); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: GeneralizedTime invalid length"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, offset, unknown_tree); - } - return end_offset; - } - - tmpstr=tvb_get_ephemeral_string(tvb, offset, len); - strptr = str; - /* those fields are allways present */ - strptr += g_snprintf(str, 20, "%.4s-%.2s-%.2s %.2s:%.2s:%.2s", - tmpstr, tmpstr+4, tmpstr+6, tmpstr+8, - tmpstr+10, tmpstr+12); - - first_delim[0]=0; - second_delim[0]=0; - ret = sscanf( tmpstr, "%14d%1[.,+-Z]%4d%1[+-Z]%4d", &tmp_int, first_delim, &first_digits, second_delim, &second_digits); - /* tmp_int does not contain valid value bacause of overflow but we use it just for format checking */ - if (ret < 1) { - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "invalid_generalized_time", "BER Error: GeneralizedTime invalid format: %s", tmpstr); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: GeneralizedTime invalid format"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, offset, unknown_tree); - } - return end_offset; - } - - switch (first_delim[0]) { - case '.': - case ',': - strptr += g_snprintf(strptr, 5, "%c%.3d", first_delim[0], first_digits); - switch (second_delim[0]) { - case '+': - case '-': - g_snprintf(strptr, 12, " (UTC%c%.4d)", second_delim[0], second_digits); - break; - case 'Z': - g_snprintf(strptr, 7, " (UTC)"); - break; - case 0: - break; - default: - /* handle the malformed field */ - break; - } - break; - case '+': - case '-': - g_snprintf(strptr, 12, " (UTC%c%.4d)", first_delim[0], first_digits); - break; - case 'Z': - g_snprintf(strptr, 7, " (UTC)"); - break; - case 0: - break; - default: - /* handle the malformed field */ - break; - } - - if(hf_id >= 0){ - proto_tree_add_string(tree, hf_id, tvb, offset, len, str); - } - - offset+=len; - return offset; + char str[35]; + int tmp_int; + const guint8 *tmpstr; + char *strptr; + char first_delim[2]; + int first_digits; + char second_delim[2]; + int second_digits; + int ret; + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 len; + int end_offset; + int hoffset; + proto_item *cause; + + if(!implicit_tag){ + hoffset = offset; + offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL); + end_offset=offset+len; + + /* sanity check. we only handle universal/generalized time */ + if( (ber_class!=BER_CLASS_UNI) + ||(tag!=BER_UNI_TAG_GeneralizedTime)){ + tvb_ensure_bytes_exist(tvb, hoffset, 2); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "generalized_time_expected", "BER Error: GeneralizedTime expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: GeneralizedTime expected"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + return end_offset; + } + } else { + len=tvb_length_remaining(tvb,offset); + end_offset=offset+len; + } + + if (len < 14 || len > 23) { + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "illegal_length", "BER Error: GeneralizedTime invalid length: %u", len); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: GeneralizedTime invalid length"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, offset, unknown_tree); + } + return end_offset; + } + + tmpstr=tvb_get_ephemeral_string(tvb, offset, len); + strptr = str; + /* those fields are allways present */ + strptr += g_snprintf(str, 20, "%.4s-%.2s-%.2s %.2s:%.2s:%.2s", + tmpstr, tmpstr+4, tmpstr+6, tmpstr+8, + tmpstr+10, tmpstr+12); + + first_delim[0]=0; + second_delim[0]=0; + ret = sscanf( tmpstr, "%14d%1[.,+-Z]%4d%1[+-Z]%4d", &tmp_int, first_delim, &first_digits, second_delim, &second_digits); + /* tmp_int does not contain valid value bacause of overflow but we use it just for format checking */ + if (ret < 1) { + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "invalid_generalized_time", "BER Error: GeneralizedTime invalid format: %s", tmpstr); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: GeneralizedTime invalid format"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, offset, unknown_tree); + } + return end_offset; + } + + switch (first_delim[0]) { + case '.': + case ',': + strptr += g_snprintf(strptr, 5, "%c%.3d", first_delim[0], first_digits); + switch (second_delim[0]) { + case '+': + case '-': + g_snprintf(strptr, 12, " (UTC%c%.4d)", second_delim[0], second_digits); + break; + case 'Z': + g_snprintf(strptr, 7, " (UTC)"); + break; + case 0: + break; + default: + /* handle the malformed field */ + break; + } + break; + case '+': + case '-': + g_snprintf(strptr, 12, " (UTC%c%.4d)", first_delim[0], first_digits); + break; + case 'Z': + g_snprintf(strptr, 7, " (UTC)"); + break; + case 0: + break; + default: + /* handle the malformed field */ + break; + } + + if(hf_id >= 0){ + proto_tree_add_string(tree, hf_id, tvb, offset, len, str); + } + + offset+=len; + return offset; } int dissect_ber_UTCTime(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id) { - char outstr[33]; - char *outstrptr = outstr; - const guint8 *instr; - gint8 ber_class; - gboolean pc; - gint32 tag; - guint32 len, i, n; - int hoffset; - proto_item *cause; - proto_tree *error_tree; - gchar *error_str = NULL; - - if(!implicit_tag){ - hoffset = offset; - offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); - offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL); - - /* sanity check: we only handle UTCTime */ - if( (ber_class!=BER_CLASS_UNI) || (tag!=BER_UNI_TAG_UTCTime) ) { - tvb_ensure_bytes_exist(tvb, hoffset, 2); - cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "utctime_expected", - "BER Error: UTCTime expected but class:%s(%d) %s tag:%d was unexpected", - val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, - pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: UTCTime expected"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - return offset+len; - } - } else { - len = tvb_length_remaining(tvb,offset); - } - - if (len < 10 || len > 19) { - error_str = g_strdup_printf("BER Error: UTCTime invalid length: %u", len); - instr = tvb_get_ephemeral_string(tvb, offset, len > 19 ? 19 : len); - goto malformed; - } - - instr = tvb_get_ephemeral_string(tvb, offset, len); - - /* YYMMDDhhmm */ - for(i=0;i<10;i++) { - if(instr[i] < '0' || instr[i] > '9') { - error_str = g_strdup("BER Error: malformed UTCTime encoding, " - "first 10 octets have to contain YYMMDDhhmm in digits"); - goto malformed; - } - } - g_snprintf(outstrptr, 15, "%.2s-%.2s-%.2s %.2s:%.2s", instr, instr+2, instr+4, instr+6, instr+8); - outstrptr+= 14; - - /* (ss)? */ - if(len >= 12) { - if(instr[i] >= '0' && instr[i] <= '9') { - i++; - if(instr[i] >= '0' && instr[i] <= '9') { - i++; - g_snprintf(outstrptr, 4, ":%.2s", instr+10); - outstrptr+=3; - } else { - error_str = g_strdup("BER Error: malformed UTCTime encoding, " - "if 11th octet is a digit for seconds, " - "the 12th octet has to be a digit, too"); - goto malformed; - } - } - } - - /* Z|([+-]hhmm) */ - switch (instr[i]) { - case 'Z': - if(len!=i+1) { - error_str = g_strdup("BER Error: malformed UTCTime encoding, " - "there must be no further octets after \'Z\'"); - goto malformed; - } - g_snprintf(outstrptr, 7, " (UTC)"); - i++; - break; - case '-': - case '+': - if(len!=i+5) { - error_str = g_strdup("BER Error: malformed UTCTime encoding, " - "4 digits must follow on \'+\' resp. \'-\'"); - goto malformed; - } - for(n=i+1;n<i+5;n++) { - if(instr[n] < '0' || instr[n] > '9') { - error_str = g_strdup("BER Error: malformed UTCTime encoding, " - "4 digits must follow on \'+\' resp. \'-\'"); - goto malformed; - } - } - g_snprintf(outstrptr, 12, " (UTC%c%.4s)", instr[i], instr+i+1); - i+=5; - break; - default: - error_str = g_strdup_printf("BER Error: malformed UTCTime encoding, " - "unexpected character in %dth octet, " - "must be \'Z\', \'+\' or \'-\'", i+1); - goto malformed; - break; - } - - if(len!=i) { - error_str = g_strdup_printf("BER Error: malformed UTCTime encoding, " - "%d unexpected character%s after %dth octet", - len-i, (len==i-1?"s":""), i); - goto malformed; - } - - if(hf_id >= 0){ - proto_tree_add_string(tree, hf_id, tvb, offset, len, outstr); - } - - return offset+len; + char outstr[33]; + char *outstrptr = outstr; + const guint8 *instr; + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 len, i, n; + int hoffset; + proto_item *cause; + proto_tree *error_tree; + gchar *error_str = NULL; + + if(!implicit_tag){ + hoffset = offset; + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL); + + /* sanity check: we only handle UTCTime */ + if( (ber_class!=BER_CLASS_UNI) || (tag!=BER_UNI_TAG_UTCTime) ) { + tvb_ensure_bytes_exist(tvb, hoffset, 2); + cause = proto_tree_add_string_format(tree, hf_ber_error, tvb, offset, len, "utctime_expected", + "BER Error: UTCTime expected but class:%s(%d) %s tag:%d was unexpected", + val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, + pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: UTCTime expected"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + return offset+len; + } + } else { + len = tvb_length_remaining(tvb,offset); + } + + if (len < 10 || len > 19) { + error_str = g_strdup_printf("BER Error: UTCTime invalid length: %u", len); + instr = tvb_get_ephemeral_string(tvb, offset, len > 19 ? 19 : len); + goto malformed; + } + + instr = tvb_get_ephemeral_string(tvb, offset, len); + + /* YYMMDDhhmm */ + for(i=0;i<10;i++) { + if(instr[i] < '0' || instr[i] > '9') { + error_str = g_strdup("BER Error: malformed UTCTime encoding, " + "first 10 octets have to contain YYMMDDhhmm in digits"); + goto malformed; + } + } + g_snprintf(outstrptr, 15, "%.2s-%.2s-%.2s %.2s:%.2s", instr, instr+2, instr+4, instr+6, instr+8); + outstrptr+= 14; + + /* (ss)? */ + if(len >= 12) { + if(instr[i] >= '0' && instr[i] <= '9') { + i++; + if(instr[i] >= '0' && instr[i] <= '9') { + i++; + g_snprintf(outstrptr, 4, ":%.2s", instr+10); + outstrptr+=3; + } else { + error_str = g_strdup("BER Error: malformed UTCTime encoding, " + "if 11th octet is a digit for seconds, " + "the 12th octet has to be a digit, too"); + goto malformed; + } + } + } + + /* Z|([+-]hhmm) */ + switch (instr[i]) { + case 'Z': + if(len!=i+1) { + error_str = g_strdup("BER Error: malformed UTCTime encoding, " + "there must be no further octets after \'Z\'"); + goto malformed; + } + g_snprintf(outstrptr, 7, " (UTC)"); + i++; + break; + case '-': + case '+': + if(len!=i+5) { + error_str = g_strdup("BER Error: malformed UTCTime encoding, " + "4 digits must follow on \'+\' resp. \'-\'"); + goto malformed; + } + for(n=i+1;n<i+5;n++) { + if(instr[n] < '0' || instr[n] > '9') { + error_str = g_strdup("BER Error: malformed UTCTime encoding, " + "4 digits must follow on \'+\' resp. \'-\'"); + goto malformed; + } + } + g_snprintf(outstrptr, 12, " (UTC%c%.4s)", instr[i], instr+i+1); + i+=5; + break; + default: + error_str = g_strdup_printf("BER Error: malformed UTCTime encoding, " + "unexpected character in %dth octet, " + "must be \'Z\', \'+\' or \'-\'", i+1); + goto malformed; + break; + } + + if(len!=i) { + error_str = g_strdup_printf("BER Error: malformed UTCTime encoding, " + "%d unexpected character%s after %dth octet", + len-i, (len==i-1?"s":""), i); + goto malformed; + } + + if(hf_id >= 0){ + proto_tree_add_string(tree, hf_id, tvb, offset, len, outstr); + } + + return offset+len; malformed: - if(hf_id >= 0){ - cause = proto_tree_add_string(tree, hf_id, tvb, offset, len, instr); - error_tree = proto_item_add_subtree(cause, ett_ber_unknown); - } else { - error_tree = tree; - } + if(hf_id >= 0){ + cause = proto_tree_add_string(tree, hf_id, tvb, offset, len, instr); + error_tree = proto_item_add_subtree(cause, ett_ber_unknown); + } else { + error_tree = tree; + } - cause = proto_tree_add_string_format(error_tree, hf_ber_error, tvb, offset, len, "invalid_utctime", "%s", error_str); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: malformed UTCTime encoding"); - g_free (error_str); + cause = proto_tree_add_string_format(error_tree, hf_ber_error, tvb, offset, len, "invalid_utctime", "%s", error_str); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: malformed UTCTime encoding"); + g_free (error_str); - return offset+len; + return offset+len; } /* 8.6 Encoding of a bitstring value */ int dissect_ber_constrained_bitstring(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, gint32 min_len, gint32 max_len, const asn_namedbit *named_bits, gint hf_id, gint ett_id, tvbuff_t **out_tvb) { - gint8 ber_class; - gboolean pc, ind; - gint32 tag; - guint32 len, byteno; - guint8 pad=0, b0, b1, val, *bitstring; - int end_offset; - int hoffset; - proto_item *item = NULL; - proto_item *cause; - proto_tree *tree = NULL; - const asn_namedbit *nb; - const char *sep; - gboolean term; - - if(!implicit_tag){ - hoffset = offset; - /* read header and len for the octet string */ - offset = dissect_ber_identifier(actx->pinfo, parent_tree, tvb, offset, &ber_class, &pc, &tag); - offset = dissect_ber_length(actx->pinfo, parent_tree, tvb, offset, &len, &ind); - end_offset = offset + len; - - /* sanity check: we only handle Universal BitStrings */ - - /* for an IMPLICIT APPLICATION tag asn2eth seems to call this - function with implicit_tag = FALSE. BER_FLAGS_NOOWNTAG was - set so the APPLICATION tag was still present. - So here we relax it for APPLICATION tags. CONTEXT tags may - still cause a problem. */ - - if(!implicit_tag && (ber_class!=BER_CLASS_APP)) { - if( (ber_class!=BER_CLASS_UNI) - ||(tag!=BER_UNI_TAG_BITSTRING) ){ - tvb_ensure_bytes_exist(tvb, hoffset, 2); - cause = proto_tree_add_string_format(parent_tree, hf_ber_error, tvb, offset, len, "bitstring_expected", "BER Error: BitString expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); - expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: BitString expected"); - if (decode_unexpected) { - proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); - dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); - } - return end_offset; - } - } - } else { - pc=0; - len=tvb_length_remaining(tvb,offset); - end_offset=offset+len; - } - - actx->created_item = NULL; - - if(pc) { - /* constructed */ - /* TO DO */ - } else { - /* primitive */ - pad = tvb_get_guint8(tvb, offset); - if(pad == 0 && len == 1) { - /* empty */ - proto_tree_add_item(parent_tree, hf_ber_bitstring_empty, tvb, offset, 1, ENC_BIG_ENDIAN); - } else { - /* padding */ - proto_item *pad_item = proto_tree_add_item(parent_tree, hf_ber_bitstring_padding, tvb, offset, 1, ENC_BIG_ENDIAN); - if (pad > 7) { - expert_add_info_format(actx->pinfo, pad_item, PI_UNDECODED, PI_WARN, - "Illegal padding (0 .. 7): %d", pad); - } - } - offset++; - len--; - if(hf_id >= 0) { - item = proto_tree_add_item(parent_tree, hf_id, tvb, offset, len, ENC_BIG_ENDIAN); - actx->created_item = item; - if(ett_id != -1) { - tree = proto_item_add_subtree(item, ett_id); - } - } - if(out_tvb) { - if(len<=(guint32)tvb_length_remaining(tvb, offset)){ - *out_tvb = tvb_new_subset(tvb, offset, len, len); - } else { - *out_tvb = tvb_new_subset_remaining(tvb, offset); - } - } - } - - if(named_bits) { - sep = " ("; - term = FALSE; - nb = named_bits; - bitstring = tvb_get_ephemeral_string(tvb, offset, len); - - while (nb->p_id) { - if(len > 0 && nb->bit < (8*len-pad)) { - val = tvb_get_guint8(tvb, offset + nb->bit/8); - bitstring[(nb->bit/8)] &= ~(0x80 >> (nb->bit%8)); - val &= 0x80 >> (nb->bit%8); - b0 = (nb->gb0 == -1) ? nb->bit/8 : - ((guint32)nb->gb0)/8; - b1 = (nb->gb1 == -1) ? nb->bit/8 : - ((guint32)nb->gb1)/8; - proto_tree_add_item(tree, *(nb->p_id), tvb, offset + b0, b1 - b0 + 1, ENC_BIG_ENDIAN); - } else { /* 8.6.2.4 */ - val = 0; - proto_tree_add_boolean(tree, *(nb->p_id), tvb, offset + len, 0, 0x00); - } - if(val) { - if(item && nb->tstr) { - proto_item_append_text(item, "%s%s", sep, nb->tstr); - sep = ", "; - term = TRUE; - } - } else { - if(item && nb->fstr) { - proto_item_append_text(item, "%s%s", sep, nb->fstr); - sep = ", "; - term = TRUE; - } - } - nb++; - } - if(term) - proto_item_append_text(item, ")"); - - for (byteno = 0; byteno < len; byteno++) { - if (bitstring[byteno]) { - expert_add_info_format(actx->pinfo, item, PI_UNDECODED, PI_WARN, - "Unknown bit(s): 0x%s", bytes_to_str(bitstring, len)); - break; - } - } - } - - if (pad > 0 && pad < 8 && len > 0) { - guint8 bits_in_pad = tvb_get_guint8(tvb, offset + len - 1) & (0xFF >> (8-pad)); - if (bits_in_pad) { - expert_add_info_format(actx->pinfo, item, PI_UNDECODED, PI_WARN, - "Bits set in padded area: 0x%02x", bits_in_pad); - } - } - - ber_check_length(8*len-pad, min_len, max_len, actx, item, TRUE); - - return end_offset; + gint8 ber_class; + gboolean pc, ind; + gint32 tag; + guint32 len, byteno; + guint8 pad=0, b0, b1, val, *bitstring; + int end_offset; + int hoffset; + proto_item *item = NULL; + proto_item *cause; + proto_tree *tree = NULL; + const asn_namedbit *nb; + const char *sep; + gboolean term; + + if(!implicit_tag){ + hoffset = offset; + /* read header and len for the octet string */ + offset = dissect_ber_identifier(actx->pinfo, parent_tree, tvb, offset, &ber_class, &pc, &tag); + offset = dissect_ber_length(actx->pinfo, parent_tree, tvb, offset, &len, &ind); + end_offset = offset + len; + + /* sanity check: we only handle Universal BitStrings */ + + /* for an IMPLICIT APPLICATION tag asn2eth seems to call this + function with implicit_tag = FALSE. BER_FLAGS_NOOWNTAG was + set so the APPLICATION tag was still present. + So here we relax it for APPLICATION tags. CONTEXT tags may + still cause a problem. */ + + if(!implicit_tag && (ber_class!=BER_CLASS_APP)) { + if( (ber_class!=BER_CLASS_UNI) + ||(tag!=BER_UNI_TAG_BITSTRING) ){ + tvb_ensure_bytes_exist(tvb, hoffset, 2); + cause = proto_tree_add_string_format(parent_tree, hf_ber_error, tvb, offset, len, "bitstring_expected", "BER Error: BitString expected but class:%s(%d) %s tag:%d was unexpected", val_to_str(ber_class,ber_class_codes,"Unknown"), ber_class, pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, tag); + expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: BitString expected"); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + return end_offset; + } + } + } else { + pc=0; + len=tvb_length_remaining(tvb,offset); + end_offset=offset+len; + } + + actx->created_item = NULL; + + if(pc) { + /* constructed */ + /* TO DO */ + } else { + /* primitive */ + pad = tvb_get_guint8(tvb, offset); + if(pad == 0 && len == 1) { + /* empty */ + proto_tree_add_item(parent_tree, hf_ber_bitstring_empty, tvb, offset, 1, ENC_BIG_ENDIAN); + } else { + /* padding */ + proto_item *pad_item = proto_tree_add_item(parent_tree, hf_ber_bitstring_padding, tvb, offset, 1, ENC_BIG_ENDIAN); + if (pad > 7) { + expert_add_info_format(actx->pinfo, pad_item, PI_UNDECODED, PI_WARN, + "Illegal padding (0 .. 7): %d", pad); + } + } + offset++; + len--; + if(hf_id >= 0) { + item = proto_tree_add_item(parent_tree, hf_id, tvb, offset, len, ENC_BIG_ENDIAN); + actx->created_item = item; + if(ett_id != -1) { + tree = proto_item_add_subtree(item, ett_id); + } + } + if(out_tvb) { + if(len<=(guint32)tvb_length_remaining(tvb, offset)){ + *out_tvb = tvb_new_subset(tvb, offset, len, len); + } else { + *out_tvb = tvb_new_subset_remaining(tvb, offset); + } + } + } + + if(named_bits) { + sep = " ("; + term = FALSE; + nb = named_bits; + bitstring = tvb_get_ephemeral_string(tvb, offset, len); + + while (nb->p_id) { + if(len > 0 && nb->bit < (8*len-pad)) { + val = tvb_get_guint8(tvb, offset + nb->bit/8); + bitstring[(nb->bit/8)] &= ~(0x80 >> (nb->bit%8)); + val &= 0x80 >> (nb->bit%8); + b0 = (nb->gb0 == -1) ? nb->bit/8 : + ((guint32)nb->gb0)/8; + b1 = (nb->gb1 == -1) ? nb->bit/8 : + ((guint32)nb->gb1)/8; + proto_tree_add_item(tree, *(nb->p_id), tvb, offset + b0, b1 - b0 + 1, ENC_BIG_ENDIAN); + } else { /* 8.6.2.4 */ + val = 0; + proto_tree_add_boolean(tree, *(nb->p_id), tvb, offset + len, 0, 0x00); + } + if(val) { + if(item && nb->tstr) { + proto_item_append_text(item, "%s%s", sep, nb->tstr); + sep = ", "; + term = TRUE; + } + } else { + if(item && nb->fstr) { + proto_item_append_text(item, "%s%s", sep, nb->fstr); + sep = ", "; + term = TRUE; + } + } + nb++; + } + if(term) + proto_item_append_text(item, ")"); + + for (byteno = 0; byteno < len; byteno++) { + if (bitstring[byteno]) { + expert_add_info_format(actx->pinfo, item, PI_UNDECODED, PI_WARN, + "Unknown bit(s): 0x%s", bytes_to_str(bitstring, len)); + break; + } + } + } + + if (pad > 0 && pad < 8 && len > 0) { + guint8 bits_in_pad = tvb_get_guint8(tvb, offset + len - 1) & (0xFF >> (8-pad)); + if (bits_in_pad) { + expert_add_info_format(actx->pinfo, item, PI_UNDECODED, PI_WARN, + "Bits set in padded area: 0x%02x", bits_in_pad); + } + } + + ber_check_length(8*len-pad, min_len, max_len, actx, item, TRUE); + + return end_offset; } int dissect_ber_bitstring(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const asn_namedbit *named_bits, gint hf_id, gint ett_id, tvbuff_t **out_tvb) @@ -4509,70 +4518,70 @@ int dissect_ber_bitstring(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *p int dissect_ber_bitstring32(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, int **bit_fields, gint hf_id, gint ett_id, tvbuff_t **out_tvb) { - tvbuff_t *tmp_tvb = NULL; - proto_tree *tree; - guint32 val; - int **bf; - header_field_info *hfi; - const char *sep; - gboolean term; - unsigned int i, tvb_len; - - offset = dissect_ber_bitstring(implicit_tag, actx, parent_tree, tvb, offset, NULL, hf_id, ett_id, &tmp_tvb); - - tree = proto_item_get_subtree(actx->created_item); - if(bit_fields && tree && tmp_tvb) { - /* tmp_tvb points to the actual bitstring (including any pad bits at the end. - * note that this bitstring is not neccessarily always encoded as 4 bytes - * so we have to read it byte by byte. - */ - val=0; - tvb_len=tvb_length(tmp_tvb); - for(i=0;i<4;i++){ - val<<=8; - if(i<tvb_len){ - val|=tvb_get_guint8(tmp_tvb,i); - } - } - bf = bit_fields; - sep = " ("; - term = FALSE; - while (*bf) { - if (**bf >= 0) { - proto_tree_add_boolean(tree, **bf, tmp_tvb, 0, tvb_len, val); - hfi = proto_registrar_get_nth(**bf); - if(val & hfi->bitmask) { - proto_item_append_text(actx->created_item, "%s%s", sep, hfi->name); - sep = ", "; - term = TRUE; - } - } - bf++; - } - if(term) - proto_item_append_text(actx->created_item, ")"); - } - - if(out_tvb) - *out_tvb = tmp_tvb; - - return offset; + tvbuff_t *tmp_tvb = NULL; + proto_tree *tree; + guint32 val; + int **bf; + header_field_info *hfi; + const char *sep; + gboolean term; + unsigned int i, tvb_len; + + offset = dissect_ber_bitstring(implicit_tag, actx, parent_tree, tvb, offset, NULL, hf_id, ett_id, &tmp_tvb); + + tree = proto_item_get_subtree(actx->created_item); + if(bit_fields && tree && tmp_tvb) { + /* tmp_tvb points to the actual bitstring (including any pad bits at the end. + * note that this bitstring is not neccessarily always encoded as 4 bytes + * so we have to read it byte by byte. + */ + val=0; + tvb_len=tvb_length(tmp_tvb); + for(i=0;i<4;i++){ + val<<=8; + if(i<tvb_len){ + val|=tvb_get_guint8(tmp_tvb,i); + } + } + bf = bit_fields; + sep = " ("; + term = FALSE; + while (*bf) { + if (**bf >= 0) { + proto_tree_add_boolean(tree, **bf, tmp_tvb, 0, tvb_len, val); + hfi = proto_registrar_get_nth(**bf); + if(val & hfi->bitmask) { + proto_item_append_text(actx->created_item, "%s%s", sep, hfi->name); + sep = ", "; + term = TRUE; + } + } + bf++; + } + if(term) + proto_item_append_text(actx->created_item, ")"); + } + + if(out_tvb) + *out_tvb = tmp_tvb; + + return offset; } /* - * 8.18 Encoding of a value of the external type - * 8.18.1 The encoding of a value of the external type shall be the BER encoding of the following - * sequence type, assumed to be defined in an environment of EXPLICIT TAGS, - * with a value as specified in the subclauses below: + * 8.18 Encoding of a value of the external type + * 8.18.1 The encoding of a value of the external type shall be the BER encoding of the following + * sequence type, assumed to be defined in an environment of EXPLICIT TAGS, + * with a value as specified in the subclauses below: * - * [UNIVERSAL 8] IMPLICIT SEQUENCE { - * direct-reference OBJECT IDENTIFIER OPTIONAL, - * indirect-reference INTEGER OPTIONAL, - * data-value-descriptor ObjectDescriptor OPTIONAL, - * encoding CHOICE { - * single-ASN1-type [0] ABSTRACT-SYNTAX.&Type, - * octet-aligned [1] IMPLICIT OCTET STRING, - * arbitrary [2] IMPLICIT BIT STRING } } + * [UNIVERSAL 8] IMPLICIT SEQUENCE { + * direct-reference OBJECT IDENTIFIER OPTIONAL, + * indirect-reference INTEGER OPTIONAL, + * data-value-descriptor ObjectDescriptor OPTIONAL, + * encoding CHOICE { + * single-ASN1-type [0] ABSTRACT-SYNTAX.&Type, + * octet-aligned [1] IMPLICIT OCTET STRING, + * arbitrary [2] IMPLICIT BIT STRING } } * */ @@ -4588,353 +4597,353 @@ dissect_ber_INTEGER(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_ static int dissect_ber_T_octet_aligned(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { - if (actx->external.u.ber.ber_callback) { - offset = actx->external.u.ber.ber_callback(FALSE, tvb, offset, actx, tree, hf_index); - } else if (actx->external.direct_ref_present && - dissector_get_string_handle(ber_oid_dissector_table, actx->external.direct_reference)) { - offset = call_ber_oid_callback(actx->external.direct_reference, tvb, offset, actx->pinfo, tree); - } else { - offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &actx->external.octet_aligned); - } + if (actx->external.u.ber.ber_callback) { + offset = actx->external.u.ber.ber_callback(FALSE, tvb, offset, actx, tree, hf_index); + } else if (actx->external.direct_ref_present && + dissector_get_string_handle(ber_oid_dissector_table, actx->external.direct_reference)) { + offset = call_ber_oid_callback(actx->external.direct_reference, tvb, offset, actx->pinfo, tree); + } else { + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &actx->external.octet_aligned); + } - return offset; + return offset; } static int dissect_ber_OBJECT_IDENTIFIER(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { - offset = dissect_ber_object_identifier_str(implicit_tag, actx, tree, tvb, offset, hf_index, &actx->external.direct_reference); - actx->external.direct_ref_present = TRUE; + offset = dissect_ber_object_identifier_str(implicit_tag, actx, tree, tvb, offset, hf_index, &actx->external.direct_reference); + actx->external.direct_ref_present = TRUE; - return offset; + return offset; } static int dissect_ber_ObjectDescriptor(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { - offset = dissect_ber_restricted_string(implicit_tag, BER_UNI_TAG_ObjectDescriptor, - actx, tree, tvb, offset, hf_index, - &actx->external.data_value_descriptor); + offset = dissect_ber_restricted_string(implicit_tag, BER_UNI_TAG_ObjectDescriptor, + actx, tree, tvb, offset, hf_index, + &actx->external.data_value_descriptor); - return offset; + return offset; } static int dissect_ber_T_single_ASN1_type(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { - if (actx->external.u.ber.ber_callback) { - offset = actx->external.u.ber.ber_callback(FALSE, tvb, offset, actx, tree, hf_index); - } else { - offset = call_ber_oid_callback(actx->external.direct_reference, tvb, offset, actx->pinfo, tree); - } + if (actx->external.u.ber.ber_callback) { + offset = actx->external.u.ber.ber_callback(FALSE, tvb, offset, actx, tree, hf_index); + } else { + offset = call_ber_oid_callback(actx->external.direct_reference, tvb, offset, actx->pinfo, tree); + } - return offset; + return offset; } static int dissect_ber_T_arbitrary(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { - if (actx->external.u.ber.ber_callback) { - offset = actx->external.u.ber.ber_callback(FALSE, tvb, offset, actx, tree, hf_index); - } else { - offset = dissect_ber_bitstring(implicit_tag, actx, tree, tvb, offset, - NULL, hf_index, -1, &actx->external.arbitrary); - } + if (actx->external.u.ber.ber_callback) { + offset = actx->external.u.ber.ber_callback(FALSE, tvb, offset, actx, tree, hf_index); + } else { + offset = dissect_ber_bitstring(implicit_tag, actx, tree, tvb, offset, + NULL, hf_index, -1, &actx->external.arbitrary); + } - return offset; + return offset; } static const value_string ber_T_encoding_vals[] = { - { 0, "single-ASN1-type" }, - { 1, "octet-aligned" }, - { 2, "arbitrary" }, - { 0, NULL } + { 0, "single-ASN1-type" }, + { 1, "octet-aligned" }, + { 2, "arbitrary" }, + { 0, NULL } }; static const ber_choice_t T_encoding_choice[] = { - { 0, &hf_ber_single_ASN1_type, BER_CLASS_CON, 0, 0, dissect_ber_T_single_ASN1_type }, - { 1, &hf_ber_octet_aligned , BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_ber_T_octet_aligned }, - { 2, &hf_ber_arbitrary , BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_ber_T_arbitrary }, - { 0, NULL, 0, 0, 0, NULL } + { 0, &hf_ber_single_ASN1_type, BER_CLASS_CON, 0, 0, dissect_ber_T_single_ASN1_type }, + { 1, &hf_ber_octet_aligned , BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_ber_T_octet_aligned }, + { 2, &hf_ber_arbitrary , BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_ber_T_arbitrary }, + { 0, NULL, 0, 0, 0, NULL } }; static int dissect_ber_T_encoding(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { - offset = dissect_ber_choice(actx, tree, tvb, offset, - T_encoding_choice, hf_index, ett_ber_T_encoding, - &actx->external.encoding); + offset = dissect_ber_choice(actx, tree, tvb, offset, + T_encoding_choice, hf_index, ett_ber_T_encoding, + &actx->external.encoding); - return offset; + return offset; } static const ber_sequence_t external_U_sequence[] = { - { &hf_ber_direct_reference, BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ber_OBJECT_IDENTIFIER }, - { &hf_ber_indirect_reference, BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ber_INTEGER }, - { &hf_ber_data_value_descriptor, BER_CLASS_UNI, BER_UNI_TAG_ObjectDescriptor, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ber_ObjectDescriptor }, - { &hf_ber_encoding , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ber_T_encoding }, - { NULL, 0, 0, 0, NULL } + { &hf_ber_direct_reference, BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ber_OBJECT_IDENTIFIER }, + { &hf_ber_indirect_reference, BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ber_INTEGER }, + { &hf_ber_data_value_descriptor, BER_CLASS_UNI, BER_UNI_TAG_ObjectDescriptor, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ber_ObjectDescriptor }, + { &hf_ber_encoding , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ber_T_encoding }, + { NULL, 0, 0, 0, NULL } }; static int dissect_ber_external_U(gboolean implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_ , proto_tree *tree, int hf_index _U_) { - offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, - external_U_sequence, hf_index, ett_ber_EXTERNAL); - return offset; + offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, + external_U_sequence, hf_index, ett_ber_EXTERNAL); + return offset; } int dissect_ber_external_type(gboolean implicit_tag, proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, gint hf_id, ber_callback func){ - actx->external.u.ber.ber_callback = func; + actx->external.u.ber.ber_callback = func; - offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset, - hf_id, BER_CLASS_UNI, BER_UNI_TAG_EXTERNAL, TRUE, dissect_ber_external_U); + offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset, + hf_id, BER_CLASS_UNI, BER_UNI_TAG_EXTERNAL, TRUE, dissect_ber_external_U); - asn1_ctx_clean_external(actx); + asn1_ctx_clean_external(actx); - return offset; + return offset; } /* Experimental */ int dissect_ber_EmbeddedPDV_Type(gboolean implicit_tag, proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, gint hf_id, ber_callback func _U_){ - offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset, - hf_id, BER_CLASS_UNI, BER_UNI_TAG_EMBEDDED_PDV, TRUE, dissect_ber_external_U); + offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset, + hf_id, BER_CLASS_UNI, BER_UNI_TAG_EMBEDDED_PDV, TRUE, dissect_ber_external_U); - return offset; + return offset; } static void dissect_ber_syntax(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - (void) dissect_unknown_ber(pinfo, tvb, 0, tree); + (void) dissect_unknown_ber(pinfo, tvb, 0, tree); } static void dissect_ber(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - const char *name; + const char *name; - col_set_str(pinfo->cinfo, COL_PROTOCOL, "BER"); + col_set_str(pinfo->cinfo, COL_PROTOCOL, "BER"); - col_set_str(pinfo->cinfo, COL_DEF_SRC, "BER encoded file"); + col_set_str(pinfo->cinfo, COL_DEF_SRC, "BER encoded file"); - if(!decode_as_syntax) { + if(!decode_as_syntax) { - /* if we got here we couldn't find anything better */ - col_set_str(pinfo->cinfo, COL_INFO, "Unknown BER"); + /* if we got here we couldn't find anything better */ + col_set_str(pinfo->cinfo, COL_INFO, "Unknown BER"); - (void) dissect_unknown_ber(pinfo, tvb, 0, tree); + (void) dissect_unknown_ber(pinfo, tvb, 0, tree); - } else { + } else { - (void) call_ber_syntax_callback(decode_as_syntax, tvb, 0, pinfo, tree); + (void) call_ber_syntax_callback(decode_as_syntax, tvb, 0, pinfo, tree); - /* see if we have a better name */ - name = get_ber_oid_syntax(decode_as_syntax); - col_add_fstr(pinfo->cinfo, COL_INFO, "Decoded as %s", name ? name : decode_as_syntax); - } + /* see if we have a better name */ + name = get_ber_oid_syntax(decode_as_syntax); + col_add_fstr(pinfo->cinfo, COL_INFO, "Decoded as %s", name ? name : decode_as_syntax); + } } void proto_register_ber(void) { static hf_register_info hf[] = { - { &hf_ber_id_class, { - "Class", "ber.id.class", FT_UINT8, BASE_DEC, - VALS(ber_class_codes), 0xc0, "Class of BER TLV Identifier", HFILL }}, - { &hf_ber_bitstring_padding, { - "Padding", "ber.bitstring.padding", FT_UINT8, BASE_DEC, - NULL, 0x0, "Number of unused bits in the last octet of the bitstring", HFILL }}, - { &hf_ber_bitstring_empty, { - "Empty", "ber.bitstring.empty", FT_UINT8, BASE_DEC, - NULL, 0x0, "This is an empty bitstring", HFILL }}, - { &hf_ber_id_pc, { - "P/C", "ber.id.pc", FT_BOOLEAN, 8, - TFS(&ber_pc_codes), 0x20, "Primitive or Constructed BER encoding", HFILL }}, - { &hf_ber_id_uni_tag, { - "Tag", "ber.id.uni_tag", FT_UINT8, BASE_DEC|BASE_EXT_STRING, - &ber_uni_tag_codes_ext, 0x1f, "Universal tag type", HFILL }}, - { &hf_ber_id_uni_tag_ext, { - "Tag", "ber.id.uni_tag", FT_UINT32, BASE_DEC, - NULL, 0, "Universal tag type", HFILL }}, - { &hf_ber_id_tag, { - "Tag", "ber.id.tag", FT_UINT8, BASE_DEC, - NULL, 0x1f, "Tag value for non-Universal classes", HFILL }}, - { &hf_ber_id_tag_ext, { - "Tag", "ber.id.tag", FT_UINT32, BASE_DEC, - NULL, 0, "Tag value for non-Universal classes", HFILL }}, - { &hf_ber_length, { - "Length", "ber.length", FT_UINT32, BASE_DEC, - NULL, 0, "Length of contents", HFILL }}, - { &hf_ber_unknown_OCTETSTRING, { - "OCTETSTRING", "ber.unknown.OCTETSTRING", FT_BYTES, BASE_NONE, - NULL, 0, "This is an unknown OCTETSTRING", HFILL }}, - { &hf_ber_unknown_BER_OCTETSTRING, { - "OCTETSTRING [BER encoded]", "ber.unknown.OCTETSTRING", FT_NONE, BASE_NONE, - NULL, 0, "This is an BER encoded OCTETSTRING", HFILL }}, - { &hf_ber_unknown_BER_primitive, { - "Primitive [BER encoded]", "ber.unknown.primitive", FT_NONE, BASE_NONE, - NULL, 0, "This is a BER encoded Primitive", HFILL }}, - { &hf_ber_unknown_OID, { - "OID", "ber.unknown.OID", FT_OID, BASE_NONE, - NULL, 0, "This is an unknown Object Identifier", HFILL }}, - { &hf_ber_unknown_GraphicString, { - "GRAPHICSTRING", "ber.unknown.GRAPHICSTRING", FT_STRING, BASE_NONE, - NULL, 0, "This is an unknown GRAPHICSTRING", HFILL }}, - { &hf_ber_unknown_NumericString, { - "NumericString", "ber.unknown.NumericString", FT_STRING, BASE_NONE, - NULL, 0, "This is an unknown NumericString", HFILL }}, - { &hf_ber_unknown_PrintableString, { - "PrintableString", "ber.unknown.PrintableString", FT_STRING, BASE_NONE, - NULL, 0, "This is an unknown PrintableString", HFILL }}, - { &hf_ber_unknown_TeletexString, { - "TeletexString", "ber.unknown.TeletexString", FT_STRING, BASE_NONE, - NULL, 0, "This is an unknown TeletexString", HFILL }}, - { &hf_ber_unknown_VisibleString, { - "VisibleString", "ber.unknown.VisibleString", FT_STRING, BASE_NONE, - NULL, 0, "This is an unknown VisibleString", HFILL }}, - { &hf_ber_unknown_GeneralString, { - "GeneralString", "ber.unknown.GeneralString", FT_STRING, BASE_NONE, - NULL, 0, "This is an unknown GeneralString", HFILL }}, - { &hf_ber_unknown_UniversalString, { - "UniversalString", "ber.unknown.UniversalString", FT_STRING, BASE_NONE, - NULL, 0, "This is an unknown UniversalString", HFILL }}, - { &hf_ber_unknown_BMPString, { - "BMPString", "ber.unknown.BMPString", FT_STRING, BASE_NONE, - NULL, 0, "This is an unknown BMPString", HFILL }}, - { &hf_ber_unknown_IA5String, { - "IA5String", "ber.unknown.IA5String", FT_STRING, BASE_NONE, - NULL, 0, "This is an unknown IA5String", HFILL }}, - { &hf_ber_unknown_UTCTime, { - "UTCTime", "ber.unknown.UTCTime", FT_STRING, BASE_NONE, - NULL, 0, "This is an unknown UTCTime", HFILL }}, - { &hf_ber_unknown_UTF8String, { - "UTF8String", "ber.unknown.UTF8String", FT_STRING, BASE_NONE, - NULL, 0, "This is an unknown UTF8String", HFILL }}, - { &hf_ber_unknown_GeneralizedTime, { - "GeneralizedTime", "ber.unknown.GeneralizedTime", FT_STRING, BASE_NONE, - NULL, 0, "This is an unknown GeneralizedTime", HFILL }}, - { &hf_ber_unknown_INTEGER, { - "INTEGER", "ber.unknown.INTEGER", FT_INT64, BASE_DEC, - NULL, 0, "This is an unknown INTEGER", HFILL }}, - { &hf_ber_unknown_BITSTRING, { - "BITSTRING", "ber.unknown.BITSTRING", FT_BYTES, BASE_NONE, - NULL, 0, "This is an unknown BITSTRING", HFILL }}, - { &hf_ber_unknown_BOOLEAN, { - "BOOLEAN", "ber.unknown.BOOLEAN", FT_UINT8, BASE_HEX, - NULL, 0, "This is an unknown BOOLEAN", HFILL }}, - { &hf_ber_unknown_ENUMERATED, { - "ENUMERATED", "ber.unknown.ENUMERATED", FT_UINT32, BASE_DEC, - NULL, 0, "This is an unknown ENUMERATED", HFILL }}, - { &hf_ber_error, { - "BER Error", "ber.error", FT_STRING, BASE_NONE, - NULL, 0, NULL, HFILL }}, - { &hf_ber_no_oid, { - "No OID", "ber.no_oid", FT_NONE, BASE_NONE, - NULL, 0, "No OID supplied to call_ber_oid_callback", HFILL }}, - { &hf_ber_oid_not_implemented, { - "OID not implemented", "ber.oid_not_implemented", FT_NONE, BASE_NONE, - NULL, 0, "Dissector for OID not implemented", HFILL }}, - { &hf_ber_no_syntax, { - "No OID", "ber.no_oid", FT_NONE, BASE_NONE, - NULL, 0, "No syntax supplied to call_ber_syntax_callback", HFILL }}, - { &hf_ber_syntax_not_implemented, { - "Syntax not implemented", "ber.syntax_not_implemented", FT_NONE, BASE_NONE, - NULL, 0, "Dissector for OID not implemented", HFILL }}, - { &hf_ber_direct_reference, - { "direct-reference", "ber.direct_reference", - FT_OID, BASE_NONE, NULL, 0, - "ber.OBJECT_IDENTIFIER", HFILL }}, - { &hf_ber_indirect_reference, - { "indirect-reference", "ber.indirect_reference", - FT_INT32, BASE_DEC, NULL, 0, - "ber.INTEGER", HFILL }}, - { &hf_ber_data_value_descriptor, - { "data-value-descriptor", "ber.data_value_descriptor", - FT_STRING, BASE_NONE, NULL, 0, - "ber.ObjectDescriptor", HFILL }}, - { &hf_ber_encoding, - { "encoding", "ber.encoding", - FT_UINT32, BASE_DEC, VALS(ber_T_encoding_vals), 0, - "ber.T_encoding", HFILL }}, - { &hf_ber_octet_aligned, - { "octet-aligned", "ber.octet_aligned", - FT_BYTES, BASE_NONE, NULL, 0, - "ber.T_octet_aligned", HFILL }}, - { &hf_ber_arbitrary, - { "arbitrary", "ber.arbitrary", - FT_BYTES, BASE_NONE, NULL, 0, - "ber.T_arbitrary", HFILL }}, - { &hf_ber_single_ASN1_type, - { "single-ASN1-type", "ber.single_ASN1_type", - FT_NONE, BASE_NONE, NULL, 0, - "ber.T_single_ASN1_type", HFILL }}, - - /* Fragment entries */ - { &hf_ber_fragments, - { "OCTET STRING fragments", "ber.octet_string.fragments", FT_NONE, BASE_NONE, - NULL, 0x00, NULL, HFILL } }, - { &hf_ber_fragment, - { "OCTET STRING fragment", "ber.octet_string.fragment", FT_FRAMENUM, BASE_NONE, - NULL, 0x00, NULL, HFILL } }, - { &hf_ber_fragment_overlap, - { "OCTET STRING fragment overlap", "ber.octet_string.fragment.overlap", FT_BOOLEAN, - BASE_NONE, NULL, 0x0, NULL, HFILL } }, - { &hf_ber_fragment_overlap_conflicts, - { "OCTET STRING fragment overlapping with conflicting data", - "ber.octet_string.fragment.overlap.conflicts", FT_BOOLEAN, BASE_NONE, NULL, - 0x0, NULL, HFILL } }, - { &hf_ber_fragment_multiple_tails, - { "OCTET STRING has multiple tail fragments", - "ber.octet_string.fragment.multiple_tails", FT_BOOLEAN, BASE_NONE, - NULL, 0x0, NULL, HFILL } }, - { &hf_ber_fragment_too_long_fragment, - { "OCTET STRING fragment too long", "ber.octet_string.fragment.too_long_fragment", - FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, - HFILL } }, - { &hf_ber_fragment_error, - { "OCTET STRING defragmentation error", "ber.octet_string.fragment.error", FT_FRAMENUM, - BASE_NONE, NULL, 0x00, NULL, HFILL } }, - { &hf_ber_fragment_count, - { "OCTET STRING fragment count", "ber.octet_string.fragment.count", FT_UINT32, BASE_DEC, - NULL, 0x00, NULL, HFILL } }, - { &hf_ber_reassembled_in, - { "Reassembled in", "ber.octet_string.reassembled.in", FT_FRAMENUM, BASE_NONE, - NULL, 0x00, NULL, HFILL } }, - { &hf_ber_reassembled_length, - { "Reassembled OCTET STRING length", "ber.octet_string.reassembled.length", FT_UINT32, BASE_DEC, - NULL, 0x00, NULL, HFILL } } + { &hf_ber_id_class, { + "Class", "ber.id.class", FT_UINT8, BASE_DEC, + VALS(ber_class_codes), 0xc0, "Class of BER TLV Identifier", HFILL }}, + { &hf_ber_bitstring_padding, { + "Padding", "ber.bitstring.padding", FT_UINT8, BASE_DEC, + NULL, 0x0, "Number of unused bits in the last octet of the bitstring", HFILL }}, + { &hf_ber_bitstring_empty, { + "Empty", "ber.bitstring.empty", FT_UINT8, BASE_DEC, + NULL, 0x0, "This is an empty bitstring", HFILL }}, + { &hf_ber_id_pc, { + "P/C", "ber.id.pc", FT_BOOLEAN, 8, + TFS(&ber_pc_codes), 0x20, "Primitive or Constructed BER encoding", HFILL }}, + { &hf_ber_id_uni_tag, { + "Tag", "ber.id.uni_tag", FT_UINT8, BASE_DEC|BASE_EXT_STRING, + &ber_uni_tag_codes_ext, 0x1f, "Universal tag type", HFILL }}, + { &hf_ber_id_uni_tag_ext, { + "Tag", "ber.id.uni_tag", FT_UINT32, BASE_DEC, + NULL, 0, "Universal tag type", HFILL }}, + { &hf_ber_id_tag, { + "Tag", "ber.id.tag", FT_UINT8, BASE_DEC, + NULL, 0x1f, "Tag value for non-Universal classes", HFILL }}, + { &hf_ber_id_tag_ext, { + "Tag", "ber.id.tag", FT_UINT32, BASE_DEC, + NULL, 0, "Tag value for non-Universal classes", HFILL }}, + { &hf_ber_length, { + "Length", "ber.length", FT_UINT32, BASE_DEC, + NULL, 0, "Length of contents", HFILL }}, + { &hf_ber_unknown_OCTETSTRING, { + "OCTETSTRING", "ber.unknown.OCTETSTRING", FT_BYTES, BASE_NONE, + NULL, 0, "This is an unknown OCTETSTRING", HFILL }}, + { &hf_ber_unknown_BER_OCTETSTRING, { + "OCTETSTRING [BER encoded]", "ber.unknown.OCTETSTRING", FT_NONE, BASE_NONE, + NULL, 0, "This is an BER encoded OCTETSTRING", HFILL }}, + { &hf_ber_unknown_BER_primitive, { + "Primitive [BER encoded]", "ber.unknown.primitive", FT_NONE, BASE_NONE, + NULL, 0, "This is a BER encoded Primitive", HFILL }}, + { &hf_ber_unknown_OID, { + "OID", "ber.unknown.OID", FT_OID, BASE_NONE, + NULL, 0, "This is an unknown Object Identifier", HFILL }}, + { &hf_ber_unknown_GraphicString, { + "GRAPHICSTRING", "ber.unknown.GRAPHICSTRING", FT_STRING, BASE_NONE, + NULL, 0, "This is an unknown GRAPHICSTRING", HFILL }}, + { &hf_ber_unknown_NumericString, { + "NumericString", "ber.unknown.NumericString", FT_STRING, BASE_NONE, + NULL, 0, "This is an unknown NumericString", HFILL }}, + { &hf_ber_unknown_PrintableString, { + "PrintableString", "ber.unknown.PrintableString", FT_STRING, BASE_NONE, + NULL, 0, "This is an unknown PrintableString", HFILL }}, + { &hf_ber_unknown_TeletexString, { + "TeletexString", "ber.unknown.TeletexString", FT_STRING, BASE_NONE, + NULL, 0, "This is an unknown TeletexString", HFILL }}, + { &hf_ber_unknown_VisibleString, { + "VisibleString", "ber.unknown.VisibleString", FT_STRING, BASE_NONE, + NULL, 0, "This is an unknown VisibleString", HFILL }}, + { &hf_ber_unknown_GeneralString, { + "GeneralString", "ber.unknown.GeneralString", FT_STRING, BASE_NONE, + NULL, 0, "This is an unknown GeneralString", HFILL }}, + { &hf_ber_unknown_UniversalString, { + "UniversalString", "ber.unknown.UniversalString", FT_STRING, BASE_NONE, + NULL, 0, "This is an unknown UniversalString", HFILL }}, + { &hf_ber_unknown_BMPString, { + "BMPString", "ber.unknown.BMPString", FT_STRING, BASE_NONE, + NULL, 0, "This is an unknown BMPString", HFILL }}, + { &hf_ber_unknown_IA5String, { + "IA5String", "ber.unknown.IA5String", FT_STRING, BASE_NONE, + NULL, 0, "This is an unknown IA5String", HFILL }}, + { &hf_ber_unknown_UTCTime, { + "UTCTime", "ber.unknown.UTCTime", FT_STRING, BASE_NONE, + NULL, 0, "This is an unknown UTCTime", HFILL }}, + { &hf_ber_unknown_UTF8String, { + "UTF8String", "ber.unknown.UTF8String", FT_STRING, BASE_NONE, + NULL, 0, "This is an unknown UTF8String", HFILL }}, + { &hf_ber_unknown_GeneralizedTime, { + "GeneralizedTime", "ber.unknown.GeneralizedTime", FT_STRING, BASE_NONE, + NULL, 0, "This is an unknown GeneralizedTime", HFILL }}, + { &hf_ber_unknown_INTEGER, { + "INTEGER", "ber.unknown.INTEGER", FT_INT64, BASE_DEC, + NULL, 0, "This is an unknown INTEGER", HFILL }}, + { &hf_ber_unknown_BITSTRING, { + "BITSTRING", "ber.unknown.BITSTRING", FT_BYTES, BASE_NONE, + NULL, 0, "This is an unknown BITSTRING", HFILL }}, + { &hf_ber_unknown_BOOLEAN, { + "BOOLEAN", "ber.unknown.BOOLEAN", FT_UINT8, BASE_HEX, + NULL, 0, "This is an unknown BOOLEAN", HFILL }}, + { &hf_ber_unknown_ENUMERATED, { + "ENUMERATED", "ber.unknown.ENUMERATED", FT_UINT32, BASE_DEC, + NULL, 0, "This is an unknown ENUMERATED", HFILL }}, + { &hf_ber_error, { + "BER Error", "ber.error", FT_STRING, BASE_NONE, + NULL, 0, NULL, HFILL }}, + { &hf_ber_no_oid, { + "No OID", "ber.no_oid", FT_NONE, BASE_NONE, + NULL, 0, "No OID supplied to call_ber_oid_callback", HFILL }}, + { &hf_ber_oid_not_implemented, { + "OID not implemented", "ber.oid_not_implemented", FT_NONE, BASE_NONE, + NULL, 0, "Dissector for OID not implemented", HFILL }}, + { &hf_ber_no_syntax, { + "No OID", "ber.no_oid", FT_NONE, BASE_NONE, + NULL, 0, "No syntax supplied to call_ber_syntax_callback", HFILL }}, + { &hf_ber_syntax_not_implemented, { + "Syntax not implemented", "ber.syntax_not_implemented", FT_NONE, BASE_NONE, + NULL, 0, "Dissector for OID not implemented", HFILL }}, + { &hf_ber_direct_reference, + { "direct-reference", "ber.direct_reference", + FT_OID, BASE_NONE, NULL, 0, + "ber.OBJECT_IDENTIFIER", HFILL }}, + { &hf_ber_indirect_reference, + { "indirect-reference", "ber.indirect_reference", + FT_INT32, BASE_DEC, NULL, 0, + "ber.INTEGER", HFILL }}, + { &hf_ber_data_value_descriptor, + { "data-value-descriptor", "ber.data_value_descriptor", + FT_STRING, BASE_NONE, NULL, 0, + "ber.ObjectDescriptor", HFILL }}, + { &hf_ber_encoding, + { "encoding", "ber.encoding", + FT_UINT32, BASE_DEC, VALS(ber_T_encoding_vals), 0, + "ber.T_encoding", HFILL }}, + { &hf_ber_octet_aligned, + { "octet-aligned", "ber.octet_aligned", + FT_BYTES, BASE_NONE, NULL, 0, + "ber.T_octet_aligned", HFILL }}, + { &hf_ber_arbitrary, + { "arbitrary", "ber.arbitrary", + FT_BYTES, BASE_NONE, NULL, 0, + "ber.T_arbitrary", HFILL }}, + { &hf_ber_single_ASN1_type, + { "single-ASN1-type", "ber.single_ASN1_type", + FT_NONE, BASE_NONE, NULL, 0, + "ber.T_single_ASN1_type", HFILL }}, + + /* Fragment entries */ + { &hf_ber_fragments, + { "OCTET STRING fragments", "ber.octet_string.fragments", FT_NONE, BASE_NONE, + NULL, 0x00, NULL, HFILL } }, + { &hf_ber_fragment, + { "OCTET STRING fragment", "ber.octet_string.fragment", FT_FRAMENUM, BASE_NONE, + NULL, 0x00, NULL, HFILL } }, + { &hf_ber_fragment_overlap, + { "OCTET STRING fragment overlap", "ber.octet_string.fragment.overlap", FT_BOOLEAN, + BASE_NONE, NULL, 0x0, NULL, HFILL } }, + { &hf_ber_fragment_overlap_conflicts, + { "OCTET STRING fragment overlapping with conflicting data", + "ber.octet_string.fragment.overlap.conflicts", FT_BOOLEAN, BASE_NONE, NULL, + 0x0, NULL, HFILL } }, + { &hf_ber_fragment_multiple_tails, + { "OCTET STRING has multiple tail fragments", + "ber.octet_string.fragment.multiple_tails", FT_BOOLEAN, BASE_NONE, + NULL, 0x0, NULL, HFILL } }, + { &hf_ber_fragment_too_long_fragment, + { "OCTET STRING fragment too long", "ber.octet_string.fragment.too_long_fragment", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, + HFILL } }, + { &hf_ber_fragment_error, + { "OCTET STRING defragmentation error", "ber.octet_string.fragment.error", FT_FRAMENUM, + BASE_NONE, NULL, 0x00, NULL, HFILL } }, + { &hf_ber_fragment_count, + { "OCTET STRING fragment count", "ber.octet_string.fragment.count", FT_UINT32, BASE_DEC, + NULL, 0x00, NULL, HFILL } }, + { &hf_ber_reassembled_in, + { "Reassembled in", "ber.octet_string.reassembled.in", FT_FRAMENUM, BASE_NONE, + NULL, 0x00, NULL, HFILL } }, + { &hf_ber_reassembled_length, + { "Reassembled OCTET STRING length", "ber.octet_string.reassembled.length", FT_UINT32, BASE_DEC, + NULL, 0x00, NULL, HFILL } } }; static gint *ett[] = { - &ett_ber_octet_string, - &ett_ber_reassembled_octet_string, - &ett_ber_primitive, - &ett_ber_unknown, - &ett_ber_SEQUENCE, - &ett_ber_EXTERNAL, - &ett_ber_T_encoding, - &ett_ber_fragment, - &ett_ber_fragments + &ett_ber_octet_string, + &ett_ber_reassembled_octet_string, + &ett_ber_primitive, + &ett_ber_unknown, + &ett_ber_SEQUENCE, + &ett_ber_EXTERNAL, + &ett_ber_T_encoding, + &ett_ber_fragment, + &ett_ber_fragments }; module_t *ber_module; uat_t* users_uat = uat_new("OID Tables", - sizeof(oid_user_t), - "oid", - FALSE, - (void*) &oid_users, - &num_oid_users, - UAT_CAT_GENERAL, - "ChObjectIdentifiers", - oid_copy_cb, - NULL, - oid_free_cb, - ber_update_oids, - users_flds); + sizeof(oid_user_t), + "oid", + FALSE, + (void*) &oid_users, + &num_oid_users, + UAT_CAT_GENERAL, + "ChObjectIdentifiers", + oid_copy_cb, + NULL, + oid_free_cb, + ber_update_oids, + users_flds); proto_ber = proto_register_protocol("Basic Encoding Rules (ASN.1 X.690)", "BER", "ber"); register_dissector ("ber", dissect_ber, proto_ber); @@ -4947,27 +4956,27 @@ proto_register_ber(void) ber_module = prefs_register_protocol(proto_ber, NULL); prefs_register_bool_preference(ber_module, "show_internals", - "Show internal BER encapsulation tokens", - "Whether the dissector should also display internal" - " ASN.1 BER details such as Identifier and Length fields", &show_internal_ber_fields); + "Show internal BER encapsulation tokens", + "Whether the dissector should also display internal" + " ASN.1 BER details such as Identifier and Length fields", &show_internal_ber_fields); prefs_register_bool_preference(ber_module, "decode_unexpected", - "Decode unexpected tags as BER encoded data", - "Whether the dissector should decode unexpected tags as" - " ASN.1 BER encoded data", &decode_unexpected); + "Decode unexpected tags as BER encoded data", + "Whether the dissector should decode unexpected tags as" + " ASN.1 BER encoded data", &decode_unexpected); prefs_register_bool_preference(ber_module, "decode_octetstring", - "Decode OCTET STRING as BER encoded data", - "Whether the dissector should try decoding OCTET STRINGs as" - " constructed ASN.1 BER encoded data", &decode_octetstring_as_ber); + "Decode OCTET STRING as BER encoded data", + "Whether the dissector should try decoding OCTET STRINGs as" + " constructed ASN.1 BER encoded data", &decode_octetstring_as_ber); prefs_register_bool_preference(ber_module, "decode_primitive", - "Decode Primitive as BER encoded data", - "Whether the dissector should try decoding unknown primitive as" - " constructed ASN.1 BER encoded data", &decode_primitive_as_ber); + "Decode Primitive as BER encoded data", + "Whether the dissector should try decoding unknown primitive as" + " constructed ASN.1 BER encoded data", &decode_primitive_as_ber); prefs_register_uat_preference(ber_module, "oid_table", "Object Identifiers", - "A table that provides names for object identifiers" - " and the syntax of any associated values", - users_uat); + "A table that provides names for object identifiers" + " and the syntax of any associated values", + users_uat); ber_oid_dissector_table = register_dissector_table("ber.oid", "BER OID Dissectors", FT_STRING, BASE_NONE); ber_syntax_dissector_table = register_dissector_table("ber.syntax", "BER Syntax Dissectors", FT_STRING, BASE_NONE); @@ -4981,29 +4990,29 @@ proto_register_ber(void) void proto_reg_handoff_ber(void) { - guint i = 1; - dissector_handle_t ber_handle; + guint i = 1; + dissector_handle_t ber_handle; - oid_add_from_string("asn1","2.1"); - oid_add_from_string("basic-encoding","2.1.1"); + oid_add_from_string("asn1","2.1"); + oid_add_from_string("basic-encoding","2.1.1"); - ber_handle = create_dissector_handle(dissect_ber, proto_ber); - dissector_add_uint("wtap_encap", WTAP_ENCAP_BER, ber_handle); + ber_handle = create_dissector_handle(dissect_ber, proto_ber); + dissector_add_uint("wtap_encap", WTAP_ENCAP_BER, ber_handle); - ber_decode_as_foreach(ber_add_syntax_name, &i); + ber_decode_as_foreach(ber_add_syntax_name, &i); - if(i > 1) - qsort(&syntax_names[1], i - 1, sizeof(value_string), cmp_value_string); - syntax_names[i].value = 0; - syntax_names[i].strptr = NULL; + if(i > 1) + qsort(&syntax_names[1], i - 1, sizeof(value_string), cmp_value_string); + syntax_names[i].value = 0; + syntax_names[i].strptr = NULL; - /* allow the dissection of BER/DER carried over a TCP transport - by using "Decode As..." */ - dissector_add_handle("tcp.port", ber_handle); + /* allow the dissection of BER/DER carried over a TCP transport + by using "Decode As..." */ + dissector_add_handle("tcp.port", ber_handle); - ber_update_oids(); + ber_update_oids(); } gboolean oid_has_dissector(const char *oid) { - return(dissector_get_string_handle(ber_oid_dissector_table, oid) != NULL); + return(dissector_get_string_handle(ber_oid_dissector_table, oid) != NULL); } |