aboutsummaryrefslogtreecommitdiffstats
path: root/epan/prefs.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/prefs.c')
-rw-r--r--epan/prefs.c324
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;
}