2004-08-09 22:31:21 +00:00
|
|
|
/* addr_resolv.c
|
1998-09-16 02:39:15 +00:00
|
|
|
* Routines for network object lookup
|
|
|
|
*
|
2003-01-26 19:35:31 +00:00
|
|
|
* Laurent Deniel <laurent.deniel@free.fr>
|
1998-09-16 02:39:15 +00:00
|
|
|
*
|
2016-03-13 22:16:20 +00:00
|
|
|
* Add option to resolv VLAN ID to describing name
|
|
|
|
* Uli Heilmeier, March 2016
|
|
|
|
*
|
2006-05-21 05:12:17 +00:00
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
1998-09-16 02:39:15 +00:00
|
|
|
* Copyright 1998 Gerald Combs
|
2002-08-28 20:41:00 +00:00
|
|
|
*
|
2018-02-08 16:59:17 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
1998-09-16 02:39:15 +00:00
|
|
|
*/
|
|
|
|
|
2012-09-20 01:48:30 +00:00
|
|
|
#include "config.h"
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
#include <stdio.h>
|
1998-12-17 05:42:33 +00:00
|
|
|
#include <stdlib.h>
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <string.h>
|
2005-01-13 09:09:56 +00:00
|
|
|
#include <errno.h>
|
1999-07-13 02:53:26 +00:00
|
|
|
|
2016-09-09 15:16:10 +00:00
|
|
|
#include <wsutil/strtoi.h>
|
2021-06-18 18:21:42 +00:00
|
|
|
#include <wsutil/ws_assert.h>
|
2016-09-09 15:16:10 +00:00
|
|
|
|
2003-11-20 05:04:57 +00:00
|
|
|
/*
|
2004-10-05 22:48:36 +00:00
|
|
|
* Win32 doesn't have SIGALRM (and it's the OS where name lookup calls
|
|
|
|
* are most likely to take a long time, given the way address-to-name
|
|
|
|
* lookups are done over NBNS).
|
2003-11-20 05:04:57 +00:00
|
|
|
*
|
2017-04-05 19:15:27 +00:00
|
|
|
* macOS does have SIGALRM, but if you longjmp() out of a name resolution
|
2004-10-05 22:48:36 +00:00
|
|
|
* call in a signal handler, you might crash, because the state of the
|
|
|
|
* resolution code that sends messages to lookupd might be inconsistent
|
|
|
|
* if you jump out of it in middle of a call.
|
|
|
|
*
|
2003-11-20 05:04:57 +00:00
|
|
|
* There's no guarantee that longjmp()ing out of name resolution calls
|
|
|
|
* will work on *any* platform; OpenBSD got rid of the alarm/longjmp
|
|
|
|
* code in tcpdump, to avoid those sorts of problems, and that was
|
|
|
|
* picked up by tcpdump.org tcpdump.
|
2004-10-05 22:48:36 +00:00
|
|
|
*
|
2014-12-31 22:47:04 +00:00
|
|
|
* So, for now, we do not use alarm() and SIGALRM to time out host name
|
|
|
|
* lookups. If we get a lot of complaints about lookups taking a long time,
|
|
|
|
* we can reconsider that decision. (Note that tcpdump originally added
|
|
|
|
* such a timeout mechanism that for the benefit of systems using NIS to
|
|
|
|
* look up host names; that might now be fixed in NIS implementations, for
|
|
|
|
* those sites still using NIS rather than DNS for that.... tcpdump no
|
|
|
|
* longer does that, for the same reasons that we don't.)
|
|
|
|
*
|
|
|
|
* If we're using an asynchronous DNS resolver, that shouldn't be an issue.
|
|
|
|
* If we're using a synchronous name lookup mechanism (which we'd do mainly
|
|
|
|
* to support resolving addresses and host names using more mechanisms than
|
|
|
|
* just DNS, such as NIS, NBNS, or Mr. Hosts File), we could do that in
|
|
|
|
* a separate thread, making it, in effect, asynchronous.
|
2003-11-20 05:04:57 +00:00
|
|
|
*/
|
1999-07-13 02:53:26 +00:00
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
|
|
# include <netinet/in.h>
|
|
|
|
#endif
|
|
|
|
|
1999-07-13 02:53:26 +00:00
|
|
|
#ifdef HAVE_NETDB_H
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <netdb.h>
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_SOCKET_H
|
2009-09-07 16:07:04 +00:00
|
|
|
#include <sys/socket.h> /* needed to define AF_ values on UNIX */
|
2002-10-29 00:28:11 +00:00
|
|
|
#endif
|
|
|
|
|
2015-11-19 11:24:44 +00:00
|
|
|
#ifdef _WIN32
|
2017-10-26 00:42:15 +00:00
|
|
|
#include <winsock2.h> /* needed to define AF_ values on Windows */
|
|
|
|
#include <ws2tcpip.h>
|
2003-08-18 18:40:10 +00:00
|
|
|
#endif
|
|
|
|
|
2019-11-22 19:16:36 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
# define socklen_t unsigned int
|
|
|
|
#endif
|
|
|
|
#include <ares.h>
|
|
|
|
#include <ares_version.h>
|
2008-08-11 21:59:59 +00:00
|
|
|
|
2005-01-13 09:09:56 +00:00
|
|
|
#include <glib.h>
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
#include "packet.h"
|
2013-07-12 05:59:56 +00:00
|
|
|
#include "addr_and_mask.h"
|
2016-01-03 20:30:57 +00:00
|
|
|
#include "ipv6.h"
|
2004-08-06 19:57:49 +00:00
|
|
|
#include "addr_resolv.h"
|
2013-11-17 02:55:14 +00:00
|
|
|
#include "wsutil/filesystem.h"
|
2007-10-26 05:42:12 +00:00
|
|
|
|
2017-04-08 19:45:19 +00:00
|
|
|
#include <wsutil/report_message.h>
|
2008-05-22 15:46:27 +00:00
|
|
|
#include <wsutil/file_util.h>
|
2013-11-09 15:44:29 +00:00
|
|
|
#include <wsutil/pint.h>
|
2016-02-10 09:11:12 +00:00
|
|
|
#include <wsutil/inet_addr.h>
|
2013-07-15 02:48:26 +00:00
|
|
|
|
|
|
|
#include <epan/strutil.h>
|
2021-09-16 13:54:09 +00:00
|
|
|
#include <epan/to_str.h>
|
2018-02-09 01:20:26 +00:00
|
|
|
#include <epan/maxmind_db.h>
|
2004-09-27 22:55:15 +00:00
|
|
|
#include <epan/prefs.h>
|
2019-09-01 16:02:27 +00:00
|
|
|
#include <epan/uat.h>
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2009-09-07 16:07:04 +00:00
|
|
|
#define ENAME_HOSTS "hosts"
|
|
|
|
#define ENAME_SUBNETS "subnets"
|
2009-09-13 17:24:51 +00:00
|
|
|
#define ENAME_ETHERS "ethers"
|
|
|
|
#define ENAME_IPXNETS "ipxnets"
|
2009-09-07 16:07:04 +00:00
|
|
|
#define ENAME_MANUF "manuf"
|
2017-07-20 01:32:40 +00:00
|
|
|
#define ENAME_WKA "wka"
|
2009-09-07 16:07:04 +00:00
|
|
|
#define ENAME_SERVICES "services"
|
2016-03-13 22:16:20 +00:00
|
|
|
#define ENAME_VLANS "vlans"
|
2016-09-13 04:46:06 +00:00
|
|
|
#define ENAME_SS7PCS "ss7pcs"
|
2017-07-13 20:03:13 +00:00
|
|
|
#define ENAME_ENTERPRISES "enterprises.tsv"
|
2009-09-07 16:07:04 +00:00
|
|
|
|
2010-06-28 22:43:13 +00:00
|
|
|
#define HASHETHSIZE 2048
|
|
|
|
#define HASHHOSTSIZE 2048
|
|
|
|
#define HASHIPXNETSIZE 256
|
|
|
|
#define SUBNETLENGTHSIZE 32 /*1-32 inc.*/
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2004-11-17 08:53:20 +00:00
|
|
|
/* hash table used for IPv4 lookup */
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2009-09-04 10:53:37 +00:00
|
|
|
#define HASH_IPV4_ADDRESS(addr) (g_htonl(addr) & (HASHHOSTSIZE - 1))
|
2001-06-07 22:07:02 +00:00
|
|
|
|
2013-08-11 19:02:26 +00:00
|
|
|
|
|
|
|
typedef struct sub_net_hashipv4 {
|
|
|
|
guint addr;
|
2017-06-09 08:03:38 +00:00
|
|
|
/* XXX: No longer needed?*/
|
2013-10-10 19:17:48 +00:00
|
|
|
guint8 flags; /* B0 dummy_entry, B1 resolve, B2 If the address is used in the trace */
|
2013-08-11 19:02:26 +00:00
|
|
|
struct sub_net_hashipv4 *next;
|
|
|
|
gchar name[MAXNAMELEN];
|
|
|
|
} sub_net_hashipv4_t;
|
2004-11-17 08:53:20 +00:00
|
|
|
|
2008-01-21 21:44:34 +00:00
|
|
|
/* Array of entries of subnets of different lengths */
|
|
|
|
typedef struct {
|
2013-08-11 00:50:51 +00:00
|
|
|
gsize mask_length; /*1-32*/
|
|
|
|
guint32 mask; /* e.g. 255.255.255.*/
|
2013-08-11 19:02:26 +00:00
|
|
|
sub_net_hashipv4_t** subnet_addresses; /* Hash table of subnet addresses */
|
2008-01-21 21:44:34 +00:00
|
|
|
} subnet_length_entry_t;
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-11-21 16:32:23 +00:00
|
|
|
/* hash table used for IPX network lookup */
|
|
|
|
|
2001-06-07 22:07:02 +00:00
|
|
|
/* XXX - check goodness of hash function */
|
|
|
|
|
2009-09-07 16:07:04 +00:00
|
|
|
#define HASH_IPX_NET(net) ((net) & (HASHIPXNETSIZE - 1))
|
2001-06-07 22:07:02 +00:00
|
|
|
|
2004-11-17 08:53:20 +00:00
|
|
|
typedef struct hashipxnet {
|
2013-08-11 00:50:51 +00:00
|
|
|
guint addr;
|
|
|
|
struct hashipxnet *next;
|
|
|
|
gchar name[MAXNAMELEN];
|
2004-11-17 08:53:20 +00:00
|
|
|
} hashipxnet_t;
|
1999-11-21 16:32:23 +00:00
|
|
|
|
2016-03-13 22:16:20 +00:00
|
|
|
typedef struct hashvlan {
|
|
|
|
guint id;
|
|
|
|
/* struct hashvlan *next; */
|
|
|
|
gchar name[MAXVLANNAMELEN];
|
|
|
|
} hashvlan_t;
|
|
|
|
|
2016-09-13 04:46:06 +00:00
|
|
|
typedef struct ss7pc {
|
|
|
|
guint32 id; /* 1st byte NI, 3 following bytes: Point Code */
|
|
|
|
gchar pc_addr[MAXNAMELEN];
|
|
|
|
gchar name[MAXNAMELEN];
|
|
|
|
} hashss7pc_t;
|
|
|
|
|
1998-09-25 23:24:07 +00:00
|
|
|
/* hash tables used for ethernet and manufacturer lookup */
|
2010-07-01 15:11:02 +00:00
|
|
|
#define HASHETHER_STATUS_UNRESOLVED 1
|
|
|
|
#define HASHETHER_STATUS_RESOLVED_DUMMY 2
|
|
|
|
#define HASHETHER_STATUS_RESOLVED_NAME 3
|
|
|
|
|
2015-02-14 17:00:36 +00:00
|
|
|
struct hashether {
|
2013-08-11 00:50:51 +00:00
|
|
|
guint status; /* (See above) */
|
|
|
|
guint8 addr[6];
|
|
|
|
char hexaddr[6*3];
|
|
|
|
char resolved_name[MAXNAMELEN];
|
2015-02-14 17:00:36 +00:00
|
|
|
};
|
2015-02-12 08:33:02 +00:00
|
|
|
|
2015-02-16 18:37:58 +00:00
|
|
|
struct hashmanuf {
|
2015-02-12 03:16:01 +00:00
|
|
|
guint status; /* (See above) */
|
|
|
|
guint8 addr[3];
|
|
|
|
char hexaddr[3*3];
|
|
|
|
char resolved_name[MAXNAMELEN];
|
2017-08-20 17:33:53 +00:00
|
|
|
char resolved_longname[MAXNAMELEN];
|
2015-02-16 18:37:58 +00:00
|
|
|
};
|
2015-02-12 03:16:01 +00:00
|
|
|
|
|
|
|
/* internal ethernet type */
|
1998-09-25 23:24:07 +00:00
|
|
|
typedef struct _ether
|
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
guint8 addr[6];
|
|
|
|
char name[MAXNAMELEN];
|
2017-08-20 17:33:53 +00:00
|
|
|
char longname[MAXNAMELEN];
|
1998-09-25 23:24:07 +00:00
|
|
|
} ether_t;
|
|
|
|
|
1999-11-21 16:32:23 +00:00
|
|
|
/* internal ipxnet type */
|
|
|
|
typedef struct _ipxnet
|
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
guint addr;
|
|
|
|
char name[MAXNAMELEN];
|
1999-11-21 16:32:23 +00:00
|
|
|
} ipxnet_t;
|
|
|
|
|
2016-03-13 22:16:20 +00:00
|
|
|
/* internal vlan type */
|
|
|
|
typedef struct _vlan
|
|
|
|
{
|
|
|
|
guint id;
|
|
|
|
char name[MAXVLANNAMELEN];
|
|
|
|
} vlan_t;
|
|
|
|
|
2018-11-21 16:08:18 +00:00
|
|
|
// Maps guint -> hashipxnet_t*
|
2016-04-21 16:04:16 +00:00
|
|
|
static wmem_map_t *ipxnet_hash_table = NULL;
|
|
|
|
static wmem_map_t *ipv4_hash_table = NULL;
|
|
|
|
static wmem_map_t *ipv6_hash_table = NULL;
|
2018-11-21 16:08:18 +00:00
|
|
|
// Maps guint -> hashvlan_t*
|
2016-04-21 16:04:16 +00:00
|
|
|
static wmem_map_t *vlan_hash_table = NULL;
|
2016-09-13 04:46:06 +00:00
|
|
|
static wmem_map_t *ss7pc_hash_table = NULL;
|
2013-08-11 19:02:26 +00:00
|
|
|
|
2020-02-09 01:39:41 +00:00
|
|
|
// Maps IP address -> manually set hostname.
|
|
|
|
static wmem_map_t *manually_resolved_ipv4_list = NULL;
|
|
|
|
static wmem_map_t *manually_resolved_ipv6_list = NULL;
|
2013-10-23 12:02:15 +00:00
|
|
|
|
2013-09-22 19:40:02 +00:00
|
|
|
static addrinfo_lists_t addrinfo_lists = { NULL, NULL};
|
|
|
|
|
2017-07-18 18:47:58 +00:00
|
|
|
struct cb_serv_data {
|
|
|
|
gchar *service;
|
|
|
|
port_type proto;
|
|
|
|
};
|
2008-04-12 14:08:19 +00:00
|
|
|
|
2018-11-21 16:08:18 +00:00
|
|
|
// Maps guint -> hashmanuf_t*
|
2016-04-21 16:04:16 +00:00
|
|
|
static wmem_map_t *manuf_hashtable = NULL;
|
|
|
|
static wmem_map_t *wka_hashtable = NULL;
|
|
|
|
static wmem_map_t *eth_hashtable = NULL;
|
2018-11-21 16:08:18 +00:00
|
|
|
// Maps guint -> serv_port_t*
|
2016-04-21 16:04:16 +00:00
|
|
|
static wmem_map_t *serv_port_hashtable = NULL;
|
2017-06-24 13:25:41 +00:00
|
|
|
static GHashTable *enterprises_hashtable = NULL;
|
2013-08-01 20:11:13 +00:00
|
|
|
|
2008-01-21 21:44:34 +00:00
|
|
|
static subnet_length_entry_t subnet_length_entries[SUBNETLENGTHSIZE]; /* Ordered array of entries */
|
|
|
|
static gboolean have_subnet_entry = FALSE;
|
|
|
|
|
2009-12-22 20:01:06 +00:00
|
|
|
static gboolean new_resolved_objects = FALSE;
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2012-11-29 00:32:39 +00:00
|
|
|
static GPtrArray* extra_hosts_files = NULL;
|
2011-03-24 22:47:57 +00:00
|
|
|
|
2004-01-10 17:31:40 +00:00
|
|
|
static hashether_t *add_eth_name(const guint8 *addr, const gchar *name);
|
2017-07-18 18:47:58 +00:00
|
|
|
static void add_serv_port_cb(const guint32 port, gpointer ptr);
|
2002-09-09 19:38:11 +00:00
|
|
|
|
2014-02-25 20:42:35 +00:00
|
|
|
/* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx#existing
|
2013-08-18 19:02:48 +00:00
|
|
|
* One-at-a-Time hash
|
|
|
|
*/
|
2018-02-09 01:20:26 +00:00
|
|
|
guint
|
2013-08-18 19:02:48 +00:00
|
|
|
ipv6_oat_hash(gconstpointer key)
|
|
|
|
{
|
2013-10-23 12:02:15 +00:00
|
|
|
int len = 16;
|
2013-08-18 19:02:48 +00:00
|
|
|
const unsigned char *p = (const unsigned char *)key;
|
2018-02-09 01:20:26 +00:00
|
|
|
guint h = 0;
|
2013-08-18 19:02:48 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for ( i = 0; i < len; i++ ) {
|
|
|
|
h += p[i];
|
|
|
|
h += ( h << 10 );
|
|
|
|
h ^= ( h >> 6 );
|
|
|
|
}
|
|
|
|
|
|
|
|
h += ( h << 3 );
|
|
|
|
h ^= ( h >> 11 );
|
|
|
|
h += ( h << 15 );
|
|
|
|
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
2018-02-09 01:20:26 +00:00
|
|
|
gboolean
|
2013-08-18 19:02:48 +00:00
|
|
|
ipv6_equal(gconstpointer v1, gconstpointer v2)
|
|
|
|
{
|
|
|
|
|
2017-10-26 08:50:00 +00:00
|
|
|
if (memcmp(v1, v2, sizeof (ws_in6_addr)) == 0) {
|
2013-10-23 12:02:15 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
2013-08-18 19:02:48 +00:00
|
|
|
|
2013-10-23 12:02:15 +00:00
|
|
|
return FALSE;
|
2013-08-18 19:02:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-13 20:35:12 +00:00
|
|
|
/*
|
|
|
|
* Flag controlling what names to resolve.
|
|
|
|
*/
|
2015-07-25 13:24:48 +00:00
|
|
|
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 */
|
2016-03-13 22:16:20 +00:00
|
|
|
FALSE, /* load_hosts_file_from_profile_only */
|
2016-09-13 04:46:06 +00:00
|
|
|
FALSE, /* vlan_name */
|
|
|
|
FALSE /* ss7 point code names */
|
2015-07-25 13:24:48 +00:00
|
|
|
};
|
2012-07-06 04:48:36 +00:00
|
|
|
static guint name_resolve_concurrency = 500;
|
2018-05-20 08:44:15 +00:00
|
|
|
static gboolean resolve_synchronously = FALSE;
|
2002-01-13 20:35:12 +00:00
|
|
|
|
1998-09-25 23:24:07 +00:00
|
|
|
/*
|
|
|
|
* Global variables (can be changed in GUI sections)
|
2001-10-21 19:54:49 +00:00
|
|
|
* XXX - they could be changed in GUI code, but there's currently no
|
|
|
|
* GUI code to change them.
|
1998-09-25 23:24:07 +00:00
|
|
|
*/
|
|
|
|
|
2010-04-27 22:46:39 +00:00
|
|
|
gchar *g_ethers_path = NULL; /* global ethers file */
|
|
|
|
gchar *g_pethers_path = NULL; /* personal ethers file */
|
2017-07-20 01:32:40 +00:00
|
|
|
gchar *g_wka_path = NULL; /* global well-known-addresses file */
|
|
|
|
gchar *g_manuf_path = NULL; /* global manuf file */
|
2010-04-27 22:46:39 +00:00
|
|
|
gchar *g_ipxnets_path = NULL; /* global ipxnets file */
|
|
|
|
gchar *g_pipxnets_path = NULL; /* personal ipxnets file */
|
2009-09-07 16:07:04 +00:00
|
|
|
gchar *g_services_path = NULL; /* global services file */
|
|
|
|
gchar *g_pservices_path = NULL; /* personal services file */
|
2016-03-13 22:16:20 +00:00
|
|
|
gchar *g_pvlan_path = NULL; /* personal vlans file */
|
2016-09-13 04:46:06 +00:00
|
|
|
gchar *g_ss7pcs_path = NULL; /* personal ss7pcs file */
|
2017-06-24 13:25:41 +00:00
|
|
|
gchar *g_enterprises_path = NULL; /* global enterprises file */
|
|
|
|
gchar *g_penterprises_path = NULL; /* personal enterprises file */
|
2010-04-27 22:46:39 +00:00
|
|
|
/* first resolving call */
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2008-08-07 21:41:48 +00:00
|
|
|
/*
|
2018-05-20 08:44:15 +00:00
|
|
|
* Submitted asynchronous queries trigger a callback (c_ares_ghba_cb()).
|
2008-08-07 21:41:48 +00:00
|
|
|
* Queries are added to c_ares_queue_head. During processing, queries are
|
|
|
|
* popped off the front of c_ares_queue_head and submitted using
|
|
|
|
* ares_gethostbyaddr().
|
|
|
|
* The callback processes the response, then frees the request.
|
|
|
|
*/
|
2009-09-13 17:24:51 +00:00
|
|
|
typedef struct _async_dns_queue_msg
|
2008-08-07 21:41:48 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
union {
|
|
|
|
guint32 ip4;
|
2017-10-26 08:50:00 +00:00
|
|
|
ws_in6_addr ip6;
|
2013-08-11 00:50:51 +00:00
|
|
|
} addr;
|
|
|
|
int family;
|
2009-09-13 17:24:51 +00:00
|
|
|
} async_dns_queue_msg_t;
|
2008-08-07 21:41:48 +00:00
|
|
|
|
2009-12-24 00:58:31 +00:00
|
|
|
typedef struct _async_hostent {
|
2013-08-11 00:50:51 +00:00
|
|
|
int addr_size;
|
|
|
|
int copied;
|
|
|
|
void *addrp;
|
2009-12-24 00:58:31 +00:00
|
|
|
} async_hostent_t;
|
|
|
|
|
2018-05-20 08:44:15 +00:00
|
|
|
/*
|
|
|
|
* Submitted synchronous queries trigger a callback (c_ares_ghba_sync_cb()).
|
|
|
|
* 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;
|
|
|
|
ws_in6_addr ip6;
|
|
|
|
} addr;
|
|
|
|
int family;
|
|
|
|
gboolean *completed;
|
|
|
|
} sync_dns_data_t;
|
|
|
|
|
2018-05-20 01:35:18 +00:00
|
|
|
static ares_channel ghba_chan; /* ares_gethostbyaddr -- Usually non-interactive, no timeout */
|
|
|
|
static ares_channel ghbn_chan; /* ares_gethostbyname -- Usually interactive, timeout */
|
2016-03-16 22:11:17 +00:00
|
|
|
|
2010-06-28 22:43:13 +00:00
|
|
|
static gboolean async_dns_initialized = FALSE;
|
2012-07-06 04:48:36 +00:00
|
|
|
static guint async_dns_in_flight = 0;
|
2016-04-21 08:14:11 +00:00
|
|
|
static wmem_list_t *async_dns_queue_head = NULL;
|
2018-05-20 08:44:15 +00:00
|
|
|
|
2019-09-01 16:02:27 +00:00
|
|
|
//UAT for providing a list of DNS servers to C-ARES for name resolution
|
|
|
|
gboolean use_custom_dns_server_list = FALSE;
|
|
|
|
struct dns_server_data {
|
|
|
|
char *ipaddr;
|
2022-07-20 14:19:51 +00:00
|
|
|
guint32 udp_port;
|
|
|
|
guint32 tcp_port;
|
2019-09-01 16:02:27 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
UAT_CSTRING_CB_DEF(dnsserverlist_uats, ipaddr, struct dns_server_data)
|
2022-07-20 14:19:51 +00:00
|
|
|
UAT_DEC_CB_DEF(dnsserverlist_uats, tcp_port, struct dns_server_data)
|
|
|
|
UAT_DEC_CB_DEF(dnsserverlist_uats, udp_port, struct dns_server_data)
|
2019-09-01 16:02:27 +00:00
|
|
|
|
|
|
|
static uat_t *dnsserver_uat = NULL;
|
|
|
|
static struct dns_server_data *dnsserverlist_uats = NULL;
|
|
|
|
static guint ndnsservers = 0;
|
|
|
|
|
|
|
|
static void
|
|
|
|
dns_server_free_cb(void *data)
|
|
|
|
{
|
|
|
|
struct dns_server_data *h = (struct dns_server_data*)data;
|
|
|
|
|
|
|
|
g_free(h->ipaddr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void*
|
|
|
|
dns_server_copy_cb(void *dst_, const void *src_, size_t len _U_)
|
|
|
|
{
|
|
|
|
const struct dns_server_data *src = (const struct dns_server_data *)src_;
|
|
|
|
struct dns_server_data *dst = (struct dns_server_data *)dst_;
|
|
|
|
|
|
|
|
dst->ipaddr = g_strdup(src->ipaddr);
|
2022-07-20 14:19:51 +00:00
|
|
|
dst->udp_port = src->udp_port;
|
|
|
|
dst->tcp_port = src->tcp_port;
|
2019-09-01 16:02:27 +00:00
|
|
|
|
|
|
|
return dst;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
//Check for a valid IPv4 or IPv6 address.
|
|
|
|
if (ipaddr && g_hostname_is_ip_address(ipaddr)) {
|
|
|
|
*err = NULL;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2021-12-16 18:06:18 +00:00
|
|
|
*err = ws_strdup_printf("No valid IP address given.");
|
2019-09-01 16:02:27 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2022-07-20 11:39:28 +00:00
|
|
|
static gboolean
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
if (!p || strlen(p) == 0u) {
|
|
|
|
// This should be removed in favor of Decode As. Make it optional.
|
|
|
|
*err = NULL;
|
|
|
|
return TRUE;
|
|
|
|
}
|
2019-09-01 16:02:27 +00:00
|
|
|
|
2022-07-20 11:39:28 +00:00
|
|
|
if (strcmp(p, "53") != 0){
|
|
|
|
guint16 port;
|
|
|
|
if (!ws_strtou16(p, NULL, &port)) {
|
|
|
|
*err = g_strdup("Invalid port given.");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*err = NULL;
|
|
|
|
return TRUE;
|
|
|
|
}
|
2019-09-01 16:02:27 +00:00
|
|
|
|
2018-05-20 08:44:15 +00:00
|
|
|
static void
|
|
|
|
c_ares_ghba_sync_cb(void *arg, int status, int timeouts _U_, struct hostent *he) {
|
|
|
|
sync_dns_data_t *sdd = (sync_dns_data_t *)arg;
|
|
|
|
char **p;
|
|
|
|
|
|
|
|
if (status == ARES_SUCCESS) {
|
|
|
|
for (p = he->h_addr_list; *p != NULL; p++) {
|
|
|
|
switch(sdd->family) {
|
|
|
|
case AF_INET:
|
2022-05-05 19:27:41 +00:00
|
|
|
add_ipv4_name(sdd->addr.ip4, he->h_name, FALSE);
|
2018-05-20 08:44:15 +00:00
|
|
|
break;
|
|
|
|
case AF_INET6:
|
2022-05-05 19:27:41 +00:00
|
|
|
add_ipv6_name(&sdd->addr.ip6, he->h_name, FALSE);
|
2018-05-20 08:44:15 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Throw an exception? */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Let our caller know that this is complete.
|
|
|
|
*/
|
|
|
|
*sdd->completed = TRUE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Free the structure for this call.
|
|
|
|
*/
|
|
|
|
g_free(sdd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
wait_for_sync_resolv(gboolean *completed) {
|
|
|
|
int nfds;
|
|
|
|
fd_set rfds, wfds;
|
|
|
|
struct timeval tv;
|
|
|
|
|
|
|
|
while (!*completed) {
|
|
|
|
/*
|
|
|
|
* Not yet resolved; wait for something to show up on the
|
|
|
|
* address-to-name C-ARES channel.
|
|
|
|
*
|
|
|
|
* To quote the source code for ares_timeout() as of C-ARES
|
|
|
|
* 1.12.0, "WARNING: Beware that this is linear in the number
|
|
|
|
* of outstanding requests! You are probably far better off
|
|
|
|
* just calling ares_process() once per second, rather than
|
|
|
|
* calling ares_timeout() to figure out when to next call
|
|
|
|
* ares_process().", although we should have only one request
|
|
|
|
* outstanding.
|
|
|
|
*
|
|
|
|
* And, yes, we have to reset it each time, as select(), in
|
|
|
|
* some OSes modifies the timeout to reflect the time remaining
|
|
|
|
* (e.g., Linux) and select() in other OSes doesn't (most if not
|
|
|
|
* all other UN*Xes, Windows?), so we can't rely on *either*
|
|
|
|
* behavior.
|
|
|
|
*/
|
|
|
|
tv.tv_sec = 1;
|
|
|
|
tv.tv_usec = 0;
|
|
|
|
|
|
|
|
FD_ZERO(&rfds);
|
|
|
|
FD_ZERO(&wfds);
|
|
|
|
nfds = ares_fds(ghba_chan, &rfds, &wfds);
|
|
|
|
if (nfds > 0) {
|
|
|
|
if (select(nfds, &rfds, &wfds, NULL, &tv) == -1) { /* call to select() failed */
|
2019-04-04 19:30:46 +00:00
|
|
|
/* 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));
|
2018-05-20 08:44:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
ares_process(ghba_chan, &rfds, &wfds);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sync_lookup_ip4(const guint32 addr)
|
|
|
|
{
|
|
|
|
gboolean completed = FALSE;
|
|
|
|
sync_dns_data_t *sdd;
|
|
|
|
|
|
|
|
if (!async_dns_initialized) {
|
|
|
|
/*
|
|
|
|
* c-ares not initialized. Bail out.
|
|
|
|
*/
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Start the request.
|
|
|
|
*/
|
|
|
|
sdd = g_new(sync_dns_data_t, 1);
|
|
|
|
sdd->family = AF_INET;
|
|
|
|
sdd->addr.ip4 = addr;
|
|
|
|
sdd->completed = &completed;
|
|
|
|
ares_gethostbyaddr(ghba_chan, &addr, sizeof(guint32), AF_INET,
|
|
|
|
c_ares_ghba_sync_cb, sdd);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Now wait for it to finish.
|
|
|
|
*/
|
|
|
|
wait_for_sync_resolv(&completed);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sync_lookup_ip6(const ws_in6_addr *addr)
|
|
|
|
{
|
|
|
|
gboolean completed = FALSE;
|
|
|
|
sync_dns_data_t *sdd;
|
|
|
|
|
|
|
|
if (!async_dns_initialized) {
|
|
|
|
/*
|
|
|
|
* c-ares not initialized. Bail out.
|
|
|
|
*/
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Start the request.
|
|
|
|
*/
|
|
|
|
sdd = g_new(sync_dns_data_t, 1);
|
|
|
|
sdd->family = AF_INET6;
|
|
|
|
memcpy(&sdd->addr.ip6, addr, sizeof(sdd->addr.ip6));
|
|
|
|
sdd->completed = &completed;
|
|
|
|
ares_gethostbyaddr(ghba_chan, &addr, sizeof(ws_in6_addr), AF_INET6,
|
|
|
|
c_ares_ghba_sync_cb, sdd);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Now wait for it to finish.
|
|
|
|
*/
|
|
|
|
wait_for_sync_resolv(&completed);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
set_resolution_synchrony(gboolean synchronous)
|
|
|
|
{
|
|
|
|
resolve_synchronously = synchronous;
|
2021-01-07 21:21:42 +00:00
|
|
|
maxmind_db_set_synchrony(synchronous);
|
2018-05-20 08:44:15 +00:00
|
|
|
}
|
2019-09-01 16:02:27 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
c_ares_set_dns_servers(void)
|
|
|
|
{
|
|
|
|
if ((!async_dns_initialized) || (!use_custom_dns_server_list))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (ndnsservers == 0) {
|
|
|
|
//clear the list of servers. This may effectively disable name resolution
|
2022-07-20 11:39:28 +00:00
|
|
|
ares_set_servers_ports(ghba_chan, NULL);
|
|
|
|
ares_set_servers_ports(ghbn_chan, NULL);
|
2019-09-01 16:02:27 +00:00
|
|
|
} else {
|
2022-07-20 11:39:28 +00:00
|
|
|
struct ares_addr_port_node* servers = wmem_alloc_array(NULL, struct ares_addr_port_node, ndnsservers);
|
2019-09-01 16:02:27 +00:00
|
|
|
ws_in4_addr ipv4addr;
|
|
|
|
ws_in6_addr ipv6addr;
|
|
|
|
gboolean invalid_IP_found = FALSE;
|
2022-07-20 11:39:28 +00:00
|
|
|
struct ares_addr_port_node* server;
|
2019-09-01 16:02:27 +00:00
|
|
|
guint i;
|
|
|
|
for (i = 0, server = servers; i < ndnsservers-1; i++, server++) {
|
|
|
|
if (ws_inet_pton6(dnsserverlist_uats[i].ipaddr, &ipv6addr)) {
|
|
|
|
server->family = AF_INET6;
|
|
|
|
memcpy(&server->addr.addr6, &ipv6addr, 16);
|
|
|
|
} else if (ws_inet_pton4(dnsserverlist_uats[i].ipaddr, &ipv4addr)) {
|
|
|
|
server->family = AF_INET;
|
|
|
|
memcpy(&server->addr.addr4, &ipv4addr, 4);
|
|
|
|
} else {
|
|
|
|
//This shouldn't happen, but just in case...
|
|
|
|
invalid_IP_found = TRUE;
|
|
|
|
server->family = 0;
|
|
|
|
memset(&server->addr.addr4, 0, 4);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-07-20 14:19:51 +00:00
|
|
|
server->udp_port = (int)dnsserverlist_uats[i].udp_port;
|
|
|
|
server->tcp_port = (int)dnsserverlist_uats[i].tcp_port;
|
2022-07-20 11:39:28 +00:00
|
|
|
|
2019-09-01 16:02:27 +00:00
|
|
|
server->next = (server+1);
|
|
|
|
}
|
|
|
|
if (!invalid_IP_found) {
|
|
|
|
if (ws_inet_pton6(dnsserverlist_uats[i].ipaddr, &ipv6addr)) {
|
|
|
|
server->family = AF_INET6;
|
|
|
|
memcpy(&server->addr.addr6, &ipv6addr, 16);
|
|
|
|
}
|
|
|
|
else if (ws_inet_pton4(dnsserverlist_uats[i].ipaddr, &ipv4addr)) {
|
|
|
|
server->family = AF_INET;
|
|
|
|
memcpy(&server->addr.addr4, &ipv4addr, 4);
|
|
|
|
} else {
|
|
|
|
//This shouldn't happen, but just in case...
|
|
|
|
server->family = 0;
|
|
|
|
memset(&server->addr.addr4, 0, 4);
|
|
|
|
}
|
|
|
|
}
|
2022-07-21 09:55:02 +00:00
|
|
|
server->udp_port = (int)dnsserverlist_uats[i].udp_port;
|
|
|
|
server->tcp_port = (int)dnsserverlist_uats[i].tcp_port;
|
|
|
|
|
2019-09-01 16:02:27 +00:00
|
|
|
server->next = NULL;
|
|
|
|
|
2022-07-20 11:39:28 +00:00
|
|
|
ares_set_servers_ports(ghba_chan, servers);
|
|
|
|
ares_set_servers_ports(ghbn_chan, servers);
|
2019-09-01 16:02:27 +00:00
|
|
|
wmem_free(NULL, servers);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-01-21 21:44:34 +00:00
|
|
|
typedef struct {
|
2013-08-11 00:50:51 +00:00
|
|
|
guint32 mask;
|
|
|
|
gsize mask_length;
|
|
|
|
const gchar* name; /* Shallow copy */
|
2008-01-21 21:44:34 +00:00
|
|
|
} subnet_entry_t;
|
2007-08-06 08:44:26 +00:00
|
|
|
|
2018-11-21 15:29:30 +00:00
|
|
|
/* Maximum supported line length of hosts, services, manuf, etc. */
|
|
|
|
#define MAX_LINELEN 1024
|
2007-08-06 08:44:26 +00:00
|
|
|
|
2018-11-21 15:29:30 +00:00
|
|
|
/** Read a line without trailing (CR)LF. Returns -1 on failure. */
|
2010-04-29 18:17:29 +00:00
|
|
|
static int
|
2018-11-21 15:29:30 +00:00
|
|
|
fgetline(char *buf, int size, FILE *fp)
|
2007-08-06 08:44:26 +00:00
|
|
|
{
|
2018-11-21 15:29:30 +00:00
|
|
|
if (fgets(buf, size, fp)) {
|
|
|
|
int len = (int)strcspn(buf, "\r\n");
|
|
|
|
buf[len] = '\0';
|
|
|
|
return len;
|
2007-08-06 08:44:26 +00:00
|
|
|
}
|
2018-11-21 15:29:30 +00:00
|
|
|
return -1;
|
2007-08-06 08:44:26 +00:00
|
|
|
|
|
|
|
} /* fgetline */
|
|
|
|
|
|
|
|
|
1998-09-25 23:24:07 +00:00
|
|
|
/*
|
2002-08-28 20:41:00 +00:00
|
|
|
* Local function definitions
|
1998-09-25 23:24:07 +00:00
|
|
|
*/
|
2008-01-21 21:44:34 +00:00
|
|
|
static subnet_entry_t subnet_lookup(const guint32 addr);
|
2016-09-09 15:16:10 +00:00
|
|
|
static void subnet_entry_set(guint32 subnet_addr, const guint8 mask_length, const gchar* name);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2007-08-06 08:44:26 +00:00
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static void
|
2013-08-05 16:36:24 +00:00
|
|
|
add_service_name(port_type proto, const guint port, const char *service_name)
|
2007-08-06 08:44:26 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
serv_port_t *serv_port_table;
|
|
|
|
|
2018-11-21 16:08:18 +00:00
|
|
|
serv_port_table = (serv_port_t *)wmem_map_lookup(serv_port_hashtable, GUINT_TO_POINTER(port));
|
2013-08-11 00:50:51 +00:00
|
|
|
if (serv_port_table == NULL) {
|
2016-04-20 14:45:32 +00:00
|
|
|
serv_port_table = wmem_new0(wmem_epan_scope(), serv_port_t);
|
2018-11-21 16:08:18 +00:00
|
|
|
wmem_map_insert(serv_port_hashtable, GUINT_TO_POINTER(port), serv_port_table);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
|
|
|
|
2015-02-27 02:10:25 +00:00
|
|
|
switch(proto) {
|
2013-08-11 00:50:51 +00:00
|
|
|
case PT_TCP:
|
2016-04-20 14:45:32 +00:00
|
|
|
wmem_free(wmem_epan_scope(), serv_port_table->tcp_name);
|
|
|
|
serv_port_table->tcp_name = wmem_strdup(wmem_epan_scope(), service_name);
|
2013-08-11 00:50:51 +00:00
|
|
|
break;
|
|
|
|
case PT_UDP:
|
2016-04-20 14:45:32 +00:00
|
|
|
wmem_free(wmem_epan_scope(), serv_port_table->udp_name);
|
|
|
|
serv_port_table->udp_name = wmem_strdup(wmem_epan_scope(), service_name);
|
2013-08-11 00:50:51 +00:00
|
|
|
break;
|
|
|
|
case PT_SCTP:
|
2016-04-20 14:45:32 +00:00
|
|
|
wmem_free(wmem_epan_scope(), serv_port_table->sctp_name);
|
|
|
|
serv_port_table->sctp_name = wmem_strdup(wmem_epan_scope(), service_name);
|
2013-08-11 00:50:51 +00:00
|
|
|
break;
|
|
|
|
case PT_DCCP:
|
2016-04-20 14:45:32 +00:00
|
|
|
wmem_free(wmem_epan_scope(), serv_port_table->dccp_name);
|
|
|
|
serv_port_table->dccp_name = wmem_strdup(wmem_epan_scope(), service_name);
|
2013-08-11 00:50:51 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
/* Should not happen */
|
|
|
|
}
|
|
|
|
|
|
|
|
new_resolved_objects = TRUE;
|
2007-08-06 08:44:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static void
|
|
|
|
parse_service_line (char *line)
|
2007-08-06 08:44:26 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
gchar *cp;
|
|
|
|
gchar *service;
|
|
|
|
gchar *port;
|
|
|
|
port_type proto;
|
2017-07-18 18:47:58 +00:00
|
|
|
struct cb_serv_data cb_data;
|
2013-08-11 00:50:51 +00:00
|
|
|
range_t *port_rng = NULL;
|
|
|
|
|
|
|
|
if ((cp = strchr(line, '#')))
|
|
|
|
*cp = '\0';
|
|
|
|
|
|
|
|
if ((cp = strtok(line, " \t")) == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
service = cp;
|
|
|
|
|
|
|
|
if ((cp = strtok(NULL, " \t")) == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
port = cp;
|
|
|
|
|
|
|
|
if (strtok(cp, "/") == NULL)
|
|
|
|
return;
|
|
|
|
|
2017-07-18 18:47:58 +00:00
|
|
|
if (range_convert_str(NULL, &port_rng, port, G_MAXUINT16) != CVT_NO_ERROR) {
|
|
|
|
wmem_free (NULL, port_rng);
|
2013-08-11 00:50:51 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-07-18 18:47:58 +00:00
|
|
|
while ((cp = strtok(NULL, "/")) != NULL) {
|
|
|
|
if (strcmp(cp, "tcp") == 0) {
|
|
|
|
proto = PT_TCP;
|
|
|
|
}
|
|
|
|
else if (strcmp(cp, "udp") == 0) {
|
|
|
|
proto = PT_UDP;
|
|
|
|
}
|
|
|
|
else if (strcmp(cp, "sctp") == 0) {
|
|
|
|
proto = PT_SCTP;
|
|
|
|
}
|
|
|
|
else if (strcmp(cp, "dccp") == 0) {
|
|
|
|
proto = PT_DCCP;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cb_data.service = service;
|
|
|
|
cb_data.proto = proto;
|
2017-08-08 22:05:37 +00:00
|
|
|
range_foreach(port_rng, add_serv_port_cb, &cb_data);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
|
|
|
|
2016-12-22 20:12:27 +00:00
|
|
|
wmem_free (NULL, port_rng);
|
2007-08-06 08:44:26 +00:00
|
|
|
} /* parse_service_line */
|
|
|
|
|
|
|
|
|
2008-04-12 14:08:19 +00:00
|
|
|
static void
|
2017-07-18 18:47:58 +00:00
|
|
|
add_serv_port_cb(const guint32 port, gpointer ptr)
|
2008-04-12 14:08:19 +00:00
|
|
|
{
|
2017-07-18 18:47:58 +00:00
|
|
|
struct cb_serv_data *cb_data = (struct cb_serv_data *)ptr;
|
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if ( port ) {
|
2017-07-18 18:47:58 +00:00
|
|
|
add_service_name(cb_data->proto, port, cb_data->service);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
2008-04-12 14:08:19 +00:00
|
|
|
}
|
|
|
|
|
2007-08-06 08:44:26 +00:00
|
|
|
|
2017-01-23 03:51:54 +00:00
|
|
|
static gboolean
|
2010-04-29 18:17:29 +00:00
|
|
|
parse_services_file(const char * path)
|
2007-08-06 08:44:26 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
FILE *serv_p;
|
2018-11-21 15:29:30 +00:00
|
|
|
char buf[MAX_LINELEN];
|
2007-08-06 08:44:26 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* services hash table initialization */
|
|
|
|
serv_p = ws_fopen(path, "r");
|
2007-08-06 08:44:26 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (serv_p == NULL)
|
2017-01-23 03:51:54 +00:00
|
|
|
return FALSE;
|
2007-08-06 08:44:26 +00:00
|
|
|
|
2018-11-21 15:29:30 +00:00
|
|
|
while (fgetline(buf, sizeof(buf), serv_p) >= 0) {
|
2016-04-20 14:45:32 +00:00
|
|
|
parse_service_line(buf);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
2009-09-06 08:59:30 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
fclose(serv_p);
|
2017-01-23 03:51:54 +00:00
|
|
|
return TRUE;
|
2007-08-06 08:44:26 +00:00
|
|
|
}
|
|
|
|
|
2013-08-05 16:36:24 +00:00
|
|
|
/* -----------------
|
|
|
|
* unsigned integer to ascii
|
|
|
|
*/
|
|
|
|
static gchar *
|
2015-01-07 21:24:17 +00:00
|
|
|
wmem_utoa(wmem_allocator_t *allocator, guint port)
|
2013-08-05 16:36:24 +00:00
|
|
|
{
|
2015-01-07 21:24:17 +00:00
|
|
|
gchar *bp = (gchar *)wmem_alloc(allocator, MAXNAMELEN);
|
2013-08-05 16:36:24 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* XXX, guint32_to_str() ? */
|
|
|
|
guint32_to_str_buf(port, bp, MAXNAMELEN);
|
|
|
|
return bp;
|
2013-08-05 16:36:24 +00:00
|
|
|
}
|
2007-08-06 08:44:26 +00:00
|
|
|
|
2015-10-05 10:53:07 +00:00
|
|
|
static const gchar *
|
2015-10-05 12:51:58 +00:00
|
|
|
_serv_name_lookup(port_type proto, guint port, serv_port_t **value_ret)
|
1998-09-16 02:39:15 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
serv_port_t *serv_port_table;
|
2013-08-05 16:36:24 +00:00
|
|
|
|
2018-11-21 16:08:18 +00:00
|
|
|
serv_port_table = (serv_port_t *)wmem_map_lookup(serv_port_hashtable, GUINT_TO_POINTER(port));
|
2013-08-11 00:50:51 +00:00
|
|
|
|
2015-10-05 12:51:58 +00:00
|
|
|
if (value_ret != NULL)
|
|
|
|
*value_ret = serv_port_table;
|
2013-09-16 17:53:41 +00:00
|
|
|
|
2015-10-05 12:51:58 +00:00
|
|
|
if (serv_port_table == NULL)
|
|
|
|
return NULL;
|
2013-08-11 00:50:51 +00:00
|
|
|
|
2015-10-05 12:51:58 +00:00
|
|
|
switch (proto) {
|
2013-08-11 00:50:51 +00:00
|
|
|
case PT_UDP:
|
2015-10-05 12:51:58 +00:00
|
|
|
return serv_port_table->udp_name;
|
2013-08-11 00:50:51 +00:00
|
|
|
case PT_TCP:
|
2015-10-05 12:51:58 +00:00
|
|
|
return serv_port_table->tcp_name;
|
2013-08-11 00:50:51 +00:00
|
|
|
case PT_SCTP:
|
2015-10-05 12:51:58 +00:00
|
|
|
return serv_port_table->sctp_name;
|
2013-08-11 00:50:51 +00:00
|
|
|
case PT_DCCP:
|
2015-10-05 12:51:58 +00:00
|
|
|
return serv_port_table->dccp_name;
|
2013-08-11 00:50:51 +00:00
|
|
|
default:
|
2015-10-05 12:51:58 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const gchar *
|
|
|
|
try_serv_name_lookup(port_type proto, guint port)
|
|
|
|
{
|
|
|
|
return _serv_name_lookup(proto, port, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
const gchar *
|
|
|
|
serv_name_lookup(port_type proto, guint port)
|
|
|
|
{
|
|
|
|
serv_port_t *serv_port_table = NULL;
|
|
|
|
const char *name;
|
|
|
|
|
|
|
|
name = _serv_name_lookup(proto, port, &serv_port_table);
|
|
|
|
if (name != NULL)
|
|
|
|
return name;
|
|
|
|
|
|
|
|
if (serv_port_table == NULL) {
|
2016-04-20 14:45:32 +00:00
|
|
|
serv_port_table = wmem_new0(wmem_epan_scope(), serv_port_t);
|
2018-11-21 16:08:18 +00:00
|
|
|
wmem_map_insert(serv_port_hashtable, GUINT_TO_POINTER(port), serv_port_table);
|
2015-10-05 12:51:58 +00:00
|
|
|
}
|
|
|
|
if (serv_port_table->numeric == NULL) {
|
2016-04-20 14:45:32 +00:00
|
|
|
serv_port_table->numeric = wmem_strdup_printf(wmem_epan_scope(), "%u", port);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2015-10-05 12:51:58 +00:00
|
|
|
return serv_port_table->numeric;
|
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2013-08-07 16:46:08 +00:00
|
|
|
static void
|
|
|
|
initialize_services(void)
|
|
|
|
{
|
2017-01-23 03:51:54 +00:00
|
|
|
gboolean parse_file = TRUE;
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(serv_port_hashtable == NULL);
|
2018-11-21 16:08:18 +00:00
|
|
|
serv_port_hashtable = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
|
2013-08-07 16:46:08 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Compute the pathname of the services file. */
|
|
|
|
if (g_services_path == NULL) {
|
|
|
|
g_services_path = get_datafile_path(ENAME_SERVICES);
|
|
|
|
}
|
|
|
|
parse_services_file(g_services_path);
|
2013-08-07 16:46:08 +00:00
|
|
|
|
2015-10-06 08:11:46 +00:00
|
|
|
/* Compute the pathname of the personal services file */
|
|
|
|
if (g_pservices_path == NULL) {
|
2017-01-23 03:51:54 +00:00
|
|
|
/* Check profile directory before personal configuration */
|
|
|
|
g_pservices_path = get_persconffile_path(ENAME_SERVICES, TRUE);
|
|
|
|
if (!parse_services_file(g_pservices_path)) {
|
2017-04-15 21:29:32 +00:00
|
|
|
g_free(g_pservices_path);
|
2017-01-23 03:51:54 +00:00
|
|
|
g_pservices_path = get_persconffile_path(ENAME_SERVICES, FALSE);
|
|
|
|
} else {
|
|
|
|
parse_file = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (parse_file) {
|
|
|
|
parse_services_file(g_pservices_path);
|
2015-10-06 08:11:46 +00:00
|
|
|
}
|
|
|
|
}
|
2013-08-07 16:46:08 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
service_name_lookup_cleanup(void)
|
|
|
|
{
|
2016-04-21 16:04:16 +00:00
|
|
|
serv_port_hashtable = NULL;
|
2017-02-05 21:28:26 +00:00
|
|
|
g_free(g_services_path);
|
|
|
|
g_services_path = NULL;
|
2017-02-10 17:04:20 +00:00
|
|
|
g_free(g_pservices_path);
|
|
|
|
g_pservices_path = NULL;
|
2013-08-07 16:46:08 +00:00
|
|
|
}
|
2003-05-04 18:50:56 +00:00
|
|
|
|
2017-06-24 13:25:41 +00:00
|
|
|
static void
|
|
|
|
parse_enterprises_line (char *line)
|
|
|
|
{
|
2017-07-17 19:47:38 +00:00
|
|
|
char *tok, *dec_str, *org_str;
|
2017-06-24 13:25:41 +00:00
|
|
|
guint32 dec;
|
2020-11-07 22:11:21 +00:00
|
|
|
gboolean had_comment = FALSE;
|
2017-06-24 13:25:41 +00:00
|
|
|
|
2020-11-07 22:11:21 +00:00
|
|
|
/* Stop the line at any comment found */
|
|
|
|
if ((tok = strchr(line, '#'))) {
|
2017-07-17 19:47:38 +00:00
|
|
|
*tok = '\0';
|
2020-11-07 22:11:21 +00:00
|
|
|
had_comment = TRUE;
|
|
|
|
}
|
|
|
|
/* Get enterprise number */
|
2017-07-17 19:47:38 +00:00
|
|
|
dec_str = strtok(line, " \t");
|
2017-06-24 13:25:41 +00:00
|
|
|
if (!dec_str)
|
|
|
|
return;
|
2020-11-07 22:11:21 +00:00
|
|
|
/* Get enterprise name */
|
2017-07-17 19:47:38 +00:00
|
|
|
org_str = strtok(NULL, ""); /* everything else */
|
2020-11-07 22:11:21 +00:00
|
|
|
if (org_str && had_comment) {
|
|
|
|
/* Only need to strip after (between name and where comment was) */
|
|
|
|
org_str = g_strchomp(org_str);
|
|
|
|
}
|
2017-06-24 13:25:41 +00:00
|
|
|
if (!org_str)
|
|
|
|
return;
|
2020-11-07 22:11:21 +00:00
|
|
|
|
|
|
|
/* Add entry using number as key */
|
2017-06-24 13:25:41 +00:00
|
|
|
if (!ws_strtou32(dec_str, NULL, &dec))
|
|
|
|
return;
|
2020-11-07 22:11:21 +00:00
|
|
|
g_hash_table_insert(enterprises_hashtable, GUINT_TO_POINTER(dec), g_strdup(org_str));
|
2017-06-24 13:25:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
parse_enterprises_file(const char * path)
|
|
|
|
{
|
|
|
|
FILE *fp;
|
2018-11-21 15:29:30 +00:00
|
|
|
char buf[MAX_LINELEN];
|
2017-06-24 13:25:41 +00:00
|
|
|
|
|
|
|
fp = ws_fopen(path, "r");
|
|
|
|
if (fp == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
2018-11-21 15:29:30 +00:00
|
|
|
while (fgetline(buf, sizeof(buf), fp) >= 0) {
|
2017-06-24 13:25:41 +00:00
|
|
|
parse_enterprises_line(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(fp);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
initialize_enterprises(void)
|
|
|
|
{
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(enterprises_hashtable == NULL);
|
2017-06-24 13:25:41 +00:00
|
|
|
enterprises_hashtable = g_hash_table_new_full(NULL, NULL, NULL, g_free);
|
|
|
|
|
|
|
|
if (g_enterprises_path == NULL) {
|
|
|
|
g_enterprises_path = get_datafile_path(ENAME_ENTERPRISES);
|
|
|
|
}
|
|
|
|
parse_enterprises_file(g_enterprises_path);
|
|
|
|
|
|
|
|
if (g_penterprises_path == NULL) {
|
2020-10-10 11:34:18 +00:00
|
|
|
/* Check profile directory before personal configuration */
|
|
|
|
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);
|
|
|
|
}
|
2017-06-24 13:25:41 +00:00
|
|
|
}
|
|
|
|
parse_enterprises_file(g_penterprises_path);
|
|
|
|
}
|
|
|
|
|
|
|
|
const gchar *
|
|
|
|
try_enterprises_lookup(guint32 value)
|
|
|
|
{
|
|
|
|
return (const gchar *)g_hash_table_lookup(enterprises_hashtable, GUINT_TO_POINTER(value));
|
|
|
|
}
|
|
|
|
|
|
|
|
const gchar *
|
|
|
|
enterprises_lookup(guint32 value, const char *unknown_str)
|
|
|
|
{
|
|
|
|
const gchar *s;
|
|
|
|
|
|
|
|
s = try_enterprises_lookup(value);
|
|
|
|
if (s != NULL)
|
|
|
|
return s;
|
|
|
|
if (unknown_str != NULL)
|
|
|
|
return unknown_str;
|
|
|
|
return "<Unknown>";
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
enterprises_base_custom(char *buf, guint32 value)
|
|
|
|
{
|
|
|
|
const gchar *s;
|
|
|
|
|
|
|
|
if ((s = try_enterprises_lookup(value)) == NULL)
|
|
|
|
s = ITEM_LABEL_UNKNOWN_STR;
|
2021-12-16 18:06:18 +00:00
|
|
|
snprintf(buf, ITEM_LABEL_LENGTH, "%s (%u)", s, value);
|
2017-06-24 13:25:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
enterprises_cleanup(void)
|
|
|
|
{
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(enterprises_hashtable);
|
2017-06-24 13:25:41 +00:00
|
|
|
g_hash_table_destroy(enterprises_hashtable);
|
|
|
|
enterprises_hashtable = NULL;
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(g_enterprises_path);
|
2017-06-24 13:25:41 +00:00
|
|
|
g_free(g_enterprises_path);
|
|
|
|
g_enterprises_path = NULL;
|
2018-04-24 21:02:04 +00:00
|
|
|
g_free(g_penterprises_path);
|
|
|
|
g_penterprises_path = NULL;
|
|
|
|
g_free(g_pservices_path);
|
|
|
|
g_pservices_path = NULL;
|
2017-06-24 13:25:41 +00:00
|
|
|
}
|
|
|
|
|
2008-08-07 21:41:48 +00:00
|
|
|
/* Fill in an IP4 structure with info from subnets file or just with the
|
|
|
|
* string form of the address.
|
2008-01-21 21:44:34 +00:00
|
|
|
*/
|
2010-04-29 18:17:29 +00:00
|
|
|
static void
|
|
|
|
fill_dummy_ip4(const guint addr, hashipv4_t* volatile tp)
|
2008-01-21 21:44:34 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
subnet_entry_t subnet_entry;
|
|
|
|
|
2017-06-09 08:03:38 +00:00
|
|
|
/* Overwrite if we get async DNS reply */
|
2013-08-11 00:50:51 +00:00
|
|
|
|
|
|
|
/* Do we have a subnet for this address? */
|
|
|
|
subnet_entry = subnet_lookup(addr);
|
2015-02-27 02:10:25 +00:00
|
|
|
if (0 != subnet_entry.mask) {
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Print name, then '.' then IP address after subnet mask */
|
|
|
|
guint32 host_addr;
|
2017-10-29 05:50:33 +00:00
|
|
|
gchar buffer[WS_INET_ADDRSTRLEN];
|
2013-08-11 00:50:51 +00:00
|
|
|
gchar* paddr;
|
|
|
|
gsize i;
|
|
|
|
|
2019-01-03 16:53:42 +00:00
|
|
|
host_addr = addr & (~subnet_entry.mask);
|
2017-10-29 05:50:33 +00:00
|
|
|
ip_to_str_buf((guint8 *)&host_addr, buffer, WS_INET_ADDRSTRLEN);
|
2013-08-11 00:50:51 +00:00
|
|
|
paddr = buffer;
|
|
|
|
|
|
|
|
/* Skip to first octet that is not totally masked
|
|
|
|
* If length of mask is 32, we chomp the whole address.
|
|
|
|
* If the address string starts '.' (should not happen?),
|
|
|
|
* we skip that '.'.
|
|
|
|
*/
|
|
|
|
i = subnet_entry.mask_length / 8;
|
|
|
|
while(*(paddr) != '\0' && i > 0) {
|
2015-02-27 02:10:25 +00:00
|
|
|
if (*(++paddr) == '.') {
|
2013-08-11 00:50:51 +00:00
|
|
|
--i;
|
|
|
|
}
|
|
|
|
}
|
2010-04-27 22:46:39 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* There are more efficient ways to do this, but this is safe if we
|
2021-12-16 18:06:18 +00:00
|
|
|
* trust snprintf and MAXNAMELEN
|
2013-08-11 00:50:51 +00:00
|
|
|
*/
|
2021-12-16 18:06:18 +00:00
|
|
|
snprintf(tp->name, MAXNAMELEN, "%s%s", subnet_entry.name, paddr);
|
2013-08-11 00:50:51 +00:00
|
|
|
} else {
|
2017-06-09 08:03:38 +00:00
|
|
|
/* XXX: This means we end up printing "1.2.3.4 (1.2.3.4)" in many cases */
|
2013-08-11 00:50:51 +00:00
|
|
|
ip_to_str_buf((const guint8 *)&addr, tp->name, MAXNAMELEN);
|
2010-04-27 22:46:39 +00:00
|
|
|
}
|
2008-01-21 21:44:34 +00:00
|
|
|
}
|
|
|
|
|
2016-01-19 07:22:30 +00:00
|
|
|
|
|
|
|
/* Fill in an IP6 structure with the string form of the address.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
fill_dummy_ip6(hashipv6_t* volatile tp)
|
|
|
|
{
|
2017-06-09 08:03:38 +00:00
|
|
|
/* Overwrite if we get async DNS reply */
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(tp->name, tp->ip6, MAXNAMELEN);
|
2016-01-19 07:22:30 +00:00
|
|
|
}
|
|
|
|
|
2008-08-07 21:41:48 +00:00
|
|
|
static void
|
2017-07-20 18:03:45 +00:00
|
|
|
c_ares_ghba_cb(void *arg, int status, int timeouts _U_, struct hostent *he) {
|
2013-08-11 00:50:51 +00:00
|
|
|
async_dns_queue_msg_t *caqm = (async_dns_queue_msg_t *)arg;
|
|
|
|
char **p;
|
|
|
|
|
|
|
|
if (!caqm) return;
|
|
|
|
/* XXX, what to do if async_dns_in_flight == 0? */
|
|
|
|
async_dns_in_flight--;
|
|
|
|
|
|
|
|
if (status == ARES_SUCCESS) {
|
|
|
|
for (p = he->h_addr_list; *p != NULL; p++) {
|
|
|
|
switch(caqm->family) {
|
|
|
|
case AF_INET:
|
2022-05-05 19:27:41 +00:00
|
|
|
add_ipv4_name(caqm->addr.ip4, he->h_name, FALSE);
|
2013-08-11 00:50:51 +00:00
|
|
|
break;
|
|
|
|
case AF_INET6:
|
2022-05-05 19:27:41 +00:00
|
|
|
add_ipv6_name(&caqm->addr.ip6, he->h_name, FALSE);
|
2013-08-11 00:50:51 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Throw an exception? */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
If you allocate with wmem, free with wmem.
This g_free() causes a crash on my system for every capture file where
names are resolved.
Program received signal SIGABRT, Aborted.
0x00007ffff0347125 in *__GI_raise (sig=<optimized out>) at
../nptl/sysdeps/unix/sysv/linux/raise.c:64
64 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0 0x00007ffff0347125 in *__GI_raise (sig=<optimized out>) at
../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1 0x00007ffff034a3a0 in *__GI_abort () at abort.c:92
#2 0x00007ffff038135b in __libc_message (do_abort=<optimized out>,
fmt=<optimized out>)
at ../sysdeps/unix/sysv/linux/libc_fatal.c:189
#3 0x00007ffff038abb6 in malloc_printerr (action=3, str=0x7ffff0464532
"free(): invalid pointer", ptr=<optimized out>)
at malloc.c:6312
#4 0x00007ffff038f95c in *__GI___libc_free (mem=<optimized out>) at
malloc.c:3738
#5 0x00007fffef8cca41 in ?? () from
/usr/lib/x86_64-linux-gnu/libcares.so.2
#6 0x00007fffef8ccad2 in ?? () from
/usr/lib/x86_64-linux-gnu/libcares.so.2
#7 0x00007fffef8cceea in ?? () from
/usr/lib/x86_64-linux-gnu/libcares.so.2
#8 0x00007fffef8d501b in ?? () from
/usr/lib/x86_64-linux-gnu/libcares.so.2
#9 0x00007fffef8d3a4a in ?? () from
/usr/lib/x86_64-linux-gnu/libcares.so.2
#10 0x00007fffef8d4792 in ?? () from
/usr/lib/x86_64-linux-gnu/libcares.so.2
#11 0x00007fffef8d49de in ?? () from
/usr/lib/x86_64-linux-gnu/libcares.so.2
#12 0x00007fffef8d4cc7 in ?? () from
/usr/lib/x86_64-linux-gnu/libcares.so.2
#13 0x00007ffff4329713 in host_name_lookup_process () at
addr_resolv.c:2485
#14 0x000000000053fda9 in WiresharkApplication::refreshAddressResolution
(this=0x7fffffffe2f0) at wireshark_application.cpp:217
#15 0x000000000059c42d in WiresharkApplication::qt_static_metacall
(_o=0x7fffffffe2f0, _c=<optimized out>, _id=<optimized out>,
_a=0x7fffffffd7b0) at wireshark_application.moc.cpp:142
#16 0x00007ffff140654f in QMetaObject::activate(QObject*, QMetaObject
const*, int, void**) ()
from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
Change-Id: I20586929463259f71f325225975eec241166f123
Reviewed-on: https://code.wireshark.org/review/15047
Reviewed-by: Martin Kaiser <wireshark@kaiser.cx>
2016-04-21 21:06:07 +00:00
|
|
|
wmem_free(wmem_epan_scope(), caqm);
|
2008-08-07 21:41:48 +00:00
|
|
|
}
|
|
|
|
|
2009-09-06 08:59:30 +00:00
|
|
|
/* --------------- */
|
2010-04-29 18:17:29 +00:00
|
|
|
static hashipv4_t *
|
|
|
|
new_ipv4(const guint addr)
|
2009-09-06 08:59:30 +00:00
|
|
|
{
|
2016-04-20 14:45:32 +00:00
|
|
|
hashipv4_t *tp = wmem_new(wmem_epan_scope(), hashipv4_t);
|
2013-08-11 00:50:51 +00:00
|
|
|
tp->addr = addr;
|
2013-10-10 19:17:48 +00:00
|
|
|
tp->flags = 0;
|
2015-03-18 18:25:06 +00:00
|
|
|
tp->name[0] = '\0';
|
2013-08-29 22:08:23 +00:00
|
|
|
ip_to_str_buf((const guint8 *)&addr, tp->ip, sizeof(tp->ip));
|
2013-08-11 00:50:51 +00:00
|
|
|
return tp;
|
2009-09-06 08:59:30 +00:00
|
|
|
}
|
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static hashipv4_t *
|
2016-01-19 07:22:30 +00:00
|
|
|
host_lookup(const guint addr)
|
1998-09-16 02:39:15 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
hashipv4_t * volatile tp;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
tp = (hashipv4_t *)wmem_map_lookup(ipv4_hash_table, GUINT_TO_POINTER(addr));
|
2015-02-27 02:10:25 +00:00
|
|
|
if (tp == NULL) {
|
2016-01-19 07:22:30 +00:00
|
|
|
/*
|
|
|
|
* We don't already have an entry for this host name; create one,
|
|
|
|
* and then try to resolve it.
|
|
|
|
*/
|
2013-08-11 19:02:26 +00:00
|
|
|
tp = new_ipv4(addr);
|
2017-06-09 08:03:38 +00:00
|
|
|
fill_dummy_ip4(addr, tp);
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_insert(ipv4_hash_table, GUINT_TO_POINTER(addr), tp);
|
2017-06-09 08:03:38 +00:00
|
|
|
} else if (tp->flags & TRIED_OR_RESOLVED_MASK) {
|
2013-08-13 01:41:51 +00:00
|
|
|
return tp;
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2016-03-26 03:16:17 +00:00
|
|
|
/*
|
|
|
|
* This hasn't been resolved yet, and we haven't tried to
|
|
|
|
* resolve it already.
|
|
|
|
*/
|
2015-03-01 03:20:07 +00:00
|
|
|
|
2016-03-26 03:16:17 +00:00
|
|
|
if (!gbl_resolv_flags.network_name)
|
|
|
|
return tp;
|
2015-03-01 03:20:07 +00:00
|
|
|
|
2016-03-26 03:16:17 +00:00
|
|
|
if (gbl_resolv_flags.use_external_net_name_resolver) {
|
|
|
|
tp->flags |= TRIED_RESOLVE_ADDRESS;
|
2015-03-01 03:20:07 +00:00
|
|
|
|
2018-05-20 08:44:15 +00:00
|
|
|
if (async_dns_initialized) {
|
|
|
|
/* c-ares is initialized, so we can use it */
|
|
|
|
if (resolve_synchronously || name_resolve_concurrency == 0) {
|
|
|
|
/*
|
|
|
|
* Either all names are to be resolved synchronously or
|
|
|
|
* the concurrencly level is 0; do the resolution
|
|
|
|
* synchronously.
|
|
|
|
*/
|
|
|
|
sync_lookup_ip4(addr);
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Names are to be resolved asynchronously, and we
|
|
|
|
* allow at least one asynchronous request in flight;
|
|
|
|
* post an asynchronous request.
|
|
|
|
*/
|
|
|
|
async_dns_queue_msg_t *caqm;
|
|
|
|
|
|
|
|
caqm = wmem_new(wmem_epan_scope(), async_dns_queue_msg_t);
|
|
|
|
caqm->family = AF_INET;
|
|
|
|
caqm->addr.ip4 = addr;
|
|
|
|
wmem_list_append(async_dns_queue_head, (gpointer) caqm);
|
|
|
|
}
|
2015-03-01 03:20:07 +00:00
|
|
|
}
|
2010-04-27 22:46:39 +00:00
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
return tp;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2012-07-08 01:31:48 +00:00
|
|
|
} /* host_lookup */
|
2009-09-06 08:59:30 +00:00
|
|
|
|
|
|
|
/* --------------- */
|
2010-04-29 18:17:29 +00:00
|
|
|
static hashipv6_t *
|
2017-10-26 08:50:00 +00:00
|
|
|
new_ipv6(const ws_in6_addr *addr)
|
2009-09-06 08:59:30 +00:00
|
|
|
{
|
2016-04-20 14:45:32 +00:00
|
|
|
hashipv6_t *tp = wmem_new(wmem_epan_scope(), hashipv6_t);
|
Don't include libwireshark headers from libwiretap.
Move the definitions of hashipv4_t and hashipv6_t to wiretap/wtap.h, as
that's the main place they're used. Change them a bit not to depend on
other stuff from libwireshark, and change the code as required by those
changes.
This should fix the Solaris build; apparently, the Sun^WOracle compiler
is generating code for static inline functions even if they're never
called, so that libwiretap ends up including code that calls tvbuff and
wmem functions.
There's probably further cleanup that could be done here, but this
should at least fix the build, as well as getting rid of a dependency
between two libraries that are at least somewhat independent (libwiretap
should *not* depend on libwireshark, as some programs use libwiretap but
not libwireshark, and, ultimately, we probably want it to be possible to
use libwireshark without libwiretap but that'd be more work).
Change-Id: I91c745282f17d7c8bff7809aa277eab2b3cf47c1
Reviewed-on: https://code.wireshark.org/review/11537
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2015-11-03 22:12:14 +00:00
|
|
|
memcpy(tp->addr, addr->bytes, sizeof tp->addr);
|
2013-10-10 19:17:48 +00:00
|
|
|
tp->flags = 0;
|
2015-03-18 18:25:06 +00:00
|
|
|
tp->name[0] = '\0';
|
2016-06-01 21:22:46 +00:00
|
|
|
ip6_to_str_buf(addr, tp->ip6, sizeof(tp->ip6));
|
2013-08-11 00:50:51 +00:00
|
|
|
return tp;
|
2009-09-06 08:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------ */
|
2010-04-29 18:17:29 +00:00
|
|
|
static hashipv6_t *
|
2017-10-26 08:50:00 +00:00
|
|
|
host_lookup6(const ws_in6_addr *addr)
|
1999-03-28 18:32:03 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
hashipv6_t * volatile tp;
|
2000-08-10 22:35:30 +00:00
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
tp = (hashipv6_t *)wmem_map_lookup(ipv6_hash_table, addr);
|
2015-02-27 02:10:25 +00:00
|
|
|
if (tp == NULL) {
|
2016-01-19 07:22:30 +00:00
|
|
|
/*
|
|
|
|
* We don't already have an entry for this host name; create one,
|
|
|
|
* and then try to resolve it.
|
|
|
|
*/
|
2017-10-26 08:50:00 +00:00
|
|
|
ws_in6_addr *addr_key;
|
2004-11-17 09:44:41 +00:00
|
|
|
|
2017-10-26 08:50:00 +00:00
|
|
|
addr_key = wmem_new(wmem_epan_scope(), ws_in6_addr);
|
2013-08-18 19:02:48 +00:00
|
|
|
tp = new_ipv6(addr);
|
2013-10-23 12:02:15 +00:00
|
|
|
memcpy(addr_key, addr, 16);
|
2017-06-09 08:03:38 +00:00
|
|
|
fill_dummy_ip6(tp);
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_insert(ipv6_hash_table, addr_key, tp);
|
2017-06-09 08:03:38 +00:00
|
|
|
} else if (tp->flags & TRIED_OR_RESOLVED_MASK) {
|
2013-08-18 19:02:48 +00:00
|
|
|
return tp;
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
|
|
|
|
2016-03-26 03:16:17 +00:00
|
|
|
/*
|
|
|
|
* This hasn't been resolved yet, and we haven't tried to
|
|
|
|
* resolve it already.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (!gbl_resolv_flags.network_name)
|
|
|
|
return tp;
|
|
|
|
|
|
|
|
if (gbl_resolv_flags.use_external_net_name_resolver) {
|
2015-09-27 13:46:09 +00:00
|
|
|
tp->flags |= TRIED_RESOLVE_ADDRESS;
|
2018-05-20 08:44:15 +00:00
|
|
|
|
|
|
|
if (async_dns_initialized) {
|
|
|
|
/* c-ares is initialized, so we can use it */
|
|
|
|
if (resolve_synchronously || name_resolve_concurrency == 0) {
|
|
|
|
/*
|
|
|
|
* Either all names are to be resolved synchronously or
|
|
|
|
* the concurrencly level is 0; do the resolution
|
|
|
|
* synchronously.
|
|
|
|
*/
|
|
|
|
sync_lookup_ip6(addr);
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Names are to be resolved asynchronously, and we
|
|
|
|
* allow at least one asynchronous request in flight;
|
|
|
|
* post an asynchronous request.
|
|
|
|
*/
|
|
|
|
async_dns_queue_msg_t *caqm;
|
|
|
|
|
|
|
|
caqm = wmem_new(wmem_epan_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);
|
|
|
|
}
|
2015-03-01 03:20:07 +00:00
|
|
|
}
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
1999-03-28 18:32:03 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
return tp;
|
2009-09-06 08:59:30 +00:00
|
|
|
|
|
|
|
} /* host_lookup6 */
|
2004-11-17 09:44:41 +00:00
|
|
|
|
1998-09-25 23:24:07 +00:00
|
|
|
/*
|
|
|
|
* Ethernet / manufacturer resolution
|
|
|
|
*
|
|
|
|
* The following functions implement ethernet address resolution and
|
2002-08-28 20:41:00 +00:00
|
|
|
* ethers files parsing (see ethers(4)).
|
1998-09-25 23:24:07 +00:00
|
|
|
*
|
2002-08-28 20:41:00 +00:00
|
|
|
* The manuf file has the same format as ethers(4) except that names are
|
2010-11-30 22:28:34 +00:00
|
|
|
* truncated to MAXMANUFLEN-1 (8) characters and that an address contains
|
1998-09-25 23:24:07 +00:00
|
|
|
* only 3 bytes (instead of 6).
|
|
|
|
*
|
|
|
|
* Notes:
|
|
|
|
*
|
2002-08-28 20:41:00 +00:00
|
|
|
* I decide to not use the existing functions (see ethers(3) on some
|
1998-09-25 23:24:07 +00:00
|
|
|
* operating systems) for the following reasons:
|
|
|
|
* - performance gains (use of hash tables and some other enhancements),
|
|
|
|
* - use of two ethers files (system-wide and per user),
|
|
|
|
* - avoid the use of NIS maps,
|
|
|
|
* - lack of these functions on some systems.
|
|
|
|
*
|
|
|
|
* So the following functions do _not_ behave as the standard ones.
|
|
|
|
*
|
|
|
|
* -- Laurent.
|
|
|
|
*/
|
|
|
|
|
2018-11-21 20:08:02 +00:00
|
|
|
/*
|
2020-10-24 19:38:00 +00:00
|
|
|
* Converts Ethernet addresses of the form aa:bb:cc or aa:bb:cc:dd:ee:ff/28.
|
|
|
|
* '-' is also supported as a separator. The
|
2018-11-21 20:08:02 +00:00
|
|
|
* 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
|
2018-11-22 20:03:18 +00:00
|
|
|
parse_ether_address_fast(const guchar *cp, ether_t *eth, unsigned int *mask,
|
2018-11-21 20:08:02 +00:00
|
|
|
const gboolean accept_mask)
|
|
|
|
{
|
|
|
|
/* XXX copied from strutil.c */
|
|
|
|
/* a map from ASCII hex chars to their value */
|
|
|
|
static const gint8 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,
|
|
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
|
|
|
|
-1,10,11,12,13,14,15,-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,10,11,12,13,14,15,-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,-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,-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,-1,-1,-1,-1,-1,-1,-1,-1,-1
|
|
|
|
};
|
2018-11-22 20:03:18 +00:00
|
|
|
const guint8 *str_to_nibble_usg = (const guint8 *)str_to_nibble;
|
2018-11-21 20:08:02 +00:00
|
|
|
|
2020-10-24 19:38:00 +00:00
|
|
|
guchar sep = cp[2];
|
|
|
|
if ((sep != ':' && sep != '-') || cp[5] != sep) {
|
2018-11-21 20:08:02 +00:00
|
|
|
/* Unexpected separators. */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-10-24 19:38:00 +00:00
|
|
|
/* 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]];
|
|
|
|
|
|
|
|
if ((num0 | num1 | num2) & 0x100) {
|
2018-11-21 20:08:02 +00:00
|
|
|
/* Not hexadecimal numbers. */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-10-24 19:38:00 +00:00
|
|
|
eth->addr[0] = (guint8)num0;
|
|
|
|
eth->addr[1] = (guint8)num1;
|
|
|
|
eth->addr[2] = (guint8)num2;
|
2018-11-21 20:08:02 +00:00
|
|
|
|
|
|
|
if (cp[8] == '\0' && accept_mask) {
|
|
|
|
/* Indicate that this is a manufacturer ID (0 is not allowed as a mask). */
|
|
|
|
*mask = 0;
|
|
|
|
return TRUE;
|
2020-10-24 19:38:00 +00:00
|
|
|
} else if (cp[8] != sep || !accept_mask) {
|
2018-11-21 20:08:02 +00:00
|
|
|
/* Format not handled by this fast path. */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-10-24 19:38:00 +00:00
|
|
|
/* 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]];
|
|
|
|
|
|
|
|
if (((num3 | num4 | num5) & 0x100) || cp[11] != sep || cp[14] != sep) {
|
2018-11-21 20:08:02 +00:00
|
|
|
/* Not hexadecimal numbers or invalid separators. */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-10-24 19:38:00 +00:00
|
|
|
eth->addr[3] = (guint8)num3;
|
|
|
|
eth->addr[4] = (guint8)num4;
|
|
|
|
eth->addr[5] = (guint8)num5;
|
2018-11-21 20:08:02 +00:00
|
|
|
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;
|
|
|
|
} else if (cp[17] != '/' || cp[20] != '\0') {
|
|
|
|
/* Format not handled by this fast path. */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
int m1 = cp[18];
|
|
|
|
int m2 = cp[19];
|
|
|
|
if (m1 == '3' && m2 == '6') { /* Mask /36 */
|
|
|
|
eth->addr[4] &= 0xf0;
|
|
|
|
eth->addr[5] = 0;
|
|
|
|
*mask = 36;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
/* Unsupported mask */
|
|
|
|
return FALSE;
|
|
|
|
}
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2002-09-09 19:38:11 +00:00
|
|
|
/*
|
2018-10-10 15:25:52 +00:00
|
|
|
* If "accept_mask" is FALSE, cp must point to an address that consists
|
|
|
|
* of exactly 6 bytes.
|
2017-07-20 01:32:40 +00:00
|
|
|
* If "accept_mask" is TRUE, parse an up-to-6-byte sequence with an optional
|
2002-09-09 19:38:11 +00:00
|
|
|
* mask.
|
|
|
|
*/
|
|
|
|
static gboolean
|
|
|
|
parse_ether_address(const char *cp, ether_t *eth, unsigned int *mask,
|
2017-07-20 01:32:40 +00:00
|
|
|
const gboolean accept_mask)
|
2013-08-11 00:50:51 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
unsigned long num;
|
|
|
|
char *p;
|
|
|
|
char sep = '\0';
|
|
|
|
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
|
|
/* Get a hex number, 1 or 2 digits, no sign characters allowed. */
|
2014-10-17 23:10:53 +00:00
|
|
|
if (!g_ascii_isxdigit(*cp))
|
2013-08-11 00:50:51 +00:00
|
|
|
return FALSE;
|
|
|
|
num = strtoul(cp, &p, 16);
|
|
|
|
if (p == cp)
|
|
|
|
return FALSE; /* failed */
|
|
|
|
if (num > 0xFF)
|
|
|
|
return FALSE; /* not a valid octet */
|
|
|
|
eth->addr[i] = (guint8) num;
|
|
|
|
cp = p; /* skip past the number */
|
|
|
|
|
|
|
|
/* OK, what character terminated the octet? */
|
|
|
|
if (*cp == '/') {
|
|
|
|
/* "/" - this has a mask. */
|
2017-07-20 01:32:40 +00:00
|
|
|
if (!accept_mask) {
|
|
|
|
/* Entries with masks are not allowed in this file. */
|
2013-08-11 00:50:51 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
cp++; /* skip past the '/' to get to the mask */
|
2014-10-17 23:10:53 +00:00
|
|
|
if (!g_ascii_isdigit(*cp))
|
2013-08-11 00:50:51 +00:00
|
|
|
return FALSE; /* no sign allowed */
|
|
|
|
num = strtoul(cp, &p, 10);
|
|
|
|
if (p == cp)
|
|
|
|
return FALSE; /* failed */
|
|
|
|
cp = p; /* skip past the number */
|
2014-10-17 23:10:53 +00:00
|
|
|
if (*cp != '\0' && !g_ascii_isspace(*cp))
|
2013-08-11 00:50:51 +00:00
|
|
|
return FALSE; /* bogus terminator */
|
|
|
|
if (num == 0 || num >= 48)
|
|
|
|
return FALSE; /* bogus mask */
|
|
|
|
/* Mask out the bits not covered by the mask */
|
|
|
|
*mask = (int)num;
|
|
|
|
for (i = 0; num >= 8; i++, num -= 8)
|
|
|
|
; /* skip octets entirely covered by the mask */
|
|
|
|
/* Mask out the first masked octet */
|
|
|
|
eth->addr[i] &= (0xFF << (8 - num));
|
|
|
|
i++;
|
|
|
|
/* Mask out completely-masked-out octets */
|
|
|
|
for (; i < 6; i++)
|
|
|
|
eth->addr[i] = 0;
|
|
|
|
return TRUE;
|
2010-04-27 22:46:39 +00:00
|
|
|
}
|
2013-08-11 00:50:51 +00:00
|
|
|
if (*cp == '\0') {
|
|
|
|
/* We're at the end of the address, and there's no mask. */
|
|
|
|
if (i == 2) {
|
|
|
|
/* We got 3 bytes, so this is a manufacturer ID. */
|
2017-07-20 01:32:40 +00:00
|
|
|
if (!accept_mask) {
|
|
|
|
/* Manufacturer IDs are not allowed in this file */
|
2013-08-11 00:50:51 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
/* Indicate that this is a manufacturer ID (0 is not allowed
|
|
|
|
as a mask). */
|
|
|
|
*mask = 0;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == 5) {
|
2017-07-20 01:32:40 +00:00
|
|
|
/* We got 6 bytes, so this is a MAC address (48 is not allowed as a mask). */
|
|
|
|
if (accept_mask)
|
2013-08-11 00:50:51 +00:00
|
|
|
*mask = 48;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We didn't get 3 or 6 bytes, and there's no mask; this is
|
|
|
|
illegal. */
|
|
|
|
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;
|
|
|
|
sep = *cp; /* subsequent separators must be the same */
|
|
|
|
} else {
|
|
|
|
/* It has to be the same as the first separator */
|
|
|
|
if (*cp != sep)
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cp++;
|
|
|
|
}
|
2002-09-09 19:38:11 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
return TRUE;
|
2002-09-09 19:38:11 +00:00
|
|
|
}
|
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static int
|
|
|
|
parse_ether_line(char *line, ether_t *eth, unsigned int *mask,
|
2017-07-20 01:32:40 +00:00
|
|
|
const gboolean accept_mask)
|
1998-09-25 23:24:07 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
/*
|
|
|
|
* See the ethers(4) or ethers(5) man page for ethers file format
|
|
|
|
* (not available on all systems).
|
|
|
|
* We allow both ethernet address separators (':' and '-'),
|
|
|
|
* as well as Wireshark's '.' separator.
|
|
|
|
*/
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
gchar *cp;
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2017-08-25 22:46:23 +00:00
|
|
|
line = g_strstrip(line);
|
|
|
|
if (line[0] == '\0' || line[0] == '#')
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if ((cp = strchr(line, '#'))) {
|
2013-08-11 00:50:51 +00:00
|
|
|
*cp = '\0';
|
2018-05-23 22:28:32 +00:00
|
|
|
g_strchomp(line);
|
2017-08-25 22:46:23 +00:00
|
|
|
}
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if ((cp = strtok(line, " \t")) == NULL)
|
|
|
|
return -1;
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2018-11-21 20:08:02 +00:00
|
|
|
/* First try to match the common format for the large ethers file. */
|
|
|
|
if (!parse_ether_address_fast(cp, eth, mask, accept_mask)) {
|
|
|
|
/* Fallback for the well-known addresses (wka) file. */
|
|
|
|
if (!parse_ether_address(cp, eth, mask, accept_mask))
|
|
|
|
return -1;
|
|
|
|
}
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if ((cp = strtok(NULL, " \t")) == NULL)
|
|
|
|
return -1;
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(eth->name, cp, MAXNAMELEN);
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2018-05-23 22:28:32 +00:00
|
|
|
if ((cp = strtok(NULL, "\t")) != NULL)
|
2017-08-20 17:33:53 +00:00
|
|
|
{
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(eth->longname, cp, MAXNAMELEN);
|
2017-08-20 17:33:53 +00:00
|
|
|
} else {
|
|
|
|
/* Make the long name the short name */
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(eth->longname, eth->name, MAXNAMELEN);
|
2017-08-20 17:33:53 +00:00
|
|
|
}
|
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
return 0;
|
1998-09-25 23:24:07 +00:00
|
|
|
|
|
|
|
} /* parse_ether_line */
|
|
|
|
|
|
|
|
static FILE *eth_p = NULL;
|
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static void
|
|
|
|
set_ethent(char *path)
|
1998-09-25 23:24:07 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
if (eth_p)
|
|
|
|
rewind(eth_p);
|
|
|
|
else
|
|
|
|
eth_p = ws_fopen(path, "r");
|
1998-09-25 23:24:07 +00:00
|
|
|
}
|
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static void
|
|
|
|
end_ethent(void)
|
1998-09-25 23:24:07 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
if (eth_p) {
|
|
|
|
fclose(eth_p);
|
|
|
|
eth_p = NULL;
|
|
|
|
}
|
1998-09-25 23:24:07 +00:00
|
|
|
}
|
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static ether_t *
|
2017-07-20 01:32:40 +00:00
|
|
|
get_ethent(unsigned int *mask, const gboolean accept_mask)
|
1998-09-25 23:24:07 +00:00
|
|
|
{
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
static ether_t eth;
|
2018-11-21 15:29:30 +00:00
|
|
|
char buf[MAX_LINELEN];
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (eth_p == NULL)
|
|
|
|
return NULL;
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2018-11-21 15:29:30 +00:00
|
|
|
while (fgetline(buf, sizeof(buf), eth_p) >= 0) {
|
2017-07-20 01:32:40 +00:00
|
|
|
if (parse_ether_line(buf, ð, mask, accept_mask) == 0) {
|
2013-08-11 00:50:51 +00:00
|
|
|
return ð
|
|
|
|
}
|
1998-09-25 23:24:07 +00:00
|
|
|
}
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
return NULL;
|
1998-09-25 23:24:07 +00:00
|
|
|
|
|
|
|
} /* get_ethent */
|
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static ether_t *
|
|
|
|
get_ethbyaddr(const guint8 *addr)
|
1998-09-25 23:24:07 +00:00
|
|
|
{
|
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
ether_t *eth;
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
set_ethent(g_pethers_path);
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
while (((eth = get_ethent(NULL, FALSE)) != NULL) && memcmp(addr, eth->addr, 6) != 0)
|
|
|
|
;
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (eth == NULL) {
|
|
|
|
end_ethent();
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
set_ethent(g_ethers_path);
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
while (((eth = get_ethent(NULL, FALSE)) != NULL) && memcmp(addr, eth->addr, 6) != 0)
|
|
|
|
;
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
end_ethent();
|
|
|
|
}
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
return eth;
|
1998-09-25 23:24:07 +00:00
|
|
|
|
|
|
|
} /* get_ethbyaddr */
|
|
|
|
|
2016-11-15 22:36:26 +00:00
|
|
|
static hashmanuf_t *
|
2017-08-20 17:33:53 +00:00
|
|
|
manuf_hash_new_entry(const guint8 *addr, char* name, char* longname)
|
2015-02-12 03:16:01 +00:00
|
|
|
{
|
2018-11-21 16:08:18 +00:00
|
|
|
guint manuf_key;
|
2015-02-12 03:16:01 +00:00
|
|
|
hashmanuf_t *manuf_value;
|
|
|
|
char *endp;
|
|
|
|
|
|
|
|
/* manuf needs only the 3 most significant octets of the ethernet address */
|
2018-11-21 16:08:18 +00:00
|
|
|
manuf_key = (addr[0] << 16) + (addr[1] << 8) + addr[2];
|
2016-04-20 14:45:32 +00:00
|
|
|
manuf_value = wmem_new(wmem_epan_scope(), hashmanuf_t);
|
2015-02-12 03:16:01 +00:00
|
|
|
|
|
|
|
memcpy(manuf_value->addr, addr, 3);
|
|
|
|
if (name != NULL) {
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(manuf_value->resolved_name, name, MAXNAMELEN);
|
2015-02-12 03:16:01 +00:00
|
|
|
manuf_value->status = HASHETHER_STATUS_RESOLVED_NAME;
|
2017-08-20 17:33:53 +00:00
|
|
|
if (longname != NULL) {
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(manuf_value->resolved_longname, longname, MAXNAMELEN);
|
2017-08-20 17:33:53 +00:00
|
|
|
}
|
|
|
|
else {
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(manuf_value->resolved_longname, name, MAXNAMELEN);
|
2017-08-20 17:33:53 +00:00
|
|
|
}
|
2015-02-12 03:16:01 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
manuf_value->status = HASHETHER_STATUS_UNRESOLVED;
|
|
|
|
manuf_value->resolved_name[0] = '\0';
|
2017-08-20 17:33:53 +00:00
|
|
|
manuf_value->resolved_longname[0] = '\0';
|
2015-02-12 03:16:01 +00:00
|
|
|
}
|
|
|
|
/* Values returned by bytes_to_hexstr_punct() are *not* null-terminated */
|
2015-02-20 11:47:52 +00:00
|
|
|
endp = bytes_to_hexstr_punct(manuf_value->hexaddr, addr, sizeof(manuf_value->addr), ':');
|
2015-02-12 03:16:01 +00:00
|
|
|
*endp = '\0';
|
|
|
|
|
2018-11-21 16:08:18 +00:00
|
|
|
wmem_map_insert(manuf_hashtable, GUINT_TO_POINTER(manuf_key), manuf_value);
|
2015-02-12 03:16:01 +00:00
|
|
|
return manuf_value;
|
|
|
|
}
|
2002-09-09 19:38:11 +00:00
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static void
|
2016-11-15 22:36:26 +00:00
|
|
|
wka_hash_new_entry(const guint8 *addr, char* name)
|
1998-09-25 23:24:07 +00:00
|
|
|
{
|
2014-05-07 01:45:16 +00:00
|
|
|
guint8 *wka_key;
|
2002-09-09 19:38:11 +00:00
|
|
|
|
2016-04-20 14:45:32 +00:00
|
|
|
wka_key = (guint8 *)wmem_alloc(wmem_epan_scope(), 6);
|
2014-05-07 01:45:16 +00:00
|
|
|
memcpy(wka_key, addr, 6);
|
2013-08-11 00:50:51 +00:00
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_insert(wka_hashtable, wka_key, wmem_strdup(wmem_epan_scope(), name));
|
2016-11-15 22:36:26 +00:00
|
|
|
}
|
2002-09-09 19:38:11 +00:00
|
|
|
|
2016-11-15 22:36:26 +00:00
|
|
|
static void
|
2017-08-20 17:33:53 +00:00
|
|
|
add_manuf_name(const guint8 *addr, unsigned int mask, gchar *name, gchar *longname)
|
2016-11-15 22:36:26 +00:00
|
|
|
{
|
|
|
|
switch (mask)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
/* This is a manufacturer ID; add it to the manufacturer ID hash table */
|
2017-08-20 17:33:53 +00:00
|
|
|
manuf_hash_new_entry(addr, name, longname);
|
2016-11-15 22:36:26 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 48:
|
|
|
|
/* This is a well-known MAC address; add it to the Ethernet hash table */
|
|
|
|
add_eth_name(addr, name);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
/* This is a range of well-known addresses; add it to the well-known-address table */
|
|
|
|
wka_hash_new_entry(addr, name);
|
|
|
|
break;
|
|
|
|
}
|
1998-09-25 23:24:07 +00:00
|
|
|
} /* add_manuf_name */
|
|
|
|
|
2015-02-12 03:16:01 +00:00
|
|
|
static hashmanuf_t *
|
2010-04-29 18:17:29 +00:00
|
|
|
manuf_name_lookup(const guint8 *addr)
|
1998-09-25 23:24:07 +00:00
|
|
|
{
|
2018-11-21 16:08:18 +00:00
|
|
|
guint32 manuf_key;
|
2013-08-11 00:50:51 +00:00
|
|
|
guint8 oct;
|
2015-02-12 03:16:01 +00:00
|
|
|
hashmanuf_t *manuf_value;
|
2013-08-01 20:11:13 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* 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;
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2001-06-07 22:07:02 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* first try to find a "perfect match" */
|
2018-11-21 16:08:18 +00:00
|
|
|
manuf_value = (hashmanuf_t*)wmem_map_lookup(manuf_hashtable, GUINT_TO_POINTER(manuf_key));
|
2015-02-12 03:16:01 +00:00
|
|
|
if (manuf_value != NULL) {
|
|
|
|
return manuf_value;
|
2007-08-14 23:52:51 +00:00
|
|
|
}
|
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Mask out the broadcast/multicast flag but not the locally
|
2016-01-06 00:58:42 +00:00
|
|
|
* administered flag as locally administered means: not assigned
|
2013-08-11 00:50:51 +00:00
|
|
|
* by the IEEE but the local administrator instead.
|
|
|
|
* 0x01 multicast / broadcast bit
|
|
|
|
* 0x02 locally administered bit */
|
2015-02-27 02:10:25 +00:00
|
|
|
if ((manuf_key & 0x00010000) != 0) {
|
2013-08-11 00:50:51 +00:00
|
|
|
manuf_key &= 0x00FEFFFF;
|
2018-11-21 16:08:18 +00:00
|
|
|
manuf_value = (hashmanuf_t*)wmem_map_lookup(manuf_hashtable, GUINT_TO_POINTER(manuf_key));
|
2015-02-12 03:16:01 +00:00
|
|
|
if (manuf_value != NULL) {
|
|
|
|
return manuf_value;
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-12 03:16:01 +00:00
|
|
|
/* Add the address as a hex string */
|
2017-08-20 17:33:53 +00:00
|
|
|
return manuf_hash_new_entry(addr, NULL, NULL);
|
1998-09-25 23:24:07 +00:00
|
|
|
|
|
|
|
} /* manuf_name_lookup */
|
|
|
|
|
2013-08-01 20:11:13 +00:00
|
|
|
static gchar *
|
2010-04-29 18:17:29 +00:00
|
|
|
wka_name_lookup(const guint8 *addr, const unsigned int mask)
|
2002-09-09 19:38:11 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
guint8 masked_addr[6];
|
|
|
|
guint num;
|
|
|
|
gint i;
|
|
|
|
gchar *name;
|
2002-09-09 19:38:11 +00:00
|
|
|
|
2015-02-27 02:10:25 +00:00
|
|
|
if (wka_hashtable == NULL) {
|
2013-08-11 00:50:51 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/* Get the part of the address covered by the mask. */
|
|
|
|
for (i = 0, num = mask; num >= 8; i++, num -= 8)
|
|
|
|
masked_addr[i] = addr[i]; /* copy octets entirely covered by the mask */
|
|
|
|
/* Mask out the first masked octet */
|
|
|
|
masked_addr[i] = addr[i] & (0xFF << (8 - num));
|
|
|
|
i++;
|
|
|
|
/* Zero out completely-masked-out octets */
|
|
|
|
for (; i < 6; i++)
|
|
|
|
masked_addr[i] = 0;
|
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
name = (gchar *)wmem_map_lookup(wka_hashtable, masked_addr);
|
2013-08-11 00:50:51 +00:00
|
|
|
|
|
|
|
return name;
|
2002-09-09 19:38:11 +00:00
|
|
|
|
|
|
|
} /* wka_name_lookup */
|
|
|
|
|
2015-02-12 01:13:36 +00:00
|
|
|
|
|
|
|
guint get_hash_ether_status(hashether_t* ether)
|
|
|
|
{
|
|
|
|
return ether->status;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* get_hash_ether_hexaddr(hashether_t* ether)
|
|
|
|
{
|
|
|
|
return ether->hexaddr;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* get_hash_ether_resolved_name(hashether_t* ether)
|
|
|
|
{
|
|
|
|
return ether->resolved_name;
|
|
|
|
}
|
|
|
|
|
2014-05-07 01:45:16 +00:00
|
|
|
static guint
|
|
|
|
eth_addr_hash(gconstpointer key)
|
|
|
|
{
|
|
|
|
return wmem_strong_hash((const guint8 *)key, 6);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
eth_addr_cmp(gconstpointer a, gconstpointer b)
|
|
|
|
{
|
|
|
|
return (memcmp(a, b, 6) == 0);
|
|
|
|
}
|
|
|
|
|
2013-08-07 16:46:08 +00:00
|
|
|
static void
|
2010-04-29 18:17:29 +00:00
|
|
|
initialize_ethers(void)
|
1999-11-20 05:35:15 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
ether_t *eth;
|
2015-08-18 13:58:34 +00:00
|
|
|
guint mask = 0;
|
1999-11-20 05:35:15 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* hash table initialization */
|
2016-08-13 23:41:54 +00:00
|
|
|
wka_hashtable = wmem_map_new(wmem_epan_scope(), eth_addr_hash, eth_addr_cmp);
|
2018-11-21 16:08:18 +00:00
|
|
|
manuf_hashtable = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
|
2016-08-13 23:41:54 +00:00
|
|
|
eth_hashtable = wmem_map_new(wmem_epan_scope(), eth_addr_hash, eth_addr_cmp);
|
2013-08-07 16:46:08 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Compute the pathname of the ethers file. */
|
|
|
|
if (g_ethers_path == NULL) {
|
2017-07-20 01:32:40 +00:00
|
|
|
g_ethers_path = g_build_filename(get_systemfile_dir(), ENAME_ETHERS, NULL);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
2001-10-21 19:54:49 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Set g_pethers_path here, but don't actually do anything
|
2017-08-25 20:50:02 +00:00
|
|
|
* with it. It's used in get_ethbyaddr().
|
2013-08-11 00:50:51 +00:00
|
|
|
*/
|
2020-10-10 11:34:18 +00:00
|
|
|
if (g_pethers_path == NULL) {
|
|
|
|
/* Check profile directory before personal configuration */
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
1999-11-20 05:35:15 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Compute the pathname of the manuf file */
|
2017-07-20 01:32:40 +00:00
|
|
|
if (g_manuf_path == NULL)
|
|
|
|
g_manuf_path = get_datafile_path(ENAME_MANUF);
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Read it and initialize the hash table */
|
2017-07-20 01:32:40 +00:00
|
|
|
set_ethent(g_manuf_path);
|
2013-08-11 00:50:51 +00:00
|
|
|
while ((eth = get_ethent(&mask, TRUE))) {
|
2017-08-20 17:33:53 +00:00
|
|
|
add_manuf_name(eth->addr, mask, eth->name, eth->longname);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
|
|
|
end_ethent();
|
1999-11-20 05:35:15 +00:00
|
|
|
|
2017-07-20 01:32:40 +00:00
|
|
|
/* Compute the pathname of the wka file */
|
|
|
|
if (g_wka_path == NULL)
|
|
|
|
g_wka_path = get_datafile_path(ENAME_WKA);
|
|
|
|
|
|
|
|
/* Read it and initialize the hash table */
|
|
|
|
set_ethent(g_wka_path);
|
|
|
|
while ((eth = get_ethent(&mask, TRUE))) {
|
2017-08-20 17:33:53 +00:00
|
|
|
add_manuf_name(eth->addr, mask, eth->name, eth->longname);
|
2017-07-20 01:32:40 +00:00
|
|
|
}
|
|
|
|
end_ethent();
|
On Windows, use the directory in which the binary resides as the
directory in which global data files are stored. If an installed binary
is being run, that's the correct directory for them; if a build-tree
binary is being run, the "manuf" file will be there, and you can put
other data files there as well, if necessary.
Do the same with plugins, except that, if there's no
"plugins\\{version}" subdirectory of that directory, fall back on the
default installation directory, so you at least have a place where you
can put plugins for use by build-tree binaries. (Should we, instead,
have the Windows build procedure create a subdirectory of the "plugins"
source directory, with the plugin version number as its name, and copy
the plugins there, so you'd use the build-tree plugin binaries?)
Move "test_for_directory()" out of "util.c" and into
"epan/filesystem.c", with the other file system access portability
wrappers and convenience routines. Fix "util.h" not to declare it - or
other routines moved to "epan/filesystem.c" a while ago.
svn path=/trunk/; revision=3858
2001-08-21 06:39:18 +00:00
|
|
|
|
1999-11-20 05:35:15 +00:00
|
|
|
} /* initialize_ethers */
|
|
|
|
|
2017-02-10 17:04:20 +00:00
|
|
|
static void
|
|
|
|
ethers_cleanup(void)
|
|
|
|
{
|
2017-07-20 01:32:40 +00:00
|
|
|
g_free(g_ethers_path);
|
|
|
|
g_ethers_path = NULL;
|
2017-02-10 17:04:20 +00:00
|
|
|
g_free(g_pethers_path);
|
|
|
|
g_pethers_path = NULL;
|
2017-07-20 01:32:40 +00:00
|
|
|
g_free(g_manuf_path);
|
|
|
|
g_manuf_path = NULL;
|
|
|
|
g_free(g_wka_path);
|
|
|
|
g_wka_path = NULL;
|
2017-02-10 17:04:20 +00:00
|
|
|
}
|
|
|
|
|
2010-07-01 15:11:02 +00:00
|
|
|
/* Resolve ethernet address */
|
2010-04-29 18:17:29 +00:00
|
|
|
static hashether_t *
|
2010-07-01 15:11:02 +00:00
|
|
|
eth_addr_resolve(hashether_t *tp) {
|
2013-08-11 00:50:51 +00:00
|
|
|
ether_t *eth;
|
2015-02-12 03:16:01 +00:00
|
|
|
hashmanuf_t *manuf_value;
|
2013-08-11 00:50:51 +00:00
|
|
|
const guint8 *addr = tp->addr;
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if ( (eth = get_ethbyaddr(addr)) != NULL) {
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(tp->resolved_name, eth->name, MAXNAMELEN);
|
2013-08-11 00:50:51 +00:00
|
|
|
tp->status = HASHETHER_STATUS_RESOLVED_NAME;
|
2010-04-27 22:46:39 +00:00
|
|
|
return tp;
|
2013-08-11 00:50:51 +00:00
|
|
|
} else {
|
|
|
|
guint mask;
|
|
|
|
gchar *name;
|
2014-12-20 02:42:14 +00:00
|
|
|
address ether_addr;
|
2013-08-11 00:50:51 +00:00
|
|
|
|
|
|
|
/* Unknown name. Try looking for it in the well-known-address
|
|
|
|
tables for well-known address ranges smaller than 2^24. */
|
|
|
|
mask = 7;
|
2016-11-15 22:36:26 +00:00
|
|
|
do {
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Only the topmost 5 bytes participate fully */
|
|
|
|
if ((name = wka_name_lookup(addr, mask+40)) != NULL) {
|
2021-12-16 18:06:18 +00:00
|
|
|
snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x",
|
2013-08-11 00:50:51 +00:00
|
|
|
name, addr[5] & (0xFF >> mask));
|
|
|
|
tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
|
|
|
|
return tp;
|
|
|
|
}
|
2016-11-15 22:36:26 +00:00
|
|
|
} while (mask--);
|
2013-08-11 00:50:51 +00:00
|
|
|
|
|
|
|
mask = 7;
|
2016-11-15 22:36:26 +00:00
|
|
|
do {
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Only the topmost 4 bytes participate fully */
|
|
|
|
if ((name = wka_name_lookup(addr, mask+32)) != NULL) {
|
2021-12-16 18:06:18 +00:00
|
|
|
snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x",
|
2013-08-11 00:50:51 +00:00
|
|
|
name, addr[4] & (0xFF >> mask), addr[5]);
|
|
|
|
tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
|
|
|
|
return tp;
|
|
|
|
}
|
2016-11-15 22:36:26 +00:00
|
|
|
} while (mask--);
|
2013-08-11 00:50:51 +00:00
|
|
|
|
|
|
|
mask = 7;
|
2016-11-15 22:36:26 +00:00
|
|
|
do {
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Only the topmost 3 bytes participate fully */
|
|
|
|
if ((name = wka_name_lookup(addr, mask+24)) != NULL) {
|
2021-12-16 18:06:18 +00:00
|
|
|
snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x",
|
2013-08-11 00:50:51 +00:00
|
|
|
name, addr[3] & (0xFF >> mask), addr[4], addr[5]);
|
|
|
|
tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
|
|
|
|
return tp;
|
|
|
|
}
|
2016-11-15 22:36:26 +00:00
|
|
|
} while (mask--);
|
2013-08-11 00:50:51 +00:00
|
|
|
|
|
|
|
/* Now try looking in the manufacturer table. */
|
2015-02-12 03:16:01 +00:00
|
|
|
manuf_value = manuf_name_lookup(addr);
|
|
|
|
if ((manuf_value != NULL) && (manuf_value->status != HASHETHER_STATUS_UNRESOLVED)) {
|
2021-12-16 18:06:18 +00:00
|
|
|
snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x",
|
2015-02-12 03:16:01 +00:00
|
|
|
manuf_value->resolved_name, addr[3], addr[4], addr[5]);
|
2013-08-11 00:50:51 +00:00
|
|
|
tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
|
|
|
|
return tp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now try looking for it in the well-known-address
|
|
|
|
tables for well-known address ranges larger than 2^24. */
|
|
|
|
mask = 7;
|
2016-11-15 22:36:26 +00:00
|
|
|
do {
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Only the topmost 2 bytes participate fully */
|
|
|
|
if ((name = wka_name_lookup(addr, mask+16)) != NULL) {
|
2021-12-16 18:06:18 +00:00
|
|
|
snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x:%02x",
|
2013-08-11 00:50:51 +00:00
|
|
|
name, addr[2] & (0xFF >> mask), addr[3], addr[4],
|
|
|
|
addr[5]);
|
|
|
|
tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
|
|
|
|
return tp;
|
|
|
|
}
|
2016-11-15 22:36:26 +00:00
|
|
|
} while (mask--);
|
2013-08-11 00:50:51 +00:00
|
|
|
|
|
|
|
mask = 7;
|
2016-11-15 22:36:26 +00:00
|
|
|
do {
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Only the topmost byte participates fully */
|
|
|
|
if ((name = wka_name_lookup(addr, mask+8)) != NULL) {
|
2021-12-16 18:06:18 +00:00
|
|
|
snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x:%02x:%02x",
|
2013-08-11 00:50:51 +00:00
|
|
|
name, addr[1] & (0xFF >> mask), addr[2], addr[3],
|
|
|
|
addr[4], addr[5]);
|
|
|
|
tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
|
|
|
|
return tp;
|
|
|
|
}
|
2016-11-15 22:36:26 +00:00
|
|
|
} while (mask--);
|
2013-08-11 00:50:51 +00:00
|
|
|
|
2016-11-15 22:36:26 +00:00
|
|
|
mask = 7;
|
|
|
|
do {
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Not even the topmost byte participates fully */
|
|
|
|
if ((name = wka_name_lookup(addr, mask)) != NULL) {
|
2021-12-16 18:06:18 +00:00
|
|
|
snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x:%02x:%02x:%02x",
|
2013-08-11 00:50:51 +00:00
|
|
|
name, addr[0] & (0xFF >> mask), addr[1], addr[2],
|
|
|
|
addr[3], addr[4], addr[5]);
|
|
|
|
tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
|
|
|
|
return tp;
|
|
|
|
}
|
2016-11-15 22:36:26 +00:00
|
|
|
} while (--mask); /* Work down to the last bit */
|
2013-08-11 00:50:51 +00:00
|
|
|
|
|
|
|
/* No match whatsoever. */
|
2015-10-21 19:04:16 +00:00
|
|
|
set_address(ðer_addr, AT_ETHER, 6, addr);
|
2015-01-05 16:12:08 +00:00
|
|
|
address_to_str_buf(ðer_addr, tp->resolved_name, MAXNAMELEN);
|
2010-07-01 15:11:02 +00:00
|
|
|
tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
|
2010-04-27 22:46:39 +00:00
|
|
|
return tp;
|
2002-09-09 19:38:11 +00:00
|
|
|
}
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert_not_reached();
|
2010-07-01 15:11:02 +00:00
|
|
|
} /* eth_addr_resolve */
|
1999-11-20 05:35:15 +00:00
|
|
|
|
2013-08-15 02:45:58 +00:00
|
|
|
static hashether_t *
|
|
|
|
eth_hash_new_entry(const guint8 *addr, const gboolean resolve)
|
|
|
|
{
|
|
|
|
hashether_t *tp;
|
2013-12-20 10:08:35 +00:00
|
|
|
char *endp;
|
2013-08-15 02:45:58 +00:00
|
|
|
|
2016-04-20 14:45:32 +00:00
|
|
|
tp = wmem_new(wmem_epan_scope(), hashether_t);
|
2013-08-11 00:50:51 +00:00
|
|
|
memcpy(tp->addr, addr, sizeof(tp->addr));
|
|
|
|
tp->status = HASHETHER_STATUS_UNRESOLVED;
|
2013-12-20 10:08:35 +00:00
|
|
|
/* Values returned by bytes_to_hexstr_punct() are *not* null-terminated */
|
|
|
|
endp = bytes_to_hexstr_punct(tp->hexaddr, addr, sizeof(tp->addr), ':');
|
|
|
|
*endp = '\0';
|
2013-08-11 00:50:51 +00:00
|
|
|
tp->resolved_name[0] = '\0';
|
|
|
|
|
|
|
|
if (resolve)
|
|
|
|
eth_addr_resolve(tp);
|
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_insert(eth_hashtable, tp->addr, tp);
|
2013-08-11 00:50:51 +00:00
|
|
|
|
|
|
|
return tp;
|
2010-07-01 15:11:02 +00:00
|
|
|
} /* eth_hash_new_entry */
|
|
|
|
|
|
|
|
static hashether_t *
|
|
|
|
add_eth_name(const guint8 *addr, const gchar *name)
|
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
hashether_t *tp;
|
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
tp = (hashether_t *)wmem_map_lookup(eth_hashtable, addr);
|
2013-08-11 00:50:51 +00:00
|
|
|
|
2015-02-27 02:10:25 +00:00
|
|
|
if (tp == NULL) {
|
2013-08-11 00:50:51 +00:00
|
|
|
tp = eth_hash_new_entry(addr, FALSE);
|
|
|
|
}
|
|
|
|
|
2016-02-29 11:19:19 +00:00
|
|
|
if (strcmp(tp->resolved_name, name) != 0) {
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(tp->resolved_name, name, MAXNAMELEN);
|
2016-02-29 11:19:19 +00:00
|
|
|
tp->status = HASHETHER_STATUS_RESOLVED_NAME;
|
|
|
|
new_resolved_objects = TRUE;
|
|
|
|
}
|
2013-08-11 00:50:51 +00:00
|
|
|
|
|
|
|
return tp;
|
2010-07-01 15:11:02 +00:00
|
|
|
} /* add_eth_name */
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2010-07-01 15:11:02 +00:00
|
|
|
static hashether_t *
|
2013-08-15 02:45:58 +00:00
|
|
|
eth_name_lookup(const guint8 *addr, const gboolean resolve)
|
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
hashether_t *tp;
|
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
tp = (hashether_t *)wmem_map_lookup(eth_hashtable, addr);
|
2016-11-15 22:36:26 +00:00
|
|
|
|
2015-02-27 02:10:25 +00:00
|
|
|
if (tp == NULL) {
|
2013-08-11 00:50:51 +00:00
|
|
|
tp = eth_hash_new_entry(addr, resolve);
|
|
|
|
} else {
|
2015-02-27 02:10:25 +00:00
|
|
|
if (resolve && (tp->status == HASHETHER_STATUS_UNRESOLVED)) {
|
2013-08-11 00:50:51 +00:00
|
|
|
eth_addr_resolve(tp); /* Found but needs to be resolved */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return tp;
|
2013-08-02 15:05:00 +00:00
|
|
|
|
1998-09-25 23:24:07 +00:00
|
|
|
} /* eth_name_lookup */
|
|
|
|
|
1999-11-21 16:32:23 +00:00
|
|
|
|
|
|
|
/* IPXNETS */
|
2010-04-29 18:17:29 +00:00
|
|
|
static int
|
|
|
|
parse_ipxnets_line(char *line, ipxnet_t *ipxnet)
|
1999-11-21 16:32:23 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
/*
|
|
|
|
* We allow three address separators (':', '-', and '.'),
|
|
|
|
* as well as no separators
|
|
|
|
*/
|
|
|
|
|
|
|
|
gchar *cp;
|
|
|
|
guint32 a, a0, a1, a2, a3;
|
|
|
|
gboolean found_single_number = FALSE;
|
|
|
|
|
|
|
|
if ((cp = strchr(line, '#')))
|
|
|
|
*cp = '\0';
|
|
|
|
|
|
|
|
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,
|
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2010-04-27 22:46:39 +00:00
|
|
|
}
|
1999-11-21 16:32:23 +00:00
|
|
|
}
|
1999-11-20 05:35:15 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if ((cp = strtok(NULL, " \t\n")) == NULL)
|
|
|
|
return -1;
|
1999-11-20 05:35:15 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (found_single_number) {
|
|
|
|
ipxnet->addr = a;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ipxnet->addr = (a0 << 24) | (a1 << 16) | (a2 << 8) | a3;
|
|
|
|
}
|
1999-11-21 16:32:23 +00:00
|
|
|
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(ipxnet->name, cp, MAXNAMELEN);
|
1999-11-21 16:32:23 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
return 0;
|
1999-11-21 16:32:23 +00:00
|
|
|
|
|
|
|
} /* parse_ipxnets_line */
|
|
|
|
|
|
|
|
static FILE *ipxnet_p = NULL;
|
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static void
|
|
|
|
set_ipxnetent(char *path)
|
1999-11-21 16:32:23 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
if (ipxnet_p)
|
|
|
|
rewind(ipxnet_p);
|
|
|
|
else
|
|
|
|
ipxnet_p = ws_fopen(path, "r");
|
1999-11-21 16:32:23 +00:00
|
|
|
}
|
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static void
|
|
|
|
end_ipxnetent(void)
|
1999-11-21 16:32:23 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
if (ipxnet_p) {
|
|
|
|
fclose(ipxnet_p);
|
|
|
|
ipxnet_p = NULL;
|
|
|
|
}
|
1999-11-21 16:32:23 +00:00
|
|
|
}
|
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static ipxnet_t *
|
|
|
|
get_ipxnetent(void)
|
1999-11-21 16:32:23 +00:00
|
|
|
{
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
static ipxnet_t ipxnet;
|
2018-11-21 15:29:30 +00:00
|
|
|
char buf[MAX_LINELEN];
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (ipxnet_p == NULL)
|
|
|
|
return NULL;
|
1999-11-21 16:32:23 +00:00
|
|
|
|
2018-11-21 15:29:30 +00:00
|
|
|
while (fgetline(buf, sizeof(buf), ipxnet_p) >= 0) {
|
2013-08-11 00:50:51 +00:00
|
|
|
if (parse_ipxnets_line(buf, &ipxnet) == 0) {
|
|
|
|
return &ipxnet;
|
|
|
|
}
|
1999-11-21 16:32:23 +00:00
|
|
|
}
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
return NULL;
|
1999-11-21 16:32:23 +00:00
|
|
|
|
|
|
|
} /* get_ipxnetent */
|
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static ipxnet_t *
|
|
|
|
get_ipxnetbyaddr(guint32 addr)
|
1999-11-21 16:32:23 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
ipxnet_t *ipxnet;
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
set_ipxnetent(g_ipxnets_path);
|
1999-11-21 16:32:23 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
while (((ipxnet = get_ipxnetent()) != NULL) && (addr != ipxnet->addr) ) ;
|
1999-11-21 16:32:23 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (ipxnet == NULL) {
|
|
|
|
end_ipxnetent();
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
set_ipxnetent(g_pipxnets_path);
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
while (((ipxnet = get_ipxnetent()) != NULL) && (addr != ipxnet->addr) )
|
|
|
|
;
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
end_ipxnetent();
|
|
|
|
}
|
1999-11-21 16:32:23 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
return ipxnet;
|
1999-11-21 16:32:23 +00:00
|
|
|
|
|
|
|
} /* get_ipxnetbyaddr */
|
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static void
|
|
|
|
initialize_ipxnets(void)
|
1999-11-21 16:32:23 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Compute the pathname of the ipxnets file.
|
|
|
|
*
|
|
|
|
* XXX - is there a notion of an "ipxnets file" in any flavor of
|
|
|
|
* UNIX, or with any add-on Netware package for UNIX? If not,
|
|
|
|
* should the UNIX version of the ipxnets file be in the datafile
|
|
|
|
* directory as well?
|
|
|
|
*/
|
|
|
|
if (g_ipxnets_path == NULL) {
|
2016-04-20 14:45:32 +00:00
|
|
|
g_ipxnets_path = wmem_strdup_printf(wmem_epan_scope(), "%s" G_DIR_SEPARATOR_S "%s",
|
2013-08-11 00:50:51 +00:00
|
|
|
get_systemfile_dir(), ENAME_IPXNETS);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set g_pipxnets_path here, but don't actually do anything
|
2017-08-25 20:50:02 +00:00
|
|
|
* with it. It's used in get_ipxnetbyaddr().
|
2013-08-11 00:50:51 +00:00
|
|
|
*/
|
2020-10-10 11:34:18 +00:00
|
|
|
if (g_pipxnets_path == NULL) {
|
|
|
|
/* Check profile directory before personal configuration */
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
1999-11-21 16:32:23 +00:00
|
|
|
|
|
|
|
} /* initialize_ipxnets */
|
|
|
|
|
2013-08-07 16:46:08 +00:00
|
|
|
static void
|
|
|
|
ipx_name_lookup_cleanup(void)
|
|
|
|
{
|
2017-02-10 17:04:20 +00:00
|
|
|
g_free(g_pipxnets_path);
|
|
|
|
g_pipxnets_path = NULL;
|
2013-08-07 16:46:08 +00:00
|
|
|
}
|
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static gchar *
|
2015-01-08 17:13:18 +00:00
|
|
|
ipxnet_name_lookup(wmem_allocator_t *allocator, const guint addr)
|
1999-11-21 16:32:23 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
hashipxnet_t *tp;
|
|
|
|
ipxnet_t *ipxnet;
|
1999-11-21 16:32:23 +00:00
|
|
|
|
2018-11-21 16:08:18 +00:00
|
|
|
tp = (hashipxnet_t *)wmem_map_lookup(ipxnet_hash_table, GUINT_TO_POINTER(addr));
|
2015-02-27 02:10:25 +00:00
|
|
|
if (tp == NULL) {
|
2016-04-20 14:45:32 +00:00
|
|
|
tp = wmem_new(wmem_epan_scope(), hashipxnet_t);
|
2018-11-21 16:08:18 +00:00
|
|
|
wmem_map_insert(ipxnet_hash_table, GUINT_TO_POINTER(addr), tp);
|
2015-02-27 02:10:25 +00:00
|
|
|
} else {
|
2015-01-08 17:13:18 +00:00
|
|
|
return wmem_strdup(allocator, tp->name);
|
1999-11-20 05:35:15 +00:00
|
|
|
}
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* fill in a new entry */
|
1999-11-20 05:35:15 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
tp->addr = addr;
|
1999-11-21 16:32:23 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if ( (ipxnet = get_ipxnetbyaddr(addr)) == NULL) {
|
|
|
|
/* unknown name */
|
2021-12-16 18:06:18 +00:00
|
|
|
snprintf(tp->name, MAXNAMELEN, "%X", addr);
|
1999-11-21 16:32:23 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
} else {
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(tp->name, ipxnet->name, MAXNAMELEN);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
1999-11-21 16:32:23 +00:00
|
|
|
|
2015-01-08 17:13:18 +00:00
|
|
|
return wmem_strdup(allocator, tp->name);
|
1999-11-21 16:32:23 +00:00
|
|
|
|
|
|
|
} /* ipxnet_name_lookup */
|
|
|
|
|
2016-03-13 22:16:20 +00:00
|
|
|
/* VLANS */
|
|
|
|
static int
|
|
|
|
parse_vlan_line(char *line, vlan_t *vlan)
|
|
|
|
{
|
|
|
|
gchar *cp;
|
|
|
|
guint16 id;
|
|
|
|
|
|
|
|
if ((cp = strchr(line, '#')))
|
|
|
|
*cp = '\0';
|
|
|
|
|
|
|
|
if ((cp = strtok(line, " \t\n")) == NULL)
|
|
|
|
return -1;
|
|
|
|
|
2021-12-16 18:06:18 +00:00
|
|
|
if (sscanf(cp, "%" SCNu16, &id) == 1) {
|
2016-03-13 22:16:20 +00:00
|
|
|
vlan->id = id;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((cp = strtok(NULL, "\t\n")) == NULL)
|
|
|
|
return -1;
|
|
|
|
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(vlan->name, cp, MAXVLANNAMELEN);
|
2016-03-13 22:16:20 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
} /* parse_vlan_line */
|
|
|
|
|
|
|
|
static FILE *vlan_p = NULL;
|
|
|
|
|
|
|
|
static void
|
|
|
|
set_vlanent(char *path)
|
|
|
|
{
|
|
|
|
if (vlan_p)
|
|
|
|
rewind(vlan_p);
|
|
|
|
else
|
|
|
|
vlan_p = ws_fopen(path, "r");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
end_vlanent(void)
|
|
|
|
{
|
|
|
|
if (vlan_p) {
|
|
|
|
fclose(vlan_p);
|
|
|
|
vlan_p = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static vlan_t *
|
|
|
|
get_vlanent(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
static vlan_t vlan;
|
2018-11-21 15:29:30 +00:00
|
|
|
char buf[MAX_LINELEN];
|
2016-03-13 22:16:20 +00:00
|
|
|
|
|
|
|
if (vlan_p == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2018-11-21 15:29:30 +00:00
|
|
|
while (fgetline(buf, sizeof(buf), vlan_p) >= 0) {
|
2016-03-13 22:16:20 +00:00
|
|
|
if (parse_vlan_line(buf, &vlan) == 0) {
|
|
|
|
return &vlan;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
} /* get_vlanent */
|
|
|
|
|
|
|
|
static vlan_t *
|
|
|
|
get_vlannamebyid(guint16 id)
|
|
|
|
{
|
|
|
|
vlan_t *vlan;
|
|
|
|
|
|
|
|
set_vlanent(g_pvlan_path);
|
|
|
|
|
|
|
|
while (((vlan = get_vlanent()) != NULL) && (id != vlan->id) ) ;
|
|
|
|
|
|
|
|
if (vlan == NULL) {
|
|
|
|
end_vlanent();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return vlan;
|
|
|
|
|
|
|
|
} /* get_vlannamebyid */
|
|
|
|
|
|
|
|
static void
|
|
|
|
initialize_vlans(void)
|
|
|
|
{
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(vlan_hash_table == NULL);
|
2018-11-21 16:08:18 +00:00
|
|
|
vlan_hash_table = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
|
2016-03-13 22:16:20 +00:00
|
|
|
|
2016-11-19 17:13:47 +00:00
|
|
|
/* Set g_pvlan_path here, but don't actually do anything
|
|
|
|
* with it. It's used in get_vlannamebyid()
|
2016-03-13 22:16:20 +00:00
|
|
|
*/
|
2019-05-26 10:59:07 +00:00
|
|
|
if (g_pvlan_path == NULL) {
|
|
|
|
/* Check profile directory before personal configuration */
|
|
|
|
g_pvlan_path = get_persconffile_path(ENAME_VLANS, TRUE);
|
2019-05-27 09:48:47 +00:00
|
|
|
if (!file_exists(g_pvlan_path)) {
|
2019-05-26 10:59:07 +00:00
|
|
|
g_free(g_pvlan_path);
|
|
|
|
g_pvlan_path = get_persconffile_path(ENAME_VLANS, FALSE);
|
|
|
|
}
|
|
|
|
}
|
2016-03-13 22:16:20 +00:00
|
|
|
} /* initialize_vlans */
|
|
|
|
|
|
|
|
static void
|
|
|
|
vlan_name_lookup_cleanup(void)
|
|
|
|
{
|
2022-07-10 19:54:11 +00:00
|
|
|
end_vlanent();
|
2016-04-21 16:04:16 +00:00
|
|
|
vlan_hash_table = NULL;
|
2017-02-10 17:04:20 +00:00
|
|
|
g_free(g_pvlan_path);
|
|
|
|
g_pvlan_path = NULL;
|
2016-03-13 22:16:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static const gchar *
|
|
|
|
vlan_name_lookup(const guint id)
|
|
|
|
{
|
|
|
|
hashvlan_t *tp;
|
|
|
|
vlan_t *vlan;
|
|
|
|
|
2018-11-21 16:08:18 +00:00
|
|
|
tp = (hashvlan_t *)wmem_map_lookup(vlan_hash_table, GUINT_TO_POINTER(id));
|
2016-03-13 22:16:20 +00:00
|
|
|
if (tp == NULL) {
|
2016-04-20 14:45:32 +00:00
|
|
|
tp = wmem_new(wmem_epan_scope(), hashvlan_t);
|
2018-11-21 16:08:18 +00:00
|
|
|
wmem_map_insert(vlan_hash_table, GUINT_TO_POINTER(id), tp);
|
2016-03-13 22:16:20 +00:00
|
|
|
} else {
|
|
|
|
return tp->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fill in a new entry */
|
|
|
|
|
|
|
|
tp->id = id;
|
|
|
|
|
|
|
|
if ( (vlan = get_vlannamebyid(id)) == NULL) {
|
|
|
|
/* unknown name */
|
2021-12-16 18:06:18 +00:00
|
|
|
snprintf(tp->name, MAXVLANNAMELEN, "<%u>", id);
|
2016-03-13 22:16:20 +00:00
|
|
|
|
|
|
|
} else {
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(tp->name, vlan->name, MAXVLANNAMELEN);
|
2016-03-13 22:16:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return tp->name;
|
|
|
|
|
|
|
|
} /* vlan_name_lookup */
|
|
|
|
/* VLAN END */
|
|
|
|
|
2012-11-29 00:32:39 +00:00
|
|
|
static gboolean
|
2014-09-26 17:41:43 +00:00
|
|
|
read_hosts_file (const char *hostspath, gboolean store_entries)
|
2004-11-17 08:34:36 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
FILE *hf;
|
2018-11-21 15:29:30 +00:00
|
|
|
char line[MAX_LINELEN];
|
2013-08-11 00:50:51 +00:00
|
|
|
gchar *cp;
|
2016-02-10 09:11:12 +00:00
|
|
|
union {
|
|
|
|
guint32 ip4_addr;
|
2017-10-26 08:50:00 +00:00
|
|
|
ws_in6_addr ip6_addr;
|
2016-02-10 09:11:12 +00:00
|
|
|
} host_addr;
|
2014-09-26 17:41:43 +00:00
|
|
|
gboolean is_ipv6, entry_found = FALSE;
|
2005-01-07 10:20:17 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/*
|
|
|
|
* 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;
|
2004-11-17 08:34:36 +00:00
|
|
|
|
2018-11-21 15:29:30 +00:00
|
|
|
while (fgetline(line, sizeof(line), hf) >= 0) {
|
2013-08-11 00:50:51 +00:00
|
|
|
if ((cp = strchr(line, '#')))
|
|
|
|
*cp = '\0';
|
2004-11-17 08:34:36 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if ((cp = strtok(line, " \t")) == NULL)
|
|
|
|
continue; /* no tokens in the line */
|
2004-11-17 08:34:36 +00:00
|
|
|
|
2016-02-10 09:11:12 +00:00
|
|
|
if (ws_inet_pton6(cp, &host_addr.ip6_addr)) {
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Valid IPv6 */
|
|
|
|
is_ipv6 = TRUE;
|
2016-02-10 09:11:12 +00:00
|
|
|
} else if (ws_inet_pton4(cp, &host_addr.ip4_addr)) {
|
|
|
|
/* Valid IPv4 */
|
2013-08-11 00:50:51 +00:00
|
|
|
is_ipv6 = FALSE;
|
2016-02-10 09:11:12 +00:00
|
|
|
} else {
|
|
|
|
continue;
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
2004-11-17 08:34:36 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if ((cp = strtok(NULL, " \t")) == NULL)
|
|
|
|
continue; /* no host name */
|
|
|
|
|
2014-09-26 17:41:43 +00:00
|
|
|
entry_found = TRUE;
|
|
|
|
if (store_entries) {
|
2013-08-11 00:50:51 +00:00
|
|
|
if (is_ipv6) {
|
2022-05-05 19:27:41 +00:00
|
|
|
add_ipv6_name(&host_addr.ip6_addr, cp, TRUE);
|
2016-02-10 09:11:12 +00:00
|
|
|
} else {
|
2022-05-05 19:27:41 +00:00
|
|
|
add_ipv4_name(host_addr.ip4_addr, cp, TRUE);
|
2014-09-26 17:41:43 +00:00
|
|
|
}
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
|
|
|
}
|
2004-11-17 08:34:36 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
fclose(hf);
|
2014-09-26 17:41:43 +00:00
|
|
|
return entry_found ? TRUE : FALSE;
|
2004-11-17 08:34:36 +00:00
|
|
|
} /* read_hosts_file */
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2013-08-13 01:41:51 +00:00
|
|
|
gboolean
|
2012-11-29 00:32:39 +00:00
|
|
|
add_hosts_file (const char *hosts_file)
|
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
gboolean found = FALSE;
|
|
|
|
guint i;
|
2012-11-29 00:32:39 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (!hosts_file)
|
|
|
|
return FALSE;
|
2012-11-29 00:32:39 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (!extra_hosts_files)
|
|
|
|
extra_hosts_files = g_ptr_array_new();
|
2012-11-29 00:32:39 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
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;
|
|
|
|
}
|
2012-11-29 00:32:39 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (!found) {
|
2016-04-20 14:45:32 +00:00
|
|
|
g_ptr_array_add(extra_hosts_files, wmem_strdup(wmem_epan_scope(), hosts_file));
|
2014-09-26 17:41:43 +00:00
|
|
|
return read_hosts_file (hosts_file, FALSE);
|
2012-11-29 00:32:39 +00:00
|
|
|
}
|
2013-08-11 00:50:51 +00:00
|
|
|
return TRUE;
|
2012-11-29 00:32:39 +00:00
|
|
|
}
|
|
|
|
|
2013-08-13 01:41:51 +00:00
|
|
|
gboolean
|
2010-04-27 22:46:39 +00:00
|
|
|
add_ip_name_from_string (const char *addr, const char *name)
|
2010-04-27 06:51:16 +00:00
|
|
|
{
|
2016-02-10 09:11:12 +00:00
|
|
|
union {
|
|
|
|
guint32 ip4_addr;
|
2017-10-26 08:50:00 +00:00
|
|
|
ws_in6_addr ip6_addr;
|
2016-02-10 09:11:12 +00:00
|
|
|
} host_addr;
|
2013-08-11 00:50:51 +00:00
|
|
|
gboolean is_ipv6;
|
2020-02-09 01:39:41 +00:00
|
|
|
resolved_name_t *resolved_entry;
|
2010-04-27 06:51:16 +00:00
|
|
|
|
2016-02-10 09:11:12 +00:00
|
|
|
if (ws_inet_pton6(addr, &host_addr.ip6_addr)) {
|
2013-08-11 00:50:51 +00:00
|
|
|
is_ipv6 = TRUE;
|
2016-02-10 09:11:12 +00:00
|
|
|
} else if (ws_inet_pton4(addr, &host_addr.ip4_addr)) {
|
2013-08-11 00:50:51 +00:00
|
|
|
is_ipv6 = FALSE;
|
2016-02-10 09:11:12 +00:00
|
|
|
} else {
|
|
|
|
return FALSE;
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (is_ipv6) {
|
2020-02-09 01:39:41 +00:00
|
|
|
resolved_entry = (resolved_name_t*)wmem_map_lookup(manually_resolved_ipv6_list, &host_addr.ip6_addr);
|
|
|
|
if (resolved_entry)
|
|
|
|
{
|
|
|
|
// If we found a previous matching key (IP address), then just update the value (custom hostname);
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(resolved_entry->name, name, MAXNAMELEN);
|
2020-02-09 01:39:41 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Add a new mapping entry, if this IP address isn't already in the list.
|
|
|
|
ws_in6_addr* addr_key = wmem_new(wmem_epan_scope(), ws_in6_addr);
|
|
|
|
memcpy(addr_key, &host_addr.ip6_addr, sizeof(ws_in6_addr));
|
|
|
|
|
|
|
|
resolved_entry = wmem_new(wmem_epan_scope(), resolved_name_t);
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(resolved_entry->name, name, MAXNAMELEN);
|
2020-02-09 01:39:41 +00:00
|
|
|
|
|
|
|
wmem_map_insert(manually_resolved_ipv6_list, addr_key, resolved_entry);
|
|
|
|
}
|
2013-08-11 00:50:51 +00:00
|
|
|
} else {
|
2020-02-09 01:39:41 +00:00
|
|
|
resolved_entry = (resolved_name_t*)wmem_map_lookup(manually_resolved_ipv4_list, GUINT_TO_POINTER(host_addr.ip4_addr));
|
|
|
|
if (resolved_entry)
|
|
|
|
{
|
|
|
|
// If we found a previous matching key (IP address), then just update the value (custom hostname);
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(resolved_entry->name, name, MAXNAMELEN);
|
2020-02-09 01:39:41 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Add a new mapping entry, if this IP address isn't already in the list.
|
|
|
|
resolved_entry = wmem_new(wmem_epan_scope(), resolved_name_t);
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(resolved_entry->name, name, MAXNAMELEN);
|
2020-02-09 01:39:41 +00:00
|
|
|
|
|
|
|
wmem_map_insert(manually_resolved_ipv4_list, GUINT_TO_POINTER(host_addr.ip4_addr), resolved_entry);
|
|
|
|
}
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
2010-04-27 06:51:16 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
return TRUE;
|
2010-04-27 22:46:39 +00:00
|
|
|
} /* add_ip_name_from_string */
|
2010-04-27 06:51:16 +00:00
|
|
|
|
2020-02-09 01:39:41 +00:00
|
|
|
extern resolved_name_t* get_edited_resolved_name(const char* addr)
|
|
|
|
{
|
|
|
|
guint32 ip4_addr;
|
|
|
|
ws_in6_addr ip6_addr;
|
|
|
|
resolved_name_t* resolved_entry = NULL;
|
|
|
|
|
|
|
|
if (ws_inet_pton6(addr, &ip6_addr)) {
|
|
|
|
resolved_entry = (resolved_name_t*)wmem_map_lookup(manually_resolved_ipv6_list, &ip6_addr);
|
|
|
|
}
|
|
|
|
else if (ws_inet_pton4(addr, &ip4_addr)) {
|
|
|
|
resolved_entry = (resolved_name_t*)wmem_map_lookup(manually_resolved_ipv4_list, GUINT_TO_POINTER(ip4_addr));
|
|
|
|
}
|
|
|
|
|
|
|
|
return resolved_entry;
|
|
|
|
}
|
|
|
|
|
2013-10-10 19:17:48 +00:00
|
|
|
/*
|
|
|
|
* Add the resolved addresses that are in use to the list used to create the NRB
|
|
|
|
*/
|
2013-09-22 19:40:02 +00:00
|
|
|
static void
|
|
|
|
ipv4_hash_table_resolved_to_list(gpointer key _U_, gpointer value, gpointer user_data)
|
|
|
|
{
|
2013-09-22 20:01:32 +00:00
|
|
|
addrinfo_lists_t *lists = (addrinfo_lists_t*)user_data;
|
|
|
|
hashipv4_t *ipv4_hash_table_entry = (hashipv4_t *)value;
|
2013-09-22 19:40:02 +00:00
|
|
|
|
2017-06-09 08:03:38 +00:00
|
|
|
if ((ipv4_hash_table_entry->flags & USED_AND_RESOLVED_MASK) == USED_AND_RESOLVED_MASK) {
|
2016-04-21 08:14:11 +00:00
|
|
|
lists->ipv4_addr_list = g_list_prepend(lists->ipv4_addr_list, ipv4_hash_table_entry);
|
2013-09-22 20:01:32 +00:00
|
|
|
}
|
2013-09-22 19:40:02 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-10-10 19:17:48 +00:00
|
|
|
/*
|
|
|
|
* Add the resolved addresses that are in use to the list used to create the NRB
|
|
|
|
*/
|
|
|
|
|
2013-09-22 19:40:02 +00:00
|
|
|
static void
|
|
|
|
ipv6_hash_table_resolved_to_list(gpointer key _U_, gpointer value, gpointer user_data)
|
|
|
|
{
|
2013-09-22 20:01:32 +00:00
|
|
|
addrinfo_lists_t *lists = (addrinfo_lists_t*)user_data;
|
2013-09-22 19:40:02 +00:00
|
|
|
hashipv6_t *ipv6_hash_table_entry = (hashipv6_t *)value;
|
|
|
|
|
2017-06-09 08:03:38 +00:00
|
|
|
if ((ipv6_hash_table_entry->flags & USED_AND_RESOLVED_MASK) == USED_AND_RESOLVED_MASK) {
|
2013-09-22 20:01:32 +00:00
|
|
|
lists->ipv6_addr_list = g_list_prepend (lists->ipv6_addr_list, ipv6_hash_table_entry);
|
|
|
|
}
|
2013-09-22 19:40:02 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
addrinfo_lists_t *
|
2016-04-21 16:04:16 +00:00
|
|
|
get_addrinfo_list(void)
|
|
|
|
{
|
2015-02-27 02:10:25 +00:00
|
|
|
if (ipv4_hash_table) {
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_foreach(ipv4_hash_table, ipv4_hash_table_resolved_to_list, &addrinfo_lists);
|
2013-09-22 20:01:32 +00:00
|
|
|
}
|
2013-09-22 19:40:02 +00:00
|
|
|
|
2015-02-27 02:10:25 +00:00
|
|
|
if (ipv6_hash_table) {
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_foreach(ipv6_hash_table, ipv6_hash_table_resolved_to_list, &addrinfo_lists);
|
2013-09-22 20:01:32 +00:00
|
|
|
}
|
2013-09-22 19:40:02 +00:00
|
|
|
|
|
|
|
return &addrinfo_lists;
|
2011-03-24 22:47:57 +00:00
|
|
|
}
|
2008-01-21 21:44:34 +00:00
|
|
|
|
|
|
|
/* Read in a list of subnet definition - name pairs.
|
|
|
|
* <line> = <comment> | <entry> | <whitespace>
|
|
|
|
* <comment> = <whitespace>#<any>
|
2008-05-22 15:46:27 +00:00
|
|
|
* <entry> = <subnet_definition> <whitespace> <subnet_name> [<comment>|<whitespace><any>]
|
2008-01-21 21:44:34 +00:00
|
|
|
* <subnet_definition> = <ipv4_address> / <subnet_mask_length>
|
|
|
|
* <ipv4_address> is a full address; it will be masked to get the subnet-ID.
|
|
|
|
* <subnet_mask_length> is a decimal 1-31
|
|
|
|
* <subnet_name> is a string containing no whitespace.
|
|
|
|
* <whitespace> = (space | tab)+
|
|
|
|
* Any malformed entries are ignored.
|
|
|
|
* Any trailing data after the subnet_name is ignored.
|
|
|
|
*
|
|
|
|
* XXX Support IPv6
|
|
|
|
*/
|
|
|
|
static gboolean
|
|
|
|
read_subnets_file (const char *subnetspath)
|
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
FILE *hf;
|
2018-11-21 15:29:30 +00:00
|
|
|
char line[MAX_LINELEN];
|
2013-08-11 00:50:51 +00:00
|
|
|
gchar *cp, *cp2;
|
|
|
|
guint32 host_addr; /* IPv4 ONLY */
|
2016-09-09 15:16:10 +00:00
|
|
|
guint8 mask_length;
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if ((hf = ws_fopen(subnetspath, "r")) == NULL)
|
|
|
|
return FALSE;
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2018-11-21 15:29:30 +00:00
|
|
|
while (fgetline(line, sizeof(line), hf) >= 0) {
|
2013-08-11 00:50:51 +00:00
|
|
|
if ((cp = strchr(line, '#')))
|
|
|
|
*cp = '\0';
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if ((cp = strtok(line, " \t")) == NULL)
|
|
|
|
continue; /* no tokens in the line */
|
2008-01-21 21:44:34 +00:00
|
|
|
|
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Expected format is <IP4 address>/<subnet length> */
|
|
|
|
cp2 = strchr(cp, '/');
|
2015-02-27 02:10:25 +00:00
|
|
|
if (NULL == cp2) {
|
2013-08-11 00:50:51 +00:00
|
|
|
/* No length */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
*cp2 = '\0'; /* Cut token */
|
|
|
|
++cp2 ;
|
2008-05-22 15:46:27 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Check if this is a valid IPv4 address */
|
2013-12-21 16:16:56 +00:00
|
|
|
if (!str_to_ip(cp, &host_addr)) {
|
2013-08-11 00:50:51 +00:00
|
|
|
continue; /* no */
|
|
|
|
}
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2016-09-09 15:16:10 +00:00
|
|
|
if (!ws_strtou8(cp2, NULL, &mask_length) || mask_length == 0 || mask_length > 32) {
|
2013-08-11 00:50:51 +00:00
|
|
|
continue; /* invalid mask length */
|
|
|
|
}
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if ((cp = strtok(NULL, " \t")) == NULL)
|
|
|
|
continue; /* no subnet name */
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2016-09-09 15:16:10 +00:00
|
|
|
subnet_entry_set(host_addr, mask_length, cp);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
fclose(hf);
|
|
|
|
return TRUE;
|
2008-01-21 21:44:34 +00:00
|
|
|
} /* read_subnets_file */
|
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static subnet_entry_t
|
|
|
|
subnet_lookup(const guint32 addr)
|
2008-01-21 21:44:34 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
subnet_entry_t subnet_entry;
|
|
|
|
guint32 i;
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Search mask lengths linearly, longest first */
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
i = SUBNETLENGTHSIZE;
|
|
|
|
while(have_subnet_entry && i > 0) {
|
|
|
|
guint32 masked_addr;
|
|
|
|
subnet_length_entry_t* length_entry;
|
2008-05-22 15:46:27 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Note that we run from 31 (length 32) to 0 (length 1) */
|
|
|
|
--i;
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(i < SUBNETLENGTHSIZE);
|
2008-01-21 21:44:34 +00:00
|
|
|
|
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
length_entry = &subnet_length_entries[i];
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2015-02-27 02:10:25 +00:00
|
|
|
if (NULL != length_entry->subnet_addresses) {
|
2013-08-11 19:02:26 +00:00
|
|
|
sub_net_hashipv4_t * tp;
|
2013-08-11 00:50:51 +00:00
|
|
|
guint32 hash_idx;
|
2008-05-22 15:46:27 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
masked_addr = addr & length_entry->mask;
|
|
|
|
hash_idx = HASH_IPV4_ADDRESS(masked_addr);
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
tp = length_entry->subnet_addresses[hash_idx];
|
|
|
|
while(tp != NULL && tp->addr != masked_addr) {
|
|
|
|
tp = tp->next;
|
|
|
|
}
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2015-02-27 02:10:25 +00:00
|
|
|
if (NULL != tp) {
|
2013-08-11 00:50:51 +00:00
|
|
|
subnet_entry.mask = length_entry->mask;
|
|
|
|
subnet_entry.mask_length = i + 1; /* Length is offset + 1 */
|
|
|
|
subnet_entry.name = tp->name;
|
|
|
|
return subnet_entry;
|
|
|
|
}
|
|
|
|
}
|
2008-01-21 21:44:34 +00:00
|
|
|
}
|
2008-05-22 15:46:27 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
subnet_entry.mask = 0;
|
|
|
|
subnet_entry.mask_length = 0;
|
|
|
|
subnet_entry.name = NULL;
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
return subnet_entry;
|
2008-01-21 21:44:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Add a subnet-definition - name pair to the set.
|
|
|
|
* The definition is taken by masking the address passed in with the mask of the
|
|
|
|
* given length.
|
|
|
|
*/
|
2010-04-29 18:17:29 +00:00
|
|
|
static void
|
2016-09-09 15:16:10 +00:00
|
|
|
subnet_entry_set(guint32 subnet_addr, const guint8 mask_length, const gchar* name)
|
2008-01-21 21:44:34 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
subnet_length_entry_t* entry;
|
2013-08-11 19:02:26 +00:00
|
|
|
sub_net_hashipv4_t * tp;
|
2013-08-11 00:50:51 +00:00
|
|
|
gsize hash_idx;
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(mask_length > 0 && mask_length <= 32);
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
entry = &subnet_length_entries[mask_length - 1];
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
subnet_addr &= entry->mask;
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
hash_idx = HASH_IPV4_ADDRESS(subnet_addr);
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2015-02-27 02:10:25 +00:00
|
|
|
if (NULL == entry->subnet_addresses) {
|
2016-04-20 14:45:32 +00:00
|
|
|
entry->subnet_addresses = (sub_net_hashipv4_t**)wmem_alloc0(wmem_epan_scope(), sizeof(sub_net_hashipv4_t*) * HASHHOSTSIZE);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
2008-01-21 21:44:34 +00:00
|
|
|
|
2015-02-27 02:10:25 +00:00
|
|
|
if (NULL != (tp = entry->subnet_addresses[hash_idx])) {
|
2015-06-07 00:04:42 +00:00
|
|
|
sub_net_hashipv4_t * new_tp;
|
|
|
|
|
|
|
|
while (tp->next) {
|
|
|
|
if (tp->addr == subnet_addr) {
|
|
|
|
return; /* XXX provide warning that an address was repeated? */
|
|
|
|
} else {
|
|
|
|
tp = tp->next;
|
|
|
|
}
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
2015-06-07 00:04:42 +00:00
|
|
|
|
2016-04-28 21:53:11 +00:00
|
|
|
new_tp = wmem_new(wmem_epan_scope(), sub_net_hashipv4_t);
|
2015-06-07 00:04:42 +00:00
|
|
|
tp->next = new_tp;
|
|
|
|
tp = new_tp;
|
2008-01-21 21:44:34 +00:00
|
|
|
} else {
|
2016-04-20 14:45:32 +00:00
|
|
|
tp = entry->subnet_addresses[hash_idx] = wmem_new(wmem_epan_scope(), sub_net_hashipv4_t);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
tp->next = NULL;
|
|
|
|
tp->addr = subnet_addr;
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(tp->name, name, MAXNAMELEN); /* This is longer than subnet names can actually be */
|
2013-08-11 00:50:51 +00:00
|
|
|
have_subnet_entry = TRUE;
|
2008-01-21 21:44:34 +00:00
|
|
|
}
|
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
static void
|
|
|
|
subnet_name_lookup_init(void)
|
2008-01-21 21:44:34 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
gchar* subnetspath;
|
|
|
|
guint32 i;
|
|
|
|
|
|
|
|
for(i = 0; i < SUBNETLENGTHSIZE; ++i) {
|
|
|
|
guint32 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));
|
|
|
|
}
|
|
|
|
|
2017-01-23 03:51:54 +00:00
|
|
|
/* Check profile directory before personal configuration */
|
|
|
|
subnetspath = get_persconffile_path(ENAME_SUBNETS, TRUE);
|
|
|
|
if (!read_subnets_file(subnetspath)) {
|
|
|
|
if (errno != ENOENT) {
|
|
|
|
report_open_failure(subnetspath, errno, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(subnetspath);
|
|
|
|
subnetspath = get_persconffile_path(ENAME_SUBNETS, FALSE);
|
|
|
|
if (!read_subnets_file(subnetspath) && errno != ENOENT) {
|
|
|
|
report_open_failure(subnetspath, errno, FALSE);
|
|
|
|
}
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
|
|
|
g_free(subnetspath);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Load the global subnets file, if we have one.
|
|
|
|
*/
|
|
|
|
subnetspath = get_datafile_path(ENAME_SUBNETS);
|
|
|
|
if (!read_subnets_file(subnetspath) && errno != ENOENT) {
|
|
|
|
report_open_failure(subnetspath, errno, FALSE);
|
|
|
|
}
|
|
|
|
g_free(subnetspath);
|
2008-01-21 21:44:34 +00:00
|
|
|
}
|
|
|
|
|
2016-09-13 04:46:06 +00:00
|
|
|
/* SS7 PC Name Resolution Portion */
|
|
|
|
static hashss7pc_t *
|
|
|
|
new_ss7pc(const guint8 ni, const guint32 pc)
|
|
|
|
{
|
|
|
|
hashss7pc_t *tp = wmem_new(wmem_epan_scope(), hashss7pc_t);
|
|
|
|
tp->id = (ni<<24) + (pc&0xffffff);
|
|
|
|
tp->pc_addr[0] = '\0';
|
|
|
|
tp->name[0] = '\0';
|
|
|
|
|
|
|
|
return tp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static hashss7pc_t *
|
|
|
|
host_lookup_ss7pc(const guint8 ni, const guint32 pc)
|
|
|
|
{
|
|
|
|
hashss7pc_t * volatile tp;
|
|
|
|
guint32 id;
|
|
|
|
|
|
|
|
id = (ni<<24) + (pc&0xffffff);
|
|
|
|
|
|
|
|
tp = (hashss7pc_t *)wmem_map_lookup(ss7pc_hash_table, GUINT_TO_POINTER(id));
|
|
|
|
if (tp == NULL) {
|
|
|
|
tp = new_ss7pc(ni, pc);
|
|
|
|
wmem_map_insert(ss7pc_hash_table, GUINT_TO_POINTER(id), tp);
|
|
|
|
}
|
|
|
|
|
|
|
|
return tp;
|
|
|
|
}
|
|
|
|
|
|
|
|
void fill_unresolved_ss7pc(const gchar * pc_addr, const guint8 ni, const guint32 pc)
|
|
|
|
{
|
|
|
|
hashss7pc_t *tp = host_lookup_ss7pc(ni, pc);
|
|
|
|
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(tp->pc_addr, pc_addr, MAXNAMELEN);
|
2016-09-13 04:46:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const gchar *
|
|
|
|
get_hostname_ss7pc(const guint8 ni, const guint32 pc)
|
|
|
|
{
|
|
|
|
hashss7pc_t *tp = host_lookup_ss7pc(ni, pc);
|
|
|
|
|
|
|
|
/* never resolved yet*/
|
|
|
|
if (tp->pc_addr[0] == '\0')
|
|
|
|
return tp->pc_addr;
|
|
|
|
|
|
|
|
/* Don't have name in file */
|
|
|
|
if (tp->name[0] == '\0')
|
|
|
|
return tp->pc_addr;
|
|
|
|
|
|
|
|
if (!gbl_resolv_flags.ss7pc_name)
|
|
|
|
return tp->pc_addr;
|
|
|
|
|
|
|
|
return tp->name;
|
|
|
|
}
|
|
|
|
|
2016-10-16 20:34:54 +00:00
|
|
|
static void
|
2016-09-13 04:46:06 +00:00
|
|
|
add_ss7pc_name(const guint8 ni, guint32 pc, const gchar *name)
|
|
|
|
{
|
|
|
|
hashss7pc_t *tp;
|
|
|
|
guint32 id;
|
|
|
|
|
|
|
|
if (!name || name[0] == '\0')
|
|
|
|
return;
|
|
|
|
|
|
|
|
id = (ni<<24) + (pc&0xffffff);
|
|
|
|
tp = (hashss7pc_t *)wmem_map_lookup(ss7pc_hash_table, GUINT_TO_POINTER(id));
|
|
|
|
if (!tp) {
|
|
|
|
tp = new_ss7pc(ni, pc);
|
|
|
|
wmem_map_insert(ss7pc_hash_table, GUINT_TO_POINTER(id), tp);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_ascii_strcasecmp(tp->name, name)) {
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(tp->name, name, MAXNAMELEN);
|
2016-09-13 04:46:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
read_ss7pcs_file(const char *ss7pcspath)
|
|
|
|
{
|
|
|
|
FILE *hf;
|
2018-11-21 15:29:30 +00:00
|
|
|
char line[MAX_LINELEN];
|
2016-09-13 04:46:06 +00:00
|
|
|
gchar *cp;
|
|
|
|
guint8 ni;
|
|
|
|
guint32 pc;
|
|
|
|
gboolean entry_found = FALSE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* File format is Network Indicator (decimal)<dash>Point Code (Decimal)<tab/space>Hostname
|
|
|
|
*/
|
|
|
|
if ((hf = ws_fopen(ss7pcspath, "r")) == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
2018-11-21 15:29:30 +00:00
|
|
|
while (fgetline(line, sizeof(line), hf) >= 0) {
|
2016-09-13 04:46:06 +00:00
|
|
|
if ((cp = strchr(line, '#')))
|
|
|
|
*cp = '\0';
|
|
|
|
|
|
|
|
if ((cp = strtok(line, "-")) == NULL)
|
|
|
|
continue; /*no ni-pc separator*/
|
|
|
|
if (!ws_strtou8(cp, NULL, &ni))
|
|
|
|
continue;
|
|
|
|
if (ni > 3)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if ((cp = strtok(NULL, " \t")) == NULL)
|
|
|
|
continue; /* no tokens for pc and name */
|
|
|
|
if (!ws_strtou32(cp, NULL, &pc))
|
|
|
|
continue;
|
|
|
|
if (pc >> 24 > 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if ((cp = strtok(NULL, " \t")) == NULL)
|
|
|
|
continue; /* no host name */
|
|
|
|
|
|
|
|
entry_found = TRUE;
|
|
|
|
add_ss7pc_name(ni, pc, cp);
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(hf);
|
|
|
|
return entry_found ? TRUE : FALSE;
|
|
|
|
}
|
|
|
|
|
2016-10-16 20:34:54 +00:00
|
|
|
static void
|
2016-09-13 04:46:06 +00:00
|
|
|
ss7pc_name_lookup_init(void)
|
|
|
|
{
|
|
|
|
char *ss7pcspath;
|
|
|
|
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(ss7pc_hash_table == NULL);
|
2016-09-13 04:46:06 +00:00
|
|
|
|
|
|
|
ss7pc_hash_table = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Load the user's ss7pcs file
|
|
|
|
*/
|
|
|
|
ss7pcspath = get_persconffile_path(ENAME_SS7PCS, TRUE);
|
|
|
|
if (!read_ss7pcs_file(ss7pcspath) && errno != ENOENT) {
|
|
|
|
report_open_failure(ss7pcspath, errno, FALSE);
|
|
|
|
}
|
|
|
|
g_free(ss7pcspath);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* SS7PC Name Resolution End*/
|
|
|
|
|
|
|
|
|
2002-08-28 20:41:00 +00:00
|
|
|
/*
|
1998-09-25 23:24:07 +00:00
|
|
|
* External Functions
|
|
|
|
*/
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2013-08-13 01:41:51 +00:00
|
|
|
void
|
2012-07-06 04:48:36 +00:00
|
|
|
addr_resolve_pref_init(module_t *nameres)
|
|
|
|
{
|
|
|
|
prefs_register_bool_preference(nameres, "mac_name",
|
2013-08-11 00:50:51 +00:00
|
|
|
"Resolve MAC addresses",
|
2016-11-19 17:13:47 +00:00
|
|
|
"Resolve Ethernet MAC addresses to host names from the preferences"
|
|
|
|
" or system's Ethers file, or to a manufacturer based name.",
|
2013-08-11 00:50:51 +00:00
|
|
|
&gbl_resolv_flags.mac_name);
|
2012-07-06 04:48:36 +00:00
|
|
|
|
|
|
|
prefs_register_bool_preference(nameres, "transport_name",
|
2013-08-11 00:50:51 +00:00
|
|
|
"Resolve transport names",
|
|
|
|
"Resolve TCP/UDP ports into service names",
|
|
|
|
&gbl_resolv_flags.transport_name);
|
2012-07-06 04:48:36 +00:00
|
|
|
|
2012-07-10 07:24:01 +00:00
|
|
|
prefs_register_bool_preference(nameres, "network_name",
|
2013-08-11 00:50:51 +00:00
|
|
|
"Resolve network (IP) addresses",
|
|
|
|
"Resolve IPv4, IPv6, and IPX addresses into host names."
|
|
|
|
" The next set of check boxes determines how name resolution should be performed."
|
2019-01-17 22:00:31 +00:00
|
|
|
" If no other options are checked name resolution is made from Wireshark's host file"
|
|
|
|
" and capture file name resolution blocks.",
|
2013-08-11 00:50:51 +00:00
|
|
|
&gbl_resolv_flags.network_name);
|
2012-07-10 07:24:01 +00:00
|
|
|
|
2015-07-25 13:24:48 +00:00
|
|
|
prefs_register_bool_preference(nameres, "dns_pkt_addr_resolution",
|
2022-08-03 21:21:22 +00:00
|
|
|
"Use captured DNS packet data for name resolution",
|
|
|
|
"Use address/name pairs found in captured DNS packets for name resolution.",
|
2015-07-25 13:24:48 +00:00
|
|
|
&gbl_resolv_flags.dns_pkt_addr_resolution);
|
|
|
|
|
2012-07-08 01:31:48 +00:00
|
|
|
prefs_register_bool_preference(nameres, "use_external_name_resolver",
|
2022-08-03 21:21:22 +00:00
|
|
|
"Use your system's DNS settings for name resolution",
|
2013-08-11 00:50:51 +00:00
|
|
|
"Use your system's configured name resolver"
|
|
|
|
" (usually DNS) to resolve network names."
|
|
|
|
" Only applies when network name resolution"
|
|
|
|
" is enabled.",
|
|
|
|
&gbl_resolv_flags.use_external_net_name_resolver);
|
2012-07-08 01:31:48 +00:00
|
|
|
|
2019-09-01 16:02:27 +00:00
|
|
|
prefs_register_bool_preference(nameres, "use_custom_dns_servers",
|
2022-08-03 21:21:22 +00:00
|
|
|
"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_custom_dns_server_list);
|
2019-09-01 16:02:27 +00:00
|
|
|
|
|
|
|
static uat_field_t dns_server_uats_flds[] = {
|
|
|
|
UAT_FLD_CSTRING_OTHER(dnsserverlist_uats, ipaddr, "IP address", dnsserver_uat_fld_ip_chk_cb, "IPv4 or IPv6 address"),
|
2022-07-20 11:39:28 +00:00
|
|
|
UAT_FLD_CSTRING_OTHER(dnsserverlist_uats, tcp_port, "TCP Port", dnsserver_uat_fld_port_chk_cb, "Port Number (TCP)"),
|
|
|
|
UAT_FLD_CSTRING_OTHER(dnsserverlist_uats, udp_port, "UDP Port", dnsserver_uat_fld_port_chk_cb, "Port Number (UDP)"),
|
2019-09-01 16:02:27 +00:00
|
|
|
UAT_END_FIELDS
|
|
|
|
};
|
|
|
|
|
|
|
|
dnsserver_uat = uat_new("DNS Servers",
|
|
|
|
sizeof(struct dns_server_data),
|
|
|
|
"addr_resolve_dns_servers", /* filename */
|
|
|
|
TRUE, /* from_profile */
|
|
|
|
&dnsserverlist_uats, /* data_ptr */
|
|
|
|
&ndnsservers, /* numitems_ptr */
|
|
|
|
UAT_AFFECTS_DISSECTION,
|
|
|
|
NULL,
|
|
|
|
dns_server_copy_cb,
|
|
|
|
NULL,
|
|
|
|
dns_server_free_cb,
|
|
|
|
c_ares_set_dns_servers,
|
|
|
|
NULL,
|
|
|
|
dns_server_uats_flds);
|
2022-11-03 11:40:41 +00:00
|
|
|
static const char *dnsserver_uat_defaults[] = { NULL, "53", "53" };
|
|
|
|
uat_set_default_values(dnsserver_uat, dnsserver_uat_defaults);
|
2019-09-01 16:02:27 +00:00
|
|
|
prefs_register_uat_preference(nameres, "dns_servers",
|
|
|
|
"DNS Servers",
|
2019-11-10 01:00:43 +00:00
|
|
|
"A table of IPv4 and IPv6 addresses of DNS servers to be used to resolve IP names and addresses",
|
2019-09-01 16:02:27 +00:00
|
|
|
dnsserver_uat);
|
|
|
|
|
2016-03-26 03:16:17 +00:00
|
|
|
prefs_register_obsolete_preference(nameres, "concurrent_dns");
|
2012-07-06 04:48:36 +00:00
|
|
|
|
2012-07-08 01:31:48 +00:00
|
|
|
prefs_register_uint_preference(nameres, "name_resolve_concurrency",
|
2013-08-11 00:50:51 +00:00
|
|
|
"Maximum concurrent requests",
|
|
|
|
"The maximum number of DNS requests that may"
|
|
|
|
" be active at any time. A large value (many"
|
|
|
|
" thousands) might overload the network or make"
|
|
|
|
" your DNS server behave badly.",
|
|
|
|
10,
|
|
|
|
&name_resolve_concurrency);
|
2012-07-11 08:52:51 +00:00
|
|
|
|
|
|
|
prefs_register_bool_preference(nameres, "hosts_file_handling",
|
2013-08-11 00:50:51 +00:00
|
|
|
"Only use the profile \"hosts\" file",
|
|
|
|
"By default \"hosts\" files will be loaded from multiple sources."
|
|
|
|
" Checking this box only loads the \"hosts\" in the current profile.",
|
|
|
|
&gbl_resolv_flags.load_hosts_file_from_profile_only);
|
2012-07-11 08:52:51 +00:00
|
|
|
|
2016-03-13 22:16:20 +00:00
|
|
|
prefs_register_bool_preference(nameres, "vlan_name",
|
|
|
|
"Resolve VLAN IDs",
|
2016-11-19 17:13:47 +00:00
|
|
|
"Resolve VLAN IDs to network names from the preferences \"vlans\" file."
|
|
|
|
" Format of the file is: \"ID<Tab>Name\"."
|
|
|
|
" One line per VLAN, e.g.: 1 Management",
|
2016-03-13 22:16:20 +00:00
|
|
|
&gbl_resolv_flags.vlan_name);
|
|
|
|
|
2016-09-13 04:46:06 +00:00
|
|
|
prefs_register_bool_preference(nameres, "ss7_pc_name",
|
2016-11-19 17:13:47 +00:00
|
|
|
"Resolve SS7 PCs",
|
|
|
|
"Resolve SS7 Point Codes to node names from the profiles \"ss7pcs\" file."
|
|
|
|
" Format of the file is: \"Network_Indicator<Dash>PC_Decimal<Tab>Name\"."
|
|
|
|
" One line per Point Code, e.g.: 2-1234 MyPointCode1",
|
|
|
|
&gbl_resolv_flags.ss7pc_name);
|
2016-09-13 04:46:06 +00:00
|
|
|
|
2012-07-06 04:48:36 +00:00
|
|
|
}
|
|
|
|
|
2019-09-01 16:02:27 +00:00
|
|
|
void addr_resolve_pref_apply(void)
|
|
|
|
{
|
|
|
|
c_ares_set_dns_servers();
|
|
|
|
}
|
|
|
|
|
2015-07-25 13:24:48 +00:00
|
|
|
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;
|
2016-03-13 22:16:20 +00:00
|
|
|
gbl_resolv_flags.vlan_name = FALSE;
|
2016-09-13 04:46:06 +00:00
|
|
|
gbl_resolv_flags.ss7pc_name = FALSE;
|
2015-07-25 13:24:48 +00:00
|
|
|
}
|
|
|
|
|
2008-08-07 21:41:48 +00:00
|
|
|
gboolean
|
2012-10-02 21:13:59 +00:00
|
|
|
host_name_lookup_process(void) {
|
2013-08-11 00:50:51 +00:00
|
|
|
async_dns_queue_msg_t *caqm;
|
|
|
|
struct timeval tv = { 0, 0 };
|
|
|
|
int nfds;
|
|
|
|
fd_set rfds, wfds;
|
|
|
|
gboolean nro = new_resolved_objects;
|
2016-04-21 08:14:11 +00:00
|
|
|
wmem_list_frame_t* head;
|
2008-08-07 21:41:48 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
new_resolved_objects = FALSE;
|
2018-02-09 01:20:26 +00:00
|
|
|
nro |= maxmind_db_lookup_process();
|
2009-06-24 19:10:50 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (!async_dns_initialized)
|
|
|
|
/* c-ares not initialized. Bail out and cancel timers. */
|
2013-08-07 16:46:08 +00:00
|
|
|
return nro;
|
2013-08-11 00:50:51 +00:00
|
|
|
|
2016-04-21 08:14:11 +00:00
|
|
|
head = wmem_list_head(async_dns_queue_head);
|
2013-08-11 00:50:51 +00:00
|
|
|
|
2016-04-21 08:14:11 +00:00
|
|
|
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);
|
2013-08-11 00:50:51 +00:00
|
|
|
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) {
|
2017-10-26 08:50:00 +00:00
|
|
|
ares_gethostbyaddr(ghba_chan, &caqm->addr.ip6, sizeof(ws_in6_addr),
|
2013-08-11 00:50:51 +00:00
|
|
|
AF_INET6, c_ares_ghba_cb, caqm);
|
|
|
|
async_dns_in_flight++;
|
|
|
|
}
|
addr_resolv: don't free the same wmem_list entry twice
fetch the list head each time we iterate through the list
if we don't, we crash when the same entry is removed a second time
#0 wmem_block_remove_from_block_list (block=0x7fffecd7b1c0, allocator=<optimized out>) at wmem_allocator_block.c:738
#1 wmem_block_free_jumbo (chunk=0x7fffecd7b1d0, allocator=0x65c060) at wmem_allocator_block.c:822
#2 wmem_block_free (private_data=0x65c060, ptr=0x7fffecd7b1e0) at wmem_allocator_block.c:913
#3 0x00007ffff452eac1 in host_name_lookup_process () at addr_resolv.c:2466
#4 0x000000000041733d in process_packet (cf=cf@entry=0x63fe20, edt=edt@entry=0xce08f0, offset=<optimized out>, whdr=0xc97c70,
pd=pd@entry=0xc9f550 "", tap_flags=tap_flags@entry=0) at tshark.c:3699
#5 0x000000000040f199 in load_cap_file (max_byte_count=13197776, max_packet_count=<optimized out>, out_file_name_res=0,
out_file_type=2, save_file=0x0, cf=<optimized out>) at tshark.c:3483
#6 main (argc=<optimized out>, argv=<optimized out>) at tshark.c:2192
Change-Id: I1ac813242188842130f4070ef326b12fe23b782f
Reviewed-on: https://code.wireshark.org/review/15068
Reviewed-by: Martin Kaiser <wireshark@kaiser.cx>
2016-04-23 11:58:09 +00:00
|
|
|
|
|
|
|
head = wmem_list_head(async_dns_queue_head);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
FD_ZERO(&rfds);
|
|
|
|
FD_ZERO(&wfds);
|
|
|
|
nfds = ares_fds(ghba_chan, &rfds, &wfds);
|
|
|
|
if (nfds > 0) {
|
|
|
|
if (select(nfds, &rfds, &wfds, NULL, &tv) == -1) { /* call to select() failed */
|
2019-04-04 19:30:46 +00:00
|
|
|
/* 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));
|
2013-08-11 00:50:51 +00:00
|
|
|
return nro;
|
|
|
|
}
|
|
|
|
ares_process(ghba_chan, &rfds, &wfds);
|
2012-11-05 09:18:43 +00:00
|
|
|
}
|
2008-08-07 21:41:48 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Any new entries? */
|
|
|
|
return nro;
|
2008-08-07 21:41:48 +00:00
|
|
|
}
|
|
|
|
|
2012-10-20 20:50:25 +00:00
|
|
|
static void
|
|
|
|
_host_name_lookup_cleanup(void) {
|
2013-08-11 00:50:51 +00:00
|
|
|
async_dns_queue_head = NULL;
|
2008-08-07 21:41:48 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (async_dns_initialized) {
|
|
|
|
ares_destroy(ghba_chan);
|
|
|
|
ares_destroy(ghbn_chan);
|
|
|
|
}
|
2009-10-30 21:57:43 +00:00
|
|
|
#ifdef CARES_HAVE_ARES_LIBRARY_INIT
|
2013-08-11 00:50:51 +00:00
|
|
|
ares_library_cleanup();
|
2009-10-30 21:57:43 +00:00
|
|
|
#endif
|
2013-08-11 00:50:51 +00:00
|
|
|
async_dns_initialized = FALSE;
|
2008-08-07 21:41:48 +00:00
|
|
|
}
|
|
|
|
|
2012-04-13 22:23:04 +00:00
|
|
|
const gchar *
|
2010-04-29 18:17:29 +00:00
|
|
|
get_hostname(const guint addr)
|
1998-09-16 02:39:15 +00:00
|
|
|
{
|
2013-08-29 22:08:23 +00:00
|
|
|
/* XXX why do we call this if we're not resolving? To create hash entries?
|
|
|
|
* Why?
|
|
|
|
*/
|
2016-01-19 07:22:30 +00:00
|
|
|
hashipv4_t *tp = host_lookup(addr);
|
2013-08-29 18:59:49 +00:00
|
|
|
|
2013-08-29 22:08:23 +00:00
|
|
|
if (!gbl_resolv_flags.network_name)
|
|
|
|
return tp->ip;
|
2009-09-06 08:59:30 +00:00
|
|
|
|
2015-09-27 13:46:09 +00:00
|
|
|
tp->flags |= RESOLVED_ADDRESS_USED;
|
2013-10-10 19:17:48 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
return tp->name;
|
2009-09-06 08:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* -------------------------- */
|
|
|
|
|
2012-04-13 22:23:04 +00:00
|
|
|
const gchar *
|
2017-10-26 08:50:00 +00:00
|
|
|
get_hostname6(const ws_in6_addr *addr)
|
1999-03-28 18:32:03 +00:00
|
|
|
{
|
2013-08-29 22:08:23 +00:00
|
|
|
/* XXX why do we call this if we're not resolving? To create hash entries?
|
|
|
|
* Why?
|
|
|
|
*/
|
2016-01-19 07:22:30 +00:00
|
|
|
hashipv6_t *tp = host_lookup6(addr);
|
2011-01-25 22:11:59 +00:00
|
|
|
|
2013-08-29 22:08:23 +00:00
|
|
|
if (!gbl_resolv_flags.network_name)
|
|
|
|
return tp->ip6;
|
2013-08-29 18:59:49 +00:00
|
|
|
|
2015-09-27 13:46:09 +00:00
|
|
|
tp->flags |= RESOLVED_ADDRESS_USED;
|
2013-10-10 19:17:48 +00:00
|
|
|
|
2013-08-29 22:08:23 +00:00
|
|
|
return tp->name;
|
2009-09-06 08:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* -------------------------- */
|
2012-04-13 22:23:04 +00:00
|
|
|
void
|
2022-05-05 19:27:41 +00:00
|
|
|
add_ipv4_name(const guint addr, const gchar *name, gboolean static_entry)
|
1998-09-25 23:24:07 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
hashipv4_t *tp;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't add zero-length names; apparently, some resolvers will return
|
|
|
|
* them if they get them from DNS.
|
|
|
|
*/
|
2015-03-18 18:25:06 +00:00
|
|
|
if (!name || name[0] == '\0')
|
2013-08-11 00:50:51 +00:00
|
|
|
return;
|
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
tp = (hashipv4_t *)wmem_map_lookup(ipv4_hash_table, GUINT_TO_POINTER(addr));
|
2015-03-18 18:25:06 +00:00
|
|
|
if (!tp) {
|
2013-08-11 19:02:26 +00:00
|
|
|
tp = new_ipv4(addr);
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_insert(ipv4_hash_table, GUINT_TO_POINTER(addr), tp);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
2013-08-11 19:02:26 +00:00
|
|
|
|
2022-05-05 19:27:41 +00:00
|
|
|
if (g_ascii_strcasecmp(tp->name, name) && (static_entry || !(tp->flags & STATIC_HOSTNAME))) {
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(tp->name, name, MAXNAMELEN);
|
2015-03-18 18:25:06 +00:00
|
|
|
new_resolved_objects = TRUE;
|
2022-05-05 19:27:41 +00:00
|
|
|
if (static_entry)
|
|
|
|
tp->flags |= STATIC_HOSTNAME;
|
2015-03-18 18:25:06 +00:00
|
|
|
}
|
2016-01-19 07:22:30 +00:00
|
|
|
tp->flags |= TRIED_RESOLVE_ADDRESS|NAME_RESOLVED;
|
2004-11-17 08:53:20 +00:00
|
|
|
} /* add_ipv4_name */
|
1998-09-25 23:24:07 +00:00
|
|
|
|
2009-09-06 08:59:30 +00:00
|
|
|
/* -------------------------- */
|
2012-04-13 22:23:04 +00:00
|
|
|
void
|
2022-05-05 19:27:41 +00:00
|
|
|
add_ipv6_name(const ws_in6_addr *addrp, const gchar *name, const gboolean static_entry)
|
2004-11-17 09:44:41 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
hashipv6_t *tp;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't add zero-length names; apparently, some resolvers will return
|
|
|
|
* them if they get them from DNS.
|
|
|
|
*/
|
2015-03-18 18:25:06 +00:00
|
|
|
if (!name || name[0] == '\0')
|
2013-08-11 00:50:51 +00:00
|
|
|
return;
|
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
tp = (hashipv6_t *)wmem_map_lookup(ipv6_hash_table, addrp);
|
2015-03-18 18:25:06 +00:00
|
|
|
if (!tp) {
|
2017-10-26 08:50:00 +00:00
|
|
|
ws_in6_addr *addr_key;
|
2013-08-11 00:50:51 +00:00
|
|
|
|
2017-10-26 08:50:00 +00:00
|
|
|
addr_key = wmem_new(wmem_epan_scope(), ws_in6_addr);
|
2013-08-18 19:02:48 +00:00
|
|
|
tp = new_ipv6(addrp);
|
2013-10-23 12:02:15 +00:00
|
|
|
memcpy(addr_key, addrp, 16);
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_insert(ipv6_hash_table, addr_key, tp);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
2013-08-18 19:02:48 +00:00
|
|
|
|
2022-05-05 19:27:41 +00:00
|
|
|
if (g_ascii_strcasecmp(tp->name, name) && (static_entry || !(tp->flags & STATIC_HOSTNAME))) {
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(tp->name, name, MAXNAMELEN);
|
2015-03-18 18:25:06 +00:00
|
|
|
new_resolved_objects = TRUE;
|
2022-05-05 19:27:41 +00:00
|
|
|
if (static_entry)
|
|
|
|
tp->flags |= STATIC_HOSTNAME;
|
2015-03-18 18:25:06 +00:00
|
|
|
}
|
2016-01-19 07:22:30 +00:00
|
|
|
tp->flags |= TRIED_RESOLVE_ADDRESS|NAME_RESOLVED;
|
2004-11-17 09:44:41 +00:00
|
|
|
} /* add_ipv6_name */
|
|
|
|
|
2013-10-23 12:02:15 +00:00
|
|
|
static void
|
2020-02-09 01:39:41 +00:00
|
|
|
add_manually_resolved_ipv4(gpointer key, gpointer value, gpointer user_data _U_)
|
2013-10-23 12:02:15 +00:00
|
|
|
{
|
2020-02-09 01:39:41 +00:00
|
|
|
resolved_name_t *resolved_ipv4_entry = (resolved_name_t*)value;
|
2022-05-05 19:27:41 +00:00
|
|
|
add_ipv4_name(GPOINTER_TO_UINT(key), resolved_ipv4_entry->name, TRUE);
|
2013-10-23 12:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-09 01:39:41 +00:00
|
|
|
add_manually_resolved_ipv6(gpointer key, gpointer value, gpointer user_data _U_)
|
2013-10-23 12:02:15 +00:00
|
|
|
{
|
2020-02-09 01:39:41 +00:00
|
|
|
resolved_name_t *resolved_ipv6_entry = (resolved_name_t*)value;
|
2022-05-05 19:27:41 +00:00
|
|
|
add_ipv6_name((ws_in6_addr*)key, resolved_ipv6_entry->name, TRUE);
|
2013-10-23 12:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
add_manually_resolved(void)
|
|
|
|
{
|
2015-02-27 02:10:25 +00:00
|
|
|
if (manually_resolved_ipv4_list) {
|
2020-02-09 01:39:41 +00:00
|
|
|
wmem_map_foreach(manually_resolved_ipv4_list, add_manually_resolved_ipv4, NULL);
|
2013-10-23 12:02:15 +00:00
|
|
|
}
|
|
|
|
|
2015-02-27 02:10:25 +00:00
|
|
|
if (manually_resolved_ipv6_list) {
|
2020-02-09 01:39:41 +00:00
|
|
|
wmem_map_foreach(manually_resolved_ipv6_list, add_manually_resolved_ipv6, NULL);
|
2013-10-23 12:02:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-02 12:43:40 +00:00
|
|
|
static void
|
2013-08-07 16:46:08 +00:00
|
|
|
host_name_lookup_init(void)
|
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
char *hostspath;
|
|
|
|
guint i;
|
2013-08-07 16:46:08 +00:00
|
|
|
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(ipxnet_hash_table == NULL);
|
2018-11-21 16:08:18 +00:00
|
|
|
ipxnet_hash_table = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
|
2013-08-20 05:06:26 +00:00
|
|
|
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(ipv4_hash_table == NULL);
|
2016-04-21 16:04:16 +00:00
|
|
|
ipv4_hash_table = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
|
2013-08-12 18:33:08 +00:00
|
|
|
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(ipv6_hash_table == NULL);
|
2016-04-21 16:04:16 +00:00
|
|
|
ipv6_hash_table = wmem_map_new(wmem_epan_scope(), ipv6_oat_hash, ipv6_equal);
|
2013-08-18 19:02:48 +00:00
|
|
|
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(async_dns_queue_head == NULL);
|
2016-04-21 08:14:11 +00:00
|
|
|
async_dns_queue_head = wmem_list_new(wmem_epan_scope());
|
|
|
|
|
2016-04-22 23:44:19 +00:00
|
|
|
if (manually_resolved_ipv4_list == NULL)
|
2020-02-09 01:39:41 +00:00
|
|
|
manually_resolved_ipv4_list = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
|
2016-04-21 08:14:11 +00:00
|
|
|
|
2016-04-22 23:44:19 +00:00
|
|
|
if (manually_resolved_ipv6_list == NULL)
|
2020-02-09 01:39:41 +00:00
|
|
|
manually_resolved_ipv6_list = wmem_map_new(wmem_epan_scope(), ipv6_oat_hash, ipv6_equal);
|
2016-04-21 08:14:11 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/*
|
|
|
|
* Load the global hosts file, if we have one.
|
|
|
|
*/
|
2015-02-27 02:10:25 +00:00
|
|
|
if (!gbl_resolv_flags.load_hosts_file_from_profile_only) {
|
2013-08-11 00:50:51 +00:00
|
|
|
hostspath = get_datafile_path(ENAME_HOSTS);
|
2014-09-26 17:41:43 +00:00
|
|
|
if (!read_hosts_file(hostspath, TRUE) && errno != ENOENT) {
|
2013-08-11 00:50:51 +00:00
|
|
|
report_open_failure(hostspath, errno, FALSE);
|
|
|
|
}
|
|
|
|
g_free(hostspath);
|
|
|
|
}
|
2013-08-13 01:41:51 +00:00
|
|
|
/*
|
|
|
|
* Load the user's hosts file no matter what, if they have one.
|
|
|
|
*/
|
|
|
|
hostspath = get_persconffile_path(ENAME_HOSTS, TRUE);
|
2014-09-26 17:41:43 +00:00
|
|
|
if (!read_hosts_file(hostspath, TRUE) && errno != ENOENT) {
|
2013-08-13 01:41:51 +00:00
|
|
|
report_open_failure(hostspath, errno, FALSE);
|
|
|
|
}
|
|
|
|
g_free(hostspath);
|
2013-08-07 16:46:08 +00:00
|
|
|
#ifdef CARES_HAVE_ARES_LIBRARY_INIT
|
2016-03-26 03:16:17 +00:00
|
|
|
if (ares_library_init(ARES_LIB_INIT_ALL) == ARES_SUCCESS) {
|
2013-08-07 16:46:08 +00:00
|
|
|
#endif
|
2016-03-26 03:16:17 +00:00
|
|
|
if (ares_init(&ghba_chan) == ARES_SUCCESS && ares_init(&ghbn_chan) == ARES_SUCCESS) {
|
|
|
|
async_dns_initialized = TRUE;
|
2019-09-01 16:02:27 +00:00
|
|
|
c_ares_set_dns_servers();
|
2014-06-30 23:46:58 +00:00
|
|
|
}
|
2016-03-26 03:16:17 +00:00
|
|
|
#ifdef CARES_HAVE_ARES_LIBRARY_INIT
|
2014-06-30 23:46:58 +00:00
|
|
|
}
|
2016-03-26 03:16:17 +00:00
|
|
|
#endif
|
2013-08-07 16:46:08 +00:00
|
|
|
|
2015-02-27 02:10:25 +00:00
|
|
|
if (extra_hosts_files && !gbl_resolv_flags.load_hosts_file_from_profile_only) {
|
2013-08-11 00:50:51 +00:00
|
|
|
for (i = 0; i < extra_hosts_files->len; i++) {
|
2014-09-26 17:41:43 +00:00
|
|
|
read_hosts_file((const char *) g_ptr_array_index(extra_hosts_files, i), TRUE);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
2013-08-07 16:46:08 +00:00
|
|
|
}
|
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
subnet_name_lookup_init();
|
2013-10-23 12:02:15 +00:00
|
|
|
|
|
|
|
add_manually_resolved();
|
2016-09-13 04:46:06 +00:00
|
|
|
|
|
|
|
ss7pc_name_lookup_init();
|
2013-08-07 16:46:08 +00:00
|
|
|
}
|
|
|
|
|
2018-09-02 12:43:40 +00:00
|
|
|
static void
|
2013-08-07 16:46:08 +00:00
|
|
|
host_name_lookup_cleanup(void)
|
|
|
|
{
|
2015-01-16 17:35:14 +00:00
|
|
|
guint32 i, j;
|
2016-04-28 21:46:31 +00:00
|
|
|
sub_net_hashipv4_t *entry, *next_entry;
|
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
_host_name_lookup_cleanup();
|
2013-08-07 16:46:08 +00:00
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
ipxnet_hash_table = NULL;
|
|
|
|
ipv4_hash_table = NULL;
|
|
|
|
ipv6_hash_table = NULL;
|
2016-09-13 04:46:06 +00:00
|
|
|
ss7pc_hash_table = NULL;
|
2013-08-07 16:46:08 +00:00
|
|
|
|
2015-01-16 17:35:14 +00:00
|
|
|
for(i = 0; i < SUBNETLENGTHSIZE; ++i) {
|
|
|
|
if (subnet_length_entries[i].subnet_addresses != NULL) {
|
|
|
|
for (j = 0; j < HASHHOSTSIZE; j++) {
|
2016-04-28 21:46:31 +00:00
|
|
|
for (entry = subnet_length_entries[i].subnet_addresses[j];
|
|
|
|
entry != NULL; entry = next_entry) {
|
|
|
|
next_entry = entry->next;
|
|
|
|
wmem_free(wmem_epan_scope(), entry);
|
2015-01-16 17:35:14 +00:00
|
|
|
}
|
|
|
|
}
|
2016-04-20 14:45:32 +00:00
|
|
|
wmem_free(wmem_epan_scope(), subnet_length_entries[i].subnet_addresses);
|
2015-01-16 17:35:14 +00:00
|
|
|
subnet_length_entries[i].subnet_addresses = NULL;
|
|
|
|
}
|
|
|
|
}
|
2013-08-07 16:46:08 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
have_subnet_entry = FALSE;
|
|
|
|
new_resolved_objects = FALSE;
|
2013-08-07 16:46:08 +00:00
|
|
|
}
|
|
|
|
|
2018-09-02 12:43:40 +00:00
|
|
|
|
|
|
|
void host_name_lookup_reset(void)
|
|
|
|
{
|
|
|
|
host_name_lookup_cleanup();
|
|
|
|
host_name_lookup_init();
|
2019-05-26 10:59:07 +00:00
|
|
|
vlan_name_lookup_cleanup();
|
|
|
|
initialize_vlans();
|
2020-10-10 11:34:18 +00:00
|
|
|
ethers_cleanup();
|
|
|
|
initialize_ethers();
|
2021-05-17 22:05:31 +00:00
|
|
|
service_name_lookup_cleanup();
|
|
|
|
initialize_services();
|
2020-10-10 11:34:18 +00:00
|
|
|
ipx_name_lookup_cleanup();
|
|
|
|
initialize_ipxnets();
|
|
|
|
enterprises_cleanup();
|
|
|
|
initialize_enterprises();
|
2018-09-02 12:43:40 +00:00
|
|
|
}
|
|
|
|
|
2012-04-13 22:23:04 +00:00
|
|
|
gchar *
|
2015-01-07 21:24:17 +00:00
|
|
|
udp_port_to_display(wmem_allocator_t *allocator, guint port)
|
1998-09-16 02:39:15 +00:00
|
|
|
{
|
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (!gbl_resolv_flags.transport_name) {
|
2015-01-07 21:24:17 +00:00
|
|
|
return wmem_utoa(allocator, port);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2015-10-05 12:51:58 +00:00
|
|
|
return wmem_strdup(allocator, serv_name_lookup(PT_UDP, port));
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2015-01-07 21:24:17 +00:00
|
|
|
} /* udp_port_to_display */
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2012-04-13 22:23:04 +00:00
|
|
|
gchar *
|
2015-01-07 21:24:17 +00:00
|
|
|
dccp_port_to_display(wmem_allocator_t *allocator, guint port)
|
2005-09-20 15:18:28 +00:00
|
|
|
{
|
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (!gbl_resolv_flags.transport_name) {
|
2015-01-07 21:24:17 +00:00
|
|
|
return wmem_utoa(allocator, port);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
2005-09-20 15:18:28 +00:00
|
|
|
|
2015-10-05 12:51:58 +00:00
|
|
|
return wmem_strdup(allocator, serv_name_lookup(PT_DCCP, port));
|
2005-09-20 15:18:28 +00:00
|
|
|
|
2015-01-07 21:24:17 +00:00
|
|
|
} /* dccp_port_to_display */
|
2005-09-20 15:18:28 +00:00
|
|
|
|
2012-04-13 22:23:04 +00:00
|
|
|
gchar *
|
2015-01-07 21:24:17 +00:00
|
|
|
tcp_port_to_display(wmem_allocator_t *allocator, guint port)
|
1998-09-16 02:39:15 +00:00
|
|
|
{
|
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (!gbl_resolv_flags.transport_name) {
|
2015-01-07 21:24:17 +00:00
|
|
|
return wmem_utoa(allocator, port);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2015-10-05 12:51:58 +00:00
|
|
|
return wmem_strdup(allocator, serv_name_lookup(PT_TCP, port));
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2015-01-07 21:24:17 +00:00
|
|
|
} /* tcp_port_to_display */
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2012-04-13 22:23:04 +00:00
|
|
|
gchar *
|
2015-01-07 21:24:17 +00:00
|
|
|
sctp_port_to_display(wmem_allocator_t *allocator, guint port)
|
2000-08-19 08:26:04 +00:00
|
|
|
{
|
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (!gbl_resolv_flags.transport_name) {
|
2015-01-07 21:24:17 +00:00
|
|
|
return wmem_utoa(allocator, port);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
2000-08-19 08:26:04 +00:00
|
|
|
|
2015-10-05 12:51:58 +00:00
|
|
|
return wmem_strdup(allocator, serv_name_lookup(PT_SCTP, port));
|
2000-08-19 08:26:04 +00:00
|
|
|
|
2015-01-07 21:24:17 +00:00
|
|
|
} /* sctp_port_to_display */
|
2000-08-19 08:26:04 +00:00
|
|
|
|
2015-10-05 12:51:58 +00:00
|
|
|
gchar *
|
|
|
|
port_with_resolution_to_str(wmem_allocator_t *scope, port_type proto, guint port)
|
|
|
|
{
|
|
|
|
const gchar *port_str;
|
|
|
|
|
|
|
|
if (!gbl_resolv_flags.transport_name || (proto == PT_NONE)) {
|
|
|
|
/* No name resolution support, just return port string */
|
|
|
|
return wmem_strdup_printf(scope, "%u", port);
|
|
|
|
}
|
|
|
|
port_str = serv_name_lookup(proto, port);
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(port_str);
|
2015-10-05 12:51:58 +00:00
|
|
|
return wmem_strdup_printf(scope, "%s (%u)", port_str, port);
|
|
|
|
}
|
|
|
|
|
2015-10-05 10:53:07 +00:00
|
|
|
int
|
2015-10-05 12:51:58 +00:00
|
|
|
port_with_resolution_to_str_buf(gchar *buf, gulong buf_size, port_type proto, guint port)
|
2015-10-05 10:53:07 +00:00
|
|
|
{
|
2015-10-05 12:51:58 +00:00
|
|
|
const gchar *port_str;
|
2015-10-05 10:53:07 +00:00
|
|
|
|
2015-10-05 12:51:58 +00:00
|
|
|
if (!gbl_resolv_flags.transport_name || (proto == PT_NONE)) {
|
2015-10-05 10:53:07 +00:00
|
|
|
/* No name resolution support, just return port string */
|
2021-12-16 18:06:18 +00:00
|
|
|
return snprintf(buf, buf_size, "%u", port);
|
2015-10-05 10:53:07 +00:00
|
|
|
}
|
2015-10-05 12:51:58 +00:00
|
|
|
port_str = serv_name_lookup(proto, port);
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(port_str);
|
2021-12-16 18:06:18 +00:00
|
|
|
return snprintf(buf, buf_size, "%s (%u)", port_str, port);
|
2015-10-05 10:53:07 +00:00
|
|
|
}
|
|
|
|
|
2016-02-10 19:07:29 +00:00
|
|
|
const gchar *
|
2010-04-29 18:17:29 +00:00
|
|
|
get_ether_name(const guint8 *addr)
|
1998-09-25 23:24:07 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
hashether_t *tp;
|
|
|
|
gboolean resolve = gbl_resolv_flags.mac_name;
|
2010-07-01 15:11:02 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
tp = eth_name_lookup(addr, resolve);
|
2010-07-01 15:11:02 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
return resolve ? tp->resolved_name : tp->hexaddr;
|
2010-07-01 15:11:02 +00:00
|
|
|
|
1998-09-25 23:24:07 +00:00
|
|
|
} /* get_ether_name */
|
|
|
|
|
2016-02-10 19:07:29 +00:00
|
|
|
const gchar *
|
2015-03-02 14:33:52 +00:00
|
|
|
tvb_get_ether_name(tvbuff_t *tvb, gint offset)
|
|
|
|
{
|
|
|
|
return get_ether_name(tvb_get_ptr(tvb, offset, 6));
|
|
|
|
}
|
|
|
|
|
2010-06-28 22:29:49 +00:00
|
|
|
/* Look for a (non-dummy) ether name in the hash, and return it if found.
|
|
|
|
* If it's not found, simply return NULL.
|
1999-11-21 16:32:23 +00:00
|
|
|
*/
|
2015-11-30 07:14:44 +00:00
|
|
|
const gchar *
|
2010-04-29 18:17:29 +00:00
|
|
|
get_ether_name_if_known(const guint8 *addr)
|
1999-11-21 16:32:23 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
hashether_t *tp;
|
1999-11-21 16:32:23 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Initialize ether structs if we're the first
|
|
|
|
* ether-related function called */
|
|
|
|
if (!gbl_resolv_flags.mac_name)
|
|
|
|
return NULL;
|
2002-08-28 20:41:00 +00:00
|
|
|
|
2021-01-20 05:14:10 +00:00
|
|
|
/* eth_name_lookup will create a (resolved) hash entry
|
|
|
|
* if it doesn't exist, so it never returns NULL */
|
2013-08-11 00:50:51 +00:00
|
|
|
tp = eth_name_lookup(addr, TRUE);
|
1999-11-21 16:32:23 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (tp->status == HASHETHER_STATUS_RESOLVED_NAME) {
|
2016-11-15 22:36:26 +00:00
|
|
|
/* Name is from an ethers file */
|
2013-08-11 00:50:51 +00:00
|
|
|
return tp->resolved_name;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* Name was created */
|
|
|
|
return NULL;
|
|
|
|
}
|
1999-11-21 16:32:23 +00:00
|
|
|
}
|
|
|
|
|
2012-04-13 22:23:04 +00:00
|
|
|
void
|
2010-04-29 18:17:29 +00:00
|
|
|
add_ether_byip(const guint ip, const guint8 *eth)
|
2000-08-10 20:09:29 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
hashipv4_t *tp;
|
2000-08-10 20:09:29 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* first check that IP address can be resolved */
|
|
|
|
if (!gbl_resolv_flags.network_name)
|
|
|
|
return;
|
2000-08-10 20:09:29 +00:00
|
|
|
|
2016-01-19 07:22:30 +00:00
|
|
|
tp = host_lookup(ip);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Was this IP address resolved to a host name?
|
|
|
|
*/
|
|
|
|
if (tp->flags & NAME_RESOLVED) {
|
|
|
|
/*
|
|
|
|
* Yes, so add an entry in the ethers hashtable resolving
|
|
|
|
* the MAC address to that name.
|
|
|
|
*/
|
2013-08-11 00:50:51 +00:00
|
|
|
add_eth_name(eth, tp->name);
|
|
|
|
}
|
2000-08-10 20:09:29 +00:00
|
|
|
|
|
|
|
} /* add_ether_byip */
|
1999-11-21 16:32:23 +00:00
|
|
|
|
2015-11-30 07:14:44 +00:00
|
|
|
gchar *
|
2015-01-08 17:13:18 +00:00
|
|
|
get_ipxnet_name(wmem_allocator_t *allocator, const guint32 addr)
|
1999-11-21 16:32:23 +00:00
|
|
|
{
|
1999-11-22 06:03:46 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
if (!gbl_resolv_flags.network_name) {
|
2015-01-08 17:13:18 +00:00
|
|
|
return ipxnet_to_str_punct(allocator, addr, '\0');
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
1999-11-21 16:32:23 +00:00
|
|
|
|
2015-01-08 17:13:18 +00:00
|
|
|
return ipxnet_name_lookup(allocator, addr);
|
1999-11-21 16:32:23 +00:00
|
|
|
|
|
|
|
} /* get_ipxnet_name */
|
|
|
|
|
2016-03-13 22:16:20 +00:00
|
|
|
gchar *
|
|
|
|
get_vlan_name(wmem_allocator_t *allocator, const guint16 id)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!gbl_resolv_flags.vlan_name) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return wmem_strdup(allocator, vlan_name_lookup(id));
|
|
|
|
|
|
|
|
} /* get_vlan_name */
|
|
|
|
|
2015-02-12 03:16:01 +00:00
|
|
|
const gchar *
|
|
|
|
get_manuf_name(const guint8 *addr)
|
1998-09-25 23:24:07 +00:00
|
|
|
{
|
2015-02-12 03:16:01 +00:00
|
|
|
hashmanuf_t *manuf_value;
|
2013-08-11 00:50:51 +00:00
|
|
|
|
2015-02-12 03:16:01 +00:00
|
|
|
manuf_value = manuf_name_lookup(addr);
|
|
|
|
if (gbl_resolv_flags.mac_name && manuf_value->status != HASHETHER_STATUS_UNRESOLVED)
|
|
|
|
return manuf_value->resolved_name;
|
2013-08-11 00:50:51 +00:00
|
|
|
|
2015-02-12 03:16:01 +00:00
|
|
|
return manuf_value->hexaddr;
|
1998-09-25 23:24:07 +00:00
|
|
|
|
|
|
|
} /* get_manuf_name */
|
1999-07-07 22:52:57 +00:00
|
|
|
|
2012-04-13 22:23:04 +00:00
|
|
|
const gchar *
|
2011-05-20 02:42:14 +00:00
|
|
|
tvb_get_manuf_name(tvbuff_t *tvb, gint offset)
|
|
|
|
{
|
2015-02-12 03:16:01 +00:00
|
|
|
return get_manuf_name(tvb_get_ptr(tvb, offset, 3));
|
2011-05-20 02:42:14 +00:00
|
|
|
}
|
1999-07-07 22:52:57 +00:00
|
|
|
|
2010-04-29 18:17:29 +00:00
|
|
|
const gchar *
|
|
|
|
get_manuf_name_if_known(const guint8 *addr)
|
2005-05-20 21:44:17 +00:00
|
|
|
{
|
2015-02-12 03:16:01 +00:00
|
|
|
hashmanuf_t *manuf_value;
|
2018-11-21 16:08:18 +00:00
|
|
|
guint manuf_key;
|
2013-08-11 00:50:51 +00:00
|
|
|
guint8 oct;
|
2005-05-20 21:44:17 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* 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;
|
|
|
|
|
2018-11-21 16:08:18 +00:00
|
|
|
manuf_value = (hashmanuf_t *)wmem_map_lookup(manuf_hashtable, GUINT_TO_POINTER(manuf_key));
|
2016-11-12 12:19:34 +00:00
|
|
|
if ((manuf_value == NULL) || (manuf_value->status == HASHETHER_STATUS_UNRESOLVED)) {
|
2013-08-11 00:50:51 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2005-05-20 21:44:17 +00:00
|
|
|
|
2017-08-20 17:33:53 +00:00
|
|
|
return manuf_value->resolved_longname;
|
2005-05-20 21:44:17 +00:00
|
|
|
|
|
|
|
} /* get_manuf_name_if_known */
|
|
|
|
|
2012-04-13 22:23:04 +00:00
|
|
|
const gchar *
|
2013-08-01 20:11:13 +00:00
|
|
|
uint_get_manuf_name_if_known(const guint manuf_key)
|
2012-04-13 22:23:04 +00:00
|
|
|
{
|
2015-02-12 03:16:01 +00:00
|
|
|
hashmanuf_t *manuf_value;
|
2012-04-13 22:23:04 +00:00
|
|
|
|
2018-11-21 16:08:18 +00:00
|
|
|
manuf_value = (hashmanuf_t *)wmem_map_lookup(manuf_hashtable, GUINT_TO_POINTER(manuf_key));
|
2016-11-12 12:19:34 +00:00
|
|
|
if ((manuf_value == NULL) || (manuf_value->status == HASHETHER_STATUS_UNRESOLVED)) {
|
2013-08-11 00:50:51 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2013-08-01 20:11:13 +00:00
|
|
|
|
2017-08-20 17:33:53 +00:00
|
|
|
return manuf_value->resolved_longname;
|
2012-04-13 22:23:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const gchar *
|
2011-05-20 02:42:14 +00:00
|
|
|
tvb_get_manuf_name_if_known(tvbuff_t *tvb, gint offset)
|
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
return get_manuf_name_if_known(tvb_get_ptr(tvb, offset, 3));
|
2011-05-20 02:42:14 +00:00
|
|
|
}
|
|
|
|
|
2015-02-12 03:16:01 +00:00
|
|
|
char* get_hash_manuf_resolved_name(hashmanuf_t* manuf)
|
|
|
|
{
|
2017-08-20 17:33:53 +00:00
|
|
|
return manuf->resolved_longname;
|
2015-02-12 03:16:01 +00:00
|
|
|
}
|
|
|
|
|
2016-02-10 19:07:29 +00:00
|
|
|
gchar *
|
2015-01-08 18:16:01 +00:00
|
|
|
eui64_to_display(wmem_allocator_t *allocator, const guint64 addr_eui64)
|
2011-05-08 10:23:53 +00:00
|
|
|
{
|
2015-06-21 14:02:43 +00:00
|
|
|
guint8 *addr = (guint8 *)wmem_alloc(NULL, 8);
|
2015-02-12 03:16:01 +00:00
|
|
|
hashmanuf_t *manuf_value;
|
2016-02-10 19:07:29 +00:00
|
|
|
gchar *ret;
|
2011-05-20 02:42:14 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* Copy and convert the address to network byte order. */
|
|
|
|
*(guint64 *)(void *)(addr) = pntoh64(&(addr_eui64));
|
2011-05-08 10:23:53 +00:00
|
|
|
|
2015-02-12 03:16:01 +00:00
|
|
|
manuf_value = manuf_name_lookup(addr);
|
|
|
|
if (!gbl_resolv_flags.mac_name || (manuf_value->status == HASHETHER_STATUS_UNRESOLVED)) {
|
2015-06-21 14:02:43 +00:00
|
|
|
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]);
|
2013-08-11 00:50:51 +00:00
|
|
|
}
|
2011-05-08 10:23:53 +00:00
|
|
|
|
2015-06-21 14:02:43 +00:00
|
|
|
wmem_free(NULL, addr);
|
|
|
|
return ret;
|
2015-01-08 18:16:01 +00:00
|
|
|
} /* eui64_to_display */
|
1999-07-07 22:52:57 +00:00
|
|
|
|
2009-12-24 00:58:31 +00:00
|
|
|
#define GHI_TIMEOUT (250 * 1000)
|
|
|
|
static void
|
2017-07-20 18:03:45 +00:00
|
|
|
c_ares_ghi_cb(void *arg, int status, int timeouts _U_, struct hostent *hp) {
|
2013-08-11 00:50:51 +00:00
|
|
|
/*
|
|
|
|
* XXX - If we wanted to be really fancy we could cache results here and
|
|
|
|
* look them up in get_host_ipaddr* below.
|
|
|
|
*/
|
|
|
|
async_hostent_t *ahp = (async_hostent_t *)arg;
|
|
|
|
if (status == ARES_SUCCESS && hp && ahp && hp->h_length == ahp->addr_size) {
|
|
|
|
memcpy(ahp->addrp, hp->h_addr, hp->h_length);
|
|
|
|
ahp->copied = hp->h_length;
|
|
|
|
}
|
2009-12-24 00:58:31 +00:00
|
|
|
}
|
|
|
|
|
2017-10-25 19:36:02 +00:00
|
|
|
/* 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. */
|
2010-04-29 18:17:29 +00:00
|
|
|
gboolean
|
|
|
|
get_host_ipaddr(const char *host, guint32 *addrp)
|
1999-07-07 22:52:57 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
struct timeval tv = { 0, GHI_TIMEOUT }, *tvp;
|
|
|
|
int nfds;
|
|
|
|
fd_set rfds, wfds;
|
|
|
|
async_hostent_t ahe;
|
2009-09-07 16:07:04 +00:00
|
|
|
|
2017-10-25 19:36:02 +00:00
|
|
|
/*
|
|
|
|
* XXX - are there places where this is used to translate something
|
|
|
|
* that's *only* supposed to be an IPv4 address, and where it
|
|
|
|
* *shouldn't* translate host names?
|
|
|
|
*/
|
2017-10-25 19:51:33 +00:00
|
|
|
if (!ws_inet_pton4(host, addrp)) {
|
2013-08-11 00:50:51 +00:00
|
|
|
|
|
|
|
/* It's not a valid dotted-quad IP address; is it a valid
|
|
|
|
* host name?
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* If we're not allowed to do name resolution, don't do name
|
|
|
|
* resolution...
|
|
|
|
*/
|
|
|
|
if (!gbl_resolv_flags.network_name ||
|
|
|
|
!gbl_resolv_flags.use_external_net_name_resolver) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
2012-07-10 15:02:23 +00:00
|
|
|
|
2016-03-26 03:16:17 +00:00
|
|
|
if (!async_dns_initialized || name_resolve_concurrency < 1) {
|
2013-08-11 00:50:51 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
ahe.addr_size = (int) sizeof (struct in_addr);
|
|
|
|
ahe.copied = 0;
|
|
|
|
ahe.addrp = addrp;
|
|
|
|
ares_gethostbyname(ghbn_chan, host, AF_INET, c_ares_ghi_cb, &ahe);
|
|
|
|
FD_ZERO(&rfds);
|
|
|
|
FD_ZERO(&wfds);
|
|
|
|
nfds = ares_fds(ghbn_chan, &rfds, &wfds);
|
|
|
|
if (nfds > 0) {
|
|
|
|
tvp = ares_timeout(ghbn_chan, &tv, &tv);
|
|
|
|
if (select(nfds, &rfds, &wfds, NULL, tvp) == -1) { /* call to select() failed */
|
2019-04-04 19:30:46 +00:00
|
|
|
/* 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));
|
2013-08-11 00:50:51 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
ares_process(ghbn_chan, &rfds, &wfds);
|
|
|
|
}
|
|
|
|
ares_cancel(ghbn_chan);
|
|
|
|
if (ahe.addr_size == ahe.copied) {
|
|
|
|
return TRUE;
|
|
|
|
}
|
2013-08-07 16:46:08 +00:00
|
|
|
return FALSE;
|
2009-09-07 16:07:04 +00:00
|
|
|
}
|
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
return TRUE;
|
1999-07-07 22:52:57 +00:00
|
|
|
}
|
1999-10-14 05:41:33 +00:00
|
|
|
|
|
|
|
/*
|
2017-10-25 19:36:02 +00:00
|
|
|
* Translate IPv6 numeric address or FQDN hostname into binary IPv6 address.
|
|
|
|
* Return TRUE if we succeed and set "*addrp" to that numeric IPv6 address;
|
1999-10-14 05:41:33 +00:00
|
|
|
* return FALSE if we fail.
|
|
|
|
*/
|
2010-04-29 18:17:29 +00:00
|
|
|
gboolean
|
2017-10-26 08:50:00 +00:00
|
|
|
get_host_ipaddr6(const char *host, ws_in6_addr *addrp)
|
1999-10-14 05:41:33 +00:00
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
struct timeval tv = { 0, GHI_TIMEOUT }, *tvp;
|
|
|
|
int nfds;
|
|
|
|
fd_set rfds, wfds;
|
|
|
|
async_hostent_t ahe;
|
1999-10-14 05:41:33 +00:00
|
|
|
|
2013-12-21 16:16:56 +00:00
|
|
|
if (str_to_ip6(host, addrp))
|
2013-08-11 00:50:51 +00:00
|
|
|
return TRUE;
|
1999-10-14 05:41:33 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* It's not a valid dotted-quad IP address; is it a valid
|
|
|
|
* host name?
|
2017-10-25 19:36:02 +00:00
|
|
|
*
|
|
|
|
* XXX - are there places where this is used to translate something
|
|
|
|
* that's *only* supposed to be an IPv6 address, and where it
|
|
|
|
* *shouldn't* translate host names?
|
2013-08-11 00:50:51 +00:00
|
|
|
*/
|
2012-07-10 15:02:23 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* If we're not allowed to do name resolution, don't do name
|
|
|
|
* resolution...
|
|
|
|
*/
|
|
|
|
if (!gbl_resolv_flags.network_name ||
|
|
|
|
!gbl_resolv_flags.use_external_net_name_resolver) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
2009-12-24 17:21:02 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/* try FQDN */
|
2016-03-26 03:16:17 +00:00
|
|
|
if (!async_dns_initialized || name_resolve_concurrency < 1) {
|
2013-08-07 16:46:08 +00:00
|
|
|
return FALSE;
|
2012-11-05 09:18:43 +00:00
|
|
|
}
|
2017-10-26 08:50:00 +00:00
|
|
|
ahe.addr_size = (int) sizeof (ws_in6_addr);
|
2013-08-11 00:50:51 +00:00
|
|
|
ahe.copied = 0;
|
|
|
|
ahe.addrp = addrp;
|
|
|
|
ares_gethostbyname(ghbn_chan, host, AF_INET6, c_ares_ghi_cb, &ahe);
|
|
|
|
FD_ZERO(&rfds);
|
|
|
|
FD_ZERO(&wfds);
|
|
|
|
nfds = ares_fds(ghbn_chan, &rfds, &wfds);
|
|
|
|
if (nfds > 0) {
|
|
|
|
tvp = ares_timeout(ghbn_chan, &tv, &tv);
|
|
|
|
if (select(nfds, &rfds, &wfds, NULL, tvp) == -1) { /* call to select() failed */
|
2019-04-04 19:30:46 +00:00
|
|
|
/* 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));
|
2013-08-11 00:50:51 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
ares_process(ghbn_chan, &rfds, &wfds);
|
|
|
|
}
|
|
|
|
ares_cancel(ghbn_chan);
|
|
|
|
if (ahe.addr_size == ahe.copied) {
|
|
|
|
return TRUE;
|
|
|
|
}
|
1999-10-14 05:41:33 +00:00
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
return FALSE;
|
1999-10-14 05:41:33 +00:00
|
|
|
}
|
2004-06-25 07:00:54 +00:00
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_t *
|
2013-08-01 20:11:13 +00:00
|
|
|
get_manuf_hashtable(void)
|
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
return manuf_hashtable;
|
2013-08-01 20:11:13 +00:00
|
|
|
}
|
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_t *
|
2013-08-01 20:11:13 +00:00
|
|
|
get_wka_hashtable(void)
|
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
return wka_hashtable;
|
2013-08-01 20:11:13 +00:00
|
|
|
}
|
2013-08-02 15:05:00 +00:00
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_t *
|
2013-08-02 15:05:00 +00:00
|
|
|
get_eth_hashtable(void)
|
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
return eth_hashtable;
|
2013-08-02 15:05:00 +00:00
|
|
|
}
|
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_t *
|
2013-08-05 16:36:24 +00:00
|
|
|
get_serv_port_hashtable(void)
|
|
|
|
{
|
2013-08-11 00:50:51 +00:00
|
|
|
return serv_port_hashtable;
|
2013-08-07 16:46:08 +00:00
|
|
|
}
|
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_t *
|
2013-08-20 05:06:26 +00:00
|
|
|
get_ipxnet_hash_table(void)
|
|
|
|
{
|
|
|
|
return ipxnet_hash_table;
|
|
|
|
}
|
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_t *
|
2016-03-13 22:16:20 +00:00
|
|
|
get_vlan_hash_table(void)
|
|
|
|
{
|
|
|
|
return vlan_hash_table;
|
|
|
|
}
|
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_t *
|
2013-08-11 19:02:26 +00:00
|
|
|
get_ipv4_hash_table(void)
|
|
|
|
{
|
|
|
|
return ipv4_hash_table;
|
|
|
|
}
|
|
|
|
|
2016-04-21 16:04:16 +00:00
|
|
|
wmem_map_t *
|
2013-08-18 19:02:48 +00:00
|
|
|
get_ipv6_hash_table(void)
|
|
|
|
{
|
|
|
|
return ipv6_hash_table;
|
|
|
|
}
|
2013-08-07 16:46:08 +00:00
|
|
|
/* Initialize all the address resolution subsystems in this file */
|
|
|
|
void
|
|
|
|
addr_resolv_init(void)
|
|
|
|
{
|
|
|
|
initialize_services();
|
|
|
|
initialize_ethers();
|
|
|
|
initialize_ipxnets();
|
2016-03-13 22:16:20 +00:00
|
|
|
initialize_vlans();
|
2017-06-24 13:25:41 +00:00
|
|
|
initialize_enterprises();
|
2018-09-02 12:43:40 +00:00
|
|
|
host_name_lookup_init();
|
2013-08-05 16:36:24 +00:00
|
|
|
}
|
|
|
|
|
2013-08-07 16:46:08 +00:00
|
|
|
/* Clean up all the address resolution subsystems in this file */
|
|
|
|
void
|
|
|
|
addr_resolv_cleanup(void)
|
|
|
|
{
|
2016-03-13 22:16:20 +00:00
|
|
|
vlan_name_lookup_cleanup();
|
2016-04-21 16:04:16 +00:00
|
|
|
service_name_lookup_cleanup();
|
2017-02-10 17:04:20 +00:00
|
|
|
ethers_cleanup();
|
2016-04-21 16:04:16 +00:00
|
|
|
ipx_name_lookup_cleanup();
|
2017-06-24 13:25:41 +00:00
|
|
|
enterprises_cleanup();
|
2018-09-02 12:43:40 +00:00
|
|
|
host_name_lookup_cleanup();
|
2013-08-07 16:46:08 +00:00
|
|
|
}
|
2013-08-11 00:50:51 +00:00
|
|
|
|
2013-12-21 16:16:56 +00:00
|
|
|
gboolean
|
|
|
|
str_to_ip(const char *str, void *dst)
|
|
|
|
{
|
2016-02-10 09:11:12 +00:00
|
|
|
return ws_inet_pton4(str, (guint32 *)dst);
|
2013-12-21 16:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
str_to_ip6(const char *str, void *dst)
|
|
|
|
{
|
2017-10-26 08:50:00 +00:00
|
|
|
return ws_inet_pton6(str, (ws_in6_addr *)dst);
|
2013-12-21 16:16:56 +00:00
|
|
|
}
|
|
|
|
|
2018-10-10 15:25:52 +00:00
|
|
|
/*
|
|
|
|
* convert a 0-terminated string that contains an ethernet address into
|
|
|
|
* the corresponding sequence of 6 bytes
|
|
|
|
* eth_bytes is a buffer >= 6 bytes that was allocated by the caller
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
str_to_eth(const char *str, char *eth_bytes)
|
|
|
|
{
|
|
|
|
ether_t eth;
|
|
|
|
|
|
|
|
if (!parse_ether_address(str, ð, NULL, FALSE))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
memcpy(eth_bytes, eth.addr, sizeof(eth.addr));
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2013-08-11 00:50:51 +00:00
|
|
|
/*
|
2019-07-26 18:43:17 +00:00
|
|
|
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
2013-08-11 00:50:51 +00:00
|
|
|
*
|
|
|
|
* Local variables:
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* tab-width: 8
|
|
|
|
* indent-tabs-mode: nil
|
|
|
|
* End:
|
|
|
|
*
|
|
|
|
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
|
|
|
* :indentSize=4:tabSize=8:noTabs=true:
|
|
|
|
*/
|