aboutsummaryrefslogtreecommitdiffstats
path: root/epan/addr_resolv.c
diff options
context:
space:
mode:
authorUli Heilmeier <uh@heilmeier.eu>2016-03-13 23:16:20 +0100
committerAlexis La Goutte <alexis.lagoutte@gmail.com>2016-03-18 05:41:36 +0000
commite1d54cfc3e8223bb4334e5aeed019dab35528e9b (patch)
treeab97ecbc78feb49dcd60f7b0bc053ac1954dfe5f /epan/addr_resolv.c
parenteb6abe3a75f80776865332d4c28977a348b09a52 (diff)
IEEE 802.1Q/VLAN: Resolve ID to a describing name
A vlans file in the personal preference directory add an option to resolve VLAN IDs to a describing name. Format of vlan file is 123\tName of VLAN To enable the resolving the preference nameres.vlan_name must be set to TRUE. Bug: 11209 Change-Id: I3f00b4897aace89c03c57b68b6c4b6c8b7d4685a Reviewed-on: https://code.wireshark.org/review/14471 Reviewed-by: Michael Mann <mmann78@netscape.net> Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Diffstat (limited to 'epan/addr_resolv.c')
-rw-r--r--epan/addr_resolv.c199
1 files changed, 198 insertions, 1 deletions
diff --git a/epan/addr_resolv.c b/epan/addr_resolv.c
index db96820a17..f1c3d79335 100644
--- a/epan/addr_resolv.c
+++ b/epan/addr_resolv.c
@@ -3,6 +3,9 @@
*
* Laurent Deniel <laurent.deniel@free.fr>
*
+ * Add option to resolv VLAN ID to describing name
+ * Uli Heilmeier, March 2016
+ *
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
@@ -125,6 +128,7 @@
#define ENAME_IPXNETS "ipxnets"
#define ENAME_MANUF "manuf"
#define ENAME_SERVICES "services"
+#define ENAME_VLANS "vlans"
#define HASHETHSIZE 2048
#define HASHHOSTSIZE 2048
@@ -164,6 +168,12 @@ typedef struct hashipxnet {
gchar name[MAXNAMELEN];
} hashipxnet_t;
+typedef struct hashvlan {
+ guint id;
+/* struct hashvlan *next; */
+ gchar name[MAXVLANNAMELEN];
+} hashvlan_t;
+
/* hash tables used for ethernet and manufacturer lookup */
#define HASHETHER_STATUS_UNRESOLVED 1
#define HASHETHER_STATUS_RESOLVED_DUMMY 2
@@ -197,9 +207,17 @@ typedef struct _ipxnet
char name[MAXNAMELEN];
} ipxnet_t;
+/* internal vlan type */
+typedef struct _vlan
+{
+ guint id;
+ char name[MAXVLANNAMELEN];
+} vlan_t;
+
static GHashTable *ipxnet_hash_table = NULL;
static GHashTable *ipv4_hash_table = NULL;
static GHashTable *ipv6_hash_table = NULL;
+static GHashTable *vlan_hash_table = NULL;
static GSList *manually_resolved_ipv4_list = NULL;
static GSList *manually_resolved_ipv6_list = NULL;
@@ -283,7 +301,8 @@ e_addr_resolve gbl_resolv_flags = {
TRUE, /* concurrent_dns */
TRUE, /* dns_pkt_addr_resolution */
TRUE, /* use_external_net_name_resolver */
- FALSE /* load_hosts_file_from_profile_only */
+ FALSE, /* load_hosts_file_from_profile_only */
+ FALSE /* vlan_name */
};
#if defined(HAVE_C_ARES) || defined(HAVE_GNU_ADNS)
static guint name_resolve_concurrency = 500;
@@ -301,6 +320,7 @@ gchar *g_ipxnets_path = NULL; /* global ipxnets file */
gchar *g_pipxnets_path = NULL; /* personal ipxnets file */
gchar *g_services_path = NULL; /* global services file */
gchar *g_pservices_path = NULL; /* personal services file */
+gchar *g_pvlan_path = NULL; /* personal vlans file */
/* first resolving call */
/* c-ares */
@@ -1947,6 +1967,153 @@ ipxnet_addr_lookup(const gchar *name _U_, gboolean *success)
#endif
} /* ipxnet_addr_lookup */
+/* VLANS */
+static int
+parse_vlan_line(char *line, vlan_t *vlan)
+{
+ gchar *cp;
+ guint16 id;
+
+ if ((cp = strchr(line, '#')))
+ *cp = '\0';
+
+ if ((cp = strtok(line, " \t\n")) == NULL)
+ return -1;
+
+ if (sscanf(cp, "%" G_GUINT16_FORMAT, &id) == 1) {
+ vlan->id = id;
+ }
+ else {
+ return -1;
+ }
+
+ if ((cp = strtok(NULL, "\t\n")) == NULL)
+ return -1;
+
+ g_strlcpy(vlan->name, cp, MAXVLANNAMELEN);
+
+ return 0;
+
+} /* parse_vlan_line */
+
+static FILE *vlan_p = NULL;
+
+static void
+set_vlanent(char *path)
+{
+ if (vlan_p)
+ rewind(vlan_p);
+ else
+ vlan_p = ws_fopen(path, "r");
+}
+
+static void
+end_vlanent(void)
+{
+ if (vlan_p) {
+ fclose(vlan_p);
+ vlan_p = NULL;
+ }
+}
+
+static vlan_t *
+get_vlanent(void)
+{
+
+ static vlan_t vlan;
+ static int size = 0;
+ static char *buf = NULL;
+
+ if (vlan_p == NULL)
+ return NULL;
+
+ while (fgetline(&buf, &size, vlan_p) >= 0) {
+ if (parse_vlan_line(buf, &vlan) == 0) {
+ return &vlan;
+ }
+ }
+
+ return NULL;
+
+} /* get_vlanent */
+
+static vlan_t *
+get_vlannamebyid(guint16 id)
+{
+ vlan_t *vlan;
+
+ set_vlanent(g_pvlan_path);
+
+ while (((vlan = get_vlanent()) != NULL) && (id != vlan->id) ) ;
+
+ if (vlan == NULL) {
+ end_vlanent();
+
+ }
+
+ return vlan;
+
+} /* get_vlannamebyid */
+
+static void
+initialize_vlans(void)
+{
+ g_assert(vlan_hash_table == NULL);
+ vlan_hash_table = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
+
+ /* Set g_pipxnets_path here, but don't actually do anything
+ * with it. It's used in get_ipxnetbyname() and get_ipxnetbyaddr()
+ */
+ if (g_pvlan_path == NULL)
+ g_pvlan_path = get_persconffile_path(ENAME_VLANS, FALSE);
+
+} /* initialize_vlans */
+
+static void
+vlan_name_lookup_cleanup(void)
+{
+ if (vlan_hash_table) {
+ g_hash_table_destroy(vlan_hash_table);
+ vlan_hash_table = NULL;
+ }
+
+}
+
+static const gchar *
+vlan_name_lookup(const guint id)
+{
+ hashvlan_t *tp;
+ vlan_t *vlan;
+
+ tp = (hashvlan_t *)g_hash_table_lookup(vlan_hash_table, &id);
+ if (tp == NULL) {
+ int *key;
+
+ key = (int *)g_new(int, 1);
+ *key = id;
+ tp = g_new(hashvlan_t, 1);
+ g_hash_table_insert(vlan_hash_table, key, tp);
+ } else {
+ return tp->name;
+ }
+
+ /* fill in a new entry */
+
+ tp->id = id;
+
+ if ( (vlan = get_vlannamebyid(id)) == NULL) {
+ /* unknown name */
+ g_snprintf(tp->name, MAXVLANNAMELEN, "<%u>", id);
+
+ } else {
+ g_strlcpy(tp->name, vlan->name, MAXVLANNAMELEN);
+ }
+
+ return tp->name;
+
+} /* vlan_name_lookup */
+/* VLAN END */
+
static gboolean
read_hosts_file (const char *hostspath, gboolean store_entries)
{
@@ -2374,6 +2541,15 @@ addr_resolve_pref_init(module_t *nameres)
" Checking this box only loads the \"hosts\" in the current profile.",
&gbl_resolv_flags.load_hosts_file_from_profile_only);
+ prefs_register_bool_preference(nameres, "vlan_name",
+ "Resolve VLAN IDs",
+ "Resolve VLAN IDs to describing names."
+ " To do so you need a file called vlans in your"
+ " user preference directory. Format of the file is:"
+ " \"ID<Tab>Name\""
+ " One line per VLAN.",
+ &gbl_resolv_flags.vlan_name);
+
}
void
@@ -2384,6 +2560,7 @@ disable_name_resolution(void) {
gbl_resolv_flags.concurrent_dns = FALSE;
gbl_resolv_flags.dns_pkt_addr_resolution = FALSE;
gbl_resolv_flags.use_external_net_name_resolver = FALSE;
+ gbl_resolv_flags.vlan_name = FALSE;
}
#ifdef HAVE_C_ARES
@@ -3045,6 +3222,18 @@ get_ipxnet_addr(const gchar *name, gboolean *known)
} /* get_ipxnet_addr */
+gchar *
+get_vlan_name(wmem_allocator_t *allocator, const guint16 id)
+{
+
+ if (!gbl_resolv_flags.vlan_name) {
+ return NULL;
+ }
+
+ return wmem_strdup(allocator, vlan_name_lookup(id));
+
+} /* get_vlan_name */
+
const gchar *
get_manuf_name(const guint8 *addr)
{
@@ -3434,6 +3623,12 @@ get_ipxnet_hash_table(void)
}
GHashTable *
+get_vlan_hash_table(void)
+{
+ return vlan_hash_table;
+}
+
+GHashTable *
get_ipv4_hash_table(void)
{
return ipv4_hash_table;
@@ -3451,6 +3646,7 @@ addr_resolv_init(void)
initialize_services();
initialize_ethers();
initialize_ipxnets();
+ initialize_vlans();
/* host name initialization is done on a per-capture-file basis */
/*host_name_lookup_init();*/
}
@@ -3462,6 +3658,7 @@ addr_resolv_cleanup(void)
service_name_lookup_cleanup();
eth_name_lookup_cleanup();
ipx_name_lookup_cleanup();
+ vlan_name_lookup_cleanup();
/* host name initialization is done on a per-capture-file basis */
/*host_name_lookup_cleanup();*/
}