summaryrefslogtreecommitdiffstats
path: root/epan/addr_resolv.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/addr_resolv.c')
-rw-r--r--epan/addr_resolv.c1523
1 files changed, 911 insertions, 612 deletions
diff --git a/epan/addr_resolv.c b/epan/addr_resolv.c
index e5535069..5a37c200 100644
--- a/epan/addr_resolv.c
+++ b/epan/addr_resolv.c
@@ -82,15 +82,13 @@
#include <glib.h>
#include "packet.h"
-#include "addr_and_mask.h"
-#include "ipv6.h"
#include "addr_resolv.h"
#include "wsutil/filesystem.h"
#include <wsutil/report_message.h>
#include <wsutil/file_util.h>
#include <wsutil/pint.h>
-#include <wsutil/inet_addr.h>
+#include <wsutil/inet_cidr.h>
#include <epan/strutil.h>
#include <epan/to_str.h>
@@ -121,17 +119,17 @@
typedef struct sub_net_hashipv4 {
- guint addr;
+ unsigned addr;
/* XXX: No longer needed?*/
- guint8 flags; /* B0 dummy_entry, B1 resolve, B2 If the address is used in the trace */
+ uint8_t flags; /* B0 dummy_entry, B1 resolve, B2 If the address is used in the trace */
struct sub_net_hashipv4 *next;
- gchar name[MAXNAMELEN];
+ char name[MAXNAMELEN];
} sub_net_hashipv4_t;
/* Array of entries of subnets of different lengths */
typedef struct {
- gsize mask_length; /*1-32*/
- guint32 mask; /* e.g. 255.255.255.*/
+ size_t mask_length; /*1-32*/
+ uint32_t mask; /* e.g. 255.255.255.*/
sub_net_hashipv4_t** subnet_addresses; /* Hash table of subnet addresses */
} subnet_length_entry_t;
@@ -143,38 +141,39 @@ typedef struct {
#define HASH_IPX_NET(net) ((net) & (HASHIPXNETSIZE - 1))
typedef struct hashipxnet {
- guint addr;
+ unsigned addr;
struct hashipxnet *next;
- gchar name[MAXNAMELEN];
+ char name[MAXNAMELEN];
} hashipxnet_t;
typedef struct hashvlan {
- guint id;
+ unsigned id;
/* struct hashvlan *next; */
- gchar name[MAXVLANNAMELEN];
+ char name[MAXVLANNAMELEN];
} hashvlan_t;
typedef struct ss7pc {
- guint32 id; /* 1st byte NI, 3 following bytes: Point Code */
- gchar pc_addr[MAXNAMELEN];
- gchar name[MAXNAMELEN];
+ uint32_t id; /* 1st byte NI, 3 following bytes: Point Code */
+ char pc_addr[MAXNAMELEN];
+ char name[MAXNAMELEN];
} hashss7pc_t;
/* hash tables used for ethernet and manufacturer lookup */
-#define HASHETHER_STATUS_UNRESOLVED 1
-#define HASHETHER_STATUS_RESOLVED_DUMMY 2
-#define HASHETHER_STATUS_RESOLVED_NAME 3
-
struct hashether {
- guint status; /* (See above) */
- guint8 addr[6];
+ uint8_t flags; /* (See above) */
+ uint8_t addr[6];
char hexaddr[6*3];
char resolved_name[MAXNAMELEN];
};
+struct hashwka {
+ uint8_t flags; /* (See above) */
+ char* name;
+};
+
struct hashmanuf {
- guint status; /* (See above) */
- guint8 addr[3];
+ uint8_t flags; /* (See above) */
+ uint8_t addr[3];
char hexaddr[3*3];
char resolved_name[MAXNAMELEN];
char resolved_longname[MAXNAMELEN];
@@ -183,7 +182,7 @@ struct hashmanuf {
/* internal ethernet type */
typedef struct _ether
{
- guint8 addr[6];
+ uint8_t addr[6];
char name[MAXNAMELEN];
char longname[MAXNAMELEN];
} ether_t;
@@ -191,67 +190,79 @@ typedef struct _ether
/* internal ipxnet type */
typedef struct _ipxnet
{
- guint addr;
+ unsigned addr;
char name[MAXNAMELEN];
} ipxnet_t;
/* internal vlan type */
typedef struct _vlan
{
- guint id;
+ unsigned id;
char name[MAXVLANNAMELEN];
} vlan_t;
-static wmem_allocator_t *addr_resolv_scope = NULL;
+/* internal services custom type */
+typedef struct _serv_port_custom_key {
+ uint16_t port;
+ port_type type;
+} serv_port_custom_key_t;
-// Maps guint -> hashipxnet_t*
-static wmem_map_t *ipxnet_hash_table = NULL;
-static wmem_map_t *ipv4_hash_table = NULL;
-static wmem_map_t *ipv6_hash_table = NULL;
-// Maps guint -> hashvlan_t*
-static wmem_map_t *vlan_hash_table = NULL;
-static wmem_map_t *ss7pc_hash_table = NULL;
+static wmem_allocator_t *addr_resolv_scope;
+
+// Maps unsigned -> hashipxnet_t*
+static wmem_map_t *ipxnet_hash_table;
+static wmem_map_t *ipv4_hash_table;
+static wmem_map_t *ipv6_hash_table;
+// Maps unsigned -> hashvlan_t*
+static wmem_map_t *vlan_hash_table;
+static wmem_map_t *ss7pc_hash_table;
// Maps IP address -> manually set hostname.
-static wmem_map_t *manually_resolved_ipv4_list = NULL;
-static wmem_map_t *manually_resolved_ipv6_list = NULL;
+static wmem_map_t *manually_resolved_ipv4_list;
+static wmem_map_t *manually_resolved_ipv6_list;
-static addrinfo_lists_t addrinfo_lists = { NULL, NULL};
+static addrinfo_lists_t addrinfo_lists;
struct cb_serv_data {
- gchar *service;
+ char *service;
port_type proto;
};
-// Maps guint -> hashmanuf_t*
-static wmem_map_t *manuf_hashtable = NULL;
-static wmem_map_t *wka_hashtable = NULL;
-static wmem_map_t *eth_hashtable = NULL;
-// Maps guint -> serv_port_t*
-static wmem_map_t *serv_port_hashtable = NULL;
+// Maps unsigned -> hashmanuf_t*
+// XXX: Note that hashmanuf_t* only accommodates 24-bit OUIs.
+// We might want to store vendor names from MA-M and MA-S to
+// present in the Resolved Addresses dialog.
+static wmem_map_t *manuf_hashtable;
+// Maps address -> hashwka_t*
+static wmem_map_t *wka_hashtable;
+// Maps address -> hashether_t*
+static wmem_map_t *eth_hashtable;
+// Maps unsigned -> serv_port_t*
+static wmem_map_t *serv_port_hashtable;
+static wmem_map_t *serv_port_custom_hashtable;
// Maps enterprise-id -> enterprise-desc (only used for user additions)
-static GHashTable *enterprises_hashtable = NULL;
+static GHashTable *enterprises_hashtable;
static subnet_length_entry_t subnet_length_entries[SUBNETLENGTHSIZE]; /* Ordered array of entries */
-static gboolean have_subnet_entry = FALSE;
+static bool have_subnet_entry;
-static gboolean new_resolved_objects = FALSE;
+static bool new_resolved_objects;
-static GPtrArray* extra_hosts_files = NULL;
+static GPtrArray* extra_hosts_files;
-static hashether_t *add_eth_name(const guint8 *addr, const gchar *name);
-static void add_serv_port_cb(const guint32 port, gpointer ptr);
+static hashether_t *add_eth_name(const uint8_t *addr, const char *name);
+static void add_serv_port_cb(const uint32_t port, void *ptr);
/* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx#existing
* One-at-a-Time hash
*/
-guint
-ipv6_oat_hash(gconstpointer key)
+unsigned
+ipv6_oat_hash(const void *key)
{
int len = 16;
const unsigned char *p = (const unsigned char *)key;
- guint h = 0;
+ unsigned h = 0;
int i;
for ( i = 0; i < len; i++ ) {
@@ -268,31 +279,36 @@ ipv6_oat_hash(gconstpointer key)
}
gboolean
-ipv6_equal(gconstpointer v1, gconstpointer v2)
+ipv6_equal(const void *v1, const void *v2)
{
if (memcmp(v1, v2, sizeof (ws_in6_addr)) == 0) {
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
/*
* Flag controlling what names to resolve.
*/
e_addr_resolve gbl_resolv_flags = {
- TRUE, /* mac_name */
- FALSE, /* network_name */
- FALSE, /* transport_name */
- TRUE, /* dns_pkt_addr_resolution */
- TRUE, /* use_external_net_name_resolver */
- FALSE, /* vlan_name */
- FALSE, /* ss7 point code names */
- TRUE, /* maxmind_geoip */
+ true, /* mac_name */
+ false, /* network_name */
+ false, /* transport_name */
+ true, /* dns_pkt_addr_resolution */
+ false, /* handshake_sni_addr_resolution */
+ true, /* use_external_net_name_resolver */
+ false, /* vlan_name */
+ false, /* ss7 point code names */
+ true, /* maxmind_geoip */
};
-static guint name_resolve_concurrency = 500;
-static gboolean resolve_synchronously = FALSE;
+
+/* XXX - ares_init_options(3) says:
+ * "The recommended concurrent query limit is about 32k queries"
+ */
+static unsigned name_resolve_concurrency = 500;
+static bool resolve_synchronously;
/*
* Global variables (can be changed in GUI sections)
@@ -300,19 +316,19 @@ static gboolean resolve_synchronously = FALSE;
* GUI code to change them.
*/
-gchar *g_ethers_path = NULL; /* global ethers file */
-gchar *g_pethers_path = NULL; /* personal ethers file */
-gchar *g_wka_path = NULL; /* global well-known-addresses file */
-gchar *g_manuf_path = NULL; /* global manuf file */
-gchar *g_pmanuf_path = NULL; /* personal manuf file */
-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 */
-gchar *g_ss7pcs_path = NULL; /* personal ss7pcs file */
-gchar *g_enterprises_path = NULL; /* global enterprises file */
-gchar *g_penterprises_path = NULL; /* personal enterprises file */
+char *g_ethers_path; /* global ethers file */
+char *g_pethers_path; /* personal ethers file */
+char *g_wka_path; /* global well-known-addresses file */
+char *g_manuf_path; /* global manuf file */
+char *g_pmanuf_path; /* personal manuf file */
+char *g_ipxnets_path; /* global ipxnets file */
+char *g_pipxnets_path; /* personal ipxnets file */
+char *g_services_path; /* global services file */
+char *g_pservices_path; /* personal services file */
+char *g_pvlan_path; /* personal vlans file */
+char *g_ss7pcs_path; /* personal ss7pcs file */
+char *g_enterprises_path; /* global enterprises file */
+char *g_penterprises_path; /* personal enterprises file */
/* first resolving call */
/*
@@ -325,7 +341,7 @@ gchar *g_penterprises_path = NULL; /* personal enterprises file */
typedef struct _async_dns_queue_msg
{
union {
- guint32 ip4;
+ uint32_t ip4;
ws_in6_addr ip6;
} addr;
int family;
@@ -337,43 +353,47 @@ typedef struct _async_hostent {
void *addrp;
} async_hostent_t;
+static void
+c_ares_ghba_cb(void *arg, int status, int timeouts _U_, struct hostent *he);
+
/*
* Submitted synchronous queries trigger a callback (c_ares_ghba_sync_cb()).
- * The callback processes the response, sets completed to TRUE if
+ * The callback processes the response, sets completed to true if
* completed is non-NULL, then frees the request.
*/
typedef struct _sync_dns_data
{
union {
- guint32 ip4;
+ uint32_t ip4;
ws_in6_addr ip6;
} addr;
int family;
- gboolean *completed;
+ bool *completed;
} sync_dns_data_t;
static ares_channel ghba_chan; /* ares_gethostbyaddr -- Usually non-interactive, no timeout */
static ares_channel ghbn_chan; /* ares_gethostbyname -- Usually interactive, timeout */
-static gboolean async_dns_initialized = FALSE;
-static guint async_dns_in_flight = 0;
-static wmem_list_t *async_dns_queue_head = NULL;
+static bool async_dns_initialized;
+static unsigned async_dns_in_flight;
+static wmem_list_t *async_dns_queue_head;
+static GMutex async_dns_queue_mtx;
//UAT for providing a list of DNS servers to C-ARES for name resolution
-gboolean use_custom_dns_server_list = FALSE;
+bool use_custom_dns_server_list;
struct dns_server_data {
char *ipaddr;
- guint32 udp_port;
- guint32 tcp_port;
+ uint32_t udp_port;
+ uint32_t tcp_port;
};
UAT_CSTRING_CB_DEF(dnsserverlist_uats, ipaddr, struct dns_server_data)
UAT_DEC_CB_DEF(dnsserverlist_uats, tcp_port, struct dns_server_data)
UAT_DEC_CB_DEF(dnsserverlist_uats, udp_port, struct dns_server_data)
-static uat_t *dnsserver_uat = NULL;
-static struct dns_server_data *dnsserverlist_uats = NULL;
-static guint ndnsservers = 0;
+static uat_t *dnsserver_uat;
+static struct dns_server_data *dnsserverlist_uats;
+static unsigned ndnsservers;
static void
dns_server_free_cb(void *data)
@@ -397,37 +417,37 @@ dns_server_copy_cb(void *dst_, const void *src_, size_t len _U_)
}
static bool
-dnsserver_uat_fld_ip_chk_cb(void* r _U_, const char* ipaddr, guint len _U_, const void* u1 _U_, const void* u2 _U_, char** err)
+dnsserver_uat_fld_ip_chk_cb(void* r _U_, const char* ipaddr, unsigned len _U_, const void* u1 _U_, const void* u2 _U_, char** err)
{
//Check for a valid IPv4 or IPv6 address.
if (ipaddr && g_hostname_is_ip_address(ipaddr)) {
*err = NULL;
- return TRUE;
+ return true;
}
*err = ws_strdup_printf("No valid IP address given.");
- return FALSE;
+ return false;
}
static bool
-dnsserver_uat_fld_port_chk_cb(void* r _U_, const char* p, guint len _U_, const void* u1 _U_, const void* u2 _U_, char** err)
+dnsserver_uat_fld_port_chk_cb(void* r _U_, const char* p, unsigned len _U_, const void* u1 _U_, const void* u2 _U_, char** err)
{
if (!p || strlen(p) == 0u) {
// This should be removed in favor of Decode As. Make it optional.
*err = NULL;
- return TRUE;
+ return true;
}
if (strcmp(p, "53") != 0){
- guint16 port;
+ uint16_t port;
if (!ws_strtou16(p, NULL, &port)) {
*err = g_strdup("Invalid port given.");
- return FALSE;
+ return false;
}
}
*err = NULL;
- return TRUE;
+ return true;
}
static void
@@ -439,10 +459,10 @@ c_ares_ghba_sync_cb(void *arg, int status, int timeouts _U_, struct hostent *he)
for (p = he->h_addr_list; *p != NULL; p++) {
switch(sdd->family) {
case AF_INET:
- add_ipv4_name(sdd->addr.ip4, he->h_name, FALSE);
+ add_ipv4_name(sdd->addr.ip4, he->h_name, false);
break;
case AF_INET6:
- add_ipv6_name(&sdd->addr.ip6, he->h_name, FALSE);
+ add_ipv6_name(&sdd->addr.ip6, he->h_name, false);
break;
default:
/* Throw an exception? */
@@ -455,7 +475,7 @@ c_ares_ghba_sync_cb(void *arg, int status, int timeouts _U_, struct hostent *he)
/*
* Let our caller know that this is complete.
*/
- *sdd->completed = TRUE;
+ *sdd->completed = true;
/*
* Free the structure for this call.
@@ -464,7 +484,7 @@ c_ares_ghba_sync_cb(void *arg, int status, int timeouts _U_, struct hostent *he)
}
static void
-wait_for_sync_resolv(gboolean *completed) {
+wait_for_sync_resolv(bool *completed) {
int nfds;
fd_set rfds, wfds;
struct timeval tv;
@@ -481,6 +501,9 @@ wait_for_sync_resolv(gboolean *completed) {
* calling ares_timeout() to figure out when to next call
* ares_process().", although we should have only one request
* outstanding.
+ * As of C-ARES 1.20.0, the ares_timeout() function is now O(1),
+ * but we don't require that minimum version.
+ * https://github.com/c-ares/c-ares/commit/cf99c025cfb3e21295b59923876a31a68ea2cb4b
*
* And, yes, we have to reset it each time, as select(), in
* some OSes modifies the timeout to reflect the time remaining
@@ -507,9 +530,91 @@ wait_for_sync_resolv(gboolean *completed) {
}
static void
-sync_lookup_ip4(const guint32 addr)
+process_async_dns_queue(void)
+{
+ wmem_list_frame_t* head;
+ async_dns_queue_msg_t *caqm;
+
+ if (async_dns_queue_head == NULL)
+ return;
+
+ if (!g_mutex_trylock(&async_dns_queue_mtx))
+ return;
+
+ head = wmem_list_head(async_dns_queue_head);
+
+ while (head != NULL && async_dns_in_flight <= name_resolve_concurrency) {
+ caqm = (async_dns_queue_msg_t *)wmem_list_frame_data(head);
+ wmem_list_remove_frame(async_dns_queue_head, head);
+ if (caqm->family == AF_INET) {
+ ares_gethostbyaddr(ghba_chan, &caqm->addr.ip4, sizeof(uint32_t), AF_INET,
+ c_ares_ghba_cb, caqm);
+ async_dns_in_flight++;
+ } else if (caqm->family == AF_INET6) {
+ ares_gethostbyaddr(ghba_chan, &caqm->addr.ip6, sizeof(ws_in6_addr),
+ AF_INET6, c_ares_ghba_cb, caqm);
+ async_dns_in_flight++;
+ }
+
+ head = wmem_list_head(async_dns_queue_head);
+ }
+
+ g_mutex_unlock(&async_dns_queue_mtx);
+}
+
+static void
+wait_for_async_queue(void)
+{
+ struct timeval tv = { 0, 0 };
+ int nfds;
+ fd_set rfds, wfds;
+
+ new_resolved_objects = false;
+
+ if (!async_dns_initialized) {
+ maxmind_db_lookup_process();
+ return;
+ }
+
+ while (1) {
+ /* We're switching to synchronous lookups, so process anything in
+ * the asynchronous queue. There might be more in the queue than
+ * name_resolve_concurrency allows, so check each cycle.
+ */
+ process_async_dns_queue();
+
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+ nfds = ares_fds(ghba_chan, &rfds, &wfds);
+ if (nfds == 0) {
+ /* No more requests waiting for reply; we're done here. */
+ break;
+ }
+
+ /* See comment in wait_for_sync_resolv() about ares_timeout() being
+ * O(N) in the number of outstanding requests until c-ares 1.20, and
+ * why we might as well just set a 1 second to select().
+ */
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+
+ if (select(nfds, &rfds, &wfds, NULL, &tv) == -1) { /* call to select() failed */
+ /* If it's interrupted by a signal, no need to put out a message */
+ if (errno != EINTR)
+ fprintf(stderr, "Warning: call to select() failed, error is %s\n", g_strerror(errno));
+ return;
+ }
+ ares_process(ghba_chan, &rfds, &wfds);
+ }
+
+ maxmind_db_lookup_process();
+ return;
+}
+
+static void
+sync_lookup_ip4(const uint32_t addr)
{
- gboolean completed = FALSE;
+ bool completed = false;
sync_dns_data_t *sdd;
if (!async_dns_initialized) {
@@ -526,7 +631,7 @@ sync_lookup_ip4(const guint32 addr)
sdd->family = AF_INET;
sdd->addr.ip4 = addr;
sdd->completed = &completed;
- ares_gethostbyaddr(ghba_chan, &addr, sizeof(guint32), AF_INET,
+ ares_gethostbyaddr(ghba_chan, &addr, sizeof(uint32_t), AF_INET,
c_ares_ghba_sync_cb, sdd);
/*
@@ -538,7 +643,7 @@ sync_lookup_ip4(const guint32 addr)
static void
sync_lookup_ip6(const ws_in6_addr *addrp)
{
- gboolean completed = FALSE;
+ bool completed = false;
sync_dns_data_t *sdd;
if (!async_dns_initialized) {
@@ -565,10 +670,14 @@ sync_lookup_ip6(const ws_in6_addr *addrp)
}
void
-set_resolution_synchrony(gboolean synchronous)
+set_resolution_synchrony(bool synchronous)
{
resolve_synchronously = synchronous;
maxmind_db_set_synchrony(synchronous);
+
+ if (synchronous) {
+ wait_for_async_queue();
+ }
}
static void
@@ -585,9 +694,9 @@ c_ares_set_dns_servers(void)
struct ares_addr_port_node* servers = wmem_alloc_array(NULL, struct ares_addr_port_node, ndnsservers);
ws_in4_addr ipv4addr;
ws_in6_addr ipv6addr;
- gboolean invalid_IP_found = FALSE;
+ bool invalid_IP_found = false;
struct ares_addr_port_node* server;
- guint i;
+ unsigned i;
for (i = 0, server = servers; i < ndnsservers-1; i++, server++) {
if (ws_inet_pton6(dnsserverlist_uats[i].ipaddr, &ipv6addr)) {
server->family = AF_INET6;
@@ -597,7 +706,7 @@ c_ares_set_dns_servers(void)
memcpy(&server->addr.addr4, &ipv4addr, 4);
} else {
//This shouldn't happen, but just in case...
- invalid_IP_found = TRUE;
+ invalid_IP_found = true;
server->family = 0;
memset(&server->addr.addr4, 0, 4);
break;
@@ -634,9 +743,9 @@ c_ares_set_dns_servers(void)
}
typedef struct {
- guint32 mask;
- gsize mask_length;
- const gchar* name; /* Shallow copy */
+ uint32_t mask;
+ size_t mask_length;
+ const char* name; /* Shallow copy */
} subnet_entry_t;
/* Maximum supported line length of hosts, services, manuf, etc. */
@@ -659,53 +768,88 @@ fgetline(char *buf, int size, FILE *fp)
/*
* Local function definitions
*/
-static subnet_entry_t subnet_lookup(const guint32 addr);
-static void subnet_entry_set(guint32 subnet_addr, const guint8 mask_length, const gchar* name);
+static subnet_entry_t subnet_lookup(const uint32_t addr);
+static void subnet_entry_set(uint32_t subnet_addr, const uint8_t mask_length, const char* name);
+
+static unsigned serv_port_custom_hash(const void *k)
+{
+ const serv_port_custom_key_t *key = (const serv_port_custom_key_t*)k;
+ return key->port + (key->type << 16);
+}
+static gboolean serv_port_custom_equal(const void *k1, const void *k2)
+{
+ const serv_port_custom_key_t *key1 = (const serv_port_custom_key_t*)k1;
+ const serv_port_custom_key_t *key2 = (const serv_port_custom_key_t*)k2;
+
+ return (key1->port == key2->port) && (key1->type == key2->type);
+}
static void
-add_service_name(port_type proto, const guint port, const char *service_name)
+add_custom_service_name(port_type proto, const unsigned port, const char *service_name)
{
- serv_port_t *serv_port_table;
+ char *name;
+ serv_port_custom_key_t *key, *orig_key;
+
+ key = wmem_new(addr_resolv_scope, serv_port_custom_key_t);
+ key->port = (uint16_t)port;
+ key->type = proto;
- serv_port_table = (serv_port_t *)wmem_map_lookup(serv_port_hashtable, GUINT_TO_POINTER(port));
- if (serv_port_table == NULL) {
- serv_port_table = wmem_new0(addr_resolv_scope, serv_port_t);
- wmem_map_insert(serv_port_hashtable, GUINT_TO_POINTER(port), serv_port_table);
+ if (wmem_map_lookup_extended(serv_port_custom_hashtable, key, (const void**)&orig_key, (void**)&name)) {
+ wmem_free(addr_resolv_scope, orig_key);
+ wmem_free(addr_resolv_scope, name);
}
+ name = wmem_strdup(addr_resolv_scope, service_name);
+ wmem_map_insert(serv_port_custom_hashtable, key, name);
+
+ // A new custom entry is not a new resolved object.
+ // new_resolved_objects = true;
+}
+
+static serv_port_t*
+add_service_name(port_type proto, const unsigned port, const char *service_name)
+{
+ serv_port_t *serv_port_names;
+
+ serv_port_names = (serv_port_t *)wmem_map_lookup(serv_port_hashtable, GUINT_TO_POINTER(port));
+ if (serv_port_names == NULL) {
+ serv_port_names = wmem_new0(addr_resolv_scope, serv_port_t);
+ wmem_map_insert(serv_port_hashtable, GUINT_TO_POINTER(port), serv_port_names);
+ }
+
+ /* We don't need to strdup because service_name is owned by either
+ * the global arrays or the custom table, which manage the memory
+ * and have lifespans at least as long as the addr_resolv_scope.
+ */
switch(proto) {
case PT_TCP:
- wmem_free(addr_resolv_scope, serv_port_table->tcp_name);
- serv_port_table->tcp_name = wmem_strdup(addr_resolv_scope, service_name);
+ serv_port_names->tcp_name = service_name;
break;
case PT_UDP:
- wmem_free(addr_resolv_scope, serv_port_table->udp_name);
- serv_port_table->udp_name = wmem_strdup(addr_resolv_scope, service_name);
+ serv_port_names->udp_name = service_name;
break;
case PT_SCTP:
- wmem_free(addr_resolv_scope, serv_port_table->sctp_name);
- serv_port_table->sctp_name = wmem_strdup(addr_resolv_scope, service_name);
+ serv_port_names->sctp_name = service_name;
break;
case PT_DCCP:
- wmem_free(addr_resolv_scope, serv_port_table->dccp_name);
- serv_port_table->dccp_name = wmem_strdup(addr_resolv_scope, service_name);
+ serv_port_names->dccp_name = service_name;
break;
default:
- return;
+ return serv_port_names;
/* Should not happen */
}
- new_resolved_objects = TRUE;
+ new_resolved_objects = true;
+ return serv_port_names;
}
-
static void
parse_service_line (char *line)
{
- gchar *cp;
- gchar *service;
- gchar *port;
+ char *cp;
+ char *service;
+ char *port;
port_type proto;
struct cb_serv_data cb_data;
range_t *port_rng = NULL;
@@ -726,7 +870,7 @@ parse_service_line (char *line)
if (strtok(cp, "/") == NULL)
return;
- if (range_convert_str(NULL, &port_rng, port, G_MAXUINT16) != CVT_NO_ERROR) {
+ if (range_convert_str(NULL, &port_rng, port, UINT16_MAX) != CVT_NO_ERROR) {
wmem_free (NULL, port_rng);
return;
}
@@ -757,17 +901,17 @@ parse_service_line (char *line)
static void
-add_serv_port_cb(const guint32 port, gpointer ptr)
+add_serv_port_cb(const uint32_t port, void *ptr)
{
struct cb_serv_data *cb_data = (struct cb_serv_data *)ptr;
if ( port ) {
- add_service_name(cb_data->proto, port, cb_data->service);
+ add_custom_service_name(cb_data->proto, port, cb_data->service);
}
}
-static gboolean
+static bool
parse_services_file(const char * path)
{
FILE *serv_p;
@@ -777,102 +921,118 @@ parse_services_file(const char * path)
serv_p = ws_fopen(path, "r");
if (serv_p == NULL)
- return FALSE;
+ return false;
while (fgetline(buf, sizeof(buf), serv_p) >= 0) {
parse_service_line(buf);
}
fclose(serv_p);
- return TRUE;
+ return true;
}
/* -----------------
* unsigned integer to ascii
*/
-static gchar *
-wmem_utoa(wmem_allocator_t *allocator, guint port)
+static char *
+wmem_utoa(wmem_allocator_t *allocator, unsigned port)
{
- gchar *bp = (gchar *)wmem_alloc(allocator, MAXNAMELEN);
+ char *bp = (char *)wmem_alloc(allocator, MAXNAMELEN);
- /* XXX, guint32_to_str() ? */
- guint32_to_str_buf(port, bp, MAXNAMELEN);
+ /* XXX, uint32_to_str() ? */
+ uint32_to_str_buf(port, bp, MAXNAMELEN);
return bp;
}
-static const gchar *
-_serv_name_lookup(port_type proto, guint port, serv_port_t **value_ret)
+static const char *
+_serv_name_lookup(port_type proto, unsigned port, serv_port_t **value_ret)
{
- serv_port_t *serv_port_table;
+ serv_port_t *serv_port_names;
+ const char* name = NULL;
+ ws_services_proto_t p;
+ ws_services_entry_t const *serv;
+
+ /* Look in the cache */
+ serv_port_names = (serv_port_t *)wmem_map_lookup(serv_port_hashtable, GUINT_TO_POINTER(port));
+
+ if (serv_port_names == NULL) {
+ /* Try the user custom table */
+ serv_port_custom_key_t custom_key = { (uint16_t)port, proto };
+ name = wmem_map_lookup(serv_port_custom_hashtable, &custom_key);
+ }
+
+ if (name == NULL) {
+ /* now look in the global tables */
+ bool valid_proto = true;
+ switch(proto) {
+ case PT_TCP: p = ws_tcp; break;
+ case PT_UDP: p = ws_udp; break;
+ case PT_SCTP: p = ws_sctp; break;
+ case PT_DCCP: p = ws_dccp; break;
+ default: valid_proto = false;
+ }
+ if (valid_proto) {
+ serv = global_services_lookup(port, p);
+ if (serv) {
+ name = serv->name;
+ }
+ }
+ }
- serv_port_table = (serv_port_t *)wmem_map_lookup(serv_port_hashtable, GUINT_TO_POINTER(port));
+ if (name) {
+ /* Cache result */
+ serv_port_names = add_service_name(proto, port, name);
+ }
if (value_ret != NULL)
- *value_ret = serv_port_table;
+ *value_ret = serv_port_names;
- if (serv_port_table == NULL)
+ if (serv_port_names == NULL)
return NULL;
switch (proto) {
case PT_UDP:
- return serv_port_table->udp_name;
+ return serv_port_names->udp_name;
case PT_TCP:
- return serv_port_table->tcp_name;
+ return serv_port_names->tcp_name;
case PT_SCTP:
- return serv_port_table->sctp_name;
+ return serv_port_names->sctp_name;
case PT_DCCP:
- return serv_port_table->dccp_name;
+ return serv_port_names->dccp_name;
default:
break;
}
return NULL;
}
-const gchar *
-try_serv_name_lookup(port_type proto, guint port)
+const char *
+try_serv_name_lookup(port_type proto, unsigned port)
{
- return _serv_name_lookup(proto, port, NULL);
+ return (proto == PT_NONE) ? NULL : _serv_name_lookup(proto, port, NULL);
}
-const gchar *
-serv_name_lookup(port_type proto, guint port)
+const char *
+serv_name_lookup(port_type proto, unsigned port)
{
- serv_port_t *serv_port_table = NULL;
+ serv_port_t *serv_port_names = NULL;
const char *name;
- ws_services_proto_t p;
- ws_services_entry_t *serv;
- /* first look in the personal services file + cache */
- name = _serv_name_lookup(proto, port, &serv_port_table);
+ /* first look for the name */
+ name = _serv_name_lookup(proto, port, &serv_port_names);
if (name != NULL)
return name;
- /* now look in the global tables */
- switch(proto) {
- case PT_TCP: p = ws_tcp; break;
- case PT_UDP: p = ws_udp; break;
- case PT_SCTP: p = ws_sctp; break;
- case PT_DCCP: p = ws_dccp; break;
- default: ws_assert_not_reached();
- }
- serv = global_services_lookup(port, p);
- if (serv) {
- /* Cache result */
- /* XXX would be nice to avoid the strdup for this name static string but user/custom entries
- * are dynamic and they share the same table. */
- add_service_name(proto, port, serv->name);
- return serv->name;
+ if (serv_port_names == NULL) {
+ serv_port_names = wmem_new0(addr_resolv_scope, serv_port_t);
+ wmem_map_insert(serv_port_hashtable, GUINT_TO_POINTER(port), serv_port_names);
}
- if (serv_port_table == NULL) {
- serv_port_table = wmem_new0(addr_resolv_scope, serv_port_t);
- wmem_map_insert(serv_port_hashtable, GUINT_TO_POINTER(port), serv_port_table);
- }
- if (serv_port_table->numeric == NULL) {
- serv_port_table->numeric = wmem_strdup_printf(addr_resolv_scope, "%u", port);
+ /* No name; create the numeric string. */
+ if (serv_port_names->numeric == NULL) {
+ serv_port_names->numeric = wmem_strdup_printf(addr_resolv_scope, "%u", port);
}
- return serv_port_table->numeric;
+ return serv_port_names->numeric;
}
static void
@@ -880,6 +1040,8 @@ initialize_services(void)
{
ws_assert(serv_port_hashtable == NULL);
serv_port_hashtable = wmem_map_new(addr_resolv_scope, g_direct_hash, g_direct_equal);
+ ws_assert(serv_port_custom_hashtable == NULL);
+ serv_port_custom_hashtable = wmem_map_new(addr_resolv_scope, serv_port_custom_hash, serv_port_custom_equal);
/* Compute the pathname of the global services file. */
if (g_services_path == NULL) {
@@ -890,10 +1052,10 @@ initialize_services(void)
/* Compute the pathname of the personal services file */
if (g_pservices_path == NULL) {
/* Check profile directory before personal configuration */
- g_pservices_path = get_persconffile_path(ENAME_SERVICES, TRUE);
+ g_pservices_path = get_persconffile_path(ENAME_SERVICES, true);
if (!parse_services_file(g_pservices_path)) {
g_free(g_pservices_path);
- g_pservices_path = get_persconffile_path(ENAME_SERVICES, FALSE);
+ g_pservices_path = get_persconffile_path(ENAME_SERVICES, false);
parse_services_file(g_pservices_path);
}
}
@@ -903,6 +1065,7 @@ static void
service_name_lookup_cleanup(void)
{
serv_port_hashtable = NULL;
+ serv_port_custom_hashtable = NULL;
g_free(g_services_path);
g_services_path = NULL;
g_free(g_pservices_path);
@@ -913,13 +1076,13 @@ static void
parse_enterprises_line (char *line)
{
char *tok, *dec_str, *org_str;
- guint32 dec;
- gboolean had_comment = FALSE;
+ uint32_t dec;
+ bool had_comment = false;
/* Stop the line at any comment found */
if ((tok = strchr(line, '#'))) {
*tok = '\0';
- had_comment = TRUE;
+ had_comment = true;
}
/* Get enterprise number */
dec_str = strtok(line, " \t");
@@ -941,7 +1104,7 @@ parse_enterprises_line (char *line)
}
-static gboolean
+static bool
parse_enterprises_file(const char * path)
{
FILE *fp;
@@ -949,14 +1112,14 @@ parse_enterprises_file(const char * path)
fp = ws_fopen(path, "r");
if (fp == NULL)
- return FALSE;
+ return false;
while (fgetline(buf, sizeof(buf), fp) >= 0) {
parse_enterprises_line(buf);
}
fclose(fp);
- return TRUE;
+ return true;
}
static void
@@ -973,21 +1136,21 @@ initialize_enterprises(void)
/* Populate entries from profile or personal */
if (g_penterprises_path == NULL) {
/* Check profile directory before personal configuration */
- g_penterprises_path = get_persconffile_path(ENAME_ENTERPRISES, TRUE);
+ g_penterprises_path = get_persconffile_path(ENAME_ENTERPRISES, true);
if (!file_exists(g_penterprises_path)) {
g_free(g_penterprises_path);
- g_penterprises_path = get_persconffile_path(ENAME_ENTERPRISES, FALSE);
+ g_penterprises_path = get_persconffile_path(ENAME_ENTERPRISES, false);
}
}
/* Parse personal file (if present) */
parse_enterprises_file(g_penterprises_path);
}
-const gchar *
-try_enterprises_lookup(guint32 value)
+const char *
+try_enterprises_lookup(uint32_t value)
{
/* Trying extra entries first. N.B. This does allow entries to be overwritten and found.. */
- const char *name = (const gchar *)g_hash_table_lookup(enterprises_hashtable, GUINT_TO_POINTER(value));
+ const char *name = (const char *)g_hash_table_lookup(enterprises_hashtable, GUINT_TO_POINTER(value));
if (name) {
return name;
}
@@ -996,10 +1159,10 @@ try_enterprises_lookup(guint32 value)
}
}
-const gchar *
-enterprises_lookup(guint32 value, const char *unknown_str)
+const char *
+enterprises_lookup(uint32_t value, const char *unknown_str)
{
- const gchar *s;
+ const char *s;
s = try_enterprises_lookup(value);
if (s != NULL)
@@ -1010,9 +1173,9 @@ enterprises_lookup(guint32 value, const char *unknown_str)
}
void
-enterprises_base_custom(char *buf, guint32 value)
+enterprises_base_custom(char *buf, uint32_t value)
{
- const gchar *s;
+ const char *s;
if ((s = try_enterprises_lookup(value)) == NULL)
s = ITEM_LABEL_UNKNOWN_STR;
@@ -1034,24 +1197,27 @@ enterprises_cleanup(void)
/* Fill in an IP4 structure with info from subnets file or just with the
* string form of the address.
*/
-static void
-fill_dummy_ip4(const guint addr, hashipv4_t* volatile tp)
+bool
+fill_dummy_ip4(const unsigned addr, hashipv4_t* volatile tp)
{
subnet_entry_t subnet_entry;
+ /* return value : true if addr matches any subnet */
+ bool cidr_covered = false;
+
/* Overwrite if we get async DNS reply */
/* Do we have a subnet for this address? */
subnet_entry = subnet_lookup(addr);
if (0 != subnet_entry.mask) {
/* Print name, then '.' then IP address after subnet mask */
- guint32 host_addr;
- gchar buffer[WS_INET_ADDRSTRLEN];
- gchar* paddr;
- gsize i;
+ uint32_t host_addr;
+ char buffer[WS_INET_ADDRSTRLEN];
+ char* paddr;
+ size_t i;
host_addr = addr & (~subnet_entry.mask);
- ip_to_str_buf((guint8 *)&host_addr, buffer, WS_INET_ADDRSTRLEN);
+ ip_addr_to_str_buf(&host_addr, buffer, WS_INET_ADDRSTRLEN);
paddr = buffer;
/* Skip to first octet that is not totally masked
@@ -1070,10 +1236,29 @@ fill_dummy_ip4(const guint addr, hashipv4_t* volatile tp)
* trust snprintf and MAXNAMELEN
*/
snprintf(tp->name, MAXNAMELEN, "%s%s", subnet_entry.name, paddr);
+
+ /* Evaluate the subnet in CIDR notation
+ * Reuse buffers built above
+ */
+ uint32_t subnet_addr;
+ subnet_addr = addr & subnet_entry.mask;
+
+ char buffer_subnet[WS_INET_ADDRSTRLEN];
+ ip_addr_to_str_buf(&subnet_addr, buffer_subnet, WS_INET_ADDRSTRLEN);
+
+ char buffer_cidr[WS_INET_CIDRADDRSTRLEN];
+ snprintf(buffer_cidr, WS_INET_CIDRADDRSTRLEN, "%s%s%u", buffer_subnet, "/", (unsigned)subnet_entry.mask_length);
+
+ snprintf(tp->cidr_addr, WS_INET_CIDRADDRSTRLEN, "%s%s%u", buffer_subnet, "/", (unsigned)subnet_entry.mask_length);
+ cidr_covered = true;
} else {
/* XXX: This means we end up printing "1.2.3.4 (1.2.3.4)" in many cases */
- ip_to_str_buf((const guint8 *)&addr, tp->name, MAXNAMELEN);
+ ip_addr_to_str_buf(&addr, tp->name, MAXNAMELEN);
+
+ /* IP does not belong to any known subnet, just indicate this IP without "/.32" */
+ ip_addr_to_str_buf(&addr, tp->cidr_addr, MAXNAMELEN);
}
+ return cidr_covered;
}
@@ -1099,10 +1284,10 @@ c_ares_ghba_cb(void *arg, int status, int timeouts _U_, struct hostent *he) {
for (p = he->h_addr_list; *p != NULL; p++) {
switch(caqm->family) {
case AF_INET:
- add_ipv4_name(caqm->addr.ip4, he->h_name, FALSE);
+ add_ipv4_name(caqm->addr.ip4, he->h_name, false);
break;
case AF_INET6:
- add_ipv6_name(&caqm->addr.ip6, he->h_name, FALSE);
+ add_ipv6_name(&caqm->addr.ip6, he->h_name, false);
break;
default:
/* Throw an exception? */
@@ -1114,19 +1299,19 @@ c_ares_ghba_cb(void *arg, int status, int timeouts _U_, struct hostent *he) {
}
/* --------------- */
-static hashipv4_t *
-new_ipv4(const guint addr)
+hashipv4_t *
+new_ipv4(const unsigned addr)
{
hashipv4_t *tp = wmem_new(addr_resolv_scope, hashipv4_t);
tp->addr = addr;
tp->flags = 0;
tp->name[0] = '\0';
- ip_to_str_buf((const guint8 *)&addr, tp->ip, sizeof(tp->ip));
+ ip_addr_to_str_buf(&addr, tp->ip, sizeof(tp->ip));
return tp;
}
static hashipv4_t *
-host_lookup(const guint addr)
+host_lookup(const unsigned addr)
{
hashipv4_t * volatile tp;
@@ -1174,7 +1359,7 @@ host_lookup(const guint addr)
caqm = wmem_new(addr_resolv_scope, async_dns_queue_msg_t);
caqm->family = AF_INET;
caqm->addr.ip4 = addr;
- wmem_list_append(async_dns_queue_head, (gpointer) caqm);
+ wmem_list_append(async_dns_queue_head, (void *) caqm);
}
}
}
@@ -1249,7 +1434,7 @@ host_lookup6(const ws_in6_addr *addr)
caqm = wmem_new(addr_resolv_scope, async_dns_queue_msg_t);
caqm->family = AF_INET6;
memcpy(&caqm->addr.ip6, addr, sizeof(caqm->addr.ip6));
- wmem_list_append(async_dns_queue_head, (gpointer) caqm);
+ wmem_list_append(async_dns_queue_head, (void *) caqm);
}
}
}
@@ -1288,13 +1473,13 @@ host_lookup6(const ws_in6_addr *addr)
* octets must be exactly two hexadecimal characters and the mask must be either
* 28 or 36. Pre-condition: cp MUST be at least 21 bytes.
*/
-static gboolean
-parse_ether_address_fast(const guchar *cp, ether_t *eth, unsigned int *mask,
- const gboolean accept_mask)
+static bool
+parse_ether_address_fast(const unsigned char *cp, ether_t *eth, unsigned int *mask,
+ const bool accept_mask)
{
/* XXX copied from strutil.c */
/* a map from ASCII hex chars to their value */
- static const gint8 str_to_nibble[256] = {
+ static const int8_t str_to_nibble[256] = {
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
@@ -1312,57 +1497,57 @@ parse_ether_address_fast(const guchar *cp, ether_t *eth, unsigned int *mask,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
};
- const guint8 *str_to_nibble_usg = (const guint8 *)str_to_nibble;
+ const uint8_t *str_to_nibble_usg = (const uint8_t *)str_to_nibble;
- guchar sep = cp[2];
+ unsigned char sep = cp[2];
if ((sep != ':' && sep != '-') || cp[5] != sep) {
/* Unexpected separators. */
- return FALSE;
+ return false;
}
/* N.B. store octet values in an int to detect invalid (-1) entries */
- int num0 = (str_to_nibble_usg[cp[0]] << 4) | (gint8)str_to_nibble_usg[cp[1]];
- int num1 = (str_to_nibble_usg[cp[3]] << 4) | (gint8)str_to_nibble_usg[cp[4]];
- int num2 = (str_to_nibble_usg[cp[6]] << 4) | (gint8)str_to_nibble_usg[cp[7]];
+ int num0 = (str_to_nibble_usg[cp[0]] << 4) | (int8_t)str_to_nibble_usg[cp[1]];
+ int num1 = (str_to_nibble_usg[cp[3]] << 4) | (int8_t)str_to_nibble_usg[cp[4]];
+ int num2 = (str_to_nibble_usg[cp[6]] << 4) | (int8_t)str_to_nibble_usg[cp[7]];
if ((num0 | num1 | num2) & 0x100) {
/* Not hexadecimal numbers. */
- return FALSE;
+ return false;
}
- eth->addr[0] = (guint8)num0;
- eth->addr[1] = (guint8)num1;
- eth->addr[2] = (guint8)num2;
+ eth->addr[0] = (uint8_t)num0;
+ eth->addr[1] = (uint8_t)num1;
+ eth->addr[2] = (uint8_t)num2;
if (cp[8] == '\0' && accept_mask) {
/* Indicate that this is a manufacturer ID (0 is not allowed as a mask). */
*mask = 0;
- return TRUE;
+ return true;
} else if (cp[8] != sep || !accept_mask) {
/* Format not handled by this fast path. */
- return FALSE;
+ return false;
}
/* N.B. store octet values in an int to detect invalid (-1) entries */
- int num3 = (str_to_nibble_usg[cp[9]] << 4) | (gint8)str_to_nibble_usg[cp[10]];
- int num4 = (str_to_nibble_usg[cp[12]] << 4) | (gint8)str_to_nibble_usg[cp[13]];
- int num5 = (str_to_nibble_usg[cp[15]] << 4) | (gint8)str_to_nibble_usg[cp[16]];
+ int num3 = (str_to_nibble_usg[cp[9]] << 4) | (int8_t)str_to_nibble_usg[cp[10]];
+ int num4 = (str_to_nibble_usg[cp[12]] << 4) | (int8_t)str_to_nibble_usg[cp[13]];
+ int num5 = (str_to_nibble_usg[cp[15]] << 4) | (int8_t)str_to_nibble_usg[cp[16]];
if (((num3 | num4 | num5) & 0x100) || cp[11] != sep || cp[14] != sep) {
/* Not hexadecimal numbers or invalid separators. */
- return FALSE;
+ return false;
}
- eth->addr[3] = (guint8)num3;
- eth->addr[4] = (guint8)num4;
- eth->addr[5] = (guint8)num5;
+ eth->addr[3] = (uint8_t)num3;
+ eth->addr[4] = (uint8_t)num4;
+ eth->addr[5] = (uint8_t)num5;
if (cp[17] == '\0') {
/* We got 6 bytes, so this is a MAC address (48 is not allowed as a mask). */
*mask = 48;
- return TRUE;
+ return true;
} else if (cp[17] != '/' || cp[20] != '\0') {
/* Format not handled by this fast path. */
- return FALSE;
+ return false;
}
int m1 = cp[18];
@@ -1371,28 +1556,28 @@ parse_ether_address_fast(const guchar *cp, ether_t *eth, unsigned int *mask,
eth->addr[4] &= 0xf0;
eth->addr[5] = 0;
*mask = 36;
- return TRUE;
+ return true;
}
if (m1 == '2' && m2 == '8') { /* Mask /28 */
eth->addr[3] &= 0xf0;
eth->addr[4] = 0;
eth->addr[5] = 0;
*mask = 28;
- return TRUE;
+ return true;
}
/* Unsupported mask */
- return FALSE;
+ return false;
}
/*
- * If "accept_mask" is FALSE, cp must point to an address that consists
+ * If "accept_mask" is false, cp must point to an address that consists
* of exactly 6 bytes.
- * If "accept_mask" is TRUE, parse an up-to-6-byte sequence with an optional
+ * If "accept_mask" is true, parse an up-to-6-byte sequence with an optional
* mask.
*/
-static gboolean
+static bool
parse_ether_address(const char *cp, ether_t *eth, unsigned int *mask,
- const gboolean accept_mask)
+ const bool accept_mask)
{
int i;
unsigned long num;
@@ -1402,13 +1587,13 @@ parse_ether_address(const char *cp, ether_t *eth, unsigned int *mask,
for (i = 0; i < 6; i++) {
/* Get a hex number, 1 or 2 digits, no sign characters allowed. */
if (!g_ascii_isxdigit(*cp))
- return FALSE;
+ return false;
num = strtoul(cp, &p, 16);
if (p == cp)
- return FALSE; /* failed */
+ return false; /* failed */
if (num > 0xFF)
- return FALSE; /* not a valid octet */
- eth->addr[i] = (guint8) num;
+ return false; /* not a valid octet */
+ eth->addr[i] = (uint8_t) num;
cp = p; /* skip past the number */
/* OK, what character terminated the octet? */
@@ -1416,19 +1601,19 @@ parse_ether_address(const char *cp, ether_t *eth, unsigned int *mask,
/* "/" - this has a mask. */
if (!accept_mask) {
/* Entries with masks are not allowed in this file. */
- return FALSE;
+ return false;
}
cp++; /* skip past the '/' to get to the mask */
if (!g_ascii_isdigit(*cp))
- return FALSE; /* no sign allowed */
+ return false; /* no sign allowed */
num = strtoul(cp, &p, 10);
if (p == cp)
- return FALSE; /* failed */
+ return false; /* failed */
cp = p; /* skip past the number */
if (*cp != '\0' && !g_ascii_isspace(*cp))
- return FALSE; /* bogus terminator */
+ return false; /* bogus terminator */
if (num == 0 || num >= 48)
- return FALSE; /* bogus mask */
+ return false; /* bogus mask */
/* Mask out the bits not covered by the mask */
*mask = (int)num;
for (i = 0; num >= 8; i++, num -= 8)
@@ -1439,7 +1624,7 @@ parse_ether_address(const char *cp, ether_t *eth, unsigned int *mask,
/* Mask out completely-masked-out octets */
for (; i < 6; i++)
eth->addr[i] = 0;
- return TRUE;
+ return true;
}
if (*cp == '\0') {
/* We're at the end of the address, and there's no mask. */
@@ -1447,46 +1632,46 @@ parse_ether_address(const char *cp, ether_t *eth, unsigned int *mask,
/* We got 3 bytes, so this is a manufacturer ID. */
if (!accept_mask) {
/* Manufacturer IDs are not allowed in this file */
- return FALSE;
+ return false;
}
/* Indicate that this is a manufacturer ID (0 is not allowed
as a mask). */
*mask = 0;
- return TRUE;
+ return true;
}
if (i == 5) {
/* We got 6 bytes, so this is a MAC address (48 is not allowed as a mask). */
if (accept_mask)
*mask = 48;
- return TRUE;
+ return true;
}
/* We didn't get 3 or 6 bytes, and there's no mask; this is
illegal. */
- return FALSE;
+ return false;
} else {
if (sep == '\0') {
/* We don't know the separator used in this number; it can either
be ':', '-', or '.'. */
if (*cp != ':' && *cp != '-' && *cp != '.')
- return FALSE;
+ return false;
sep = *cp; /* subsequent separators must be the same */
} else {
/* It has to be the same as the first separator */
if (*cp != sep)
- return FALSE;
+ return false;
}
}
cp++;
}
- return TRUE;
+ return true;
}
static int
parse_ether_line(char *line, ether_t *eth, unsigned int *mask,
- const gboolean accept_mask)
+ const bool accept_mask)
{
/*
* See the ethers(4) or ethers(5) man page for ethers file format
@@ -1495,7 +1680,7 @@ parse_ether_line(char *line, ether_t *eth, unsigned int *mask,
* as well as Wireshark's '.' separator.
*/
- gchar *cp;
+ char *cp;
line = g_strstrip(line);
if (line[0] == '\0' || line[0] == '#')
@@ -1533,7 +1718,7 @@ parse_ether_line(char *line, ether_t *eth, unsigned int *mask,
} /* parse_ether_line */
-static FILE *eth_p = NULL;
+static FILE *eth_p;
static void
set_ethent(char *path)
@@ -1554,7 +1739,7 @@ end_ethent(void)
}
static ether_t *
-get_ethent(unsigned int *mask, const gboolean accept_mask)
+get_ethent(unsigned int *mask, const bool accept_mask)
{
static ether_t eth;
@@ -1574,14 +1759,14 @@ get_ethent(unsigned int *mask, const gboolean accept_mask)
} /* get_ethent */
static ether_t *
-get_ethbyaddr(const guint8 *addr)
+get_ethbyaddr(const uint8_t *addr)
{
ether_t *eth;
set_ethent(g_pethers_path);
- while (((eth = get_ethent(NULL, FALSE)) != NULL) && memcmp(addr, eth->addr, 6) != 0)
+ while (((eth = get_ethent(NULL, false)) != NULL) && memcmp(addr, eth->addr, 6) != 0)
;
if (eth == NULL) {
@@ -1589,7 +1774,7 @@ get_ethbyaddr(const guint8 *addr)
set_ethent(g_ethers_path);
- while (((eth = get_ethent(NULL, FALSE)) != NULL) && memcmp(addr, eth->addr, 6) != 0)
+ while (((eth = get_ethent(NULL, false)) != NULL) && memcmp(addr, eth->addr, 6) != 0)
;
end_ethent();
@@ -1600,9 +1785,9 @@ get_ethbyaddr(const guint8 *addr)
} /* get_ethbyaddr */
static hashmanuf_t *
-manuf_hash_new_entry(const guint8 *addr, const char* name, const char* longname)
+manuf_hash_new_entry(const uint8_t *addr, const char* name, const char* longname)
{
- guint manuf_key;
+ unsigned manuf_key;
hashmanuf_t *manuf_value;
char *endp;
@@ -1613,7 +1798,7 @@ manuf_hash_new_entry(const guint8 *addr, const char* name, const char* longname)
memcpy(manuf_value->addr, addr, 3);
if (name != NULL) {
(void) g_strlcpy(manuf_value->resolved_name, name, MAXNAMELEN);
- manuf_value->status = HASHETHER_STATUS_RESOLVED_NAME;
+ manuf_value->flags = NAME_RESOLVED;
if (longname != NULL) {
(void) g_strlcpy(manuf_value->resolved_longname, longname, MAXNAMELEN);
}
@@ -1622,7 +1807,7 @@ manuf_hash_new_entry(const guint8 *addr, const char* name, const char* longname)
}
}
else {
- manuf_value->status = HASHETHER_STATUS_UNRESOLVED;
+ manuf_value->flags = 0;
manuf_value->resolved_name[0] = '\0';
manuf_value->resolved_longname[0] = '\0';
}
@@ -1634,47 +1819,65 @@ manuf_hash_new_entry(const guint8 *addr, const char* name, const char* longname)
return manuf_value;
}
-static void
-wka_hash_new_entry(const guint8 *addr, char* name)
+static hashwka_t*
+wka_hash_new_entry(const uint8_t *addr, char* name)
{
- guint8 *wka_key;
+ uint8_t *wka_key;
+ hashwka_t *wka_value;
- wka_key = (guint8 *)wmem_alloc(addr_resolv_scope, 6);
+ wka_key = (uint8_t *)wmem_alloc(addr_resolv_scope, 6);
memcpy(wka_key, addr, 6);
- wmem_map_insert(wka_hashtable, wka_key, wmem_strdup(addr_resolv_scope, name));
+ wka_value = (hashwka_t*)wmem_new(addr_resolv_scope, hashwka_t);
+ wka_value->flags = NAME_RESOLVED;
+ wka_value->name = wmem_strdup(addr_resolv_scope, name);
+
+ wmem_map_insert(wka_hashtable, wka_key, wka_value);
+ return wka_value;
}
static void
-add_manuf_name(const guint8 *addr, unsigned int mask, gchar *name, gchar *longname)
+add_manuf_name(const uint8_t *addr, unsigned int mask, char *name, char *longname)
{
switch (mask)
{
case 0:
+ {
/* This is a manufacturer ID; add it to the manufacturer ID hash table */
- manuf_hash_new_entry(addr, name, longname);
+ hashmanuf_t *entry = manuf_hash_new_entry(addr, name, longname);
+ entry->flags |= STATIC_HOSTNAME;
break;
-
+ }
case 48:
+ {
/* This is a well-known MAC address; add it to the Ethernet hash table */
- add_eth_name(addr, name);
+ hashether_t *entry = add_eth_name(addr, name);
+ entry->flags |= STATIC_HOSTNAME;
break;
-
+ }
default:
+ {
/* This is a range of well-known addresses; add it to the well-known-address table */
- wka_hash_new_entry(addr, name);
+ hashwka_t *entry = wka_hash_new_entry(addr, name);
+ entry->flags |= STATIC_HOSTNAME;
break;
+ }
}
} /* add_manuf_name */
+/* XXX: manuf_name_lookup returns a hashmanuf_t*, which cannot hold a 28 or
+ * 36 bit MA-M or MA-S. So it returns those as unresolved. For EUI-48 and
+ * EUI-64, MA-M and MA-S should be checked for separately in the global
+ * tables.
+ */
static hashmanuf_t *
-manuf_name_lookup(const guint8 *addr, size_t size)
+manuf_name_lookup(const uint8_t *addr, size_t size)
{
- guint32 manuf_key;
- guint8 oct;
+ uint32_t manuf_key;
+ uint8_t oct;
hashmanuf_t *manuf_value;
- ws_return_val_if(size < 6, NULL);
+ ws_return_val_if(size < 3, NULL);
/* manuf needs only the 3 most significant octets of the ethernet address */
manuf_key = addr[0];
@@ -1689,6 +1892,7 @@ manuf_name_lookup(const guint8 *addr, size_t size)
/* first try to find a "perfect match" */
manuf_value = (hashmanuf_t*)wmem_map_lookup(manuf_hashtable, GUINT_TO_POINTER(manuf_key));
if (manuf_value != NULL) {
+ manuf_value->flags |= TRIED_RESOLVE_ADDRESS;
return manuf_value;
}
@@ -1701,30 +1905,35 @@ manuf_name_lookup(const guint8 *addr, size_t size)
manuf_key &= 0x00FEFFFF;
manuf_value = (hashmanuf_t*)wmem_map_lookup(manuf_hashtable, GUINT_TO_POINTER(manuf_key));
if (manuf_value != NULL) {
+ manuf_value->flags |= TRIED_RESOLVE_ADDRESS;
return manuf_value;
}
}
/* Try the global manuf tables. */
const char *short_name, *long_name;
- short_name = ws_manuf_lookup_str(addr, &long_name);
+ /* We can't insert a 28 or 36 bit entry into the used hash table. */
+ short_name = ws_manuf_lookup_oui24(addr, &long_name);
if (short_name != NULL) {
/* Found it */
- return manuf_hash_new_entry(addr, short_name, long_name);
+ manuf_value = manuf_hash_new_entry(addr, short_name, long_name);
+ } else {
+ /* Add the address as a hex string */
+ manuf_value = manuf_hash_new_entry(addr, NULL, NULL);
}
- /* Add the address as a hex string */
- return manuf_hash_new_entry(addr, NULL, NULL);
+ manuf_value->flags |= TRIED_RESOLVE_ADDRESS;
+ return manuf_value;
} /* manuf_name_lookup */
-static gchar *
-wka_name_lookup(const guint8 *addr, const unsigned int mask)
+static char *
+wka_name_lookup(const uint8_t *addr, const unsigned int mask)
{
- guint8 masked_addr[6];
- guint num;
- gint i;
- gchar *name;
+ uint8_t masked_addr[6];
+ unsigned num;
+ int i;
+ hashwka_t *value;
if (wka_hashtable == NULL) {
return NULL;
@@ -1739,16 +1948,25 @@ wka_name_lookup(const guint8 *addr, const unsigned int mask)
for (; i < 6; i++)
masked_addr[i] = 0;
- name = (gchar *)wmem_map_lookup(wka_hashtable, masked_addr);
+ value = (hashwka_t*)wmem_map_lookup(wka_hashtable, masked_addr);
- return name;
+ if (value) {
+ value->flags |= TRIED_RESOLVE_ADDRESS;
+ return value->name;
+ }
+
+ return NULL;
} /* wka_name_lookup */
+unsigned get_hash_ether_status(hashether_t* ether)
+{
+ return ether->flags;
+}
-guint get_hash_ether_status(hashether_t* ether)
+bool get_hash_ether_used(hashether_t* ether)
{
- return ether->status;
+ return ((ether->flags & TRIED_OR_RESOLVED_MASK) == TRIED_OR_RESOLVED_MASK);
}
char* get_hash_ether_hexaddr(hashether_t* ether)
@@ -1761,14 +1979,24 @@ char* get_hash_ether_resolved_name(hashether_t* ether)
return ether->resolved_name;
}
-static guint
-eth_addr_hash(gconstpointer key)
+bool get_hash_wka_used(hashwka_t* wka)
+{
+ return ((wka->flags & TRIED_OR_RESOLVED_MASK) == TRIED_OR_RESOLVED_MASK);
+}
+
+char* get_hash_wka_resolved_name(hashwka_t* wka)
{
- return wmem_strong_hash((const guint8 *)key, 6);
+ return wka->name;
+}
+
+static unsigned
+eth_addr_hash(const void *key)
+{
+ return wmem_strong_hash((const uint8_t *)key, 6);
}
static gboolean
-eth_addr_cmp(gconstpointer a, gconstpointer b)
+eth_addr_cmp(const void *a, const void *b)
{
return (memcmp(a, b, 6) == 0);
}
@@ -1777,7 +2005,7 @@ static void
initialize_ethers(void)
{
ether_t *eth;
- guint mask = 0;
+ unsigned mask = 0;
/* hash table initialization */
ws_assert(wka_hashtable == NULL);
@@ -1797,10 +2025,10 @@ initialize_ethers(void)
*/
if (g_pethers_path == NULL) {
/* Check profile directory before personal configuration */
- g_pethers_path = get_persconffile_path(ENAME_ETHERS, TRUE);
+ g_pethers_path = get_persconffile_path(ENAME_ETHERS, true);
if (!file_exists(g_pethers_path)) {
g_free(g_pethers_path);
- g_pethers_path = get_persconffile_path(ENAME_ETHERS, FALSE);
+ g_pethers_path = get_persconffile_path(ENAME_ETHERS, false);
}
}
@@ -1810,7 +2038,7 @@ initialize_ethers(void)
/* Read it and initialize the hash table */
if (file_exists(g_manuf_path)) {
set_ethent(g_manuf_path);
- while ((eth = get_ethent(&mask, TRUE))) {
+ while ((eth = get_ethent(&mask, true))) {
add_manuf_name(eth->addr, mask, eth->name, eth->longname);
}
end_ethent();
@@ -1819,16 +2047,16 @@ initialize_ethers(void)
/* Compute the pathname of the personal manuf file */
if (g_pmanuf_path == NULL) {
/* Check profile directory before personal configuration */
- g_pmanuf_path = get_persconffile_path(ENAME_MANUF, TRUE);
+ g_pmanuf_path = get_persconffile_path(ENAME_MANUF, true);
if (!file_exists(g_pmanuf_path)) {
g_free(g_pmanuf_path);
- g_pmanuf_path = get_persconffile_path(ENAME_MANUF, FALSE);
+ g_pmanuf_path = get_persconffile_path(ENAME_MANUF, false);
}
}
/* Read it and initialize the hash table */
if (file_exists(g_pmanuf_path)) {
set_ethent(g_pmanuf_path);
- while ((eth = get_ethent(&mask, TRUE))) {
+ while ((eth = get_ethent(&mask, true))) {
add_manuf_name(eth->addr, mask, eth->name, eth->longname);
}
end_ethent();
@@ -1840,7 +2068,7 @@ initialize_ethers(void)
/* Read it and initialize the hash table */
set_ethent(g_wka_path);
- while ((eth = get_ethent(&mask, TRUE))) {
+ while ((eth = get_ethent(&mask, true))) {
add_manuf_name(eth->addr, mask, eth->name, eth->longname);
}
end_ethent();
@@ -1865,21 +2093,62 @@ ethers_cleanup(void)
g_wka_path = NULL;
}
+static void
+eth_resolved_name_fill(hashether_t *tp, const char *name, unsigned mask, const uint8_t *addr)
+{
+ switch (mask) {
+ case 24:
+ snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x",
+ name, addr[3], addr[4], addr[5]);
+ break;
+ case 28:
+ snprintf(tp->resolved_name, MAXNAMELEN, "%s_%01x:%02x:%02x",
+ name, addr[3] & 0x0F, addr[4], addr[5]);
+ break;
+ case 36:
+ snprintf(tp->resolved_name, MAXNAMELEN, "%s_%01x:%02x",
+ name, addr[4] & 0x0F, addr[5]);
+ break;
+ default: // Future-proof generic algorithm
+ {
+ unsigned bytes = mask / 8;
+ unsigned bitmask = mask % 8;
+
+ int pos = snprintf(tp->resolved_name, MAXNAMELEN, "%s", name);
+ if (pos >= MAXNAMELEN) return;
+
+ if (bytes < 6) {
+ pos += snprintf(tp->resolved_name + pos, MAXNAMELEN - pos,
+ bitmask >= 4 ? "_%01x" : "_%02x",
+ addr[bytes] & (0xFF >> bitmask));
+ bytes++;
+ }
+
+ while (bytes < 6) {
+ if (pos >= MAXNAMELEN) return;
+ pos += snprintf(tp->resolved_name + pos, MAXNAMELEN - pos, ":%02x",
+ addr[bytes]);
+ bytes++;
+ }
+ }
+ }
+}
+
/* Resolve ethernet address */
static hashether_t *
eth_addr_resolve(hashether_t *tp) {
ether_t *eth;
hashmanuf_t *manuf_value;
- const guint8 *addr = tp->addr;
+ const uint8_t *addr = tp->addr;
size_t addr_size = sizeof(tp->addr);
if ( (eth = get_ethbyaddr(addr)) != NULL) {
(void) g_strlcpy(tp->resolved_name, eth->name, MAXNAMELEN);
- tp->status = HASHETHER_STATUS_RESOLVED_NAME;
+ tp->flags |= NAME_RESOLVED | STATIC_HOSTNAME;
return tp;
- } else {
- guint mask;
- gchar *name;
+ } else if (!(tp->flags & NAME_RESOLVED)) {
+ unsigned mask;
+ char *name;
address ether_addr;
/* Unknown name. Try looking for it in the well-known-address
@@ -1890,7 +2159,7 @@ eth_addr_resolve(hashether_t *tp) {
if ((name = wka_name_lookup(addr, mask+40)) != NULL) {
snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x",
name, addr[5] & (0xFF >> mask));
- tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
+ tp->flags |= NAME_RESOLVED | NAME_RESOLVED_PREFIX;
return tp;
}
} while (mask--);
@@ -1901,7 +2170,7 @@ eth_addr_resolve(hashether_t *tp) {
if ((name = wka_name_lookup(addr, mask+32)) != NULL) {
snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x",
name, addr[4] & (0xFF >> mask), addr[5]);
- tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
+ tp->flags |= NAME_RESOLVED | NAME_RESOLVED_PREFIX;
return tp;
}
} while (mask--);
@@ -1912,17 +2181,17 @@ eth_addr_resolve(hashether_t *tp) {
if ((name = wka_name_lookup(addr, mask+24)) != NULL) {
snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x",
name, addr[3] & (0xFF >> mask), addr[4], addr[5]);
- tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
+ tp->flags |= NAME_RESOLVED | NAME_RESOLVED_PREFIX;
return tp;
}
} while (mask--);
/* Now try looking in the manufacturer table. */
manuf_value = manuf_name_lookup(addr, addr_size);
- if ((manuf_value != NULL) && (manuf_value->status != HASHETHER_STATUS_UNRESOLVED)) {
+ if ((manuf_value != NULL) && ((manuf_value->flags & NAME_RESOLVED) == NAME_RESOLVED)) {
snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x",
manuf_value->resolved_name, addr[3], addr[4], addr[5]);
- tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
+ tp->flags |= NAME_RESOLVED | NAME_RESOLVED_PREFIX;
return tp;
}
@@ -1935,7 +2204,7 @@ eth_addr_resolve(hashether_t *tp) {
snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x:%02x",
name, addr[2] & (0xFF >> mask), addr[3], addr[4],
addr[5]);
- tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
+ tp->flags |= NAME_RESOLVED | NAME_RESOLVED_PREFIX;
return tp;
}
} while (mask--);
@@ -1947,7 +2216,7 @@ eth_addr_resolve(hashether_t *tp) {
snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x:%02x:%02x",
name, addr[1] & (0xFF >> mask), addr[2], addr[3],
addr[4], addr[5]);
- tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
+ tp->flags |= NAME_RESOLVED | NAME_RESOLVED_PREFIX;
return tp;
}
} while (mask--);
@@ -1959,29 +2228,45 @@ eth_addr_resolve(hashether_t *tp) {
snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x:%02x:%02x:%02x",
name, addr[0] & (0xFF >> mask), addr[1], addr[2],
addr[3], addr[4], addr[5]);
- tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
+ tp->flags |= NAME_RESOLVED | NAME_RESOLVED_PREFIX;
return tp;
}
} while (--mask); /* Work down to the last bit */
+ /* Now try looking in the global manuf data for a MA-M or MA-S
+ * match. We do this last so that the other files override this
+ * result.
+ */
+ const char *short_name, *long_name;
+ short_name = ws_manuf_lookup(addr, &long_name, &mask);
+ if (short_name != NULL) {
+ if (mask == 24) {
+ /* This shouldn't happen as it should be handled above,
+ * but it doesn't hurt.
+ */
+ manuf_hash_new_entry(addr, short_name, long_name);
+ }
+ eth_resolved_name_fill(tp, short_name, mask, addr);
+ tp->flags |= NAME_RESOLVED | NAME_RESOLVED_PREFIX;
+ return tp;
+ }
/* No match whatsoever. */
set_address(&ether_addr, AT_ETHER, 6, addr);
address_to_str_buf(&ether_addr, tp->resolved_name, MAXNAMELEN);
- tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
return tp;
}
- ws_assert_not_reached();
+ return tp;
} /* eth_addr_resolve */
static hashether_t *
-eth_hash_new_entry(const guint8 *addr, const gboolean resolve)
+eth_hash_new_entry(const uint8_t *addr, const bool resolve)
{
hashether_t *tp;
char *endp;
tp = wmem_new(addr_resolv_scope, hashether_t);
memcpy(tp->addr, addr, sizeof(tp->addr));
- tp->status = HASHETHER_STATUS_UNRESOLVED;
+ tp->flags = 0;
/* Values returned by bytes_to_hexstr_punct() are *not* null-terminated */
endp = bytes_to_hexstr_punct(tp->hexaddr, addr, sizeof(tp->addr), ':');
*endp = '\0';
@@ -1996,27 +2281,27 @@ eth_hash_new_entry(const guint8 *addr, const gboolean resolve)
} /* eth_hash_new_entry */
static hashether_t *
-add_eth_name(const guint8 *addr, const gchar *name)
+add_eth_name(const uint8_t *addr, const char *name)
{
hashether_t *tp;
tp = (hashether_t *)wmem_map_lookup(eth_hashtable, addr);
if (tp == NULL) {
- tp = eth_hash_new_entry(addr, FALSE);
+ tp = eth_hash_new_entry(addr, false);
}
if (strcmp(tp->resolved_name, name) != 0) {
(void) g_strlcpy(tp->resolved_name, name, MAXNAMELEN);
- tp->status = HASHETHER_STATUS_RESOLVED_NAME;
- new_resolved_objects = TRUE;
+ tp->flags |= NAME_RESOLVED;
+ new_resolved_objects = true;
}
return tp;
} /* add_eth_name */
static hashether_t *
-eth_name_lookup(const guint8 *addr, const gboolean resolve)
+eth_name_lookup(const uint8_t *addr, const bool resolve)
{
hashether_t *tp;
@@ -2025,10 +2310,18 @@ eth_name_lookup(const guint8 *addr, const gboolean resolve)
if (tp == NULL) {
tp = eth_hash_new_entry(addr, resolve);
} else {
- if (resolve && (tp->status == HASHETHER_STATUS_UNRESOLVED)) {
+ if (resolve && !(tp->flags & TRIED_RESOLVE_ADDRESS)) {
+ /* We don't test TRIED_OR_RESOLVED_MASK (but check
+ * RESOLVED_NAME in eth_addr_resolve) so that the ethers
+ * files take precendent over wka, NRBs, ARP discovery, etc.
+ * XXX: What _is_ the proper precedence, and should it
+ * be configurable? (cf. #18075) */
eth_addr_resolve(tp); /* Found but needs to be resolved */
}
}
+ if (resolve) {
+ tp->flags |= TRIED_RESOLVE_ADDRESS;
+ }
return tp;
@@ -2044,9 +2337,9 @@ parse_ipxnets_line(char *line, ipxnet_t *ipxnet)
* as well as no separators
*/
- gchar *cp;
- guint32 a, a0, a1, a2, a3;
- gboolean found_single_number = FALSE;
+ char *cp;
+ uint32_t a, a0, a1, a2, a3;
+ bool found_single_number = false;
if ((cp = strchr(line, '#')))
*cp = '\0';
@@ -2054,15 +2347,15 @@ parse_ipxnets_line(char *line, ipxnet_t *ipxnet)
if ((cp = strtok(line, " \t\n")) == NULL)
return -1;
- /* Either fill a0,a1,a2,a3 and found_single_number is FALSE,
- * fill a and found_single_number is TRUE,
+ /* Either fill a0,a1,a2,a3 and found_single_number is false,
+ * fill a and found_single_number is true,
* or return -1
*/
if (sscanf(cp, "%x:%x:%x:%x", &a0, &a1, &a2, &a3) != 4) {
if (sscanf(cp, "%x-%x-%x-%x", &a0, &a1, &a2, &a3) != 4) {
if (sscanf(cp, "%x.%x.%x.%x", &a0, &a1, &a2, &a3) != 4) {
if (sscanf(cp, "%x", &a) == 1) {
- found_single_number = TRUE;
+ found_single_number = true;
}
else {
return -1;
@@ -2087,7 +2380,7 @@ parse_ipxnets_line(char *line, ipxnet_t *ipxnet)
} /* parse_ipxnets_line */
-static FILE *ipxnet_p = NULL;
+static FILE *ipxnet_p;
static void
set_ipxnetent(char *path)
@@ -2128,7 +2421,7 @@ get_ipxnetent(void)
} /* get_ipxnetent */
static ipxnet_t *
-get_ipxnetbyaddr(guint32 addr)
+get_ipxnetbyaddr(uint32_t addr)
{
ipxnet_t *ipxnet;
@@ -2171,10 +2464,10 @@ initialize_ipxnets(void)
*/
if (g_pipxnets_path == NULL) {
/* Check profile directory before personal configuration */
- g_pipxnets_path = get_persconffile_path(ENAME_IPXNETS, TRUE);
+ g_pipxnets_path = get_persconffile_path(ENAME_IPXNETS, true);
if (!file_exists(g_pipxnets_path)) {
g_free(g_pipxnets_path);
- g_pipxnets_path = get_persconffile_path(ENAME_IPXNETS, FALSE);
+ g_pipxnets_path = get_persconffile_path(ENAME_IPXNETS, false);
}
}
@@ -2188,8 +2481,8 @@ ipx_name_lookup_cleanup(void)
g_pipxnets_path = NULL;
}
-static gchar *
-ipxnet_name_lookup(wmem_allocator_t *allocator, const guint addr)
+static char *
+ipxnet_name_lookup(wmem_allocator_t *allocator, const unsigned addr)
{
hashipxnet_t *tp;
ipxnet_t *ipxnet;
@@ -2222,8 +2515,8 @@ ipxnet_name_lookup(wmem_allocator_t *allocator, const guint addr)
static int
parse_vlan_line(char *line, vlan_t *vlan)
{
- gchar *cp;
- guint16 id;
+ char *cp;
+ uint16_t id;
if ((cp = strchr(line, '#')))
*cp = '\0';
@@ -2247,7 +2540,7 @@ parse_vlan_line(char *line, vlan_t *vlan)
} /* parse_vlan_line */
-static FILE *vlan_p = NULL;
+static FILE *vlan_p;
static void
set_vlanent(char *path)
@@ -2288,7 +2581,7 @@ get_vlanent(void)
} /* get_vlanent */
static vlan_t *
-get_vlannamebyid(guint16 id)
+get_vlannamebyid(uint16_t id)
{
vlan_t *vlan;
@@ -2316,10 +2609,10 @@ initialize_vlans(void)
*/
if (g_pvlan_path == NULL) {
/* Check profile directory before personal configuration */
- g_pvlan_path = get_persconffile_path(ENAME_VLANS, TRUE);
+ g_pvlan_path = get_persconffile_path(ENAME_VLANS, true);
if (!file_exists(g_pvlan_path)) {
g_free(g_pvlan_path);
- g_pvlan_path = get_persconffile_path(ENAME_VLANS, FALSE);
+ g_pvlan_path = get_persconffile_path(ENAME_VLANS, false);
}
}
} /* initialize_vlans */
@@ -2333,8 +2626,8 @@ vlan_name_lookup_cleanup(void)
g_pvlan_path = NULL;
}
-static const gchar *
-vlan_name_lookup(const guint id)
+static const char *
+vlan_name_lookup(const unsigned id)
{
hashvlan_t *tp;
vlan_t *vlan;
@@ -2364,24 +2657,24 @@ vlan_name_lookup(const guint id)
} /* vlan_name_lookup */
/* VLAN END */
-static gboolean
-read_hosts_file (const char *hostspath, gboolean store_entries)
+static bool
+read_hosts_file (const char *hostspath, bool store_entries)
{
FILE *hf;
char line[MAX_LINELEN];
- gchar *cp;
+ char *cp;
union {
- guint32 ip4_addr;
+ uint32_t ip4_addr;
ws_in6_addr ip6_addr;
} host_addr;
- gboolean is_ipv6, entry_found = FALSE;
+ bool is_ipv6, entry_found = false;
/*
* See the hosts(4) or hosts(5) man page for hosts file format
* (not available on all systems).
*/
if ((hf = ws_fopen(hostspath, "r")) == NULL)
- return FALSE;
+ return false;
while (fgetline(line, sizeof(line), hf) >= 0) {
if ((cp = strchr(line, '#')))
@@ -2392,10 +2685,10 @@ read_hosts_file (const char *hostspath, gboolean store_entries)
if (ws_inet_pton6(cp, &host_addr.ip6_addr)) {
/* Valid IPv6 */
- is_ipv6 = TRUE;
+ is_ipv6 = true;
} else if (ws_inet_pton4(cp, &host_addr.ip4_addr)) {
/* Valid IPv4 */
- is_ipv6 = FALSE;
+ is_ipv6 = false;
} else {
continue;
}
@@ -2403,60 +2696,60 @@ read_hosts_file (const char *hostspath, gboolean store_entries)
if ((cp = strtok(NULL, " \t")) == NULL)
continue; /* no host name */
- entry_found = TRUE;
+ entry_found = true;
if (store_entries) {
if (is_ipv6) {
- add_ipv6_name(&host_addr.ip6_addr, cp, TRUE);
+ add_ipv6_name(&host_addr.ip6_addr, cp, true);
} else {
- add_ipv4_name(host_addr.ip4_addr, cp, TRUE);
+ add_ipv4_name(host_addr.ip4_addr, cp, true);
}
}
}
fclose(hf);
- return entry_found ? TRUE : FALSE;
+ return entry_found ? true : false;
} /* read_hosts_file */
-gboolean
+bool
add_hosts_file (const char *hosts_file)
{
- gboolean found = FALSE;
- guint i;
+ bool found = false;
+ unsigned i;
if (!hosts_file)
- return FALSE;
+ return false;
if (!extra_hosts_files)
extra_hosts_files = g_ptr_array_new();
for (i = 0; i < extra_hosts_files->len; i++) {
if (strcmp(hosts_file, (const char *) g_ptr_array_index(extra_hosts_files, i)) == 0)
- found = TRUE;
+ found = true;
}
if (!found) {
g_ptr_array_add(extra_hosts_files, wmem_strdup(addr_resolv_scope, hosts_file));
- return read_hosts_file (hosts_file, FALSE);
+ return read_hosts_file (hosts_file, false);
}
- return TRUE;
+ return true;
}
-gboolean
+bool
add_ip_name_from_string (const char *addr, const char *name)
{
union {
- guint32 ip4_addr;
+ uint32_t ip4_addr;
ws_in6_addr ip6_addr;
} host_addr;
- gboolean is_ipv6;
+ bool is_ipv6;
resolved_name_t *resolved_entry;
if (ws_inet_pton6(addr, &host_addr.ip6_addr)) {
- is_ipv6 = TRUE;
+ is_ipv6 = true;
} else if (ws_inet_pton4(addr, &host_addr.ip4_addr)) {
- is_ipv6 = FALSE;
+ is_ipv6 = false;
} else {
- return FALSE;
+ return false;
}
if (is_ipv6) {
@@ -2494,12 +2787,12 @@ add_ip_name_from_string (const char *addr, const char *name)
}
}
- return TRUE;
+ return true;
} /* add_ip_name_from_string */
extern resolved_name_t* get_edited_resolved_name(const char* addr)
{
- guint32 ip4_addr;
+ uint32_t ip4_addr;
ws_in6_addr ip6_addr;
resolved_name_t* resolved_entry = NULL;
@@ -2514,34 +2807,31 @@ extern resolved_name_t* get_edited_resolved_name(const char* addr)
}
/*
- * Add the resolved addresses that are in use to the list used to create the NRB
+ * Add the resolved addresses that are in use to the list used to create the pcapng NRB
*/
static void
-ipv4_hash_table_resolved_to_list(gpointer key _U_, gpointer value, gpointer user_data)
+ipv4_hash_table_resolved_to_list(void *key _U_, void *value, void *user_data)
{
- addrinfo_lists_t *lists = (addrinfo_lists_t*)user_data;
+ addrinfo_lists_t *lists = (addrinfo_lists_t *)user_data;
hashipv4_t *ipv4_hash_table_entry = (hashipv4_t *)value;
if ((ipv4_hash_table_entry->flags & USED_AND_RESOLVED_MASK) == USED_AND_RESOLVED_MASK) {
lists->ipv4_addr_list = g_list_prepend(lists->ipv4_addr_list, ipv4_hash_table_entry);
}
-
}
/*
- * Add the resolved addresses that are in use to the list used to create the NRB
+ * Add the resolved addresses that are in use to the list used to create the pcapng NRB
*/
-
static void
-ipv6_hash_table_resolved_to_list(gpointer key _U_, gpointer value, gpointer user_data)
+ipv6_hash_table_resolved_to_list(void *key _U_, void *value, void *user_data)
{
- addrinfo_lists_t *lists = (addrinfo_lists_t*)user_data;
+ addrinfo_lists_t *lists = (addrinfo_lists_t *)user_data;
hashipv6_t *ipv6_hash_table_entry = (hashipv6_t *)value;
if ((ipv6_hash_table_entry->flags & USED_AND_RESOLVED_MASK) == USED_AND_RESOLVED_MASK) {
- lists->ipv6_addr_list = g_list_prepend (lists->ipv6_addr_list, ipv6_hash_table_entry);
+ lists->ipv6_addr_list = g_list_prepend(lists->ipv6_addr_list, ipv6_hash_table_entry);
}
-
}
addrinfo_lists_t *
@@ -2572,17 +2862,17 @@ get_addrinfo_list(void)
*
* XXX Support IPv6
*/
-static gboolean
+static bool
read_subnets_file (const char *subnetspath)
{
FILE *hf;
char line[MAX_LINELEN];
- gchar *cp, *cp2;
- guint32 host_addr; /* IPv4 ONLY */
- guint8 mask_length;
+ char *cp, *cp2;
+ uint32_t host_addr; /* IPv4 ONLY */
+ uint8_t mask_length;
if ((hf = ws_fopen(subnetspath, "r")) == NULL)
- return FALSE;
+ return false;
while (fgetline(line, sizeof(line), hf) >= 0) {
if ((cp = strchr(line, '#')))
@@ -2617,20 +2907,20 @@ read_subnets_file (const char *subnetspath)
}
fclose(hf);
- return TRUE;
+ return true;
} /* read_subnets_file */
static subnet_entry_t
-subnet_lookup(const guint32 addr)
+subnet_lookup(const uint32_t addr)
{
subnet_entry_t subnet_entry;
- guint32 i;
+ uint32_t i;
/* Search mask lengths linearly, longest first */
i = SUBNETLENGTHSIZE;
while(have_subnet_entry && i > 0) {
- guint32 masked_addr;
+ uint32_t masked_addr;
subnet_length_entry_t* length_entry;
/* Note that we run from 31 (length 32) to 0 (length 1) */
@@ -2642,7 +2932,7 @@ subnet_lookup(const guint32 addr)
if (NULL != length_entry->subnet_addresses) {
sub_net_hashipv4_t * tp;
- guint32 hash_idx;
+ uint32_t hash_idx;
masked_addr = addr & length_entry->mask;
hash_idx = HASH_IPV4_ADDRESS(masked_addr);
@@ -2673,11 +2963,11 @@ subnet_lookup(const guint32 addr)
* given length.
*/
static void
-subnet_entry_set(guint32 subnet_addr, const guint8 mask_length, const gchar* name)
+subnet_entry_set(uint32_t subnet_addr, const uint8_t mask_length, const char* name)
{
subnet_length_entry_t* entry;
sub_net_hashipv4_t * tp;
- gsize hash_idx;
+ size_t hash_idx;
ws_assert(mask_length > 0 && mask_length <= 32);
@@ -2712,34 +3002,34 @@ subnet_entry_set(guint32 subnet_addr, const guint8 mask_length, const gchar* nam
tp->next = NULL;
tp->addr = subnet_addr;
(void) g_strlcpy(tp->name, name, MAXNAMELEN); /* This is longer than subnet names can actually be */
- have_subnet_entry = TRUE;
+ have_subnet_entry = true;
}
static void
subnet_name_lookup_init(void)
{
- gchar* subnetspath;
- guint32 i;
+ char* subnetspath;
+ uint32_t i;
for(i = 0; i < SUBNETLENGTHSIZE; ++i) {
- guint32 length = i + 1;
+ uint32_t length = i + 1;
subnet_length_entries[i].subnet_addresses = NULL;
subnet_length_entries[i].mask_length = length;
- subnet_length_entries[i].mask = g_htonl(ip_get_subnet_mask(length));
+ subnet_length_entries[i].mask = g_htonl(ws_ipv4_get_subnet_mask(length));
}
/* Check profile directory before personal configuration */
- subnetspath = get_persconffile_path(ENAME_SUBNETS, TRUE);
+ subnetspath = get_persconffile_path(ENAME_SUBNETS, true);
if (!read_subnets_file(subnetspath)) {
if (errno != ENOENT) {
- report_open_failure(subnetspath, errno, FALSE);
+ report_open_failure(subnetspath, errno, false);
}
g_free(subnetspath);
- subnetspath = get_persconffile_path(ENAME_SUBNETS, FALSE);
+ subnetspath = get_persconffile_path(ENAME_SUBNETS, false);
if (!read_subnets_file(subnetspath) && errno != ENOENT) {
- report_open_failure(subnetspath, errno, FALSE);
+ report_open_failure(subnetspath, errno, false);
}
}
g_free(subnetspath);
@@ -2749,14 +3039,14 @@ subnet_name_lookup_init(void)
*/
subnetspath = get_datafile_path(ENAME_SUBNETS);
if (!read_subnets_file(subnetspath) && errno != ENOENT) {
- report_open_failure(subnetspath, errno, FALSE);
+ report_open_failure(subnetspath, errno, false);
}
g_free(subnetspath);
}
/* SS7 PC Name Resolution Portion */
static hashss7pc_t *
-new_ss7pc(const guint8 ni, const guint32 pc)
+new_ss7pc(const uint8_t ni, const uint32_t pc)
{
hashss7pc_t *tp = wmem_new(addr_resolv_scope, hashss7pc_t);
tp->id = (ni<<24) + (pc&0xffffff);
@@ -2767,10 +3057,10 @@ new_ss7pc(const guint8 ni, const guint32 pc)
}
static hashss7pc_t *
-host_lookup_ss7pc(const guint8 ni, const guint32 pc)
+host_lookup_ss7pc(const uint8_t ni, const uint32_t pc)
{
hashss7pc_t * volatile tp;
- guint32 id;
+ uint32_t id;
id = (ni<<24) + (pc&0xffffff);
@@ -2783,15 +3073,15 @@ host_lookup_ss7pc(const guint8 ni, const guint32 pc)
return tp;
}
-void fill_unresolved_ss7pc(const gchar * pc_addr, const guint8 ni, const guint32 pc)
+void fill_unresolved_ss7pc(const char * pc_addr, const uint8_t ni, const uint32_t pc)
{
hashss7pc_t *tp = host_lookup_ss7pc(ni, pc);
(void) g_strlcpy(tp->pc_addr, pc_addr, MAXNAMELEN);
}
-const gchar *
-get_hostname_ss7pc(const guint8 ni, const guint32 pc)
+const char *
+get_hostname_ss7pc(const uint8_t ni, const uint32_t pc)
{
hashss7pc_t *tp = host_lookup_ss7pc(ni, pc);
@@ -2810,10 +3100,10 @@ get_hostname_ss7pc(const guint8 ni, const guint32 pc)
}
static void
-add_ss7pc_name(const guint8 ni, guint32 pc, const gchar *name)
+add_ss7pc_name(const uint8_t ni, uint32_t pc, const char *name)
{
hashss7pc_t *tp;
- guint32 id;
+ uint32_t id;
if (!name || name[0] == '\0')
return;
@@ -2830,21 +3120,21 @@ add_ss7pc_name(const guint8 ni, guint32 pc, const gchar *name)
}
}
-static gboolean
+static bool
read_ss7pcs_file(const char *ss7pcspath)
{
FILE *hf;
char line[MAX_LINELEN];
- gchar *cp;
- guint8 ni;
- guint32 pc;
- gboolean entry_found = FALSE;
+ char *cp;
+ uint8_t ni;
+ uint32_t pc;
+ bool 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;
+ return false;
while (fgetline(line, sizeof(line), hf) >= 0) {
if ((cp = strchr(line, '#')))
@@ -2867,12 +3157,12 @@ read_ss7pcs_file(const char *ss7pcspath)
if ((cp = strtok(NULL, " \t")) == NULL)
continue; /* no host name */
- entry_found = TRUE;
+ entry_found = true;
add_ss7pc_name(ni, pc, cp);
}
fclose(hf);
- return entry_found ? TRUE : FALSE;
+ return entry_found ? true : false;
}
static void
@@ -2887,9 +3177,9 @@ ss7pc_name_lookup_init(void)
/*
* Load the user's ss7pcs file
*/
- ss7pcspath = get_persconffile_path(ENAME_SS7PCS, TRUE);
+ ss7pcspath = get_persconffile_path(ENAME_SS7PCS, true);
if (!read_ss7pcs_file(ss7pcspath) && errno != ENOENT) {
- report_open_failure(ss7pcspath, errno, FALSE);
+ report_open_failure(ss7pcspath, errno, false);
}
g_free(ss7pcspath);
}
@@ -2928,6 +3218,11 @@ addr_resolve_pref_init(module_t *nameres)
"Use address/name pairs found in captured DNS packets for name resolution.",
&gbl_resolv_flags.dns_pkt_addr_resolution);
+ prefs_register_bool_preference(nameres, "handshake_sni_addr_resolution",
+ "Use SNI information from captured handshake packets",
+ "Use the Server Name Indication found in TLS handshakes for name resolution.",
+ &gbl_resolv_flags.handshake_sni_addr_resolution);
+
prefs_register_bool_preference(nameres, "use_external_name_resolver",
"Use your system's DNS settings for name resolution",
"Use your system's configured name resolver"
@@ -2938,7 +3233,7 @@ addr_resolve_pref_init(module_t *nameres)
prefs_register_bool_preference(nameres, "use_custom_dns_servers",
"Use a custom list of DNS servers for name resolution",
- "Use a DNS Servers list to resolve network names if TRUE. If FALSE, default information is used",
+ "Use a DNS Servers list to resolve network names if true. If false, default information is used",
&use_custom_dns_server_list);
static uat_field_t dns_server_uats_flds[] = {
@@ -2951,7 +3246,7 @@ addr_resolve_pref_init(module_t *nameres)
dnsserver_uat = uat_new("DNS Servers",
sizeof(struct dns_server_data),
"addr_resolve_dns_servers", /* filename */
- TRUE, /* from_profile */
+ true, /* from_profile */
&dnsserverlist_uats, /* data_ptr */
&ndnsservers, /* numitems_ptr */
UAT_AFFECTS_DISSECTION,
@@ -3006,49 +3301,32 @@ void addr_resolve_pref_apply(void)
void
disable_name_resolution(void) {
- gbl_resolv_flags.mac_name = FALSE;
- gbl_resolv_flags.network_name = FALSE;
- gbl_resolv_flags.transport_name = FALSE;
- 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;
- gbl_resolv_flags.maxmind_geoip = FALSE;
+ gbl_resolv_flags.mac_name = false;
+ gbl_resolv_flags.network_name = false;
+ gbl_resolv_flags.transport_name = false;
+ gbl_resolv_flags.dns_pkt_addr_resolution = false;
+ gbl_resolv_flags.handshake_sni_addr_resolution = false;
+ gbl_resolv_flags.use_external_net_name_resolver = false;
+ gbl_resolv_flags.vlan_name = false;
+ gbl_resolv_flags.ss7pc_name = false;
+ gbl_resolv_flags.maxmind_geoip = false;
}
-gboolean
+bool
host_name_lookup_process(void) {
- async_dns_queue_msg_t *caqm;
struct timeval tv = { 0, 0 };
int nfds;
fd_set rfds, wfds;
- gboolean nro = new_resolved_objects;
- wmem_list_frame_t* head;
+ bool nro = new_resolved_objects;
- new_resolved_objects = FALSE;
+ new_resolved_objects = false;
nro |= maxmind_db_lookup_process();
if (!async_dns_initialized)
/* c-ares not initialized. Bail out and cancel timers. */
return nro;
- head = wmem_list_head(async_dns_queue_head);
-
- while (head != NULL && async_dns_in_flight <= name_resolve_concurrency) {
- caqm = (async_dns_queue_msg_t *)wmem_list_frame_data(head);
- wmem_list_remove_frame(async_dns_queue_head, head);
- if (caqm->family == AF_INET) {
- ares_gethostbyaddr(ghba_chan, &caqm->addr.ip4, sizeof(guint32), AF_INET,
- c_ares_ghba_cb, caqm);
- async_dns_in_flight++;
- } else if (caqm->family == AF_INET6) {
- ares_gethostbyaddr(ghba_chan, &caqm->addr.ip6, sizeof(ws_in6_addr),
- AF_INET6, c_ares_ghba_cb, caqm);
- async_dns_in_flight++;
- }
-
- head = wmem_list_head(async_dns_queue_head);
- }
+ process_async_dns_queue();
FD_ZERO(&rfds);
FD_ZERO(&wfds);
@@ -3078,11 +3356,11 @@ _host_name_lookup_cleanup(void) {
#ifdef CARES_HAVE_ARES_LIBRARY_INIT
ares_library_cleanup();
#endif
- async_dns_initialized = FALSE;
+ async_dns_initialized = false;
}
-const gchar *
-get_hostname(const guint addr)
+const char *
+get_hostname(const unsigned addr)
{
/* XXX why do we call this if we're not resolving? To create hash entries?
* Why?
@@ -3099,7 +3377,7 @@ get_hostname(const guint addr)
/* -------------------------- */
-const gchar *
+const char *
get_hostname6(const ws_in6_addr *addr)
{
/* XXX why do we call this if we're not resolving? To create hash entries?
@@ -3117,7 +3395,7 @@ get_hostname6(const ws_in6_addr *addr)
/* -------------------------- */
void
-add_ipv4_name(const guint addr, const gchar *name, gboolean static_entry)
+add_ipv4_name(const unsigned addr, const char *name, bool static_entry)
{
hashipv4_t *tp;
@@ -3136,7 +3414,7 @@ add_ipv4_name(const guint addr, const gchar *name, gboolean static_entry)
if (g_ascii_strcasecmp(tp->name, name) && (static_entry || !(tp->flags & STATIC_HOSTNAME))) {
(void) g_strlcpy(tp->name, name, MAXNAMELEN);
- new_resolved_objects = TRUE;
+ new_resolved_objects = true;
if (static_entry)
tp->flags |= STATIC_HOSTNAME;
}
@@ -3145,7 +3423,7 @@ add_ipv4_name(const guint addr, const gchar *name, gboolean static_entry)
/* -------------------------- */
void
-add_ipv6_name(const ws_in6_addr *addrp, const gchar *name, const gboolean static_entry)
+add_ipv6_name(const ws_in6_addr *addrp, const char *name, const bool static_entry)
{
hashipv6_t *tp;
@@ -3168,7 +3446,7 @@ add_ipv6_name(const ws_in6_addr *addrp, const gchar *name, const gboolean static
if (g_ascii_strcasecmp(tp->name, name) && (static_entry || !(tp->flags & STATIC_HOSTNAME))) {
(void) g_strlcpy(tp->name, name, MAXNAMELEN);
- new_resolved_objects = TRUE;
+ new_resolved_objects = true;
if (static_entry)
tp->flags |= STATIC_HOSTNAME;
}
@@ -3176,17 +3454,17 @@ add_ipv6_name(const ws_in6_addr *addrp, const gchar *name, const gboolean static
} /* add_ipv6_name */
static void
-add_manually_resolved_ipv4(gpointer key, gpointer value, gpointer user_data _U_)
+add_manually_resolved_ipv4(void *key, void *value, void *user_data _U_)
{
resolved_name_t *resolved_ipv4_entry = (resolved_name_t*)value;
- add_ipv4_name(GPOINTER_TO_UINT(key), resolved_ipv4_entry->name, TRUE);
+ add_ipv4_name(GPOINTER_TO_UINT(key), resolved_ipv4_entry->name, true);
}
static void
-add_manually_resolved_ipv6(gpointer key, gpointer value, gpointer user_data _U_)
+add_manually_resolved_ipv6(void *key, void *value, void *user_data _U_)
{
resolved_name_t *resolved_ipv6_entry = (resolved_name_t*)value;
- add_ipv6_name((ws_in6_addr*)key, resolved_ipv6_entry->name, TRUE);
+ add_ipv6_name((ws_in6_addr*)key, resolved_ipv6_entry->name, true);
}
static void
@@ -3205,7 +3483,7 @@ static void
host_name_lookup_init(void)
{
char *hostspath;
- guint i;
+ unsigned i;
ws_assert(ipxnet_hash_table == NULL);
ipxnet_hash_table = wmem_map_new(addr_resolv_scope, g_direct_hash, g_direct_equal);
@@ -3236,23 +3514,24 @@ host_name_lookup_init(void)
* Load the global hosts file, if we have one.
*/
hostspath = get_datafile_path(ENAME_HOSTS);
- if (!read_hosts_file(hostspath, TRUE) && errno != ENOENT) {
- report_open_failure(hostspath, errno, FALSE);
+ if (!read_hosts_file(hostspath, true) && errno != ENOENT) {
+ report_open_failure(hostspath, errno, false);
}
g_free(hostspath);
/*
* Load the user's hosts file no matter what, if they have one.
*/
- hostspath = get_persconffile_path(ENAME_HOSTS, TRUE);
- if (!read_hosts_file(hostspath, TRUE) && errno != ENOENT) {
- report_open_failure(hostspath, errno, FALSE);
+ hostspath = get_persconffile_path(ENAME_HOSTS, true);
+ if (!read_hosts_file(hostspath, true) && errno != ENOENT) {
+ report_open_failure(hostspath, errno, false);
}
g_free(hostspath);
#ifdef CARES_HAVE_ARES_LIBRARY_INIT
if (ares_library_init(ARES_LIB_INIT_ALL) == ARES_SUCCESS) {
#endif
- if (ares_init(&ghba_chan) == ARES_SUCCESS && ares_init(&ghbn_chan) == ARES_SUCCESS) {
- async_dns_initialized = TRUE;
+ /* XXX - Check which options we should set */
+ if (ares_init_options(&ghba_chan, NULL, 0) == ARES_SUCCESS && ares_init_options(&ghbn_chan, NULL, 0) == ARES_SUCCESS) {
+ async_dns_initialized = true;
c_ares_set_dns_servers();
}
#ifdef CARES_HAVE_ARES_LIBRARY_INIT
@@ -3261,7 +3540,7 @@ host_name_lookup_init(void)
if (extra_hosts_files) {
for (i = 0; i < extra_hosts_files->len; i++) {
- read_hosts_file((const char *) g_ptr_array_index(extra_hosts_files, i), TRUE);
+ read_hosts_file((const char *) g_ptr_array_index(extra_hosts_files, i), true);
}
}
@@ -3275,7 +3554,7 @@ host_name_lookup_init(void)
static void
host_name_lookup_cleanup(void)
{
- guint32 i, j;
+ uint32_t i, j;
sub_net_hashipv4_t *entry, *next_entry;
_host_name_lookup_cleanup();
@@ -3299,8 +3578,8 @@ host_name_lookup_cleanup(void)
}
}
- have_subnet_entry = FALSE;
- new_resolved_objects = FALSE;
+ have_subnet_entry = false;
+ new_resolved_objects = false;
}
@@ -3310,8 +3589,8 @@ void host_name_lookup_reset(void)
addr_resolv_init();
}
-gchar *
-udp_port_to_display(wmem_allocator_t *allocator, guint port)
+char *
+udp_port_to_display(wmem_allocator_t *allocator, unsigned port)
{
if (!gbl_resolv_flags.transport_name) {
@@ -3322,8 +3601,8 @@ udp_port_to_display(wmem_allocator_t *allocator, guint port)
} /* udp_port_to_display */
-gchar *
-dccp_port_to_display(wmem_allocator_t *allocator, guint port)
+char *
+dccp_port_to_display(wmem_allocator_t *allocator, unsigned port)
{
if (!gbl_resolv_flags.transport_name) {
@@ -3334,8 +3613,8 @@ dccp_port_to_display(wmem_allocator_t *allocator, guint port)
} /* dccp_port_to_display */
-gchar *
-tcp_port_to_display(wmem_allocator_t *allocator, guint port)
+char *
+tcp_port_to_display(wmem_allocator_t *allocator, unsigned port)
{
if (!gbl_resolv_flags.transport_name) {
@@ -3346,8 +3625,8 @@ tcp_port_to_display(wmem_allocator_t *allocator, guint port)
} /* tcp_port_to_display */
-gchar *
-sctp_port_to_display(wmem_allocator_t *allocator, guint port)
+char *
+sctp_port_to_display(wmem_allocator_t *allocator, unsigned port)
{
if (!gbl_resolv_flags.transport_name) {
@@ -3358,10 +3637,10 @@ sctp_port_to_display(wmem_allocator_t *allocator, guint port)
} /* sctp_port_to_display */
-gchar *
-port_with_resolution_to_str(wmem_allocator_t *scope, port_type proto, guint port)
+char *
+port_with_resolution_to_str(wmem_allocator_t *scope, port_type proto, unsigned port)
{
- const gchar *port_str;
+ const char *port_str;
if (!gbl_resolv_flags.transport_name || (proto == PT_NONE)) {
/* No name resolution support, just return port string */
@@ -3373,9 +3652,9 @@ port_with_resolution_to_str(wmem_allocator_t *scope, port_type proto, guint port
}
int
-port_with_resolution_to_str_buf(gchar *buf, gulong buf_size, port_type proto, guint port)
+port_with_resolution_to_str_buf(char *buf, unsigned long buf_size, port_type proto, unsigned port)
{
- const gchar *port_str;
+ const char *port_str;
if (!gbl_resolv_flags.transport_name || (proto == PT_NONE)) {
/* No name resolution support, just return port string */
@@ -3386,11 +3665,11 @@ port_with_resolution_to_str_buf(gchar *buf, gulong buf_size, port_type proto, gu
return snprintf(buf, buf_size, "%s (%u)", port_str, port);
}
-const gchar *
-get_ether_name(const guint8 *addr)
+const char *
+get_ether_name(const uint8_t *addr)
{
hashether_t *tp;
- gboolean resolve = gbl_resolv_flags.mac_name;
+ bool resolve = gbl_resolv_flags.mac_name;
tp = eth_name_lookup(addr, resolve);
@@ -3398,8 +3677,8 @@ get_ether_name(const guint8 *addr)
} /* get_ether_name */
-const gchar *
-tvb_get_ether_name(tvbuff_t *tvb, gint offset)
+const char *
+tvb_get_ether_name(tvbuff_t *tvb, int offset)
{
return get_ether_name(tvb_get_ptr(tvb, offset, 6));
}
@@ -3407,8 +3686,8 @@ tvb_get_ether_name(tvbuff_t *tvb, gint offset)
/* Look for a (non-dummy) ether name in the hash, and return it if found.
* If it's not found, simply return NULL.
*/
-const gchar *
-get_ether_name_if_known(const guint8 *addr)
+const char *
+get_ether_name_if_known(const uint8_t *addr)
{
hashether_t *tp;
@@ -3419,10 +3698,10 @@ get_ether_name_if_known(const guint8 *addr)
/* eth_name_lookup will create a (resolved) hash entry
* if it doesn't exist, so it never returns NULL */
- tp = eth_name_lookup(addr, TRUE);
+ tp = eth_name_lookup(addr, true);
- if (tp->status == HASHETHER_STATUS_RESOLVED_NAME) {
- /* Name is from an ethers file */
+ if ((tp->flags & (NAME_RESOLVED | NAME_RESOLVED_PREFIX)) == NAME_RESOLVED) {
+ /* Name is from an exact match, not a prefix/OUI */
return tp->resolved_name;
}
else {
@@ -3432,7 +3711,7 @@ get_ether_name_if_known(const guint8 *addr)
}
void
-add_ether_byip(const guint ip, const guint8 *eth)
+add_ether_byip(const unsigned ip, const uint8_t *eth)
{
hashipv4_t *tp;
@@ -3455,8 +3734,8 @@ add_ether_byip(const guint ip, const guint8 *eth)
} /* add_ether_byip */
-gchar *
-get_ipxnet_name(wmem_allocator_t *allocator, const guint32 addr)
+char *
+get_ipxnet_name(wmem_allocator_t *allocator, const uint32_t addr)
{
if (!gbl_resolv_flags.network_name) {
@@ -3467,8 +3746,8 @@ get_ipxnet_name(wmem_allocator_t *allocator, const guint32 addr)
} /* get_ipxnet_name */
-gchar *
-get_vlan_name(wmem_allocator_t *allocator, const guint16 id)
+char *
+get_vlan_name(wmem_allocator_t *allocator, const uint16_t id)
{
if (!gbl_resolv_flags.vlan_name) {
@@ -3479,114 +3758,126 @@ get_vlan_name(wmem_allocator_t *allocator, const guint16 id)
} /* get_vlan_name */
-const gchar *
-get_manuf_name(const guint8 *addr, size_t size)
+const char *
+get_manuf_name(const uint8_t *addr, size_t size)
{
hashmanuf_t *manuf_value;
+ ws_return_val_if(size < 3, NULL);
+
manuf_value = manuf_name_lookup(addr, size);
- if (gbl_resolv_flags.mac_name && manuf_value->status != HASHETHER_STATUS_UNRESOLVED)
+ if (gbl_resolv_flags.mac_name && ((manuf_value->flags & NAME_RESOLVED) == NAME_RESOLVED))
return manuf_value->resolved_name;
return manuf_value->hexaddr;
} /* get_manuf_name */
-const gchar *
-tvb_get_manuf_name(tvbuff_t *tvb, gint offset)
+const char *
+tvb_get_manuf_name(tvbuff_t *tvb, int offset)
{
- guint8 buf[6] = { 0 };
+ uint8_t buf[3] = { 0 };
tvb_memcpy(tvb, buf, offset, 3);
return get_manuf_name(buf, sizeof(buf));
}
-const gchar *
-get_manuf_name_if_known(const guint8 *addr, size_t size)
+const char *
+get_manuf_name_if_known(const uint8_t *addr, size_t size)
{
hashmanuf_t *manuf_value;
- guint manuf_key;
- guint8 oct;
- ws_return_val_if(size != 6, NULL);
+ ws_return_val_if(size < 3, NULL);
- /* manuf needs only the 3 most significant octets of the ethernet address */
- manuf_key = addr[0];
- manuf_key = manuf_key<<8;
- oct = addr[1];
- manuf_key = manuf_key | oct;
- manuf_key = manuf_key<<8;
- oct = addr[2];
- manuf_key = manuf_key | oct;
-
- manuf_value = (hashmanuf_t *)wmem_map_lookup(manuf_hashtable, GUINT_TO_POINTER(manuf_key));
- if (manuf_value != NULL && manuf_value->status != HASHETHER_STATUS_UNRESOLVED) {
+ manuf_value = manuf_name_lookup(addr, size);
+ if (manuf_value != NULL && ((manuf_value->flags & NAME_RESOLVED) == NAME_RESOLVED)) {
return manuf_value->resolved_longname;
}
- /* Try the global manuf tables. */
- const char *short_name, *long_name;
- short_name = ws_manuf_lookup_str(addr, &long_name);
- if (short_name != NULL) {
- /* Found it */
- return long_name;
+ if (size >= 6) {
+ /* Try the global manuf tables. */
+ const char *short_name, *long_name;
+ short_name = ws_manuf_lookup_str(addr, &long_name);
+ if (short_name != NULL) {
+ /* Found it */
+ return long_name;
+ }
}
return NULL;
} /* get_manuf_name_if_known */
-const gchar *
-uint_get_manuf_name_if_known(const guint32 manuf_key)
+const char *
+uint_get_manuf_name_if_known(const uint32_t manuf_key)
{
- hashmanuf_t *manuf_value;
- guint8 addr[6] = { 0 };
-
- manuf_value = (hashmanuf_t *)wmem_map_lookup(manuf_hashtable, GUINT_TO_POINTER(manuf_key));
- if (manuf_value != NULL && manuf_value->status != HASHETHER_STATUS_UNRESOLVED) {
- return manuf_value->resolved_longname;
- }
-
+ uint8_t addr[6] = { 0 };
addr[0] = (manuf_key >> 16) & 0xFF;
addr[1] = (manuf_key >> 8) & 0xFF;
addr[2] = manuf_key & 0xFF;
- /* Try the global manuf tables. */
- const char *short_name, *long_name;
- short_name = ws_manuf_lookup_str(addr, &long_name);
- if (short_name != NULL) {
- /* Found it */
- return long_name;
- }
-
- return NULL;
+ return get_manuf_name_if_known(addr, sizeof(addr));
}
-const gchar *
-tvb_get_manuf_name_if_known(tvbuff_t *tvb, gint offset)
+const char *
+tvb_get_manuf_name_if_known(tvbuff_t *tvb, int offset)
{
- guint8 buf[6] = { 0 };
+ uint8_t buf[3] = { 0 };
tvb_memcpy(tvb, buf, offset, 3);
return get_manuf_name_if_known(buf, sizeof(buf));
}
+bool get_hash_manuf_used(hashmanuf_t* manuf)
+{
+ return ((manuf->flags & TRIED_OR_RESOLVED_MASK) == TRIED_OR_RESOLVED_MASK);
+}
+
char* get_hash_manuf_resolved_name(hashmanuf_t* manuf)
{
return manuf->resolved_longname;
}
-gchar *
-eui64_to_display(wmem_allocator_t *allocator, const guint64 addr_eui64)
+char *
+eui64_to_display(wmem_allocator_t *allocator, const uint64_t addr_eui64)
{
- guint8 *addr = (guint8 *)wmem_alloc(NULL, 8);
+ uint8_t *addr = (uint8_t *)wmem_alloc(NULL, 8);
hashmanuf_t *manuf_value;
- gchar *ret;
+ char *ret;
/* Copy and convert the address to network byte order. */
- *(guint64 *)(void *)(addr) = pntoh64(&(addr_eui64));
+ *(uint64_t *)(void *)(addr) = pntoh64(&(addr_eui64));
+ /* manuf_name_lookup returns a hashmanuf_t* that covers an entire /24,
+ * so we can't properly use it for MA-M and MA-S. We do want to check
+ * it first so it also covers the user-defined tables.
+ */
manuf_value = manuf_name_lookup(addr, 8);
- if (!gbl_resolv_flags.mac_name || (manuf_value->status == HASHETHER_STATUS_UNRESOLVED)) {
- ret = wmem_strdup_printf(allocator, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]);
+ if (!gbl_resolv_flags.mac_name || !manuf_value || ((manuf_value->flags & NAME_RESOLVED) == 0)) {
+ /* Now try looking in the global manuf data for a MA-M or MA-S match.
+ */
+ const char *short_name, *long_name;
+ unsigned mask;
+ short_name = ws_manuf_lookup(addr, &long_name, &mask);
+ if (short_name != NULL) {
+ switch (mask) {
+ case 24:
+ /* This shouldn't happen as it should be handled above. */
+ manuf_hash_new_entry(addr, short_name, long_name);
+ ret = wmem_strdup_printf(allocator, "%s_%02x:%02x:%02x:%02x:%02x", short_name, addr[3], addr[4], addr[5], addr[6], addr[7]);
+ break;
+ case 28:
+ ret = wmem_strdup_printf(allocator, "%s_%01x:%02x:%02x:%02x:%02x", short_name, addr[3] & 0x0F, addr[4], addr[5], addr[6], addr[7]);
+ break;
+ case 36:
+ ret = wmem_strdup_printf(allocator, "%s_%01x:%02x:%02x:%02x", short_name, addr[4] & 0x0F, addr[5], addr[6], addr[7]);
+ break;
+ default:
+ /* Doesn't happen, ignore for now. */
+ ret = wmem_strdup_printf(allocator, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]);
+ break;
+ }
+ } else {
+ ret = wmem_strdup_printf(allocator, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]);
+ }
} else {
ret = wmem_strdup_printf(allocator, "%s_%02x:%02x:%02x:%02x:%02x", manuf_value->resolved_name, addr[3], addr[4], addr[5], addr[6], addr[7]);
}
@@ -3601,6 +3892,8 @@ c_ares_ghi_cb(void *arg, int status, int timeouts _U_, struct hostent *hp) {
/*
* XXX - If we wanted to be really fancy we could cache results here and
* look them up in get_host_ipaddr* below.
+ *
+ * XXX - This only gets the first host address if there's more than one.
*/
async_hostent_t *ahp = (async_hostent_t *)arg;
if (status == ARES_SUCCESS && hp && ahp && hp->h_length == ahp->addr_size) {
@@ -3610,10 +3903,10 @@ c_ares_ghi_cb(void *arg, int status, int timeouts _U_, struct hostent *hp) {
}
/* Translate a string, assumed either to be a dotted-quad IPv4 address or
- * a host name, to a numeric IPv4 address. Return TRUE if we succeed and
- * set "*addrp" to that numeric IPv4 address; return FALSE if we fail. */
-gboolean
-get_host_ipaddr(const char *host, guint32 *addrp)
+ * a host name, to a numeric IPv4 address. Return true if we succeed and
+ * set "*addrp" to that numeric IPv4 address; return false if we fail. */
+bool
+get_host_ipaddr(const char *host, uint32_t *addrp)
{
struct timeval tv = { 0, GHI_TIMEOUT }, *tvp;
int nfds;
@@ -3633,14 +3926,17 @@ get_host_ipaddr(const char *host, guint32 *addrp)
/* If we're not allowed to do name resolution, don't do name
* resolution...
+ * XXX - What if we're allowed to do name resolution, and the name
+ * is in a DNS packet we've dissected or in a Name Resolution Block,
+ * or a user-entered manual name resolution?
*/
if (!gbl_resolv_flags.network_name ||
!gbl_resolv_flags.use_external_net_name_resolver) {
- return FALSE;
+ return false;
}
if (!async_dns_initialized || name_resolve_concurrency < 1) {
- return FALSE;
+ return false;
}
ahe.addr_size = (int) sizeof (struct in_addr);
ahe.copied = 0;
@@ -3655,26 +3951,26 @@ get_host_ipaddr(const char *host, guint32 *addrp)
/* If it's interrupted by a signal, no need to put out a message */
if (errno != EINTR)
fprintf(stderr, "Warning: call to select() failed, error is %s\n", g_strerror(errno));
- return FALSE;
+ return false;
}
ares_process(ghbn_chan, &rfds, &wfds);
}
ares_cancel(ghbn_chan);
if (ahe.addr_size == ahe.copied) {
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
/*
* Translate IPv6 numeric address or FQDN hostname into binary IPv6 address.
- * Return TRUE if we succeed and set "*addrp" to that numeric IPv6 address;
- * return FALSE if we fail.
+ * Return true if we succeed and set "*addrp" to that numeric IPv6 address;
+ * return false if we fail.
*/
-gboolean
+bool
get_host_ipaddr6(const char *host, ws_in6_addr *addrp)
{
struct timeval tv = { 0, GHI_TIMEOUT }, *tvp;
@@ -3683,7 +3979,7 @@ get_host_ipaddr6(const char *host, ws_in6_addr *addrp)
async_hostent_t ahe;
if (str_to_ip6(host, addrp))
- return TRUE;
+ return true;
/* It's not a valid dotted-quad IP address; is it a valid
* host name?
@@ -3695,15 +3991,18 @@ get_host_ipaddr6(const char *host, ws_in6_addr *addrp)
/* If we're not allowed to do name resolution, don't do name
* resolution...
+ * XXX - What if we're allowed to do name resolution, and the name
+ * is in a DNS packet we've dissected or in a Name Resolution Block,
+ * or a user-entered manual name resolution?
*/
if (!gbl_resolv_flags.network_name ||
!gbl_resolv_flags.use_external_net_name_resolver) {
- return FALSE;
+ return false;
}
/* try FQDN */
if (!async_dns_initialized || name_resolve_concurrency < 1) {
- return FALSE;
+ return false;
}
ahe.addr_size = (int) sizeof (ws_in6_addr);
ahe.copied = 0;
@@ -3718,16 +4017,16 @@ get_host_ipaddr6(const char *host, ws_in6_addr *addrp)
/* If it's interrupted by a signal, no need to put out a message */
if (errno != EINTR)
fprintf(stderr, "Warning: call to select() failed, error is %s\n", g_strerror(errno));
- return FALSE;
+ return false;
}
ares_process(ghbn_chan, &rfds, &wfds);
}
ares_cancel(ghbn_chan);
if (ahe.addr_size == ahe.copied) {
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
wmem_map_t *
@@ -3806,13 +4105,13 @@ addr_resolv_cleanup(void)
addr_resolv_scope = NULL;
}
-gboolean
+bool
str_to_ip(const char *str, void *dst)
{
- return ws_inet_pton4(str, (guint32 *)dst);
+ return ws_inet_pton4(str, (uint32_t *)dst);
}
-gboolean
+bool
str_to_ip6(const char *str, void *dst)
{
return ws_inet_pton6(str, (ws_in6_addr *)dst);
@@ -3823,16 +4122,16 @@ str_to_ip6(const char *str, void *dst)
* the corresponding sequence of 6 bytes
* eth_bytes is a buffer >= 6 bytes that was allocated by the caller
*/
-gboolean
+bool
str_to_eth(const char *str, char *eth_bytes)
{
ether_t eth;
- if (!parse_ether_address(str, &eth, NULL, FALSE))
- return FALSE;
+ if (!parse_ether_address(str, &eth, NULL, false))
+ return false;
memcpy(eth_bytes, eth.addr, sizeof(eth.addr));
- return TRUE;
+ return true;
}
/*