aboutsummaryrefslogtreecommitdiffstats
path: root/epan/expert.c
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2014-07-15 23:04:41 -0400
committerMichael Mann <mmann78@netscape.net>2014-07-26 01:03:07 +0000
commit507d07eda6ad562d4567cf0ee83aa9b03997beca (patch)
treec4b9e511807c1aa39578e0d31bbb6d60f80cf62b /epan/expert.c
parent251ee715a551543b32e6cc98f35e506fb602b04d (diff)
Allow severity levels of expert info items to be configured by the user.
UAT was the easiest way to do this and I like the "file format" of the data, but the presentation doesn't seem that great. Bug:10180 Change-Id: I7e6bc9e148bc47585a0a7eb8f96900a5c374e673 Reviewed-on: https://code.wireshark.org/review/3082 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/expert.c')
-rw-r--r--epan/expert.c157
1 files changed, 154 insertions, 3 deletions
diff --git a/epan/expert.c b/epan/expert.c
index a69566d120..287be9981e 100644
--- a/epan/expert.c
+++ b/epan/expert.c
@@ -29,7 +29,8 @@
#include "packet.h"
#include "expert.h"
-#include "emem.h"
+#include "uat.h"
+#include "prefs.h"
#include "wmem/wmem.h"
#include "tap.h"
@@ -64,6 +65,9 @@ typedef struct _gpa_expertinfo_t {
} gpa_expertinfo_t;
static gpa_expertinfo_t gpa_expertinfo;
+/* Hash table of abbreviations and IDs */
+static GHashTable *gpa_name_map = NULL;
+
const value_string expert_group_vals[] = {
{ PI_CHECKSUM, "Checksum" },
{ PI_SEQUENCE, "Sequence" },
@@ -85,7 +89,7 @@ const value_string expert_severity_vals[] = {
{ PI_NOTE, "Note" },
{ PI_CHAT, "Chat" },
{ PI_COMMENT, "Comment" },
- { 0, "Ok" },
+ { 1, "Ok" },
{ 0, NULL }
};
@@ -98,6 +102,83 @@ const value_string expert_checksum_vals[] = {
{ 0, NULL }
};
+static expert_field_info* expert_registrar_get_byname(const char *field_name);
+
+/*----------------------------------------------------------------------------*/
+/* UAT for customizing severity levels. */
+/*----------------------------------------------------------------------------*/
+typedef struct
+{
+ char * field;
+ guint32 severity;
+} expert_level_entry_t;
+
+static expert_level_entry_t* uat_expert_entries = NULL;
+static guint expert_level_entry_count = 0;
+/* Array of field names currently in UAT */
+static GArray *uat_saved_fields = NULL;
+
+UAT_CSTRING_CB_DEF(uat_expert_entries, field, expert_level_entry_t)
+UAT_VS_DEF(uat_expert_entries, severity, expert_level_entry_t, guint32, PI_ERROR, "Error")
+
+static void uat_expert_update_cb(void* r, const char** err)
+{
+ expert_level_entry_t* rec = (expert_level_entry_t *)r;
+
+ if (expert_registrar_get_byname(rec->field) == NULL) {
+ *err = g_strdup_printf("Expert Info field doesn't exist");
+ }
+}
+
+static void* uat_expert_copy_cb(void* n, const void* o, size_t siz _U_)
+{
+ expert_level_entry_t* new_record = (expert_level_entry_t*)n;
+ const expert_level_entry_t* old_record = (const expert_level_entry_t*)o;
+
+ if (old_record->field) {
+ new_record->field = g_strdup(old_record->field);
+ } else {
+ new_record->field = NULL;
+ }
+
+ new_record->severity = old_record->severity;
+
+ return new_record;
+}
+
+static void uat_expert_free_cb(void*r)
+{
+ expert_level_entry_t* rec = (expert_level_entry_t *)r;
+
+ if (rec->field)
+ g_free(rec->field);
+}
+
+static void uat_expert_post_update_cb(void)
+{
+ guint i;
+ expert_field_info* field;
+
+ /* Reset any of the previous list of expert info fields to their original severity */
+ for ( i = 0 ; i < uat_saved_fields->len; i++ ) {
+ field = g_array_index(uat_saved_fields, expert_field_info*, i);
+ if (field != NULL) {
+ field->severity = field->orig_severity;
+ }
+ }
+
+ g_array_set_size(uat_saved_fields, 0);
+
+ for (i = 0; i < expert_level_entry_count; i++)
+ {
+ field = expert_registrar_get_byname(uat_expert_entries[i].field);
+ if (field != NULL)
+ {
+ field->severity = uat_expert_entries[i].severity;
+ g_array_append_val(uat_saved_fields, field);
+ }
+ }
+}
#define EXPERT_REGISTRAR_GET_NTH(eiindex, expinfo) \
if((guint)eiindex >= gpa_expertinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG")) \
@@ -108,6 +189,9 @@ const value_string expert_checksum_vals[] = {
void
expert_packet_init(void)
{
+ module_t *module_expert;
+ uat_t * expert_uat;
+
static hf_register_info hf[] = {
{ &hf_expert_msg,
{ "Message", "_ws.expert.message", FT_STRING, BASE_NONE, NULL, 0, "Wireshark expert information", HFILL }
@@ -124,6 +208,13 @@ expert_packet_init(void)
&ett_subexpert
};
+ /* UAT for overriding severity levels */
+ static uat_field_t custom_expert_fields[] = {
+ UAT_FLD_CSTRING(uat_expert_entries, field, "Field name", "Expert Info filter name"),
+ UAT_FLD_VS(uat_expert_entries, severity, "Severity", expert_severity_vals, "Custom severity level"),
+ UAT_END_FIELDS
+ };
+
if (expert_tap == -1) {
expert_tap = register_tap("expert");
}
@@ -133,6 +224,29 @@ expert_packet_init(void)
proto_register_field_array(proto_expert, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
proto_set_cant_toggle(proto_expert);
+
+ module_expert = prefs_register_protocol(proto_expert, NULL);
+
+ expert_uat = uat_new("Expert Info Severity Level Configuration",
+ sizeof(expert_level_entry_t),
+ "expert_severity",
+ TRUE,
+ (void * *)&uat_expert_entries,
+ &expert_level_entry_count,
+ UAT_AFFECTS_DISSECTION,
+ NULL,
+ uat_expert_copy_cb,
+ uat_expert_update_cb,
+ uat_expert_free_cb,
+ uat_expert_post_update_cb,
+ custom_expert_fields);
+
+ prefs_register_uat_preference(module_expert,
+ "expert_severity_levels",
+ "Severity Level Configuration",
+ "A table that overrides Expert Info field severity levels to user configured levels",
+ expert_uat);
+
}
highest_severity = 0;
@@ -146,6 +260,8 @@ expert_init(void)
gpa_expertinfo.len = 0;
gpa_expertinfo.allocated_len = 0;
gpa_expertinfo.ei = NULL;
+ gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
+ uat_saved_fields = g_array_new(FALSE, FALSE, sizeof(expert_field_info*));
}
void
@@ -162,6 +278,18 @@ expert_cleanup(void)
g_free(gpa_expertinfo.ei);
gpa_expertinfo.ei = NULL;
}
+
+ /* Free the abbrev/ID GTree */
+ if (gpa_name_map) {
+ g_hash_table_destroy(gpa_name_map);
+ gpa_name_map = NULL;
+ }
+
+ /* Free the UAT saved fields */
+ if (uat_saved_fields) {
+ g_array_free(uat_saved_fields, TRUE);
+ uat_saved_fields = NULL;
+ }
}
@@ -211,6 +339,11 @@ expert_register_field_init(expert_field_info *expinfo, expert_module_t* module)
gpa_expertinfo.ei[gpa_expertinfo.len] = expinfo;
gpa_expertinfo.len++;
expinfo->id = gpa_expertinfo.len - 1;
+ /* Save the original severity so it can be restored by the UAT */
+ expinfo->orig_severity = expinfo->severity;
+
+ /* save field name for lookup */
+ g_hash_table_insert(gpa_name_map, (gpointer) (expinfo->name), expinfo);
return expinfo->id;
}
@@ -252,6 +385,24 @@ expert_register_field_array(expert_module_t* module, ei_register_info *exp, cons
}
}
+/* Finds a record in the expert array by name.
+ * For the moment, this function is only used "internally"
+ * but may find a reason to be exported
+ */
+static expert_field_info *
+expert_registrar_get_byname(const char *field_name)
+{
+ expert_field_info *hfinfo;
+
+ if (!field_name)
+ return NULL;
+
+ hfinfo = (expert_field_info*)g_hash_table_lookup(gpa_name_map, field_name);
+
+ return hfinfo;
+}
+
+
/** clear flags according to the mask and set new flag values */
#define FI_REPLACE_FLAGS(fi, mask, flags_in) { \
(fi->flags = (fi)->flags & ~(mask)); \
@@ -270,7 +421,7 @@ expert_set_item_flags(proto_item *pi, const int group, const guint severity)
/* propagate till toplevel item */
pi = proto_item_get_parent(pi);
expert_set_item_flags(pi, group, severity);
- }
+ }
}
static proto_tree*