diff options
author | Graeme Lunt <graeme.lunt@smhs.co.uk> | 2007-01-13 12:59:27 +0000 |
---|---|---|
committer | Graeme Lunt <graeme.lunt@smhs.co.uk> | 2007-01-13 12:59:27 +0000 |
commit | 2fd7d2c62078813f44e78f0b4b9f8b0e6e5928fb (patch) | |
tree | 8bc3e25bd6afc1b8eeb5ae59ab92988c18a6dcc8 /epan/dissectors | |
parent | 13a095e055798295514d723c15f72e8f2cd89a3e (diff) |
New "decode as ..." feature for BER-encoded files (WTAP_FILE_BER).
A BER-encoded file can be dissected as one of a number of registered syntaxes (registered using register_ber_syntax_dissector()).
Syntaxes may also be associated with OIDs (or other strings) using register_ber_oid_syntax().
A default syntax with which to dissect a BER-encoded file is determined from its filename (extension). For example, ".cer" and ".crt" files will be dissected as "Certificate".
svn path=/trunk/; revision=20414
Diffstat (limited to 'epan/dissectors')
-rw-r--r-- | epan/dissectors/packet-ber.c | 166 | ||||
-rw-r--r-- | epan/dissectors/packet-ber.h | 8 | ||||
-rw-r--r-- | epan/dissectors/packet-s4406.c | 4 | ||||
-rw-r--r-- | epan/dissectors/packet-x509af.c | 9 | ||||
-rw-r--r-- | epan/dissectors/packet-x509af.h | 2 |
5 files changed, 181 insertions, 8 deletions
diff --git a/epan/dissectors/packet-ber.c b/epan/dissectors/packet-ber.c index d97686e3fe..c3f6571737 100644 --- a/epan/dissectors/packet-ber.c +++ b/epan/dissectors/packet-ber.c @@ -108,9 +108,14 @@ static gint ett_ber_SEQUENCE = -1; static gboolean show_internal_ber_fields = FALSE; +static gchar *decode_as_syntax = NULL; +static gchar *ber_filename = NULL; + proto_item *ber_last_created_item=NULL; static dissector_table_t ber_oid_dissector_table=NULL; +static dissector_table_t ber_syntax_dissector_table=NULL; +static GHashTable *syntax_table=NULL; static const value_string ber_class_codes[] = { { BER_CLASS_UNI, "UNIVERSAL" }, @@ -158,6 +163,11 @@ static const value_string ber_uni_tag_codes[] = { { 0, NULL } }; +typedef struct _da_data { + GHFunc func; + gpointer user_data; +} da_data; + proto_item *get_ber_last_created_item(void) { return ber_last_created_item; @@ -188,6 +198,94 @@ register_ber_oid_dissector(const char *oid, dissector_t dissector, int proto, co add_oid_str_name(oid, name); } +void +register_ber_syntax_dissector(const char *syntax, int proto, dissector_t dissector) +{ + dissector_handle_t dissector_handle; + + dissector_handle=create_dissector_handle(dissector, proto); + dissector_add_string("ber.syntax", syntax, dissector_handle); + +} + +void +register_ber_oid_syntax(const char *oid, const char *name, const char *syntax) +{ + + if(syntax && *syntax) + g_hash_table_insert(syntax_table, (gpointer)oid, (gpointer)syntax); + + 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) +{ + add_oid_str_name(oid, name); +} + +static void ber_decode_as_dt(gchar *table_name, ftenum_t selector_type, gpointer key, gpointer value, gpointer user_data) +{ + da_data *decode_as_data; + + decode_as_data = (da_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; + + decode_as_data.func = func; + decode_as_data.user_data = user_data; + + dissector_table_foreach("ber.syntax", ber_decode_as_dt, &decode_as_data); + +} + +void ber_decode_as(gchar *syntax) +{ + + if(decode_as_syntax) { + g_free(decode_as_syntax); + decode_as_syntax = NULL; + } + + if(syntax) + decode_as_syntax = g_strdup(syntax); +} + +/* Get oid syntax from hash table to get translation in proto dissection(packet-per.c) */ +const char * +get_ber_oid_syntax(const char *oid) +{ + return g_hash_table_lookup(syntax_table, oid); +} + +void ber_set_filename(gchar *filename) +{ + gchar *ptr; + + if(ber_filename) { + g_free(ber_filename); + ber_filename = NULL; + } + + if(filename) { + + ber_filename = g_strdup(filename); + + if((ptr = strrchr(ber_filename, '.')) != NULL) { + + ber_decode_as(get_ber_oid_syntax(ptr)); + + } + } +} + int dissect_ber_tagged_type(gboolean implicit_tag, packet_info *pinfo, 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; @@ -432,6 +530,38 @@ call_ber_oid_callback(const char *oid, tvbuff_t *tvb, int offset, packet_info *p return offset; } +int +call_ber_syntax_callback(const char *syntax, tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) +{ + tvbuff_t *next_tvb; + const char *fsyntax = NULL; + + next_tvb = tvb_new_subset(tvb, offset, -1, -1); + 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_text(tree, next_tvb, 0, tvb_length_remaining(tvb, offset), "BER: No syntax supplied to call_ber_syntax_callback"); + else + item=proto_tree_add_text(tree, 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); + + return offset; +} + + static int dissect_ber_sq_of(gboolean implicit_tag, gint32 type, packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const ber_sequence_t *seq, gint hf_id, gint ett_id); @@ -2416,16 +2546,38 @@ int dissect_ber_bitstring32(gboolean implicit_tag, packet_info *pinfo, proto_tre static void dissect_ber(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { + const char *name; - if (check_col(pinfo->cinfo, COL_INFO)) { - col_clear(pinfo->cinfo, COL_INFO); - col_append_fstr(pinfo->cinfo, COL_INFO, "%s", "Unknown BER"); - } + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "BER"); - (void) dissect_unknown_ber(pinfo, tvb, 0, tree); + if (check_col(pinfo->cinfo, COL_DEF_SRC)) + col_set_str(pinfo->cinfo, COL_DEF_SRC, "BER encoded file"); -} + if(!decode_as_syntax) { + + /* if we got here we couldn't find anything better */ + if (check_col(pinfo->cinfo, COL_INFO)) { + col_clear(pinfo->cinfo, COL_INFO); + col_append_fstr(pinfo->cinfo, COL_INFO, "Unknown BER"); + } + + (void) dissect_unknown_ber(pinfo, tvb, 0, tree); + + } else { + + (void) call_ber_syntax_callback(decode_as_syntax, tvb, 0, pinfo, tree); + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) { + /* see if we have a better name */ + name = get_ber_oid_syntax(decode_as_syntax); + + col_clear(pinfo->cinfo, COL_PROTOCOL); + col_append_fstr(pinfo->cinfo, COL_PROTOCOL, "%s", name ? name : decode_as_syntax); + } + } +} void proto_register_ber(void) @@ -2521,6 +2673,8 @@ proto_register_ber(void) " ASN.1 BER details such as Identifier and Length fields", &show_internal_ber_fields); 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); + syntax_table=g_hash_table_new(g_str_hash, g_str_equal); /* oid to syntax */ } void diff --git a/epan/dissectors/packet-ber.h b/epan/dissectors/packet-ber.h index d7d9b264cb..c72dbc5074 100644 --- a/epan/dissectors/packet-ber.h +++ b/epan/dissectors/packet-ber.h @@ -26,6 +26,7 @@ #ifndef __PACKET_BER_H__ #define __PACKET_BER_H__ +#include <epan/proto.h> #include <epan/to_str.h> #define BER_NOT_DECODED_YET(x) \ @@ -174,8 +175,15 @@ extern proto_item *get_ber_last_created_item(void); int call_ber_oid_callback(const char *oid, tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree); void register_ber_oid_dissector_handle(const char *oid, dissector_handle_t dissector, int proto, const char *name); void register_ber_oid_dissector(const char *oid, dissector_t dissector, int proto, const char *name); +void register_ber_syntax_dissector(const char *oid, int proto, dissector_t dissector); +void register_ber_oid_name(const char *oid, const char *name); +void register_ber_oid_syntax(const char *oid, const char *name, const char *syntax); void dissect_ber_oid_NULL_callback(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); +void ber_decode_as_foreach(GHFunc func, gpointer user_data); /* iterate through known syntaxes */ +void ber_decode_as(gchar *syntax); /* decode the current capture as this syntax */ +void ber_set_filename(gchar *filename); /* name of current BER-encoded file */ + gboolean oid_has_dissector(const char *oid); #endif /* __PACKET_BER_H__ */ diff --git a/epan/dissectors/packet-s4406.c b/epan/dissectors/packet-s4406.c index d3fcee1786..4ea6944cbb 100644 --- a/epan/dissectors/packet-s4406.c +++ b/epan/dissectors/packet-s4406.c @@ -1304,4 +1304,8 @@ void proto_reg_handoff_s4406(void) { #line 114 "packet-s4406-template.c" register_ber_oid_dissector("1.3.26.0.4406.0.4.1", dissect_s4406, proto_s4406, "Military Message"); + + register_ber_syntax_dissector("MilitaryMessage", proto_s4406, dissect_s4406); + register_ber_oid_syntax(".p772", NULL, "MilitaryMessage"); + } diff --git a/epan/dissectors/packet-x509af.c b/epan/dissectors/packet-x509af.c index a414d6d0ec..97f5c72309 100644 --- a/epan/dissectors/packet-x509af.c +++ b/epan/dissectors/packet-x509af.c @@ -1,6 +1,6 @@ /* Do not modify this file. */ /* It is created automatically by the ASN.1 to Wireshark dissector compiler */ -/* .\packet-x509af.c */ +/* ./packet-x509af.c */ /* ../../tools/asn2wrs.py -b -e -p x509af -c x509af.cnf -s packet-x509af-template AuthenticationFramework.asn */ /* Input file: packet-x509af-template.c */ @@ -1557,5 +1557,12 @@ void proto_reg_handoff_x509af(void) { register_ldap_name_dissector("crossCertificatePair", dissect_CertificatePair_PDU, proto_x509af); + register_ber_syntax_dissector("Certificate", proto_x509af, dissect_Certificate_PDU); + register_ber_oid_syntax(".cer", NULL, "Certificate"); + register_ber_oid_syntax(".crt", NULL, "Certificate"); + register_ber_syntax_dissector("CertificateList", proto_x509af, dissect_CertificateList_PDU); + register_ber_oid_syntax(".crl", NULL, "CertificateList"); + register_ber_syntax_dissector("CrossCertificatePair", proto_x509af, dissect_CertificatePair_PDU); + } diff --git a/epan/dissectors/packet-x509af.h b/epan/dissectors/packet-x509af.h index c6beb1f83b..8252149a07 100644 --- a/epan/dissectors/packet-x509af.h +++ b/epan/dissectors/packet-x509af.h @@ -1,6 +1,6 @@ /* Do not modify this file. */ /* It is created automatically by the ASN.1 to Wireshark dissector compiler */ -/* .\packet-x509af.h */ +/* ./packet-x509af.h */ /* ../../tools/asn2wrs.py -b -e -p x509af -c x509af.cnf -s packet-x509af-template AuthenticationFramework.asn */ /* Input file: packet-x509af-template.h */ |