diff options
Diffstat (limited to 'epan/prefs.c')
-rw-r--r-- | epan/prefs.c | 324 |
1 files changed, 314 insertions, 10 deletions
diff --git a/epan/prefs.c b/epan/prefs.c index 175170c285..0109826338 100644 --- a/epan/prefs.c +++ b/epan/prefs.c @@ -249,6 +249,7 @@ free_pref(gpointer data, gpointer user_data _U_) case PREF_BOOL: case PREF_ENUM: case PREF_UINT: + case PREF_DECODE_AS_UINT: case PREF_STATIC_TEXT: case PREF_UAT: case PREF_COLOR: @@ -262,6 +263,7 @@ free_pref(gpointer data, gpointer user_data _U_) pref->default_val.string = NULL; break; case PREF_RANGE: + case PREF_DECODE_AS_RANGE: g_free(*pref->varp.range); *pref->varp.range = NULL; g_free(pref->default_val.range); @@ -1134,21 +1136,17 @@ DIAG_OFF(cast-qual) DIAG_ON(cast-qual) } -/* - * Register a preference with a ranged value. - */ -void -prefs_register_range_preference(module_t *module, const char *name, +/* Refactoring to handle both PREF_RANGE and PREF_DECODE_AS_RANGE */ +static void +prefs_register_range_preference_common(module_t *module, const char *name, const char *title, const char *description, - range_t **var, guint32 max_value) + range_t **var, guint32 max_value, int type) { pref_t *preference; - preference = register_preference(module, name, title, description, - PREF_RANGE); + preference = register_preference(module, name, title, description, type); preference->info.max_value = max_value; - /* * Range preference values should be non-null (as you can't * keep them null after using the preferences GUI, you can at best @@ -1164,6 +1162,18 @@ prefs_register_range_preference(module_t *module, const char *name, preference->stashed_val.range = NULL; } +/* + * Register a preference with a ranged value. + */ +void +prefs_register_range_preference(module_t *module, const char *name, + const char *title, const char *description, + range_t **var, guint32 max_value) +{ + prefs_register_range_preference_common(module, name, title, + description, var, max_value, PREF_RANGE); +} + static gboolean prefs_set_range_value_work(pref_t *pref, const gchar *value, gboolean return_range_errors, gboolean *changed) @@ -1291,6 +1301,34 @@ prefs_register_custom_preference(module_t *module, const char *name, } /* + * Register a (internal) "Decode As" preference with a ranged value. + */ +void prefs_register_decode_as_range_preference(module_t *module, const char *name, + const char *title, const char *description, range_t **var, + guint32 max_value) +{ + prefs_register_range_preference_common(module, name, title, + description, var, max_value, PREF_DECODE_AS_RANGE); +} + +/* + * Register a (internal) "Decode As" preference with an unsigned integral value + * for a dissector table. + */ +void prefs_register_decode_as_preference(module_t *module, const char *name, + const char *title, const char *description, guint *var) +{ + pref_t *preference; + + preference = register_preference(module, name, title, description, + PREF_DECODE_AS_UINT); + preference->varp.uint = var; + preference->default_val.uint = *var; + /* XXX - Presume base 10 for now */ + preference->info.base = 10; +} + +/* * Register a preference that used to be supported but no longer is. */ void @@ -3209,6 +3247,7 @@ reset_pref(pref_t *pref) switch (type) { case PREF_UINT: + case PREF_DECODE_AS_UINT: *pref->varp.uint = pref->default_val.uint; break; @@ -3234,6 +3273,7 @@ reset_pref(pref_t *pref) break; case PREF_RANGE: + case PREF_DECODE_AS_RANGE: g_free(*pref->varp.range); *pref->varp.range = range_copy(pref->default_val.range); break; @@ -4036,6 +4076,46 @@ deprecated_port_pref(gchar *pref_name, const gchar *value) guint base; }; + struct obsolete_pref_name + { + const char* pref_name; + }; + + /* For now this is only supporting TCP port dissector preferences + which are assumed to be decimal */ + struct port_pref_name port_prefs[] = { + {"cmp.tcp_alternate_port", "CMP", "tcp.port", 10}, + {"h248.tcp_port", "H248", "tcp.port", 10}, + {"cops.tcp.cops_port", "COPS", "tcp.port", 10}, + {"dhcpfo.tcp_port", "DHCPFO", "tcp.port", 10}, + {"enttec.tcp_port", "ENTTEC", "tcp.port", 10}, + {"forces.tcp_alternate_port", "ForCES", "tcp.port", 10}, + {"ged125.tcp_port", "GED125", "tcp.port", 10}, + {"hpfeeds.dissector_port", "HPFEEDS", "tcp.port", 10}, + {"lsc.port", "LSC", "tcp.port", 10}, + {"megaco.tcp.txt_port", "MEGACO", "tcp.port", 10}, + {"netsync.tcp_port", "Netsync", "tcp.port", 10}, + {"osi.tpkt_port", "OSI", "tcp.port", 10}, + {"rsync.tcp_port", "RSYNC", "tcp.port", 10}, + {"sametime.tcp_port", "SAMETIME", "tcp.port", 10}, + {"sigcomp.tcp.port2", "SIGCOMP", "tcp.port", 10}, + {"synphasor.tcp_port", "SYNCHROPHASOR", "tcp.port", 10}, + {"tipc.alternate_port", "TIPC", "tcp.port", 10}, + {"vnc.alternate_port", "VNC", "tcp.port", 10}, + }; + + struct port_pref_name port_range_prefs[] = { + {"couchbase.tcp.ports", "Couchbase", "tcp.port", 10}, + {"gsm_ipa.tcp_ports", "GSM over IP", "tcp.port", 10}, + {"kafka.tcp.ports", "Kafka", "tcp.port", 10}, + {"kt.tcp.ports", "Kyoto Tycoon", "tcp.port", 10}, + {"memcache.tcp.ports", "MEMCACHE", "tcp.port", 10}, + {"mrcpv2.tcp.port_range", "MRCPv2", "tcp.port", 10}, + {"rtsp.tcp.port_range", "RTSP", "tcp.port", 10}, + {"sip.tcp.ports", "SIP", "tcp.port", 10}, + {"uma.tcp.ports", "UMA", "tcp.port", 10}, + }; + /* These are subdissectors of TPKT/OSITP that used to have a TCP port preference even though they were never directly on TCP. Convert them to use Decode As @@ -4050,10 +4130,107 @@ deprecated_port_pref(gchar *pref_name, const gchar *value) {"rdp.tcp.port", "RDP", "tcp.port", 10}, }; + /* These are obsolete preferences from the dissectors' view, + (typically because of a switch from a single value to a + range value) but the name of the preference conflicts + with the generated preference name from the dissector table. + Don't allow the obsolete preference through to be handled */ + struct obsolete_pref_name obsolete_prefs[] = { + {"diameter.tcp.port"}, + {"kafka.tcp.port"}, + {"mrcpv2.tcp.port"}, + {"rtsp.tcp.port"}, + {"sip.tcp.port"}, + {"t38.tcp.port"}, + }; + unsigned int i; char *p; guint uval; - dissector_handle_t tpkt_handle; + dissector_table_t sub_dissectors; + dissector_handle_t handle, tpkt_handle; + + for (i = 0; i < sizeof(port_prefs)/sizeof(struct port_pref_name); i++) + { + if (strcmp(pref_name, port_prefs[i].pref_name) == 0) + { + /* XXX - give an error if it doesn't fit in a guint? */ + uval = (guint)strtoul(value, &p, port_prefs[i].base); + if (p == value || *p != '\0') + return FALSE; /* number was bad */ + + /* If the value is zero, it wouldn't add to the Decode As tables */ + if (uval != 0) + { + sub_dissectors = find_dissector_table(port_prefs[i].table_name); + if (sub_dissectors != NULL) { + handle = dissector_table_get_dissector_handle(sub_dissectors, (gchar*)port_prefs[i].module_name); + if (handle != NULL) { + dissector_change_uint(port_prefs[i].table_name, uval, handle); + decode_build_reset_list(port_prefs[i].table_name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER(uval), NULL, NULL); + } + } + } + + return TRUE; + } + } + + for (i = 0; i < sizeof(port_range_prefs)/sizeof(struct port_pref_name); i++) + { + if (strcmp(pref_name, port_range_prefs[i].pref_name) == 0) + { + range_t *newrange; + guint32 range_i, range_j; + guint32 max_value = 0; + + sub_dissectors = find_dissector_table(port_range_prefs[i].table_name); + if (sub_dissectors != NULL) { + /* Max value is based on datatype of dissector table */ + switch (dissector_table_get_type(sub_dissectors)) { + case FT_UINT8: + max_value = 0xFF; + break; + case FT_UINT16: + max_value = 0xFFFF; + break; + case FT_UINT24: + max_value = 0xFFFFFF; + break; + case FT_UINT32: + max_value = 0xFFFFFFFF; + break; + + default: + g_error("The dissector table %s (%s) is not an integer type - are you using a buggy plugin?", port_range_prefs[i].table_name, get_dissector_table_ui_name(port_range_prefs[i].table_name)); + g_assert_not_reached(); + } + + if (range_convert_str_work(&newrange, value, max_value, + TRUE) != CVT_NO_ERROR) { + return FALSE; /* number was bad */ + } + + handle = dissector_table_get_dissector_handle(sub_dissectors, (gchar*)port_range_prefs[i].module_name); + if (handle != NULL) { + + for (range_i = 0; range_i < newrange->nranges; range_i++) { + for (range_j = newrange->ranges[range_i].low; range_j < newrange->ranges[range_i].high; range_j++) { + dissector_change_uint(port_range_prefs[i].table_name, range_j, handle); + decode_build_reset_list(port_range_prefs[i].table_name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER(range_j), NULL, NULL); + } + + dissector_change_uint(port_range_prefs[i].table_name, newrange->ranges[range_i].high, handle); + decode_build_reset_list(port_range_prefs[i].table_name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER(newrange->ranges[range_i].high), NULL, NULL); + } + } + + g_free(newrange); + } + + return TRUE; + } + } for (i = 0; i < sizeof(tpkt_subdissector_port_prefs)/sizeof(struct port_pref_name); i++) { @@ -4077,6 +4254,14 @@ deprecated_port_pref(gchar *pref_name, const gchar *value) } } + for (i = 0; i < sizeof(obsolete_prefs)/sizeof(struct obsolete_pref_name); i++) + { + if (strcmp(pref_name, obsolete_prefs[i].pref_name) == 0) + { + /* Just ignore the preference */ + return TRUE; + } + } return FALSE; } @@ -4518,7 +4703,43 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_, *pref->varp.uint = uval; } break; + case PREF_DECODE_AS_UINT: + { + /* This is for backwards compatibility in case any of the preferences + that shared the "Decode As" preference name and used to be PREF_UINT + are now applied directly to the Decode As funtionality */ + dissector_table_t sub_dissectors; + dissector_handle_t handle; + + /* XXX - give an error if it doesn't fit in a guint? */ + uval = (guint)strtoul(value, &p, pref->info.base); + if (p == value || *p != '\0') + return PREFS_SET_SYNTAX_ERR; /* number was bad */ + + if (*pref->varp.uint != uval) { + containing_module->prefs_changed = TRUE; + *pref->varp.uint = uval; + + /* Name of preference is the dissector table */ + sub_dissectors = find_dissector_table(pref->name); + if (sub_dissectors != NULL) { + handle = dissector_table_get_dissector_handle(sub_dissectors, (gchar*)module->title); + if (handle != NULL) { + if (uval != 0) { + dissector_change_uint(pref->name, uval, handle); + decode_build_reset_list(pref->name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER(uval), NULL, NULL); + } else { + dissector_delete_uint(pref->name, *pref->varp.uint, handle); + decode_build_reset_list(pref->name, dissector_table_get_type(sub_dissectors), pref->varp.uint, NULL, NULL); + } + + /* XXX - Do we save the decode_as_entries file here? */ + } + } + } + break; + } case PREF_BOOL: /* XXX - give an error if it's neither "true" nor "false"? */ if (g_ascii_strcasecmp(value, "true") == 0) @@ -4554,6 +4775,61 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_, return PREFS_SET_SYNTAX_ERR; /* number was bad */ break; } + case PREF_DECODE_AS_RANGE: + { + /* This is for backwards compatibility in case any of the preferences + that shared the "Decode As" preference name and used to be PREF_RANGE + are now applied directly to the Decode As funtionality */ + range_t *newrange; + dissector_table_t sub_dissectors; + dissector_handle_t handle; + guint32 i, j; + + if (range_convert_str_work(&newrange, value, pref->info.max_value, + return_range_errors) != CVT_NO_ERROR) { + return PREFS_SET_SYNTAX_ERR; /* number was bad */ + } + + if (!ranges_are_equal(*pref->varp.range, newrange)) { + g_free(*pref->varp.range); + *pref->varp.range = newrange; + containing_module->prefs_changed = TRUE; + + /* Name of preference is the dissector table */ + sub_dissectors = find_dissector_table(pref->name); + if (sub_dissectors != NULL) { + handle = dissector_table_get_dissector_handle(sub_dissectors, (gchar*)module->title); + if (handle != NULL) { + /* Delete all of the old values from the dissector table */ + for (i = 0; i < (*pref->varp.range)->nranges; i++) { + for (j = (*pref->varp.range)->ranges[i].low; j < (*pref->varp.range)->ranges[i].high; j++) { + dissector_delete_uint(pref->name, j, handle); + decode_build_reset_list(pref->name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER(j), NULL, NULL); + } + + dissector_delete_uint(pref->name, (*pref->varp.range)->ranges[i].high, handle); + decode_build_reset_list(pref->name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER((*pref->varp.range)->ranges[i].high), NULL, NULL); + } + + /* Add new values to the dissector table */ + for (i = 0; i < newrange->nranges; i++) { + for (j = newrange->ranges[i].low; j < newrange->ranges[i].high; j++) { + dissector_change_uint(pref->name, j, handle); + decode_build_reset_list(pref->name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER(j), NULL, NULL); + } + + dissector_change_uint(pref->name, newrange->ranges[i].high, handle); + decode_build_reset_list(pref->name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER(newrange->ranges[i].high), NULL, NULL); + } + + /* XXX - Do we save the decode_as_entries file here? */ + } + } + } else { + g_free(newrange); + } + break; + } case PREF_COLOR: { @@ -4659,6 +4935,14 @@ prefs_pref_type_name(pref_t *pref) type_name = "Custom"; break; + case PREF_DECODE_AS_UINT: + type_name = "Decode As value"; + break; + + case PREF_DECODE_AS_RANGE: + type_name = "Range (for Decode As)"; + break; + case PREF_STATIC_TEXT: type_name = "Static text"; break; @@ -4756,6 +5040,14 @@ prefs_pref_type_description(pref_t *pref) type_desc = "A custom value"; break; + case PREF_DECODE_AS_UINT: + type_desc = "An integer value used in Decode As"; + break; + + case PREF_DECODE_AS_RANGE: + type_desc = "A string denoting an positive integer range for Decode As"; + break; + case PREF_STATIC_TEXT: type_desc = "[Static text]"; break; @@ -4785,6 +5077,11 @@ prefs_pref_is_default(pref_t *pref) switch (type) { + case PREF_DECODE_AS_UINT: + if (pref->default_val.uint == *pref->varp.uint) + return TRUE; + break; + case PREF_UINT: if (pref->default_val.uint == *pref->varp.uint) return TRUE; @@ -4807,6 +5104,7 @@ prefs_pref_is_default(pref_t *pref) return TRUE; break; + case PREF_DECODE_AS_RANGE: case PREF_RANGE: { if ((ranges_are_equal(pref->default_val.range, *pref->varp.range))) @@ -4876,6 +5174,7 @@ prefs_pref_to_str(pref_t *pref, pref_source_t source) { switch (type) { + case PREF_DECODE_AS_UINT: case PREF_UINT: { guint pref_uint = *(guint *) valp; @@ -4920,6 +5219,7 @@ prefs_pref_to_str(pref_t *pref, pref_source_t source) { case PREF_DIRNAME: return g_strdup(*(const char **) valp); + case PREF_DECODE_AS_RANGE: case PREF_RANGE: /* Convert wmem to g_alloc memory */ tmp_value = range_convert_range(NULL, *(range_t **) valp); @@ -4990,6 +5290,10 @@ write_pref(gpointer data, gpointer user_data) case PREF_UAT: /* Nothing to do; don't bother printing the description */ return; + case PREF_DECODE_AS_UINT: + case PREF_DECODE_AS_RANGE: + /* Data is saved through Decode As mechanism and not part of preferences file */ + return; default: break; } |