aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorGraeme Lunt <graeme.lunt@smhs.co.uk>2007-01-13 12:59:27 +0000
committerGraeme Lunt <graeme.lunt@smhs.co.uk>2007-01-13 12:59:27 +0000
commit2fd7d2c62078813f44e78f0b4b9f8b0e6e5928fb (patch)
tree8bc3e25bd6afc1b8eeb5ae59ab92988c18a6dcc8 /epan/dissectors
parent13a095e055798295514d723c15f72e8f2cd89a3e (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.c166
-rw-r--r--epan/dissectors/packet-ber.h8
-rw-r--r--epan/dissectors/packet-s4406.c4
-rw-r--r--epan/dissectors/packet-x509af.c9
-rw-r--r--epan/dissectors/packet-x509af.h2
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 */