summaryrefslogtreecommitdiff
path: root/epan
diff options
context:
space:
mode:
authorBinh Trinh <beango@gmail.com>2016-09-13 00:46:06 -0400
committerAnders Broman <a.broman58@gmail.com>2016-10-12 21:34:42 +0000
commit5ace3b9405e4845ad7df1a3b2966af7bca6c2194 (patch)
treebf6282ff95f812bdc5c6059d223bc970cdffc19e /epan
parent04143d1100342353c95c87dcaaa8d82258c25ec3 (diff)
downloadwireshark-5ace3b9405e4845ad7df1a3b2966af7bca6c2194.tar.gz
MTP3: Added SS7 Point Code Name Resolution
bug: 7592 Change-Id: I1af2c5d6664e172c358cd19bc20e9352c2582eae Reviewed-on: https://code.wireshark.org/review/17677 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan')
-rw-r--r--epan/addr_resolv.c170
-rw-r--r--epan/addr_resolv.h9
-rw-r--r--epan/dissectors/packet-mtp3.c30
3 files changed, 207 insertions, 2 deletions
diff --git a/epan/addr_resolv.c b/epan/addr_resolv.c
index 13b2ebb74c..90afb8be9b 100644
--- a/epan/addr_resolv.c
+++ b/epan/addr_resolv.c
@@ -117,6 +117,7 @@
#define ENAME_MANUF "manuf"
#define ENAME_SERVICES "services"
#define ENAME_VLANS "vlans"
+#define ENAME_SS7PCS "ss7pcs"
#define HASHETHSIZE 2048
#define HASHHOSTSIZE 2048
@@ -161,6 +162,12 @@ typedef struct hashvlan {
gchar name[MAXVLANNAMELEN];
} hashvlan_t;
+typedef struct ss7pc {
+ guint32 id; /* 1st byte NI, 3 following bytes: Point Code */
+ gchar pc_addr[MAXNAMELEN];
+ gchar name[MAXNAMELEN];
+} hashss7pc_t;
+
/* hash tables used for ethernet and manufacturer lookup */
#define HASHETHER_STATUS_UNRESOLVED 1
#define HASHETHER_STATUS_RESOLVED_DUMMY 2
@@ -205,6 +212,7 @@ static wmem_map_t *ipxnet_hash_table = NULL;
static wmem_map_t *ipv4_hash_table = NULL;
static wmem_map_t *ipv6_hash_table = NULL;
static wmem_map_t *vlan_hash_table = NULL;
+static wmem_map_t *ss7pc_hash_table = NULL;
static wmem_list_t *manually_resolved_ipv4_list = NULL;
static wmem_list_t *manually_resolved_ipv6_list = NULL;
@@ -288,7 +296,8 @@ e_addr_resolve gbl_resolv_flags = {
TRUE, /* dns_pkt_addr_resolution */
TRUE, /* use_external_net_name_resolver */
FALSE, /* load_hosts_file_from_profile_only */
- FALSE /* vlan_name */
+ FALSE, /* vlan_name */
+ FALSE /* ss7 point code names */
};
#ifdef HAVE_C_ARES
static guint name_resolve_concurrency = 500;
@@ -307,6 +316,7 @@ 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 */
+gchar *g_ss7pcs_path = NULL; /* personal ss7pcs file */
/* first resolving call */
/* c-ares */
@@ -2306,6 +2316,151 @@ subnet_name_lookup_init(void)
g_free(subnetspath);
}
+/* SS7 PC Name Resolution Portion */
+static hashss7pc_t *
+new_ss7pc(const guint8 ni, const guint32 pc)
+{
+ hashss7pc_t *tp = wmem_new(wmem_epan_scope(), hashss7pc_t);
+ tp->id = (ni<<24) + (pc&0xffffff);
+ tp->pc_addr[0] = '\0';
+ tp->name[0] = '\0';
+
+ return tp;
+}
+
+static hashss7pc_t *
+host_lookup_ss7pc(const guint8 ni, const guint32 pc)
+{
+ hashss7pc_t * volatile tp;
+ guint32 id;
+
+ id = (ni<<24) + (pc&0xffffff);
+
+ tp = (hashss7pc_t *)wmem_map_lookup(ss7pc_hash_table, GUINT_TO_POINTER(id));
+ if (tp == NULL) {
+ tp = new_ss7pc(ni, pc);
+ wmem_map_insert(ss7pc_hash_table, GUINT_TO_POINTER(id), tp);
+ }
+
+ return tp;
+}
+
+void fill_unresolved_ss7pc(const gchar * pc_addr, const guint8 ni, const guint32 pc)
+{
+ hashss7pc_t *tp = host_lookup_ss7pc(ni, pc);
+
+ g_strlcpy(tp->pc_addr, pc_addr, MAXNAMELEN);
+}
+
+const gchar *
+get_hostname_ss7pc(const guint8 ni, const guint32 pc)
+{
+ hashss7pc_t *tp = host_lookup_ss7pc(ni, pc);
+
+ /* never resolved yet*/
+ if (tp->pc_addr[0] == '\0')
+ return tp->pc_addr;
+
+ /* Don't have name in file */
+ if (tp->name[0] == '\0')
+ return tp->pc_addr;
+
+ if (!gbl_resolv_flags.ss7pc_name)
+ return tp->pc_addr;
+
+ return tp->name;
+}
+
+void
+add_ss7pc_name(const guint8 ni, guint32 pc, const gchar *name)
+{
+ hashss7pc_t *tp;
+ guint32 id;
+
+ if (!name || name[0] == '\0')
+ return;
+
+ id = (ni<<24) + (pc&0xffffff);
+ tp = (hashss7pc_t *)wmem_map_lookup(ss7pc_hash_table, GUINT_TO_POINTER(id));
+ if (!tp) {
+ tp = new_ss7pc(ni, pc);
+ wmem_map_insert(ss7pc_hash_table, GUINT_TO_POINTER(id), tp);
+ }
+
+ if (g_ascii_strcasecmp(tp->name, name)) {
+ g_strlcpy(tp->name, name, MAXNAMELEN);
+ }
+}
+
+static gboolean
+read_ss7pcs_file(const char *ss7pcspath)
+{
+ FILE *hf;
+ char *line = NULL;
+ int size = 0;
+ gchar *cp;
+ guint8 ni;
+ guint32 pc;
+ gboolean entry_found = FALSE;
+
+ /*
+ * File format is Network Indicator (decimal)<dash>Point Code (Decimal)<tab/space>Hostname
+ */
+ if ((hf = ws_fopen(ss7pcspath, "r")) == NULL)
+ return FALSE;
+
+ while (fgetline(&line, &size, hf) >= 0) {
+ if ((cp = strchr(line, '#')))
+ *cp = '\0';
+
+ if ((cp = strtok(line, "-")) == NULL)
+ continue; /*no ni-pc separator*/
+ if (!ws_strtou8(cp, NULL, &ni))
+ continue;
+ if (ni > 3)
+ continue;
+
+ if ((cp = strtok(NULL, " \t")) == NULL)
+ continue; /* no tokens for pc and name */
+ if (!ws_strtou32(cp, NULL, &pc))
+ continue;
+ if (pc >> 24 > 0)
+ continue;
+
+ if ((cp = strtok(NULL, " \t")) == NULL)
+ continue; /* no host name */
+
+ entry_found = TRUE;
+ add_ss7pc_name(ni, pc, cp);
+ }
+ wmem_free(wmem_epan_scope(), line);
+
+ fclose(hf);
+ return entry_found ? TRUE : FALSE;
+}
+
+void
+ss7pc_name_lookup_init(void)
+{
+ char *ss7pcspath;
+
+ g_assert(ss7pc_hash_table == NULL);
+
+ ss7pc_hash_table = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
+
+ /*
+ * Load the user's ss7pcs file
+ */
+ ss7pcspath = get_persconffile_path(ENAME_SS7PCS, TRUE);
+ if (!read_ss7pcs_file(ss7pcspath) && errno != ENOENT) {
+ report_open_failure(ss7pcspath, errno, FALSE);
+ }
+ g_free(ss7pcspath);
+}
+
+/* SS7PC Name Resolution End*/
+
+
/*
* External Functions
*/
@@ -2377,6 +2532,15 @@ addr_resolve_pref_init(module_t *nameres)
" One line per VLAN.",
&gbl_resolv_flags.vlan_name);
+ prefs_register_bool_preference(nameres, "ss7_pc_name",
+ "Resolve SS7 PC",
+ "Resolve SS7 Point Codes to describing names."
+ " To do so you need a file called ss7pcs in your"
+ " user preference directory. Format of the file is:"
+ " \"Network_Indicator<Dash>PC_Decimal<Tab>Name\""
+ " One line per Point Code. e.g.: 2-1234 MyPointCode1",
+ &gbl_resolv_flags.ss7pc_name);
+
}
void
@@ -2387,6 +2551,7 @@ disable_name_resolution(void) {
gbl_resolv_flags.dns_pkt_addr_resolution = FALSE;
gbl_resolv_flags.use_external_net_name_resolver = FALSE;
gbl_resolv_flags.vlan_name = FALSE;
+ gbl_resolv_flags.ss7pc_name = FALSE;
}
#ifdef HAVE_C_ARES
@@ -2653,6 +2818,8 @@ host_name_lookup_init(void)
subnet_name_lookup_init();
add_manually_resolved();
+
+ ss7pc_name_lookup_init();
}
void
@@ -2666,6 +2833,7 @@ host_name_lookup_cleanup(void)
ipxnet_hash_table = NULL;
ipv4_hash_table = NULL;
ipv6_hash_table = NULL;
+ ss7pc_hash_table = NULL;
for(i = 0; i < SUBNETLENGTHSIZE; ++i) {
if (subnet_length_entries[i].subnet_addresses != NULL) {
diff --git a/epan/addr_resolv.h b/epan/addr_resolv.h
index cb8c3291d0..38827c442e 100644
--- a/epan/addr_resolv.h
+++ b/epan/addr_resolv.h
@@ -62,6 +62,7 @@ typedef struct _e_addr_resolve {
gboolean use_external_net_name_resolver; /**< Whether to system's configured DNS server to resolve names */
gboolean load_hosts_file_from_profile_only; /**< Whether to only load the hosts in the current profile, not hosts files */
gboolean vlan_name; /**< Whether to resolve VLAN IDs to names */
+ gboolean ss7pc_name; /**< Whether to resolve SS7 Point Codes to names */
} e_addr_resolve;
#define ADDR_RESOLV_MACADDR(at) \
@@ -192,6 +193,14 @@ WS_DLL_PUBLIC const gchar *get_hostname6(const struct e_in6_addr *ad);
"%02x:%02x:%02x:%02x:%02x:%02x" */
WS_DLL_PUBLIC const gchar *get_ether_name(const guint8 *addr);
+/* get_hostname_ss7pc returns the logical name if found in ss7pcs file else
+ '\0' on the first call or the unresolved Point Code in the subsequent calls */
+const gchar *get_hostname_ss7pc(const guint8 ni, const guint32 pc);
+
+/* fill_unresolved_ss7pc initializes the unresolved Point Code Address string in the hashtable */
+void fill_unresolved_ss7pc(const gchar * pc_addr, const guint8 ni, const guint32 pc);
+
+
/* Same as get_ether_name with tvb support */
WS_DLL_PUBLIC const gchar *tvb_get_ether_name(tvbuff_t *tvb, gint offset);
diff --git a/epan/dissectors/packet-mtp3.c b/epan/dissectors/packet-mtp3.c
index dc12d27376..a826180eb6 100644
--- a/epan/dissectors/packet-mtp3.c
+++ b/epan/dissectors/packet-mtp3.c
@@ -43,6 +43,7 @@
#include <epan/prefs.h>
#include <epan/address_types.h>
#include <wiretap/wtap.h>
+#include <epan/addr_resolv.h>
#include "packet-q708.h"
#include "packet-sccp.h"
@@ -424,6 +425,33 @@ int mtp3_addr_len(void)
return sizeof(mtp3_addr_pc_t);
}
+static const gchar* mtp3_addr_name_res_str(const address* addr)
+{
+ const mtp3_addr_pc_t *mtp3_addr = (const mtp3_addr_pc_t *)addr->data;
+ const gchar *tmp;
+
+ tmp = get_hostname_ss7pc(mtp3_addr->ni, mtp3_addr->pc);
+
+ if (tmp[0] == '\0') {
+ gchar* str;
+ str = (gchar *)wmem_alloc(NULL, MAXNAMELEN);
+ mtp3_addr_to_str_buf(mtp3_addr, str, MAXNAMELEN);
+ fill_unresolved_ss7pc(str, mtp3_addr->ni, mtp3_addr->pc);
+ wmem_free(NULL, str);
+ return get_hostname_ss7pc(mtp3_addr->ni, mtp3_addr->pc);
+ }
+ return tmp;
+
+}
+
+static int mtp3_addr_name_res_len(void)
+{
+ return MAXNAMELEN;
+}
+
+
+
+
/* Common function for dissecting 3-byte (ANSI or China) PCs. */
void
dissect_mtp3_3byte_pc(tvbuff_t *tvb, guint offset, proto_tree *tree, gint ett_pc, int hf_pc_string, int hf_pc_network,
@@ -1078,7 +1106,7 @@ proto_register_mtp3(void)
proto_mtp3, FT_UINT8, BASE_HEX);
mtp3_address_type = address_type_dissector_register("AT_SS7PC", "SS7 Point Code", mtp3_addr_to_str, mtp3_str_addr_len, NULL, NULL,
- mtp3_addr_len, NULL, NULL);
+ mtp3_addr_len, mtp3_addr_name_res_str, mtp3_addr_name_res_len);
mtp3_tap = register_tap("mtp3");