summaryrefslogtreecommitdiff
path: root/ui/capture_ui_utils.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2015-03-18 16:58:15 -0700
committerGuy Harris <guy@alum.mit.edu>2015-03-18 23:58:54 +0000
commit096e5231ff41eb1b7c9c13fa1c6217fa78d73c6b (patch)
tree32c20cb47bb1c6320ac32431bfa0f2abb4807604 /ui/capture_ui_utils.c
parent9762c32709b2d2ed6f8d99b89c550c60a546fad9 (diff)
downloadwireshark-096e5231ff41eb1b7c9c13fa1c6217fa78d73c6b.tar.gz
Fix parsing of interface properties strings.
The first entry in the list does not have a leading comma, so a strstr() for ",{ifname}(" will not work. Instead, use g_strsplit() with a comma for all of the preferences. Have common code for all the "uncomplicated" preferences. Have a specialized handler for the one "complicated" preference. Change-Id: I2144a98ab0cb70db56eaaba88175d6e03885de2a Reviewed-on: https://code.wireshark.org/review/7741 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'ui/capture_ui_utils.c')
-rw-r--r--ui/capture_ui_utils.c302
1 files changed, 152 insertions, 150 deletions
diff --git a/ui/capture_ui_utils.c b/ui/capture_ui_utils.c
index 825ed4df47..4827f56ac0 100644
--- a/ui/capture_ui_utils.c
+++ b/ui/capture_ui_utils.c
@@ -37,217 +37,219 @@
#include "epan/to_str.h"
/*
- * Find user-specified capture device description that matches interface
- * name, if any.
+ * In a list of interface information, in the form of a comma-separated
+ * list of {name}({property}) items, find the entry for a particular
+ * interface, and return a pointer a g_malloced string containing
+ * the property.
*/
-char *
-capture_dev_user_descr_find(const gchar *if_name)
+static char *
+capture_dev_get_if_property(const gchar *pref, const gchar *if_name)
{
gchar **if_tokens;
- gchar *descr = NULL;
+ gchar *property = NULL;
int i;
if (if_name == NULL || strlen(if_name) < 1) {
return NULL;
}
- if (prefs.capture_devices_descr == NULL ||
- strlen(prefs.capture_devices_descr) < 1) {
- /* There are no descriptions. */
+ if (pref == NULL || strlen(pref) < 1) {
+ /* There is no interface information list. */
return NULL;
}
-
- if_tokens = g_strsplit(prefs.capture_devices_descr, ",", -1);
+ /*
+ * Split the list into a sequence of items.
+ *
+ * XXX - this relies on the items not themselves containing commas.
+ */
+ if_tokens = g_strsplit(pref, ",", -1);
for (i = 0; if_tokens[i] != NULL; i++) {
- gchar **descr_tokens;
- descr_tokens = g_strsplit_set(if_tokens[i], "()", -1);
- if (g_strv_length(descr_tokens) == 3) { /* interface + description + empty */
- if (strcmp(descr_tokens[0], if_name) == 0 && strlen(descr_tokens[1]) > 0) {
- descr = g_strdup(descr_tokens[1]);
- g_strfreev(descr_tokens);
+ gchar *opening_parenp, *closing_parenp;
+
+ /*
+ * Separate this item into name and property.
+ * The first opening parenthesis and the last closing parenthesis
+ * surround the property. Any other parentheses are part of
+ * the property.
+ */
+ opening_parenp = strchr(if_tokens[i], '(');
+ if (opening_parenp == NULL) {
+ /* No opening parenthesis. Give up. */
+ break;
+ }
+ *opening_parenp = '\0'; /* Split {name} from what follows */
+ if (strcmp(if_tokens[i], if_name) == 0) {
+ closing_parenp = strrchr(if_tokens[i], ')');
+ if (closing_parenp == NULL) {
+ /* No closing parenthesis. Give up. */
break;
}
+ /*
+ * Copy everything from opening_parenp + 1 to closing_parenp - 1.
+ * That requires (closing_parenp - 1) - (opening_parenp + 1) + 1
+ * bytes, including the trailing '\0', so that's
+ * closing_parenp - opening_parenp + 1.
+ */
+ property = g_malloc(closing_parenp - opening_parenp + 1);
+ memcpy(property, opening_parenp + 1, closing_parenp - opening_parenp);
+ property[closing_parenp - opening_parenp] = '\0';
+ break;
}
- g_strfreev(descr_tokens);
}
g_strfreev(if_tokens);
- return descr;
+ return property;
}
-gint
-capture_dev_user_linktype_find(const gchar *if_name)
+/*
+ * Find a property that should be an integral value, and return the
+ * value or, if it's not found or not a valid integral value, -1.
+ */
+static gint
+capture_dev_get_if_int_property(const gchar *pref, const gchar *if_name)
{
- gchar *p, *next, *tmpname;
- long linktype;
+ gchar *property_string, *next;
+ long property;
- if ((prefs.capture_devices_linktypes == NULL) ||
- (*prefs.capture_devices_linktypes == '\0')) {
- /* There are no link-layer header types */
+ property_string = capture_dev_get_if_property(pref, if_name);
+ if (property_string == NULL) {
+ /* No link-layer type found for this interface. */
return -1;
}
- tmpname = g_strdup_printf(",%s(", if_name);
- if ((p = strstr(prefs.capture_devices_linktypes, tmpname)) == NULL) {
- /* There are, but there isn't one for this interface. */
- return -1;
- }
-
- p += strlen(if_name) + 2;
- linktype = strtol(p, &next, 10);
- if (next == p || *next != ')' || linktype < 0) {
+ property = strtol(property_string, &next, 10);
+ if (next == property_string || *next != '\0' || property < 0) {
/* Syntax error */
+ g_free(property_string);
return -1;
}
- if (linktype > G_MAXINT) {
+ if (property > G_MAXINT) {
/* Value doesn't fit in a gint */
+ g_free(property_string);
return -1;
}
- return (gint)linktype;
+ g_free(property_string);
+ return (gint)property;
}
-#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-gint
-capture_dev_user_buffersize_find(const gchar *if_name)
+/*
+ * Find user-specified capture device description that matches interface
+ * name, if any.
+ */
+char *
+capture_dev_user_descr_find(const gchar *if_name)
{
- gchar *p, *next, *tmpname;
- gint buffersize;
-
- if ((prefs.capture_devices_buffersize == NULL) ||
- (*prefs.capture_devices_buffersize == '\0')) {
- /* There are no buffersizes defined */
- return -1;
- }
- tmpname = g_strdup_printf(",%s(", if_name);
- if ((p = strstr(prefs.capture_devices_buffersize, tmpname)) == NULL) {
- /* There are, but there isn't one for this interface. */
- return -1;
- }
-
- p += strlen(if_name) + 2;
- buffersize = (gint)strtol(p, &next, 10);
- if (next == p || *next != ')' || buffersize < 0) {
- /* Syntax error */
- return -1;
- }
- if (buffersize > G_MAXINT) {
- /* Value doesn't fit in a gint */
- return -1;
- }
-
- return (gint)buffersize;
+ return capture_dev_get_if_property(prefs.capture_devices_descr, if_name);
}
-#endif
gint
-capture_dev_user_snaplen_find(const gchar *if_name)
+capture_dev_user_linktype_find(const gchar *if_name)
{
- gchar *p, *next, *tmpname;
- gint snaplen;
-
- if ((prefs.capture_devices_snaplen == NULL) ||
- (*prefs.capture_devices_snaplen == '\0')) {
- /* There is no snap length defined */
- return -1;
- }
- tmpname = g_strdup_printf(",%s:", if_name);
- if ((p = strstr(prefs.capture_devices_snaplen, tmpname)) == NULL) {
- /* There are, but there isn't one for this interface. */
- return -1;
- }
-
- p += strlen(if_name) + 4;
- snaplen = (gint)strtol(p, &next, 10);
- if (next == p || *next != ')' || snaplen < 0) {
- /* Syntax error */
- return -1;
- }
- if (snaplen > WTAP_MAX_PACKET_SIZE) {
- /* Value doesn't fit in a gint */
- return -1;
- }
+ return capture_dev_get_if_int_property(prefs.capture_devices_linktypes, if_name);
+}
- return (gint)snaplen;
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+gint
+capture_dev_user_buffersize_find(const gchar *if_name)
+{
+ return capture_dev_get_if_int_property(prefs.capture_devices_buffersize, if_name);
}
+#endif
gboolean
-capture_dev_user_hassnap_find(const gchar *if_name)
+capture_dev_user_snaplen_find(const gchar *if_name, gboolean *hassnap, int *snaplen)
{
- gchar *p, *next, *tmpname;
- gboolean hassnap;
+ gboolean found = FALSE;
+ gchar **if_tokens;
+ int i;
+
+ if (if_name == NULL || strlen(if_name) < 1) {
+ return FALSE;
+ }
if ((prefs.capture_devices_snaplen == NULL) ||
(*prefs.capture_devices_snaplen == '\0')) {
- /* There is no snap length defined */
- return -1;
- }
- tmpname = g_strdup_printf(",%s:", if_name);
- if ((p = strstr(prefs.capture_devices_snaplen, tmpname)) == NULL) {
- /* There are, but there isn't one for this interface. */
- return -1;
+ /* There are no snap lengths defined */
+ return FALSE;
}
- p += strlen(if_name) + 2;
- hassnap = (gboolean)strtol(p, &next, 10);
- if (next == p || *next != '(') {
- /* Syntax error */
- return -1;
+ /*
+ * Split the list into a sequence of items.
+ *
+ * XXX - this relies on the items not themselves containing commas.
+ */
+ if_tokens = g_strsplit(prefs.capture_devices_snaplen, ",", -1);
+ for (i = 0; if_tokens[i] != NULL; i++) {
+ gchar *colonp, *next;
+ long value;
+
+ /*
+ * This one's a bit ugly.
+ * The syntax of the item is {name}:{hassnap}({snaplen}),
+ * where {hassnap} is 0 if the interface shouldn't have a snapshot
+ * length and 1 if it should, and {snaplen} is the maximum snapshot
+ * length if {hassnap} is 0 and the specified snapshot length if
+ * {hassnap} is 1.
+ *
+ * Sadly, : was a bad choice of separator, given that, on some OSes,
+ * an interface can have a colon in its name.
+ *
+ * So we look for the *last* colon in the string.
+ */
+ colonp = strrchr(if_tokens[i], ':');
+ if (colonp == NULL) {
+ /* No separating colon. Give up. */
+ break;
+ }
+ *colonp = '\0'; /* Split {name} from what follows */
+ if (strcmp(if_tokens[i], if_name) == 0) {
+ /* OK, this matches. */
+ if (*(colonp + 1) == '0') {
+ /* {hassnap} is false, so just set the snaplen to WTAP_MAX_PACKET_SIZE. */
+ found = TRUE;
+ *hassnap = FALSE;
+ *snaplen = WTAP_MAX_PACKET_SIZE;
+ } else if (*(colonp + 1) == '1') {
+ /* {hassnap} is true, so extract {snaplen} */
+ if (*(colonp + 2) != '(') {
+ /* Not followed by a parenthesis. Give up. */
+ break;
+ }
+ value = strtol(colonp + 3, &next, 10);
+ if (next == colonp + 3 || *next != ')' || value < 0) {
+ /* Syntax error. Give up. */
+ break;
+ }
+ if (value > G_MAXINT) {
+ /* Value doesn't fit in a gint. Give up. */
+ break;
+ }
+ found = TRUE;
+ *hassnap = TRUE;
+ *snaplen = (gint)value;
+ } else {
+ /* Bad {hassnap}. Give up. */
+ break;
+ }
+ break;
+ }
}
+ g_strfreev(if_tokens);
- return (gboolean)hassnap;
+ return found;
}
gboolean
capture_dev_user_pmode_find(const gchar *if_name)
{
- gchar *p, *next, *tmpname;
- gboolean pmode;
-
- if ((prefs.capture_devices_pmode == NULL) ||
- (*prefs.capture_devices_pmode == '\0')) {
- /* There is no promiscuous mode defined */
- return -1;
- }
- tmpname = g_strdup_printf(",%s(", if_name);
- if ((p = strstr(prefs.capture_devices_pmode, tmpname)) == NULL) {
- /* There are, but there isn't one for this interface. */
- return -1;
- }
-
- p += strlen(if_name) + 2;
- pmode = (gboolean)strtol(p, &next, 10);
- if (next == p || *next != ')') {
- /* Syntax error */
- return -1;
- }
- return (gboolean)pmode;
+ return (capture_dev_get_if_int_property(prefs.capture_devices_pmode, if_name) != 0);
}
gchar*
capture_dev_user_cfilter_find(const gchar *if_name)
{
- gchar *p, q[MAX_VAL_LEN], *tmpname;
- int i = 0;
-
- if ((prefs.capture_devices_filter == NULL) ||
- (*prefs.capture_devices_filter == '\0')) {
- /* There is no capture filter defined */
- return NULL;
- }
- tmpname = g_strdup_printf(",%s(", if_name);
- if ((p = strstr(prefs.capture_devices_filter, tmpname)) == NULL) {
- /* There are, but there isn't one for this interface. */
- return NULL;
- }
-
- p += strlen(if_name) + 2;
- while (p[i+1] != ',' && p[i+1] != '\0') {
- q[i] = p[i];
- i++;
- }
- q[i] = '\0';
- return g_strdup(q);
+ return capture_dev_get_if_property(prefs.capture_devices_filter, if_name);
}
/*