From c302812566373c5ac7383b825bea830b716778a5 Mon Sep 17 00:00:00 2001 From: Michael Mann Date: Fri, 23 Dec 2016 15:20:31 -0500 Subject: [PATCH] Add enabled protocol list for dissectors who are disabled by default We save a list of dissectors that are disabled through the Enabled Protocols dialog. This is because we assume dissectors are enabled by default. For dissectors that are disabled by default, we have no way to keep them enabled through the Enabled Protocols dialog. A dissector that defaults to being disabled has to be reset to enabled each time Wireshark is launched. Add a list similar to the disabled list for enabling dissectors that are disabled by default. This mostly applies to post-dissectors. Change-Id: I31a8d97a9fdbc472fe2a8666384e0f8786bb8e9f Reviewed-on: https://code.wireshark.org/review/19405 Petri-Dish: Michael Mann Tested-by: Petri Dish Buildbot Reviewed-by: Michael Mann --- debian/libwireshark0.symbols | 4 + echld/dispatcher.c | 2 + epan/disabled_protos.c | 592 +++++++++++++++++------------ epan/disabled_protos.h | 45 ++- epan/proto.c | 6 + epan/proto.h | 4 + rawshark.c | 3 + tfshark.c | 3 + tshark.c | 12 + ui/commandline.c | 1 + ui/dissect_opts.c | 4 + ui/dissect_opts.h | 3 + ui/gtk/main.c | 12 + ui/gtk/proto_dlg.c | 8 + ui/qt/enabled_protocols_dialog.cpp | 9 + ui/qt/wireshark_application.cpp | 3 + wireshark-qt.cpp | 9 + 17 files changed, 486 insertions(+), 234 deletions(-) diff --git a/debian/libwireshark0.symbols b/debian/libwireshark0.symbols index 0bc0ca8ddc..92ac448880 100644 --- a/debian/libwireshark0.symbols +++ b/debian/libwireshark0.symbols @@ -989,6 +989,7 @@ libwireshark.so.0 libwireshark0 #MINVER# proto_disable_proto_by_name@Base 1.99.8 proto_enable_all@Base 1.9.1 proto_enable_heuristic_by_name@Base 1.99.8 + proto_enable_proto_by_name@2.3.0 proto_expert@Base 1.9.1 proto_field_is_referenced@Base 1.9.1 proto_field_display_to_string@Base 2.1.0 @@ -1014,6 +1015,7 @@ libwireshark.so.0 libwireshark0 #MINVER# proto_heuristic_dissector_foreach@Base 2.0.0 proto_initialize_all_prefixes@Base 1.9.1 proto_is_protocol_enabled@Base 1.9.1 + proto_is_protocol_enabled_by_default@Base 2.3.0 proto_is_frame_protocol@Base 1.99.1 proto_item_add_subtree@Base 1.9.1 proto_item_append_text@Base 1.9.1 @@ -1271,6 +1273,7 @@ libwireshark.so.0 libwireshark0 #MINVER# save_decode_as_entries@Base 2.3.0 save_disabled_heur_dissector_list@Base 1.99.8 save_disabled_protos_list@Base 1.12.0~rc1 + save_enabled_protos_list@Base 2.3.0 sccp_address_signal_values@Base 1.9.1 sccp_error_cause_values@Base 1.9.1 sccp_message_type_acro_values@Base 1.9.1 @@ -1294,6 +1297,7 @@ libwireshark.so.0 libwireshark0 #MINVER# set_column_visible@Base 1.9.1 set_disabled_heur_dissector_list@Base 1.99.8 set_disabled_protos_list@Base 1.12.0~rc1 + set_enabled_protos_list@Base 2.3.0 set_fd_time@Base 1.9.1 set_mac_lte_proto_data@Base 1.9.1 set_srt_table_param_data@Base 1.99.8 diff --git a/echld/dispatcher.c b/echld/dispatcher.c index 36642c194a..1bcf041e54 100644 --- a/echld/dispatcher.c +++ b/echld/dispatcher.c @@ -508,12 +508,14 @@ static void preinit_epan(char* argv0, int (*main)(int, char **)) { /* disabled protocols as per configuration file */ set_disabled_protos_list(); + set_enabled_protos_list(); set_disabled_heur_dissector_list(); setlocale(LC_ALL, ""); DISP_DBG((1,"---5")); read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, &dp_path, &dp_open_errno, &dp_read_errno); + read_enabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, &dp_path, &dp_open_errno, &dp_read_errno); read_disabled_heur_dissector_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, &dp_path, &dp_open_errno, &dp_read_errno); DISP_DBG((1,"---6")); diff --git a/epan/disabled_protos.c b/epan/disabled_protos.c index 38aef4c1c7..3744f9d282 100644 --- a/epan/disabled_protos.c +++ b/epan/disabled_protos.c @@ -1,5 +1,6 @@ /* disabled_protos.c - * Code for reading and writing the disabled protocols file. + * Declarations of routines for reading and writing protocols file that determine + * enabling and disabling of protocols. * * Wireshark - Network traffic analyzer * By Gerald Combs @@ -36,7 +37,8 @@ #include #include /* ws_g_warning */ -#define PROTOCOLS_FILE_NAME "disabled_protos" +#define ENABLED_PROTOCOLS_FILE_NAME "enabled_protos" +#define DISABLED_PROTOCOLS_FILE_NAME "disabled_protos" #define HEURISTICS_FILE_NAME "heuristic_protos" /* @@ -59,6 +61,11 @@ typedef struct { */ static GList *global_disabled_protos = NULL; static GList *disabled_protos = NULL; +/* + * List of enabled protocols (that are disabled by default) + */ +static GList *global_enabled_protos = NULL; +static GList *enabled_protos = NULL; /* * List of disabled heuristics */ @@ -106,216 +113,22 @@ heur_discard_existing_list (GList **flp) } /* - * Read in a list of disabled protocols. - * - * On success, "*pref_path_return" is set to NULL. - * On error, "*pref_path_return" is set to point to the pathname of - * the file we tried to read - it should be freed by our caller - - * and "*open_errno_return" is set to the error if an open failed - * or "*read_errno_return" is set to the error if a read failed. + * Enable/Disable protocols as per the stored configuration */ - -static int read_disabled_protos_list_file(const char *ff_path, FILE *ff, - GList **flp); - -void -read_disabled_protos_list(char **gpath_return, int *gopen_errno_return, - int *gread_errno_return, - char **path_return, int *open_errno_return, - int *read_errno_return) -{ - int err; - char *gff_path, *ff_path; - FILE *ff; - - /* Construct the pathname of the global disabled protocols file. */ - gff_path = get_datafile_path(PROTOCOLS_FILE_NAME); - - /* If we already have a list of protocols, discard it. */ - discard_existing_list (&global_disabled_protos); - - /* Read the global disabled protocols file, if it exists. */ - *gpath_return = NULL; - if ((ff = ws_fopen(gff_path, "r")) != NULL) { - /* We succeeded in opening it; read it. */ - err = read_disabled_protos_list_file(gff_path, ff, - &global_disabled_protos); - if (err != 0) { - /* We had an error reading the file; return the errno and the - pathname, so our caller can report the error. */ - *gopen_errno_return = 0; - *gread_errno_return = err; - *gpath_return = gff_path; - } else - g_free(gff_path); - fclose(ff); - } else { - /* We failed to open it. If we failed for some reason other than - "it doesn't exist", return the errno and the pathname, so our - caller can report the error. */ - if (errno != ENOENT) { - *gopen_errno_return = errno; - *gread_errno_return = 0; - *gpath_return = gff_path; - } else - g_free(gff_path); - } - - /* Construct the pathname of the user's disabled protocols file. */ - ff_path = get_persconffile_path(PROTOCOLS_FILE_NAME, TRUE); - - /* If we already have a list of protocols, discard it. */ - discard_existing_list (&disabled_protos); - - /* Read the user's disabled protocols file, if it exists. */ - *path_return = NULL; - if ((ff = ws_fopen(ff_path, "r")) != NULL) { - /* We succeeded in opening it; read it. */ - err = read_disabled_protos_list_file(ff_path, ff, &disabled_protos); - if (err != 0) { - /* We had an error reading the file; return the errno and the - pathname, so our caller can report the error. */ - *open_errno_return = 0; - *read_errno_return = err; - *path_return = ff_path; - } else - g_free(ff_path); - fclose(ff); - } else { - /* We failed to open it. If we failed for some reason other than - "it doesn't exist", return the errno and the pathname, so our - caller can report the error. */ - if (errno != ENOENT) { - *open_errno_return = errno; - *read_errno_return = 0; - *path_return = ff_path; - } else - g_free(ff_path); - } -} - -static int -read_disabled_protos_list_file(const char *ff_path, FILE *ff, - GList **flp) -{ - protocol_def *prot; - int c; - char *prot_name; - int prot_name_len; - int prot_name_index; - int line = 1; - - - /* Allocate the protocol name buffer. */ - prot_name_len = INIT_BUF_SIZE; - prot_name = (char *)g_malloc(prot_name_len + 1); - - for (line = 1; ; line++) { - /* Lines in a disabled protocol file contain the "filter name" of - a protocol to be disabled. */ - - /* Skip over leading white space, if any. */ - while ((c = ws_getc_unlocked(ff)) != EOF && g_ascii_isspace(c)) { - if (c == '\n') { - /* Blank line. */ - continue; - } - } - - if (c == EOF) { - if (ferror(ff)) - goto error; /* I/O error */ - else - break; /* Nothing more to read */ - } - ungetc(c, ff); /* Unread the non-white-space character. */ - - /* Get the name of the protocol. */ - prot_name_index = 0; - for (;;) { - c = ws_getc_unlocked(ff); - if (c == EOF) - break; /* End of file, or I/O error */ - if (g_ascii_isspace(c)) - break; /* Trailing white space, or end of line. */ - if (c == '#') - break; /* Start of comment, running to end of line. */ - /* Add this character to the protocol name string. */ - if (prot_name_index >= prot_name_len) { - /* protocol name buffer isn't long enough; double its length. */ - prot_name_len *= 2; - prot_name = (char *)g_realloc(prot_name, prot_name_len + 1); - } - prot_name[prot_name_index] = c; - prot_name_index++; - } - - if (g_ascii_isspace(c) && c != '\n') { - /* Skip over trailing white space. */ - while ((c = ws_getc_unlocked(ff)) != EOF && c != '\n' && g_ascii_isspace(c)) - ; - if (c != EOF && c != '\n' && c != '#') { - /* Non-white-space after the protocol name; warn about it, - in case we come up with a reason to use it. */ - ws_g_warning("'%s' line %d has extra stuff after the protocol name.", - ff_path, line); - } - } - if (c != EOF && c != '\n') { - /* Skip to end of line. */ - while ((c = ws_getc_unlocked(ff)) != EOF && c != '\n') - ; - } - - if (c == EOF) { - if (ferror(ff)) - goto error; /* I/O error */ - else { - /* EOF, not error; no newline seen before EOF */ - ws_g_warning("'%s' line %d doesn't have a newline.", ff_path, - line); - } - break; /* nothing more to read */ - } - - /* Null-terminate the protocol name. */ - if (prot_name_index >= prot_name_len) { - /* protocol name buffer isn't long enough; double its length. */ - prot_name_len *= 2; - prot_name = (char *)g_realloc(prot_name, prot_name_len + 1); - } - prot_name[prot_name_index] = '\0'; - - /* Add the new protocol to the list of disabled protocols */ - prot = (protocol_def *) g_malloc(sizeof(protocol_def)); - prot->name = g_strdup(prot_name); - *flp = g_list_append(*flp, prot); - } - g_free(prot_name); - return 0; - -error: - g_free(prot_name); - return errno; -} - -/* - * Disable protocols as per the stored configuration - */ -void -set_disabled_protos_list(void) +static void +set_protos_list(GList *protos_list, GList *global_protos_list, gboolean enable) { gint i; GList *fl_ent; protocol_def *prot; /* - * assume all protocols are enabled by default + * Assume no protocols disabled by default wants to be enabled */ - if (disabled_protos == NULL) + if (protos_list == NULL) goto skip; - fl_ent = g_list_first(disabled_protos); + fl_ent = g_list_first(protos_list); while (fl_ent != NULL) { prot = (protocol_def *) fl_ent->data; @@ -324,17 +137,17 @@ set_disabled_protos_list(void) /* XXX - complain here? */ } else { if (proto_can_toggle_protocol(i)) - proto_set_decoding(i, FALSE); + proto_set_decoding(i, enable); } fl_ent = fl_ent->next; } skip: - if (global_disabled_protos == NULL) + if (global_protos_list == NULL) return; - fl_ent = g_list_first(global_disabled_protos); + fl_ent = g_list_first(global_protos_list); while (fl_ent != NULL) { prot = (protocol_def *) fl_ent->data; @@ -343,7 +156,7 @@ skip: /* XXX - complain here? */ } else { if (proto_can_toggle_protocol(i)) { - proto_set_decoding(i, FALSE); + proto_set_decoding(i, enable); proto_set_cant_toggle(i); } } @@ -353,46 +166,27 @@ skip: } /* - * Disable a particular protocol by name - */ - -void -proto_disable_proto_by_name(const char *name) -{ - protocol_t *protocol; - int proto_id; - - proto_id = proto_get_id_by_filter_name(name); - if (proto_id >= 0 ) { - protocol = find_protocol_by_id(proto_id); - if (proto_is_protocol_enabled(protocol) == TRUE) { - if (proto_can_toggle_protocol(proto_id) == TRUE) { - proto_set_decoding(proto_id, FALSE); - } - } - } -} - -/* - * Write out a list of disabled protocols. + * Write out a list of protocols based on condition * * On success, "*pref_path_return" is set to NULL. * On error, "*pref_path_return" is set to point to the pathname of * the file we tried to read - it should be freed by our caller - * and "*errno_return" is set to the error. */ -void -save_disabled_protos_list(char **pref_path_return, int *errno_return) +static void +save_protos_list(char **pref_path_return, int *errno_return, const char* filename, + const char* header_comment, gboolean (*protocol_check)(protocol_t *protocol)) { gchar *ff_path, *ff_path_new; FILE *ff; gint i; protocol_t *protocol; void *cookie; + gboolean first = TRUE; *pref_path_return = NULL; /* assume no error */ - ff_path = get_persconffile_path(PROTOCOLS_FILE_NAME, TRUE); + ff_path = get_persconffile_path(filename, TRUE); /* Write to "XXX.new", and rename if that succeeds. That means we don't trash the file if we fail to write it out @@ -407,7 +201,6 @@ save_disabled_protos_list(char **pref_path_return, int *errno_return) } /* Iterate over all the protocols */ - for (i = proto_get_first_protocol(&cookie); i != -1; i = proto_get_next_protocol(&cookie)) { @@ -416,8 +209,15 @@ save_disabled_protos_list(char **pref_path_return, int *errno_return) } protocol = find_protocol_by_id(i); - if (proto_is_protocol_enabled(protocol)) { + if (protocol_check(protocol) == FALSE) continue; + + if (first) { + if (header_comment != NULL) { + /* Write out a comment explaining what the file is */ + fprintf(ff, "%s\n", header_comment); + } + first = FALSE; } /* Write out the protocol name. */ @@ -467,6 +267,332 @@ save_disabled_protos_list(char **pref_path_return, int *errno_return) g_free(ff_path); } +static int +read_protos_list_file(const char *ff_path, FILE *ff, + GList **flp) +{ + protocol_def *prot; + int c; + char *prot_name; + int prot_name_len; + int prot_name_index; + int line = 1; + gboolean in_comment = FALSE; + + + /* Allocate the protocol name buffer. */ + prot_name_len = INIT_BUF_SIZE; + prot_name = (char *)g_malloc(prot_name_len + 1); + + for (line = 1; ; line++) { + /* Lines in a disabled protocol file contain the "filter name" of + a protocol to be disabled. */ + + /* Skip over leading white space, if any. */ + while ((c = ws_getc_unlocked(ff)) != EOF && g_ascii_isspace(c)) { + if (c == '\n') { + /* Blank line. */ + continue; + } + } + + if (c == EOF) { + if (ferror(ff)) + goto error; /* I/O error */ + else + break; /* Nothing more to read */ + } + ungetc(c, ff); /* Unread the non-white-space character. */ + + /* Get the name of the protocol. */ + prot_name_index = 0; + for (;;) { + c = ws_getc_unlocked(ff); + if (c == EOF) + break; /* End of file, or I/O error */ + if (g_ascii_isspace(c)) + break; /* Trailing white space, or end of line. */ + if (c == '#') { + in_comment = TRUE; + break; /* Start of comment, running to end of line. */ + } + /* Add this character to the protocol name string. */ + if (prot_name_index >= prot_name_len) { + /* protocol name buffer isn't long enough; double its length. */ + prot_name_len *= 2; + prot_name = (char *)g_realloc(prot_name, prot_name_len + 1); + } + prot_name[prot_name_index] = c; + prot_name_index++; + } + + if (g_ascii_isspace(c) && c != '\n') { + /* Skip over trailing white space. */ + while ((c = ws_getc_unlocked(ff)) != EOF && c != '\n' && g_ascii_isspace(c)) + ; + if (c != EOF && c != '\n' && c != '#') { + /* Non-white-space after the protocol name; warn about it, + in case we come up with a reason to use it. */ + ws_g_warning("'%s' line %d has extra stuff after the protocol name.", + ff_path, line); + } + } + if (c != EOF && c != '\n' && in_comment == TRUE) { + /* Skip to end of line. */ + while ((c = ws_getc_unlocked(ff)) != EOF && c != '\n') + ; + } + + if (c == EOF) { + if (ferror(ff)) + goto error; /* I/O error */ + else { + /* EOF, not error; no newline seen before EOF */ + ws_g_warning("'%s' line %d doesn't have a newline.", ff_path, + line); + } + break; /* nothing more to read */ + } + + if (in_comment) { + in_comment = FALSE; + continue; + } + + /* Null-terminate the protocol name. */ + if (prot_name_index >= prot_name_len) { + /* protocol name buffer isn't long enough; double its length. */ + prot_name_len *= 2; + prot_name = (char *)g_realloc(prot_name, prot_name_len + 1); + } + prot_name[prot_name_index] = '\0'; + + /* Add the new protocol to the list of disabled protocols */ + prot = (protocol_def *) g_malloc(sizeof(protocol_def)); + prot->name = g_strdup(prot_name); + *flp = g_list_append(*flp, prot); + } + g_free(prot_name); + return 0; + +error: + g_free(prot_name); + return errno; +} + +/* + * Read in a list of protocols. + * + * On success, "*pref_path_return" is set to NULL. + * On error, "*pref_path_return" is set to point to the pathname of + * the file we tried to read - it should be freed by our caller - + * and "*open_errno_return" is set to the error if an open failed + * or "*read_errno_return" is set to the error if a read failed. + */ +void +read_protos_list(char **gpath_return, int *gopen_errno_return, + int *gread_errno_return, + char **path_return, int *open_errno_return, + int *read_errno_return, const char* filename, + GList **protos_list, GList **global_protos_list) +{ + int err; + char *gff_path, *ff_path; + FILE *ff; + + /* Construct the pathname of the global disabled protocols file. */ + gff_path = get_datafile_path(filename); + + /* If we already have a list of protocols, discard it. */ + discard_existing_list (global_protos_list); + + /* Read the global disabled protocols file, if it exists. */ + *gpath_return = NULL; + if ((ff = ws_fopen(gff_path, "r")) != NULL) { + /* We succeeded in opening it; read it. */ + err = read_protos_list_file(gff_path, ff, + global_protos_list); + if (err != 0) { + /* We had an error reading the file; return the errno and the + pathname, so our caller can report the error. */ + *gopen_errno_return = 0; + *gread_errno_return = err; + *gpath_return = gff_path; + } else + g_free(gff_path); + fclose(ff); + } else { + /* We failed to open it. If we failed for some reason other than + "it doesn't exist", return the errno and the pathname, so our + caller can report the error. */ + if (errno != ENOENT) { + *gopen_errno_return = errno; + *gread_errno_return = 0; + *gpath_return = gff_path; + } else + g_free(gff_path); + } + + /* Construct the pathname of the user's disabled protocols file. */ + ff_path = get_persconffile_path(filename, TRUE); + + /* If we already have a list of protocols, discard it. */ + discard_existing_list (protos_list); + + /* Read the user's disabled protocols file, if it exists. */ + *path_return = NULL; + if ((ff = ws_fopen(ff_path, "r")) != NULL) { + /* We succeeded in opening it; read it. */ + err = read_protos_list_file(ff_path, ff, protos_list); + if (err != 0) { + /* We had an error reading the file; return the errno and the + pathname, so our caller can report the error. */ + *open_errno_return = 0; + *read_errno_return = err; + *path_return = ff_path; + } else + g_free(ff_path); + fclose(ff); + } else { + /* We failed to open it. If we failed for some reason other than + "it doesn't exist", return the errno and the pathname, so our + caller can report the error. */ + if (errno != ENOENT) { + *open_errno_return = errno; + *read_errno_return = 0; + *path_return = ff_path; + } else + g_free(ff_path); + } +} + +/************************************************************************ + * Disabling dissectors + ************************************************************************/ + +/* + * Read in a list of disabled protocols. + */ +void +read_disabled_protos_list(char **gpath_return, int *gopen_errno_return, + int *gread_errno_return, + char **path_return, int *open_errno_return, + int *read_errno_return) +{ + read_protos_list(gpath_return, gopen_errno_return, gread_errno_return, + path_return, open_errno_return, read_errno_return, + DISABLED_PROTOCOLS_FILE_NAME, &disabled_protos, &global_disabled_protos); +} + +/* + * Disable protocols as per the stored configuration + */ +void +set_disabled_protos_list(void) +{ + set_protos_list(disabled_protos, global_disabled_protos, FALSE); +} + +/* + * Disable a particular protocol by name + */ +void +proto_disable_proto_by_name(const char *name) +{ + protocol_t *protocol; + int proto_id; + + proto_id = proto_get_id_by_filter_name(name); + if (proto_id >= 0 ) { + protocol = find_protocol_by_id(proto_id); + if (proto_is_protocol_enabled(protocol) == TRUE) { + if (proto_can_toggle_protocol(proto_id) == TRUE) { + proto_set_decoding(proto_id, FALSE); + } + } + } +} + +static gboolean disable_proto_list_check(protocol_t *protocol) +{ + if (proto_is_protocol_enabled(protocol) == FALSE) + return TRUE; + + return FALSE; +} + +void +save_disabled_protos_list(char **pref_path_return, int *errno_return) +{ + save_protos_list(pref_path_return, errno_return, DISABLED_PROTOCOLS_FILE_NAME, + NULL, disable_proto_list_check); +} + +/************************************************************************ + * Enabling dissectors (that are disabled by default) + ************************************************************************/ +void +set_enabled_protos_list(void) +{ + set_protos_list(enabled_protos, global_enabled_protos, TRUE); +} + + +WS_DLL_PUBLIC void +proto_enable_proto_by_name(const char *name) +{ + protocol_t *protocol; + int proto_id; + + proto_id = proto_get_id_by_filter_name(name); + if (proto_id >= 0 ) { + protocol = find_protocol_by_id(proto_id); + if ((proto_is_protocol_enabled_by_default(protocol) == FALSE) && + (proto_is_protocol_enabled(protocol) == FALSE)) { + if (proto_can_toggle_protocol(proto_id) == TRUE) { + proto_set_decoding(proto_id, TRUE); + } + } + } +} + +static gboolean enable_proto_list_check(protocol_t *protocol) +{ + if ((proto_is_protocol_enabled_by_default(protocol) == FALSE) && + (proto_is_protocol_enabled(protocol) == TRUE)) + return TRUE; + + return FALSE; +} + +void +save_enabled_protos_list(char **pref_path_return, int *errno_return) +{ + save_protos_list(pref_path_return, errno_return, ENABLED_PROTOCOLS_FILE_NAME, + "#This file is for enabling protocols that are disabled by default", + enable_proto_list_check); +} + +/* + * Read in a list of enabled protocols (that are disabled by default). + */ +void +read_enabled_protos_list(char **gpath_return, int *gopen_errno_return, + int *gread_errno_return, + char **path_return, int *open_errno_return, + int *read_errno_return) +{ + read_protos_list(gpath_return, gopen_errno_return, gread_errno_return, + path_return, open_errno_return, read_errno_return, + ENABLED_PROTOCOLS_FILE_NAME, &enabled_protos, &global_enabled_protos); +} + + +/************************************************************************ + * Heuristic dissectors + ************************************************************************/ + + void set_disabled_heur_dissector_list(void) { diff --git a/epan/disabled_protos.h b/epan/disabled_protos.h index 33e56f7d9b..656a0f0427 100644 --- a/epan/disabled_protos.h +++ b/epan/disabled_protos.h @@ -1,5 +1,6 @@ /* disabled_protos.h - * Declarations of routines for reading and writing the disabled protocols file. + * Declarations of routines for reading and writing protocols file that determine + * enabling and disabling of protocols. * * Wireshark - Network traffic analyzer * By Gerald Combs @@ -68,6 +69,48 @@ save_disabled_protos_list(char **pref_path_return, int *errno_return); WS_DLL_PUBLIC void proto_disable_proto_by_name(const char *name); + +/* + * Read in a list of enabled protocols (who are disabled by default) + * + * On success, "*pref_path_return" is set to NULL. + * On error, "*pref_path_return" is set to point to the pathname of + * the file we tried to read - it should be freed by our caller - + * and "*open_errno_return" is set to the error if we couldn't open the file + * or "*read_errno_return" is set to the error if we got an error reading + * the file. + */ +WS_DLL_PUBLIC void +read_enabled_protos_list(char **gpath_return, int *gopen_errno_return, + int *gread_errno_return, + char **path_return, int *open_errno_return, + int *read_errno_return); + +/* + * Enable protocols (that default to disabled) as per the stored configuration + */ +WS_DLL_PUBLIC void +set_enabled_protos_list(void); + +/* + * Write out a list of enabled protocols (that default to being disabled) + * + * On success, "*pref_path_return" is set to NULL. + * On error, "*pref_path_return" is set to point to the pathname of + * the file we tried to read - it should be freed by our caller - + * and "*errno_return" is set to the error. + */ +WS_DLL_PUBLIC void +save_enabled_protos_list(char **pref_path_return, int *errno_return); + + +/* + * Enable a particular protocol by name. This will only enable + * protocols that are disabled by default. All others will be ignored. + */ +WS_DLL_PUBLIC void +proto_enable_proto_by_name(const char *name); + /* * Read in a list of disabled protocols. * diff --git a/epan/proto.c b/epan/proto.c index e00f16b5ef..fc67163d66 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -6157,6 +6157,12 @@ proto_is_protocol_enabled(const protocol_t *protocol) return protocol->is_enabled; } +gboolean +proto_is_protocol_enabled_by_default(const protocol_t *protocol) +{ + return protocol->enabled_by_default; +} + gboolean proto_can_toggle_protocol(const int proto_id) { diff --git a/epan/proto.h b/epan/proto.h index 86000a8097..30f6111109 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -2250,6 +2250,10 @@ WS_DLL_PUBLIC const char *proto_get_protocol_long_name(const protocol_t *protoco @return TRUE if decoding is enabled, FALSE if not */ WS_DLL_PUBLIC gboolean proto_is_protocol_enabled(const protocol_t *protocol); +/** Is protocol's enabled by default (most are)? + @return TRUE if decoding is enabled by default, FALSE if not */ +WS_DLL_PUBLIC gboolean proto_is_protocol_enabled_by_default(const protocol_t *protocol); + /** Get a protocol's filter name by its item number. @param proto_id protocol id (0-indexed) @return its filter name. */ diff --git a/rawshark.c b/rawshark.c index f9d0a5702c..af607044ac 100644 --- a/rawshark.c +++ b/rawshark.c @@ -553,6 +553,8 @@ main(int argc, char *argv[]) /* Read the disabled protocols file. */ read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, &dp_path, &dp_open_errno, &dp_read_errno); + read_enabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, + &dp_path, &dp_open_errno, &dp_read_errno); read_disabled_heur_dissector_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, &dp_path, &dp_open_errno, &dp_read_errno); if (gdp_path != NULL) { @@ -791,6 +793,7 @@ main(int argc, char *argv[]) /* disabled protocols as per configuration file */ if (gdp_path == NULL && dp_path == NULL) { set_disabled_protos_list(); + set_enabled_protos_list(); set_disabled_heur_dissector_list(); } diff --git a/tfshark.c b/tfshark.c index 333777e01a..a255f78ff6 100644 --- a/tfshark.c +++ b/tfshark.c @@ -622,6 +622,8 @@ main(int argc, char *argv[]) /* Read the disabled protocols file. */ read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, &dp_path, &dp_open_errno, &dp_read_errno); + read_enabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, + &dp_path, &dp_open_errno, &dp_read_errno); read_disabled_heur_dissector_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, &dp_path, &dp_open_errno, &dp_read_errno); if (gdp_path != NULL) { @@ -935,6 +937,7 @@ main(int argc, char *argv[]) /* disabled protocols as per configuration file */ if (gdp_path == NULL && dp_path == NULL) { set_disabled_protos_list(); + set_enabled_protos_list(); set_disabled_heur_dissector_list(); } diff --git a/tshark.c b/tshark.c index 137a7dcead..8d4596f197 100644 --- a/tshark.c +++ b/tshark.c @@ -1024,6 +1024,8 @@ main(int argc, char *argv[]) /* Read the disabled protocols file. */ read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, &dp_path, &dp_open_errno, &dp_read_errno); + read_enabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, + &dp_path, &dp_open_errno, &dp_read_errno); read_disabled_heur_dissector_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, &dp_path, &dp_open_errno, &dp_read_errno); if (gdp_path != NULL) { @@ -1385,6 +1387,7 @@ main(int argc, char *argv[]) case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */ case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */ case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */ + case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */ if (!dissect_opts_handle_opt(opt, optarg)) return 1; break; @@ -1737,6 +1740,7 @@ main(int argc, char *argv[]) /* disabled protocols as per configuration file */ if (gdp_path == NULL && dp_path == NULL) { set_disabled_protos_list(); + set_enabled_protos_list(); set_disabled_heur_dissector_list(); } @@ -1748,6 +1752,14 @@ main(int argc, char *argv[]) } } + if(global_dissect_options.enable_protocol_slist) { + GSList *proto_enable; + for (proto_enable = global_dissect_options.enable_protocol_slist; proto_enable != NULL; proto_enable = g_slist_next(proto_enable)) + { + proto_enable_proto_by_name((char*)proto_enable->data); + } + } + if(global_dissect_options.enable_heur_slist) { GSList *heur_enable; for (heur_enable = global_dissect_options.enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable)) diff --git a/ui/commandline.c b/ui/commandline.c index 05621d82b8..24e44aae88 100644 --- a/ui/commandline.c +++ b/ui/commandline.c @@ -550,6 +550,7 @@ void commandline_other_options(int argc, char *argv[], gboolean opt_reset) case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */ case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */ case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */ + case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */ if (!dissect_opts_handle_opt(opt, optarg)) exit(1); break; diff --git a/ui/dissect_opts.c b/ui/dissect_opts.c index 267b363669..65afd245c1 100644 --- a/ui/dissect_opts.c +++ b/ui/dissect_opts.c @@ -54,6 +54,7 @@ dissect_opts_init(void) { global_dissect_options.time_format = TS_NOT_SET; global_dissect_options.disable_protocol_slist = NULL; + global_dissect_options.enable_protocol_slist = NULL; global_dissect_options.enable_heur_slist = NULL; global_dissect_options.disable_heur_slist = NULL; } @@ -150,6 +151,9 @@ dissect_opts_handle_opt(int opt, char *optarg_str_p) case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */ global_dissect_options.disable_heur_slist = g_slist_append(global_dissect_options.disable_heur_slist, optarg_str_p); break; + case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disableed by default) */ + global_dissect_options.enable_protocol_slist = g_slist_append(global_dissect_options.enable_protocol_slist, optarg_str_p); + break; default: /* the caller is responsible to send us only the right opt's */ g_assert_not_reached(); diff --git a/ui/dissect_opts.h b/ui/dissect_opts.h index 9dd06e1a40..227ebfc291 100644 --- a/ui/dissect_opts.h +++ b/ui/dissect_opts.h @@ -56,6 +56,7 @@ extern "C" { #define LONGOPT_DISABLE_PROTOCOL 4096 #define LONGOPT_ENABLE_HEURISTIC 4097 #define LONGOPT_DISABLE_HEURISTIC 4098 +#define LONGOPT_ENABLE_PROTOCOL 4099 /* * Options for dissecting common to all dissecting programs. @@ -64,6 +65,7 @@ extern "C" { {"disable-protocol", required_argument, NULL, LONGOPT_DISABLE_PROTOCOL }, \ {"enable-heuristic", required_argument, NULL, LONGOPT_ENABLE_HEURISTIC }, \ {"disable-heuristic", required_argument, NULL, LONGOPT_DISABLE_HEURISTIC }, \ + {"enable-protocol", required_argument, NULL, LONGOPT_ENABLE_PROTOCOL }, \ #define OPTSTRING_DISSECT_COMMON \ "d:K:nN:t:u:" @@ -71,6 +73,7 @@ extern "C" { /** Capture options coming from user interface */ typedef struct dissect_options_tag { ts_type time_format; + GSList *enable_protocol_slist; //enable protocols that are disabled by default GSList *disable_protocol_slist; GSList *enable_heur_slist; GSList *disable_heur_slist; diff --git a/ui/gtk/main.c b/ui/gtk/main.c index f2631006f1..ef8c82fa0a 100644 --- a/ui/gtk/main.c +++ b/ui/gtk/main.c @@ -1971,6 +1971,8 @@ read_configuration_files(char **gdp_path, char **dp_path) /* Read the disabled protocols file. */ read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno, dp_path, &dp_open_errno, &dp_read_errno); + read_enabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno, + dp_path, &dp_open_errno, &dp_read_errno); read_disabled_heur_dissector_list(gdp_path, &gdp_open_errno, &gdp_read_errno, dp_path, &dp_open_errno, &dp_read_errno); if (*gdp_path != NULL) { @@ -2462,6 +2464,7 @@ main(int argc, char *argv[]) /* disabled protocols as per configuration file */ if (gdp_path == NULL && dp_path == NULL) { set_disabled_protos_list(); + set_enabled_protos_list(); set_disabled_heur_dissector_list(); } @@ -2473,6 +2476,14 @@ main(int argc, char *argv[]) } } + if(global_dissect_options.enable_protocol_slist) { + GSList *proto_enable; + for (proto_enable = global_dissect_options.enable_protocol_slist; proto_enable != NULL; proto_enable = g_slist_next(proto_enable)) + { + proto_enable_proto_by_name((char*)proto_enable->data); + } + } + if(global_dissect_options.disable_heur_slist) { GSList *heur_enable; for (heur_enable = global_dissect_options.disable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable)) @@ -3346,6 +3357,7 @@ void change_configuration_profile (const gchar *profile_name) proto_enable_all(); if (gdp_path == NULL && dp_path == NULL) { set_disabled_protos_list(); + set_enabled_protos_list(); set_disabled_heur_dissector_list(); } diff --git a/ui/gtk/proto_dlg.c b/ui/gtk/proto_dlg.c index 8b378a4a68..2bba0a2765 100644 --- a/ui/gtk/proto_dlg.c +++ b/ui/gtk/proto_dlg.c @@ -294,6 +294,14 @@ proto_write(gpointer parent_w _U_) g_free(pf_path); } + save_enabled_protos_list(&pf_path, &pf_save_errno); + if (pf_path != NULL) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + "Could not save to your enabled protocols file\n\"%s\": %s.", + pf_path, g_strerror(pf_save_errno)); + g_free(pf_path); + } + save_disabled_heur_dissector_list(&pf_path, &pf_save_errno); if (pf_path != NULL) { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, diff --git a/ui/qt/enabled_protocols_dialog.cpp b/ui/qt/enabled_protocols_dialog.cpp index a3641e1b5c..f6f891374c 100644 --- a/ui/qt/enabled_protocols_dialog.cpp +++ b/ui/qt/enabled_protocols_dialog.cpp @@ -283,6 +283,15 @@ void EnabledProtocolsDialog::writeChanges() g_free(pf_path); } + save_enabled_protos_list(&pf_path, &pf_save_errno); + if (pf_path != NULL) + { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + "Could not save to your enabled protocols file\n\"%s\": %s.", + pf_path, g_strerror(pf_save_errno)); + g_free(pf_path); + } + save_disabled_heur_dissector_list(&pf_path, &pf_save_errno); if (pf_path != NULL) { diff --git a/ui/qt/wireshark_application.cpp b/ui/qt/wireshark_application.cpp index 7552dc8377..b27dbf07cd 100644 --- a/ui/qt/wireshark_application.cpp +++ b/ui/qt/wireshark_application.cpp @@ -411,6 +411,7 @@ void WiresharkApplication::setConfigurationProfile(const gchar *profile_name) proto_enable_all(); if (gdp_path == NULL && dp_path == NULL) { set_disabled_protos_list(); + set_enabled_protos_list(); set_disabled_heur_dissector_list(); } @@ -1029,6 +1030,8 @@ _e_prefs *WiresharkApplication::readConfigurationFiles(char **gdp_path, char **d /* Read the disabled protocols file. */ read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno, dp_path, &dp_open_errno, &dp_read_errno); + read_enabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno, + dp_path, &dp_open_errno, &dp_read_errno); read_disabled_heur_dissector_list(gdp_path, &gdp_open_errno, &gdp_read_errno, dp_path, &dp_open_errno, &dp_read_errno); if (*gdp_path != NULL) { diff --git a/wireshark-qt.cpp b/wireshark-qt.cpp index f0f1b084d3..1ab55fdab7 100644 --- a/wireshark-qt.cpp +++ b/wireshark-qt.cpp @@ -713,6 +713,7 @@ int main(int argc, char *qt_argv[]) /* disabled protocols as per configuration file */ if (gdp_path == NULL && dp_path == NULL) { set_disabled_protos_list(); + set_enabled_protos_list(); set_disabled_heur_dissector_list(); } @@ -724,6 +725,14 @@ int main(int argc, char *qt_argv[]) } } + if(global_dissect_options.enable_protocol_slist) { + GSList *proto_enable; + for (proto_enable = global_dissect_options.enable_protocol_slist; proto_enable != NULL; proto_enable = g_slist_next(proto_enable)) + { + proto_enable_proto_by_name((char*)proto_enable->data); + } + } + if(global_dissect_options.enable_heur_slist) { GSList *heur_enable; for (heur_enable = global_dissect_options.enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))