2 * Routines for network object lookup
4 * Laurent Deniel <laurent.deniel@free.fr>
6 * Add option to resolv VLAN ID to describing name
7 * Uli Heilmeier, March 2016
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * SPDX-License-Identifier: GPL-2.0-or-later
23 #include <wsutil/strtoi.h>
26 * Win32 doesn't have SIGALRM (and it's the OS where name lookup calls
27 * are most likely to take a long time, given the way address-to-name
28 * lookups are done over NBNS).
30 * macOS does have SIGALRM, but if you longjmp() out of a name resolution
31 * call in a signal handler, you might crash, because the state of the
32 * resolution code that sends messages to lookupd might be inconsistent
33 * if you jump out of it in middle of a call.
35 * There's no guarantee that longjmp()ing out of name resolution calls
36 * will work on *any* platform; OpenBSD got rid of the alarm/longjmp
37 * code in tcpdump, to avoid those sorts of problems, and that was
38 * picked up by tcpdump.org tcpdump.
40 * So, for now, we do not use alarm() and SIGALRM to time out host name
41 * lookups. If we get a lot of complaints about lookups taking a long time,
42 * we can reconsider that decision. (Note that tcpdump originally added
43 * such a timeout mechanism that for the benefit of systems using NIS to
44 * look up host names; that might now be fixed in NIS implementations, for
45 * those sites still using NIS rather than DNS for that.... tcpdump no
46 * longer does that, for the same reasons that we don't.)
48 * If we're using an asynchronous DNS resolver, that shouldn't be an issue.
49 * If we're using a synchronous name lookup mechanism (which we'd do mainly
50 * to support resolving addresses and host names using more mechanisms than
51 * just DNS, such as NIS, NBNS, or Mr. Hosts File), we could do that in
52 * a separate thread, making it, in effect, asynchronous.
55 #ifdef HAVE_NETINET_IN_H
56 # include <netinet/in.h>
63 #ifdef HAVE_SYS_SOCKET_H
64 #include <sys/socket.h> /* needed to define AF_ values on UNIX */
68 #include <winsock2.h> /* needed to define AF_ values on Windows */
74 # define socklen_t unsigned int
77 # include <ares_version.h>
78 #endif /* HAVE_C_ARES */
83 #include "addr_and_mask.h"
85 #include "addr_resolv.h"
86 #include "wsutil/filesystem.h"
88 #include <wsutil/report_message.h>
89 #include <wsutil/file_util.h>
90 #include <wsutil/pint.h>
91 #include <wsutil/inet_addr.h>
93 #include <epan/strutil.h>
94 #include <epan/to_str-int.h>
95 #include <epan/maxmind_db.h>
96 #include <epan/prefs.h>
98 #define ENAME_HOSTS "hosts"
99 #define ENAME_SUBNETS "subnets"
100 #define ENAME_ETHERS "ethers"
101 #define ENAME_IPXNETS "ipxnets"
102 #define ENAME_MANUF "manuf"
103 #define ENAME_WKA "wka"
104 #define ENAME_SERVICES "services"
105 #define ENAME_VLANS "vlans"
106 #define ENAME_SS7PCS "ss7pcs"
107 #define ENAME_ENTERPRISES "enterprises.tsv"
109 #define HASHETHSIZE 2048
110 #define HASHHOSTSIZE 2048
111 #define HASHIPXNETSIZE 256
112 #define SUBNETLENGTHSIZE 32 /*1-32 inc.*/
114 /* hash table used for IPv4 lookup */
116 #define HASH_IPV4_ADDRESS(addr) (g_htonl(addr) & (HASHHOSTSIZE - 1))
119 typedef struct sub_net_hashipv4 {
121 /* XXX: No longer needed?*/
122 guint8 flags; /* B0 dummy_entry, B1 resolve, B2 If the address is used in the trace */
123 struct sub_net_hashipv4 *next;
124 gchar name[MAXNAMELEN];
125 } sub_net_hashipv4_t;
127 /* Array of entries of subnets of different lengths */
129 gsize mask_length; /*1-32*/
130 guint32 mask; /* e.g. 255.255.255.*/
131 sub_net_hashipv4_t** subnet_addresses; /* Hash table of subnet addresses */
132 } subnet_length_entry_t;
135 /* hash table used for IPX network lookup */
137 /* XXX - check goodness of hash function */
139 #define HASH_IPX_NET(net) ((net) & (HASHIPXNETSIZE - 1))
141 typedef struct hashipxnet {
143 struct hashipxnet *next;
144 gchar name[MAXNAMELEN];
147 typedef struct hashvlan {
149 /* struct hashvlan *next; */
150 gchar name[MAXVLANNAMELEN];
153 typedef struct ss7pc {
154 guint32 id; /* 1st byte NI, 3 following bytes: Point Code */
155 gchar pc_addr[MAXNAMELEN];
156 gchar name[MAXNAMELEN];
159 /* hash tables used for ethernet and manufacturer lookup */
160 #define HASHETHER_STATUS_UNRESOLVED 1
161 #define HASHETHER_STATUS_RESOLVED_DUMMY 2
162 #define HASHETHER_STATUS_RESOLVED_NAME 3
165 guint status; /* (See above) */
168 char resolved_name[MAXNAMELEN];
172 guint status; /* (See above) */
175 char resolved_name[MAXNAMELEN];
176 char resolved_longname[MAXNAMELEN];
179 /* internal ethernet type */
180 typedef struct _ether
183 char name[MAXNAMELEN];
184 char longname[MAXNAMELEN];
187 /* internal ipxnet type */
188 typedef struct _ipxnet
191 char name[MAXNAMELEN];
194 /* internal vlan type */
198 char name[MAXVLANNAMELEN];
201 // Maps guint -> hashipxnet_t*
202 static wmem_map_t *ipxnet_hash_table = NULL;
203 static wmem_map_t *ipv4_hash_table = NULL;
204 static wmem_map_t *ipv6_hash_table = NULL;
205 // Maps guint -> hashvlan_t*
206 static wmem_map_t *vlan_hash_table = NULL;
207 static wmem_map_t *ss7pc_hash_table = NULL;
209 static wmem_list_t *manually_resolved_ipv4_list = NULL;
210 static wmem_list_t *manually_resolved_ipv6_list = NULL;
212 typedef struct _resolved_ipv4
215 char name[MAXNAMELEN];
218 typedef struct _resolved_ipv6
220 ws_in6_addr ip6_addr;
221 char name[MAXNAMELEN];
224 static addrinfo_lists_t addrinfo_lists = { NULL, NULL};
226 struct cb_serv_data {
231 // Maps guint -> hashmanuf_t*
232 static wmem_map_t *manuf_hashtable = NULL;
233 static wmem_map_t *wka_hashtable = NULL;
234 static wmem_map_t *eth_hashtable = NULL;
235 // Maps guint -> serv_port_t*
236 static wmem_map_t *serv_port_hashtable = NULL;
237 static GHashTable *enterprises_hashtable = NULL;
239 static subnet_length_entry_t subnet_length_entries[SUBNETLENGTHSIZE]; /* Ordered array of entries */
240 static gboolean have_subnet_entry = FALSE;
242 static gboolean new_resolved_objects = FALSE;
244 static GPtrArray* extra_hosts_files = NULL;
246 static hashether_t *add_eth_name(const guint8 *addr, const gchar *name);
247 static void add_serv_port_cb(const guint32 port, gpointer ptr);
250 /* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx#existing
254 ipv6_oat_hash(gconstpointer key)
257 const unsigned char *p = (const unsigned char *)key;
261 for ( i = 0; i < len; i++ ) {
275 ipv6_equal(gconstpointer v1, gconstpointer v2)
278 if (memcmp(v1, v2, sizeof (ws_in6_addr)) == 0) {
286 * Flag controlling what names to resolve.
288 e_addr_resolve gbl_resolv_flags = {
290 FALSE, /* network_name */
291 FALSE, /* transport_name */
292 TRUE, /* dns_pkt_addr_resolution */
293 TRUE, /* use_external_net_name_resolver */
294 FALSE, /* load_hosts_file_from_profile_only */
295 FALSE, /* vlan_name */
296 FALSE /* ss7 point code names */
299 static guint name_resolve_concurrency = 500;
300 static gboolean resolve_synchronously = FALSE;
304 * Global variables (can be changed in GUI sections)
305 * XXX - they could be changed in GUI code, but there's currently no
306 * GUI code to change them.
309 gchar *g_ethers_path = NULL; /* global ethers file */
310 gchar *g_pethers_path = NULL; /* personal ethers file */
311 gchar *g_wka_path = NULL; /* global well-known-addresses file */
312 gchar *g_manuf_path = NULL; /* global manuf file */
313 gchar *g_ipxnets_path = NULL; /* global ipxnets file */
314 gchar *g_pipxnets_path = NULL; /* personal ipxnets file */
315 gchar *g_services_path = NULL; /* global services file */
316 gchar *g_pservices_path = NULL; /* personal services file */
317 gchar *g_pvlan_path = NULL; /* personal vlans file */
318 gchar *g_ss7pcs_path = NULL; /* personal ss7pcs file */
319 gchar *g_enterprises_path = NULL; /* global enterprises file */
320 gchar *g_penterprises_path = NULL; /* personal enterprises file */
321 /* first resolving call */
326 * Submitted asynchronous queries trigger a callback (c_ares_ghba_cb()).
327 * Queries are added to c_ares_queue_head. During processing, queries are
328 * popped off the front of c_ares_queue_head and submitted using
329 * ares_gethostbyaddr().
330 * The callback processes the response, then frees the request.
332 typedef struct _async_dns_queue_msg
339 } async_dns_queue_msg_t;
341 typedef struct _async_hostent {
348 * Submitted synchronous queries trigger a callback (c_ares_ghba_sync_cb()).
349 * The callback processes the response, sets completed to TRUE if
350 * completed is non-NULL, then frees the request.
352 typedef struct _sync_dns_data
362 static ares_channel ghba_chan; /* ares_gethostbyaddr -- Usually non-interactive, no timeout */
363 static ares_channel ghbn_chan; /* ares_gethostbyname -- Usually interactive, timeout */
365 static gboolean async_dns_initialized = FALSE;
366 static guint async_dns_in_flight = 0;
367 static wmem_list_t *async_dns_queue_head = NULL;
370 c_ares_ghba_sync_cb(void *arg, int status, int timeouts _U_, struct hostent *he) {
371 sync_dns_data_t *sdd = (sync_dns_data_t *)arg;
374 if (status == ARES_SUCCESS) {
375 for (p = he->h_addr_list; *p != NULL; p++) {
376 switch(sdd->family) {
378 add_ipv4_name(sdd->addr.ip4, he->h_name);
381 add_ipv6_name(&sdd->addr.ip6, he->h_name);
384 /* Throw an exception? */
392 * Let our caller know that this is complete.
394 *sdd->completed = TRUE;
397 * Free the structure for this call.
403 wait_for_sync_resolv(gboolean *completed) {
408 while (!*completed) {
410 * Not yet resolved; wait for something to show up on the
411 * address-to-name C-ARES channel.
413 * To quote the source code for ares_timeout() as of C-ARES
414 * 1.12.0, "WARNING: Beware that this is linear in the number
415 * of outstanding requests! You are probably far better off
416 * just calling ares_process() once per second, rather than
417 * calling ares_timeout() to figure out when to next call
418 * ares_process().", although we should have only one request
421 * And, yes, we have to reset it each time, as select(), in
422 * some OSes modifies the timeout to reflect the time remaining
423 * (e.g., Linux) and select() in other OSes doesn't (most if not
424 * all other UN*Xes, Windows?), so we can't rely on *either*
432 nfds = ares_fds(ghba_chan, &rfds, &wfds);
434 if (select(nfds, &rfds, &wfds, NULL, &tv) == -1) { /* call to select() failed */
435 fprintf(stderr, "Warning: call to select() failed, error is %s\n", g_strerror(errno));
438 ares_process(ghba_chan, &rfds, &wfds);
444 sync_lookup_ip4(const guint32 addr)
446 gboolean completed = FALSE;
447 sync_dns_data_t *sdd;
449 if (!async_dns_initialized) {
451 * c-ares not initialized. Bail out.
459 sdd = g_new(sync_dns_data_t, 1);
460 sdd->family = AF_INET;
461 sdd->addr.ip4 = addr;
462 sdd->completed = &completed;
463 ares_gethostbyaddr(ghba_chan, &addr, sizeof(guint32), AF_INET,
464 c_ares_ghba_sync_cb, sdd);
467 * Now wait for it to finish.
469 wait_for_sync_resolv(&completed);
473 sync_lookup_ip6(const ws_in6_addr *addr)
475 gboolean completed = FALSE;
476 sync_dns_data_t *sdd;
478 if (!async_dns_initialized) {
480 * c-ares not initialized. Bail out.
488 sdd = g_new(sync_dns_data_t, 1);
489 sdd->family = AF_INET6;
490 memcpy(&sdd->addr.ip6, addr, sizeof(sdd->addr.ip6));
491 sdd->completed = &completed;
492 ares_gethostbyaddr(ghba_chan, &addr, sizeof(ws_in6_addr), AF_INET6,
493 c_ares_ghba_sync_cb, sdd);
496 * Now wait for it to finish.
498 wait_for_sync_resolv(&completed);
502 set_resolution_synchrony(gboolean synchronous)
504 resolve_synchronously = synchronous;
508 set_resolution_synchrony(gboolean synchronous _U_)
510 /* Nothing to set. */
512 #endif /* HAVE_C_ARES */
517 const gchar* name; /* Shallow copy */
520 /* Maximum supported line length of hosts, services, manuf, etc. */
521 #define MAX_LINELEN 1024
523 /** Read a line without trailing (CR)LF. Returns -1 on failure. */
525 fgetline(char *buf, int size, FILE *fp)
527 if (fgets(buf, size, fp)) {
528 int len = (int)strcspn(buf, "\r\n");
538 * Local function definitions
540 static subnet_entry_t subnet_lookup(const guint32 addr);
541 static void subnet_entry_set(guint32 subnet_addr, const guint8 mask_length, const gchar* name);
545 add_service_name(port_type proto, const guint port, const char *service_name)
547 serv_port_t *serv_port_table;
549 serv_port_table = (serv_port_t *)wmem_map_lookup(serv_port_hashtable, GUINT_TO_POINTER(port));
550 if (serv_port_table == NULL) {
551 serv_port_table = wmem_new0(wmem_epan_scope(), serv_port_t);
552 wmem_map_insert(serv_port_hashtable, GUINT_TO_POINTER(port), serv_port_table);
557 wmem_free(wmem_epan_scope(), serv_port_table->tcp_name);
558 serv_port_table->tcp_name = wmem_strdup(wmem_epan_scope(), service_name);
561 wmem_free(wmem_epan_scope(), serv_port_table->udp_name);
562 serv_port_table->udp_name = wmem_strdup(wmem_epan_scope(), service_name);
565 wmem_free(wmem_epan_scope(), serv_port_table->sctp_name);
566 serv_port_table->sctp_name = wmem_strdup(wmem_epan_scope(), service_name);
569 wmem_free(wmem_epan_scope(), serv_port_table->dccp_name);
570 serv_port_table->dccp_name = wmem_strdup(wmem_epan_scope(), service_name);
574 /* Should not happen */
577 new_resolved_objects = TRUE;
582 parse_service_line (char *line)
588 struct cb_serv_data cb_data;
589 range_t *port_rng = NULL;
591 if ((cp = strchr(line, '#')))
594 if ((cp = strtok(line, " \t")) == NULL)
599 if ((cp = strtok(NULL, " \t")) == NULL)
604 if (strtok(cp, "/") == NULL)
607 if (range_convert_str(NULL, &port_rng, port, G_MAXUINT16) != CVT_NO_ERROR) {
608 wmem_free (NULL, port_rng);
612 while ((cp = strtok(NULL, "/")) != NULL) {
613 if (strcmp(cp, "tcp") == 0) {
616 else if (strcmp(cp, "udp") == 0) {
619 else if (strcmp(cp, "sctp") == 0) {
622 else if (strcmp(cp, "dccp") == 0) {
628 cb_data.service = service;
629 cb_data.proto = proto;
630 range_foreach(port_rng, add_serv_port_cb, &cb_data);
633 wmem_free (NULL, port_rng);
634 } /* parse_service_line */
638 add_serv_port_cb(const guint32 port, gpointer ptr)
640 struct cb_serv_data *cb_data = (struct cb_serv_data *)ptr;
643 add_service_name(cb_data->proto, port, cb_data->service);
649 parse_services_file(const char * path)
652 char buf[MAX_LINELEN];
654 /* services hash table initialization */
655 serv_p = ws_fopen(path, "r");
660 while (fgetline(buf, sizeof(buf), serv_p) >= 0) {
661 parse_service_line(buf);
669 * unsigned integer to ascii
672 wmem_utoa(wmem_allocator_t *allocator, guint port)
674 gchar *bp = (gchar *)wmem_alloc(allocator, MAXNAMELEN);
676 /* XXX, guint32_to_str() ? */
677 guint32_to_str_buf(port, bp, MAXNAMELEN);
682 _serv_name_lookup(port_type proto, guint port, serv_port_t **value_ret)
684 serv_port_t *serv_port_table;
686 serv_port_table = (serv_port_t *)wmem_map_lookup(serv_port_hashtable, GUINT_TO_POINTER(port));
688 if (value_ret != NULL)
689 *value_ret = serv_port_table;
691 if (serv_port_table == NULL)
696 return serv_port_table->udp_name;
698 return serv_port_table->tcp_name;
700 return serv_port_table->sctp_name;
702 return serv_port_table->dccp_name;
710 try_serv_name_lookup(port_type proto, guint port)
712 return _serv_name_lookup(proto, port, NULL);
716 serv_name_lookup(port_type proto, guint port)
718 serv_port_t *serv_port_table = NULL;
721 name = _serv_name_lookup(proto, port, &serv_port_table);
725 if (serv_port_table == NULL) {
726 serv_port_table = wmem_new0(wmem_epan_scope(), serv_port_t);
727 wmem_map_insert(serv_port_hashtable, GUINT_TO_POINTER(port), serv_port_table);
729 if (serv_port_table->numeric == NULL) {
730 serv_port_table->numeric = wmem_strdup_printf(wmem_epan_scope(), "%u", port);
733 return serv_port_table->numeric;
737 initialize_services(void)
739 gboolean parse_file = TRUE;
740 g_assert(serv_port_hashtable == NULL);
741 serv_port_hashtable = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
743 /* Compute the pathname of the services file. */
744 if (g_services_path == NULL) {
745 g_services_path = get_datafile_path(ENAME_SERVICES);
747 parse_services_file(g_services_path);
749 /* Compute the pathname of the personal services file */
750 if (g_pservices_path == NULL) {
751 /* Check profile directory before personal configuration */
752 g_pservices_path = get_persconffile_path(ENAME_SERVICES, TRUE);
753 if (!parse_services_file(g_pservices_path)) {
754 g_free(g_pservices_path);
755 g_pservices_path = get_persconffile_path(ENAME_SERVICES, FALSE);
761 parse_services_file(g_pservices_path);
766 service_name_lookup_cleanup(void)
768 serv_port_hashtable = NULL;
769 g_free(g_services_path);
770 g_services_path = NULL;
771 g_free(g_pservices_path);
772 g_pservices_path = NULL;
776 parse_enterprises_line (char *line)
778 char *tok, *dec_str, *org_str;
781 if ((tok = strchr(line, '#')))
783 dec_str = strtok(line, " \t");
786 org_str = strtok(NULL, ""); /* everything else */
788 org_str = g_strstrip(org_str);
791 if (!ws_strtou32(dec_str, NULL, &dec))
793 g_hash_table_replace(enterprises_hashtable, GUINT_TO_POINTER(dec), g_strdup(org_str));
798 parse_enterprises_file(const char * path)
801 char buf[MAX_LINELEN];
803 fp = ws_fopen(path, "r");
807 while (fgetline(buf, sizeof(buf), fp) >= 0) {
808 parse_enterprises_line(buf);
816 initialize_enterprises(void)
818 g_assert(enterprises_hashtable == NULL);
819 enterprises_hashtable = g_hash_table_new_full(NULL, NULL, NULL, g_free);
821 if (g_enterprises_path == NULL) {
822 g_enterprises_path = get_datafile_path(ENAME_ENTERPRISES);
824 parse_enterprises_file(g_enterprises_path);
826 if (g_penterprises_path == NULL) {
827 g_penterprises_path = get_persconffile_path(ENAME_ENTERPRISES, FALSE);
829 parse_enterprises_file(g_penterprises_path);
833 try_enterprises_lookup(guint32 value)
835 return (const gchar *)g_hash_table_lookup(enterprises_hashtable, GUINT_TO_POINTER(value));
839 enterprises_lookup(guint32 value, const char *unknown_str)
843 s = try_enterprises_lookup(value);
846 if (unknown_str != NULL)
852 enterprises_base_custom(char *buf, guint32 value)
856 if ((s = try_enterprises_lookup(value)) == NULL)
857 s = ITEM_LABEL_UNKNOWN_STR;
858 g_snprintf(buf, ITEM_LABEL_LENGTH, "%s (%u)", s, value);
862 enterprises_cleanup(void)
864 g_assert(enterprises_hashtable);
865 g_hash_table_destroy(enterprises_hashtable);
866 enterprises_hashtable = NULL;
867 g_assert(g_enterprises_path);
868 g_free(g_enterprises_path);
869 g_enterprises_path = NULL;
870 g_free(g_penterprises_path);
871 g_penterprises_path = NULL;
872 g_free(g_pservices_path);
873 g_pservices_path = NULL;
876 /* Fill in an IP4 structure with info from subnets file or just with the
877 * string form of the address.
880 fill_dummy_ip4(const guint addr, hashipv4_t* volatile tp)
882 subnet_entry_t subnet_entry;
884 /* Overwrite if we get async DNS reply */
886 /* Do we have a subnet for this address? */
887 subnet_entry = subnet_lookup(addr);
888 if (0 != subnet_entry.mask) {
889 /* Print name, then '.' then IP address after subnet mask */
891 gchar buffer[WS_INET_ADDRSTRLEN];
895 host_addr = addr & (~subnet_entry.mask);
896 ip_to_str_buf((guint8 *)&host_addr, buffer, WS_INET_ADDRSTRLEN);
899 /* Skip to first octet that is not totally masked
900 * If length of mask is 32, we chomp the whole address.
901 * If the address string starts '.' (should not happen?),
904 i = subnet_entry.mask_length / 8;
905 while(*(paddr) != '\0' && i > 0) {
906 if (*(++paddr) == '.') {
911 /* There are more efficient ways to do this, but this is safe if we
912 * trust g_snprintf and MAXNAMELEN
914 g_snprintf(tp->name, MAXNAMELEN, "%s%s", subnet_entry.name, paddr);
916 /* XXX: This means we end up printing "1.2.3.4 (1.2.3.4)" in many cases */
917 ip_to_str_buf((const guint8 *)&addr, tp->name, MAXNAMELEN);
922 /* Fill in an IP6 structure with the string form of the address.
925 fill_dummy_ip6(hashipv6_t* volatile tp)
927 /* Overwrite if we get async DNS reply */
928 g_strlcpy(tp->name, tp->ip6, MAXNAMELEN);
934 c_ares_ghba_cb(void *arg, int status, int timeouts _U_, struct hostent *he) {
935 async_dns_queue_msg_t *caqm = (async_dns_queue_msg_t *)arg;
939 /* XXX, what to do if async_dns_in_flight == 0? */
940 async_dns_in_flight--;
942 if (status == ARES_SUCCESS) {
943 for (p = he->h_addr_list; *p != NULL; p++) {
944 switch(caqm->family) {
946 add_ipv4_name(caqm->addr.ip4, he->h_name);
949 add_ipv6_name(&caqm->addr.ip6, he->h_name);
952 /* Throw an exception? */
957 wmem_free(wmem_epan_scope(), caqm);
959 #endif /* HAVE_C_ARES */
961 /* --------------- */
963 new_ipv4(const guint addr)
965 hashipv4_t *tp = wmem_new(wmem_epan_scope(), hashipv4_t);
969 ip_to_str_buf((const guint8 *)&addr, tp->ip, sizeof(tp->ip));
974 host_lookup(const guint addr)
976 hashipv4_t * volatile tp;
978 tp = (hashipv4_t *)wmem_map_lookup(ipv4_hash_table, GUINT_TO_POINTER(addr));
981 * We don't already have an entry for this host name; create one,
982 * and then try to resolve it.
985 fill_dummy_ip4(addr, tp);
986 wmem_map_insert(ipv4_hash_table, GUINT_TO_POINTER(addr), tp);
987 } else if (tp->flags & TRIED_OR_RESOLVED_MASK) {
992 * This hasn't been resolved yet, and we haven't tried to
993 * resolve it already.
996 if (!gbl_resolv_flags.network_name)
999 if (gbl_resolv_flags.use_external_net_name_resolver) {
1000 tp->flags |= TRIED_RESOLVE_ADDRESS;
1003 if (async_dns_initialized) {
1004 /* c-ares is initialized, so we can use it */
1005 if (resolve_synchronously || name_resolve_concurrency == 0) {
1007 * Either all names are to be resolved synchronously or
1008 * the concurrencly level is 0; do the resolution
1011 sync_lookup_ip4(addr);
1014 * Names are to be resolved asynchronously, and we
1015 * allow at least one asynchronous request in flight;
1016 * post an asynchronous request.
1018 async_dns_queue_msg_t *caqm;
1020 caqm = wmem_new(wmem_epan_scope(), async_dns_queue_msg_t);
1021 caqm->family = AF_INET;
1022 caqm->addr.ip4 = addr;
1023 wmem_list_append(async_dns_queue_head, (gpointer) caqm);
1033 /* --------------- */
1035 new_ipv6(const ws_in6_addr *addr)
1037 hashipv6_t *tp = wmem_new(wmem_epan_scope(), hashipv6_t);
1038 memcpy(tp->addr, addr->bytes, sizeof tp->addr);
1041 ip6_to_str_buf(addr, tp->ip6, sizeof(tp->ip6));
1045 /* ------------------------------------ */
1047 host_lookup6(const ws_in6_addr *addr)
1049 hashipv6_t * volatile tp;
1051 tp = (hashipv6_t *)wmem_map_lookup(ipv6_hash_table, addr);
1054 * We don't already have an entry for this host name; create one,
1055 * and then try to resolve it.
1057 ws_in6_addr *addr_key;
1059 addr_key = wmem_new(wmem_epan_scope(), ws_in6_addr);
1060 tp = new_ipv6(addr);
1061 memcpy(addr_key, addr, 16);
1063 wmem_map_insert(ipv6_hash_table, addr_key, tp);
1064 } else if (tp->flags & TRIED_OR_RESOLVED_MASK) {
1069 * This hasn't been resolved yet, and we haven't tried to
1070 * resolve it already.
1073 if (!gbl_resolv_flags.network_name)
1076 if (gbl_resolv_flags.use_external_net_name_resolver) {
1077 tp->flags |= TRIED_RESOLVE_ADDRESS;
1080 if (async_dns_initialized) {
1081 /* c-ares is initialized, so we can use it */
1082 if (resolve_synchronously || name_resolve_concurrency == 0) {
1084 * Either all names are to be resolved synchronously or
1085 * the concurrencly level is 0; do the resolution
1088 sync_lookup_ip6(addr);
1091 * Names are to be resolved asynchronously, and we
1092 * allow at least one asynchronous request in flight;
1093 * post an asynchronous request.
1095 async_dns_queue_msg_t *caqm;
1097 caqm = wmem_new(wmem_epan_scope(), async_dns_queue_msg_t);
1098 caqm->family = AF_INET6;
1099 memcpy(&caqm->addr.ip6, addr, sizeof(caqm->addr.ip6));
1100 wmem_list_append(async_dns_queue_head, (gpointer) caqm);
1108 } /* host_lookup6 */
1111 * Ethernet / manufacturer resolution
1113 * The following functions implement ethernet address resolution and
1114 * ethers files parsing (see ethers(4)).
1116 * The manuf file has the same format as ethers(4) except that names are
1117 * truncated to MAXMANUFLEN-1 (8) characters and that an address contains
1118 * only 3 bytes (instead of 6).
1122 * I decide to not use the existing functions (see ethers(3) on some
1123 * operating systems) for the following reasons:
1124 * - performance gains (use of hash tables and some other enhancements),
1125 * - use of two ethers files (system-wide and per user),
1126 * - avoid the use of NIS maps,
1127 * - lack of these functions on some systems.
1129 * So the following functions do _not_ behave as the standard ones.
1135 * Converts Ethernet addresses of the form aa:bb:cc or aa:bb:cc:dd:ee:ff/28. The
1136 * octets must be exactly two hexadecimal characters and the mask must be either
1137 * 28 or 36. Pre-condition: cp MUST be at least 21 bytes.
1140 parse_ether_address_fast(const guchar *cp, ether_t *eth, unsigned int *mask,
1141 const gboolean accept_mask)
1143 /* XXX copied from strutil.c */
1144 /* a map from ASCII hex chars to their value */
1145 static const gint8 str_to_nibble[256] = {
1146 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1147 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1148 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1149 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
1150 -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1151 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1152 -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1153 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1154 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1155 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1156 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1157 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1158 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1159 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1160 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
1161 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
1163 const guint8 *str_to_nibble_usg = (const guint8 *)str_to_nibble;
1165 if (cp[2] != ':' || cp[5] != ':') {
1166 /* Unexpected separators. */
1170 guint8 num0 = (str_to_nibble_usg[cp[0]] << 4) | str_to_nibble_usg[cp[1]];
1171 guint8 num1 = (str_to_nibble_usg[cp[3]] << 4) | str_to_nibble_usg[cp[4]];
1172 guint8 num2 = (str_to_nibble_usg[cp[6]] << 4) | str_to_nibble_usg[cp[7]];
1173 if (((num0 | num1 | num2) & 0x80)) {
1174 /* Not hexadecimal numbers. */
1178 eth->addr[0] = num0;
1179 eth->addr[1] = num1;
1180 eth->addr[2] = num2;
1182 if (cp[8] == '\0' && accept_mask) {
1183 /* Indicate that this is a manufacturer ID (0 is not allowed as a mask). */
1186 } else if (cp[8] != ':' || !accept_mask) {
1187 /* Format not handled by this fast path. */
1191 guint8 num3 = (str_to_nibble_usg[cp[9]] << 4) | str_to_nibble_usg[cp[10]];
1192 guint8 num4 = (str_to_nibble_usg[cp[12]] << 4) | str_to_nibble_usg[cp[13]];
1193 guint8 num5 = (str_to_nibble_usg[cp[15]] << 4) | str_to_nibble_usg[cp[16]];
1194 if (((num3 | num4 | num5) & 0x80) || cp[11] != ':' || cp[14] != ':') {
1195 /* Not hexadecimal numbers or invalid separators. */
1199 eth->addr[3] = num3;
1200 eth->addr[4] = num4;
1201 eth->addr[5] = num5;
1202 if (cp[17] == '\0') {
1203 /* We got 6 bytes, so this is a MAC address (48 is not allowed as a mask). */
1206 } else if (cp[17] != '/' || cp[20] != '\0') {
1207 /* Format not handled by this fast path. */
1213 if (m1 == '3' && m2 == '6') { /* Mask /36 */
1214 eth->addr[4] &= 0xf0;
1219 if (m1 == '2' && m2 == '8') { /* Mask /28 */
1220 eth->addr[3] &= 0xf0;
1226 /* Unsupported mask */
1231 * If "accept_mask" is FALSE, cp must point to an address that consists
1232 * of exactly 6 bytes.
1233 * If "accept_mask" is TRUE, parse an up-to-6-byte sequence with an optional
1237 parse_ether_address(const char *cp, ether_t *eth, unsigned int *mask,
1238 const gboolean accept_mask)
1245 for (i = 0; i < 6; i++) {
1246 /* Get a hex number, 1 or 2 digits, no sign characters allowed. */
1247 if (!g_ascii_isxdigit(*cp))
1249 num = strtoul(cp, &p, 16);
1251 return FALSE; /* failed */
1253 return FALSE; /* not a valid octet */
1254 eth->addr[i] = (guint8) num;
1255 cp = p; /* skip past the number */
1257 /* OK, what character terminated the octet? */
1259 /* "/" - this has a mask. */
1261 /* Entries with masks are not allowed in this file. */
1264 cp++; /* skip past the '/' to get to the mask */
1265 if (!g_ascii_isdigit(*cp))
1266 return FALSE; /* no sign allowed */
1267 num = strtoul(cp, &p, 10);
1269 return FALSE; /* failed */
1270 cp = p; /* skip past the number */
1271 if (*cp != '\0' && !g_ascii_isspace(*cp))
1272 return FALSE; /* bogus terminator */
1273 if (num == 0 || num >= 48)
1274 return FALSE; /* bogus mask */
1275 /* Mask out the bits not covered by the mask */
1277 for (i = 0; num >= 8; i++, num -= 8)
1278 ; /* skip octets entirely covered by the mask */
1279 /* Mask out the first masked octet */
1280 eth->addr[i] &= (0xFF << (8 - num));
1282 /* Mask out completely-masked-out octets */
1288 /* We're at the end of the address, and there's no mask. */
1290 /* We got 3 bytes, so this is a manufacturer ID. */
1292 /* Manufacturer IDs are not allowed in this file */
1295 /* Indicate that this is a manufacturer ID (0 is not allowed
1302 /* We got 6 bytes, so this is a MAC address (48 is not allowed as a mask). */
1308 /* We didn't get 3 or 6 bytes, and there's no mask; this is
1313 /* We don't know the separator used in this number; it can either
1314 be ':', '-', or '.'. */
1315 if (*cp != ':' && *cp != '-' && *cp != '.')
1317 sep = *cp; /* subsequent separators must be the same */
1319 /* It has to be the same as the first separator */
1331 parse_ether_line(char *line, ether_t *eth, unsigned int *mask,
1332 const gboolean accept_mask)
1335 * See the ethers(4) or ethers(5) man page for ethers file format
1336 * (not available on all systems).
1337 * We allow both ethernet address separators (':' and '-'),
1338 * as well as Wireshark's '.' separator.
1343 line = g_strstrip(line);
1344 if (line[0] == '\0' || line[0] == '#')
1347 if ((cp = strchr(line, '#'))) {
1352 if ((cp = strtok(line, " \t")) == NULL)
1355 /* First try to match the common format for the large ethers file. */
1356 if (!parse_ether_address_fast(cp, eth, mask, accept_mask)) {
1357 /* Fallback for the well-known addresses (wka) file. */
1358 if (!parse_ether_address(cp, eth, mask, accept_mask))
1362 if ((cp = strtok(NULL, " \t")) == NULL)
1365 g_strlcpy(eth->name, cp, MAXNAMELEN);
1367 if ((cp = strtok(NULL, "\t")) != NULL)
1369 g_strlcpy(eth->longname, cp, MAXNAMELEN);
1371 /* Make the long name the short name */
1372 g_strlcpy(eth->longname, eth->name, MAXNAMELEN);
1377 } /* parse_ether_line */
1379 static FILE *eth_p = NULL;
1382 set_ethent(char *path)
1387 eth_p = ws_fopen(path, "r");
1400 get_ethent(unsigned int *mask, const gboolean accept_mask)
1404 char buf[MAX_LINELEN];
1409 while (fgetline(buf, sizeof(buf), eth_p) >= 0) {
1410 if (parse_ether_line(buf, ð, mask, accept_mask) == 0) {
1420 get_ethbyaddr(const guint8 *addr)
1425 set_ethent(g_pethers_path);
1427 while (((eth = get_ethent(NULL, FALSE)) != NULL) && memcmp(addr, eth->addr, 6) != 0)
1433 set_ethent(g_ethers_path);
1435 while (((eth = get_ethent(NULL, FALSE)) != NULL) && memcmp(addr, eth->addr, 6) != 0)
1443 } /* get_ethbyaddr */
1445 static hashmanuf_t *
1446 manuf_hash_new_entry(const guint8 *addr, char* name, char* longname)
1449 hashmanuf_t *manuf_value;
1452 /* manuf needs only the 3 most significant octets of the ethernet address */
1453 manuf_key = (addr[0] << 16) + (addr[1] << 8) + addr[2];
1454 manuf_value = wmem_new(wmem_epan_scope(), hashmanuf_t);
1456 memcpy(manuf_value->addr, addr, 3);
1458 g_strlcpy(manuf_value->resolved_name, name, MAXNAMELEN);
1459 manuf_value->status = HASHETHER_STATUS_RESOLVED_NAME;
1460 if (longname != NULL) {
1461 g_strlcpy(manuf_value->resolved_longname, longname, MAXNAMELEN);
1464 g_strlcpy(manuf_value->resolved_longname, name, MAXNAMELEN);
1468 manuf_value->status = HASHETHER_STATUS_UNRESOLVED;
1469 manuf_value->resolved_name[0] = '\0';
1470 manuf_value->resolved_longname[0] = '\0';
1472 /* Values returned by bytes_to_hexstr_punct() are *not* null-terminated */
1473 endp = bytes_to_hexstr_punct(manuf_value->hexaddr, addr, sizeof(manuf_value->addr), ':');
1476 wmem_map_insert(manuf_hashtable, GUINT_TO_POINTER(manuf_key), manuf_value);
1481 wka_hash_new_entry(const guint8 *addr, char* name)
1485 wka_key = (guint8 *)wmem_alloc(wmem_epan_scope(), 6);
1486 memcpy(wka_key, addr, 6);
1488 wmem_map_insert(wka_hashtable, wka_key, wmem_strdup(wmem_epan_scope(), name));
1492 add_manuf_name(const guint8 *addr, unsigned int mask, gchar *name, gchar *longname)
1497 /* This is a manufacturer ID; add it to the manufacturer ID hash table */
1498 manuf_hash_new_entry(addr, name, longname);
1502 /* This is a well-known MAC address; add it to the Ethernet hash table */
1503 add_eth_name(addr, name);
1507 /* This is a range of well-known addresses; add it to the well-known-address table */
1508 wka_hash_new_entry(addr, name);
1511 } /* add_manuf_name */
1513 static hashmanuf_t *
1514 manuf_name_lookup(const guint8 *addr)
1518 hashmanuf_t *manuf_value;
1520 /* manuf needs only the 3 most significant octets of the ethernet address */
1521 manuf_key = addr[0];
1522 manuf_key = manuf_key<<8;
1524 manuf_key = manuf_key | oct;
1525 manuf_key = manuf_key<<8;
1527 manuf_key = manuf_key | oct;
1530 /* first try to find a "perfect match" */
1531 manuf_value = (hashmanuf_t*)wmem_map_lookup(manuf_hashtable, GUINT_TO_POINTER(manuf_key));
1532 if (manuf_value != NULL) {
1536 /* Mask out the broadcast/multicast flag but not the locally
1537 * administered flag as locally administered means: not assigned
1538 * by the IEEE but the local administrator instead.
1539 * 0x01 multicast / broadcast bit
1540 * 0x02 locally administered bit */
1541 if ((manuf_key & 0x00010000) != 0) {
1542 manuf_key &= 0x00FEFFFF;
1543 manuf_value = (hashmanuf_t*)wmem_map_lookup(manuf_hashtable, GUINT_TO_POINTER(manuf_key));
1544 if (manuf_value != NULL) {
1549 /* Add the address as a hex string */
1550 return manuf_hash_new_entry(addr, NULL, NULL);
1552 } /* manuf_name_lookup */
1555 wka_name_lookup(const guint8 *addr, const unsigned int mask)
1557 guint8 masked_addr[6];
1562 if (wka_hashtable == NULL) {
1565 /* Get the part of the address covered by the mask. */
1566 for (i = 0, num = mask; num >= 8; i++, num -= 8)
1567 masked_addr[i] = addr[i]; /* copy octets entirely covered by the mask */
1568 /* Mask out the first masked octet */
1569 masked_addr[i] = addr[i] & (0xFF << (8 - num));
1571 /* Zero out completely-masked-out octets */
1575 name = (gchar *)wmem_map_lookup(wka_hashtable, masked_addr);
1579 } /* wka_name_lookup */
1582 guint get_hash_ether_status(hashether_t* ether)
1584 return ether->status;
1587 char* get_hash_ether_hexaddr(hashether_t* ether)
1589 return ether->hexaddr;
1592 char* get_hash_ether_resolved_name(hashether_t* ether)
1594 return ether->resolved_name;
1598 eth_addr_hash(gconstpointer key)
1600 return wmem_strong_hash((const guint8 *)key, 6);
1604 eth_addr_cmp(gconstpointer a, gconstpointer b)
1606 return (memcmp(a, b, 6) == 0);
1610 initialize_ethers(void)
1615 /* hash table initialization */
1616 wka_hashtable = wmem_map_new(wmem_epan_scope(), eth_addr_hash, eth_addr_cmp);
1617 manuf_hashtable = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
1618 eth_hashtable = wmem_map_new(wmem_epan_scope(), eth_addr_hash, eth_addr_cmp);
1620 /* Compute the pathname of the ethers file. */
1621 if (g_ethers_path == NULL) {
1622 g_ethers_path = g_build_filename(get_systemfile_dir(), ENAME_ETHERS, NULL);
1625 /* Set g_pethers_path here, but don't actually do anything
1626 * with it. It's used in get_ethbyaddr().
1628 if (g_pethers_path == NULL)
1629 g_pethers_path = get_persconffile_path(ENAME_ETHERS, FALSE);
1631 /* Compute the pathname of the manuf file */
1632 if (g_manuf_path == NULL)
1633 g_manuf_path = get_datafile_path(ENAME_MANUF);
1635 /* Read it and initialize the hash table */
1636 set_ethent(g_manuf_path);
1637 while ((eth = get_ethent(&mask, TRUE))) {
1638 add_manuf_name(eth->addr, mask, eth->name, eth->longname);
1642 /* Compute the pathname of the wka file */
1643 if (g_wka_path == NULL)
1644 g_wka_path = get_datafile_path(ENAME_WKA);
1646 /* Read it and initialize the hash table */
1647 set_ethent(g_wka_path);
1648 while ((eth = get_ethent(&mask, TRUE))) {
1649 add_manuf_name(eth->addr, mask, eth->name, eth->longname);
1653 } /* initialize_ethers */
1656 ethers_cleanup(void)
1658 g_free(g_ethers_path);
1659 g_ethers_path = NULL;
1660 g_free(g_pethers_path);
1661 g_pethers_path = NULL;
1662 g_free(g_manuf_path);
1663 g_manuf_path = NULL;
1668 /* Resolve ethernet address */
1669 static hashether_t *
1670 eth_addr_resolve(hashether_t *tp) {
1672 hashmanuf_t *manuf_value;
1673 const guint8 *addr = tp->addr;
1675 if ( (eth = get_ethbyaddr(addr)) != NULL) {
1676 g_strlcpy(tp->resolved_name, eth->name, MAXNAMELEN);
1677 tp->status = HASHETHER_STATUS_RESOLVED_NAME;
1684 /* Unknown name. Try looking for it in the well-known-address
1685 tables for well-known address ranges smaller than 2^24. */
1688 /* Only the topmost 5 bytes participate fully */
1689 if ((name = wka_name_lookup(addr, mask+40)) != NULL) {
1690 g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x",
1691 name, addr[5] & (0xFF >> mask));
1692 tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1699 /* Only the topmost 4 bytes participate fully */
1700 if ((name = wka_name_lookup(addr, mask+32)) != NULL) {
1701 g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x",
1702 name, addr[4] & (0xFF >> mask), addr[5]);
1703 tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1710 /* Only the topmost 3 bytes participate fully */
1711 if ((name = wka_name_lookup(addr, mask+24)) != NULL) {
1712 g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x",
1713 name, addr[3] & (0xFF >> mask), addr[4], addr[5]);
1714 tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1719 /* Now try looking in the manufacturer table. */
1720 manuf_value = manuf_name_lookup(addr);
1721 if ((manuf_value != NULL) && (manuf_value->status != HASHETHER_STATUS_UNRESOLVED)) {
1722 g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x",
1723 manuf_value->resolved_name, addr[3], addr[4], addr[5]);
1724 tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1728 /* Now try looking for it in the well-known-address
1729 tables for well-known address ranges larger than 2^24. */
1732 /* Only the topmost 2 bytes participate fully */
1733 if ((name = wka_name_lookup(addr, mask+16)) != NULL) {
1734 g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x:%02x",
1735 name, addr[2] & (0xFF >> mask), addr[3], addr[4],
1737 tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1744 /* Only the topmost byte participates fully */
1745 if ((name = wka_name_lookup(addr, mask+8)) != NULL) {
1746 g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x:%02x:%02x",
1747 name, addr[1] & (0xFF >> mask), addr[2], addr[3],
1749 tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1756 /* Not even the topmost byte participates fully */
1757 if ((name = wka_name_lookup(addr, mask)) != NULL) {
1758 g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x:%02x:%02x:%02x",
1759 name, addr[0] & (0xFF >> mask), addr[1], addr[2],
1760 addr[3], addr[4], addr[5]);
1761 tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1764 } while (--mask); /* Work down to the last bit */
1766 /* No match whatsoever. */
1767 set_address(ðer_addr, AT_ETHER, 6, addr);
1768 address_to_str_buf(ðer_addr, tp->resolved_name, MAXNAMELEN);
1769 tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1772 g_assert_not_reached();
1773 } /* eth_addr_resolve */
1775 static hashether_t *
1776 eth_hash_new_entry(const guint8 *addr, const gboolean resolve)
1781 tp = wmem_new(wmem_epan_scope(), hashether_t);
1782 memcpy(tp->addr, addr, sizeof(tp->addr));
1783 tp->status = HASHETHER_STATUS_UNRESOLVED;
1784 /* Values returned by bytes_to_hexstr_punct() are *not* null-terminated */
1785 endp = bytes_to_hexstr_punct(tp->hexaddr, addr, sizeof(tp->addr), ':');
1787 tp->resolved_name[0] = '\0';
1790 eth_addr_resolve(tp);
1792 wmem_map_insert(eth_hashtable, tp->addr, tp);
1795 } /* eth_hash_new_entry */
1797 static hashether_t *
1798 add_eth_name(const guint8 *addr, const gchar *name)
1802 tp = (hashether_t *)wmem_map_lookup(eth_hashtable, addr);
1805 tp = eth_hash_new_entry(addr, FALSE);
1808 if (strcmp(tp->resolved_name, name) != 0) {
1809 g_strlcpy(tp->resolved_name, name, MAXNAMELEN);
1810 tp->status = HASHETHER_STATUS_RESOLVED_NAME;
1811 new_resolved_objects = TRUE;
1815 } /* add_eth_name */
1817 static hashether_t *
1818 eth_name_lookup(const guint8 *addr, const gboolean resolve)
1822 tp = (hashether_t *)wmem_map_lookup(eth_hashtable, addr);
1825 tp = eth_hash_new_entry(addr, resolve);
1827 if (resolve && (tp->status == HASHETHER_STATUS_UNRESOLVED)) {
1828 eth_addr_resolve(tp); /* Found but needs to be resolved */
1834 } /* eth_name_lookup */
1839 parse_ipxnets_line(char *line, ipxnet_t *ipxnet)
1842 * We allow three address separators (':', '-', and '.'),
1843 * as well as no separators
1847 guint32 a, a0, a1, a2, a3;
1848 gboolean found_single_number = FALSE;
1850 if ((cp = strchr(line, '#')))
1853 if ((cp = strtok(line, " \t\n")) == NULL)
1856 /* Either fill a0,a1,a2,a3 and found_single_number is FALSE,
1857 * fill a and found_single_number is TRUE,
1860 if (sscanf(cp, "%x:%x:%x:%x", &a0, &a1, &a2, &a3) != 4) {
1861 if (sscanf(cp, "%x-%x-%x-%x", &a0, &a1, &a2, &a3) != 4) {
1862 if (sscanf(cp, "%x.%x.%x.%x", &a0, &a1, &a2, &a3) != 4) {
1863 if (sscanf(cp, "%x", &a) == 1) {
1864 found_single_number = TRUE;
1873 if ((cp = strtok(NULL, " \t\n")) == NULL)
1876 if (found_single_number) {
1880 ipxnet->addr = (a0 << 24) | (a1 << 16) | (a2 << 8) | a3;
1883 g_strlcpy(ipxnet->name, cp, MAXNAMELEN);
1887 } /* parse_ipxnets_line */
1889 static FILE *ipxnet_p = NULL;
1892 set_ipxnetent(char *path)
1897 ipxnet_p = ws_fopen(path, "r");
1913 static ipxnet_t ipxnet;
1914 char buf[MAX_LINELEN];
1916 if (ipxnet_p == NULL)
1919 while (fgetline(buf, sizeof(buf), ipxnet_p) >= 0) {
1920 if (parse_ipxnets_line(buf, &ipxnet) == 0) {
1927 } /* get_ipxnetent */
1930 get_ipxnetbyaddr(guint32 addr)
1934 set_ipxnetent(g_ipxnets_path);
1936 while (((ipxnet = get_ipxnetent()) != NULL) && (addr != ipxnet->addr) ) ;
1938 if (ipxnet == NULL) {
1941 set_ipxnetent(g_pipxnets_path);
1943 while (((ipxnet = get_ipxnetent()) != NULL) && (addr != ipxnet->addr) )
1951 } /* get_ipxnetbyaddr */
1954 initialize_ipxnets(void)
1956 /* Compute the pathname of the ipxnets file.
1958 * XXX - is there a notion of an "ipxnets file" in any flavor of
1959 * UNIX, or with any add-on Netware package for UNIX? If not,
1960 * should the UNIX version of the ipxnets file be in the datafile
1961 * directory as well?
1963 if (g_ipxnets_path == NULL) {
1964 g_ipxnets_path = wmem_strdup_printf(wmem_epan_scope(), "%s" G_DIR_SEPARATOR_S "%s",
1965 get_systemfile_dir(), ENAME_IPXNETS);
1968 /* Set g_pipxnets_path here, but don't actually do anything
1969 * with it. It's used in get_ipxnetbyaddr().
1971 if (g_pipxnets_path == NULL)
1972 g_pipxnets_path = get_persconffile_path(ENAME_IPXNETS, FALSE);
1974 } /* initialize_ipxnets */
1977 ipx_name_lookup_cleanup(void)
1979 ipxnet_hash_table = NULL;
1980 g_free(g_pipxnets_path);
1981 g_pipxnets_path = NULL;
1985 ipxnet_name_lookup(wmem_allocator_t *allocator, const guint addr)
1990 tp = (hashipxnet_t *)wmem_map_lookup(ipxnet_hash_table, GUINT_TO_POINTER(addr));
1992 tp = wmem_new(wmem_epan_scope(), hashipxnet_t);
1993 wmem_map_insert(ipxnet_hash_table, GUINT_TO_POINTER(addr), tp);
1995 return wmem_strdup(allocator, tp->name);
1998 /* fill in a new entry */
2002 if ( (ipxnet = get_ipxnetbyaddr(addr)) == NULL) {
2004 g_snprintf(tp->name, MAXNAMELEN, "%X", addr);
2007 g_strlcpy(tp->name, ipxnet->name, MAXNAMELEN);
2010 return wmem_strdup(allocator, tp->name);
2012 } /* ipxnet_name_lookup */
2016 parse_vlan_line(char *line, vlan_t *vlan)
2021 if ((cp = strchr(line, '#')))
2024 if ((cp = strtok(line, " \t\n")) == NULL)
2027 if (sscanf(cp, "%" G_GUINT16_FORMAT, &id) == 1) {
2034 if ((cp = strtok(NULL, "\t\n")) == NULL)
2037 g_strlcpy(vlan->name, cp, MAXVLANNAMELEN);
2041 } /* parse_vlan_line */
2043 static FILE *vlan_p = NULL;
2046 set_vlanent(char *path)
2051 vlan_p = ws_fopen(path, "r");
2068 char buf[MAX_LINELEN];
2073 while (fgetline(buf, sizeof(buf), vlan_p) >= 0) {
2074 if (parse_vlan_line(buf, &vlan) == 0) {
2084 get_vlannamebyid(guint16 id)
2088 set_vlanent(g_pvlan_path);
2090 while (((vlan = get_vlanent()) != NULL) && (id != vlan->id) ) ;
2099 } /* get_vlannamebyid */
2102 initialize_vlans(void)
2104 g_assert(vlan_hash_table == NULL);
2105 vlan_hash_table = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
2107 /* Set g_pvlan_path here, but don't actually do anything
2108 * with it. It's used in get_vlannamebyid()
2110 if (g_pvlan_path == NULL)
2111 g_pvlan_path = get_persconffile_path(ENAME_VLANS, FALSE);
2113 } /* initialize_vlans */
2116 vlan_name_lookup_cleanup(void)
2118 vlan_hash_table = NULL;
2119 g_free(g_pvlan_path);
2120 g_pvlan_path = NULL;
2123 static const gchar *
2124 vlan_name_lookup(const guint id)
2129 tp = (hashvlan_t *)wmem_map_lookup(vlan_hash_table, GUINT_TO_POINTER(id));
2131 tp = wmem_new(wmem_epan_scope(), hashvlan_t);
2132 wmem_map_insert(vlan_hash_table, GUINT_TO_POINTER(id), tp);
2137 /* fill in a new entry */
2141 if ( (vlan = get_vlannamebyid(id)) == NULL) {
2143 g_snprintf(tp->name, MAXVLANNAMELEN, "<%u>", id);
2146 g_strlcpy(tp->name, vlan->name, MAXVLANNAMELEN);
2151 } /* vlan_name_lookup */
2155 read_hosts_file (const char *hostspath, gboolean store_entries)
2158 char line[MAX_LINELEN];
2162 ws_in6_addr ip6_addr;
2164 gboolean is_ipv6, entry_found = FALSE;
2167 * See the hosts(4) or hosts(5) man page for hosts file format
2168 * (not available on all systems).
2170 if ((hf = ws_fopen(hostspath, "r")) == NULL)
2173 while (fgetline(line, sizeof(line), hf) >= 0) {
2174 if ((cp = strchr(line, '#')))
2177 if ((cp = strtok(line, " \t")) == NULL)
2178 continue; /* no tokens in the line */
2180 if (ws_inet_pton6(cp, &host_addr.ip6_addr)) {
2183 } else if (ws_inet_pton4(cp, &host_addr.ip4_addr)) {
2190 if ((cp = strtok(NULL, " \t")) == NULL)
2191 continue; /* no host name */
2194 if (store_entries) {
2196 add_ipv6_name(&host_addr.ip6_addr, cp);
2198 add_ipv4_name(host_addr.ip4_addr, cp);
2204 return entry_found ? TRUE : FALSE;
2205 } /* read_hosts_file */
2208 add_hosts_file (const char *hosts_file)
2210 gboolean found = FALSE;
2216 if (!extra_hosts_files)
2217 extra_hosts_files = g_ptr_array_new();
2219 for (i = 0; i < extra_hosts_files->len; i++) {
2220 if (strcmp(hosts_file, (const char *) g_ptr_array_index(extra_hosts_files, i)) == 0)
2225 g_ptr_array_add(extra_hosts_files, wmem_strdup(wmem_epan_scope(), hosts_file));
2226 return read_hosts_file (hosts_file, FALSE);
2232 add_ip_name_from_string (const char *addr, const char *name)
2236 ws_in6_addr ip6_addr;
2239 resolved_ipv4_t *resolved_ipv4_entry;
2240 resolved_ipv6_t *resolved_ipv6_entry;
2242 if (ws_inet_pton6(addr, &host_addr.ip6_addr)) {
2244 } else if (ws_inet_pton4(addr, &host_addr.ip4_addr)) {
2251 resolved_ipv6_entry = wmem_new(wmem_epan_scope(), resolved_ipv6_t);
2252 memcpy(&(resolved_ipv6_entry->ip6_addr), &host_addr.ip6_addr, 16);
2253 g_strlcpy(resolved_ipv6_entry->name, name, MAXNAMELEN);
2254 wmem_list_prepend(manually_resolved_ipv6_list, resolved_ipv6_entry);
2256 resolved_ipv4_entry = wmem_new(wmem_epan_scope(), resolved_ipv4_t);
2257 resolved_ipv4_entry->host_addr = host_addr.ip4_addr;
2258 g_strlcpy(resolved_ipv4_entry->name, name, MAXNAMELEN);
2259 wmem_list_prepend(manually_resolved_ipv4_list, resolved_ipv4_entry);
2263 } /* add_ip_name_from_string */
2266 * Add the resolved addresses that are in use to the list used to create the NRB
2269 ipv4_hash_table_resolved_to_list(gpointer key _U_, gpointer value, gpointer user_data)
2271 addrinfo_lists_t *lists = (addrinfo_lists_t*)user_data;
2272 hashipv4_t *ipv4_hash_table_entry = (hashipv4_t *)value;
2274 if ((ipv4_hash_table_entry->flags & USED_AND_RESOLVED_MASK) == USED_AND_RESOLVED_MASK) {
2275 lists->ipv4_addr_list = g_list_prepend(lists->ipv4_addr_list, ipv4_hash_table_entry);
2281 * Add the resolved addresses that are in use to the list used to create the NRB
2285 ipv6_hash_table_resolved_to_list(gpointer key _U_, gpointer value, gpointer user_data)
2287 addrinfo_lists_t *lists = (addrinfo_lists_t*)user_data;
2288 hashipv6_t *ipv6_hash_table_entry = (hashipv6_t *)value;
2290 if ((ipv6_hash_table_entry->flags & USED_AND_RESOLVED_MASK) == USED_AND_RESOLVED_MASK) {
2291 lists->ipv6_addr_list = g_list_prepend (lists->ipv6_addr_list, ipv6_hash_table_entry);
2297 get_addrinfo_list(void)
2299 if (ipv4_hash_table) {
2300 wmem_map_foreach(ipv4_hash_table, ipv4_hash_table_resolved_to_list, &addrinfo_lists);
2303 if (ipv6_hash_table) {
2304 wmem_map_foreach(ipv6_hash_table, ipv6_hash_table_resolved_to_list, &addrinfo_lists);
2307 return &addrinfo_lists;
2310 /* Read in a list of subnet definition - name pairs.
2311 * <line> = <comment> | <entry> | <whitespace>
2312 * <comment> = <whitespace>#<any>
2313 * <entry> = <subnet_definition> <whitespace> <subnet_name> [<comment>|<whitespace><any>]
2314 * <subnet_definition> = <ipv4_address> / <subnet_mask_length>
2315 * <ipv4_address> is a full address; it will be masked to get the subnet-ID.
2316 * <subnet_mask_length> is a decimal 1-31
2317 * <subnet_name> is a string containing no whitespace.
2318 * <whitespace> = (space | tab)+
2319 * Any malformed entries are ignored.
2320 * Any trailing data after the subnet_name is ignored.
2325 read_subnets_file (const char *subnetspath)
2328 char line[MAX_LINELEN];
2330 guint32 host_addr; /* IPv4 ONLY */
2333 if ((hf = ws_fopen(subnetspath, "r")) == NULL)
2336 while (fgetline(line, sizeof(line), hf) >= 0) {
2337 if ((cp = strchr(line, '#')))
2340 if ((cp = strtok(line, " \t")) == NULL)
2341 continue; /* no tokens in the line */
2344 /* Expected format is <IP4 address>/<subnet length> */
2345 cp2 = strchr(cp, '/');
2350 *cp2 = '\0'; /* Cut token */
2353 /* Check if this is a valid IPv4 address */
2354 if (!str_to_ip(cp, &host_addr)) {
2358 if (!ws_strtou8(cp2, NULL, &mask_length) || mask_length == 0 || mask_length > 32) {
2359 continue; /* invalid mask length */
2362 if ((cp = strtok(NULL, " \t")) == NULL)
2363 continue; /* no subnet name */
2365 subnet_entry_set(host_addr, mask_length, cp);
2370 } /* read_subnets_file */
2372 static subnet_entry_t
2373 subnet_lookup(const guint32 addr)
2375 subnet_entry_t subnet_entry;
2378 /* Search mask lengths linearly, longest first */
2380 i = SUBNETLENGTHSIZE;
2381 while(have_subnet_entry && i > 0) {
2382 guint32 masked_addr;
2383 subnet_length_entry_t* length_entry;
2385 /* Note that we run from 31 (length 32) to 0 (length 1) */
2387 g_assert(i < SUBNETLENGTHSIZE);
2390 length_entry = &subnet_length_entries[i];
2392 if (NULL != length_entry->subnet_addresses) {
2393 sub_net_hashipv4_t * tp;
2396 masked_addr = addr & length_entry->mask;
2397 hash_idx = HASH_IPV4_ADDRESS(masked_addr);
2399 tp = length_entry->subnet_addresses[hash_idx];
2400 while(tp != NULL && tp->addr != masked_addr) {
2405 subnet_entry.mask = length_entry->mask;
2406 subnet_entry.mask_length = i + 1; /* Length is offset + 1 */
2407 subnet_entry.name = tp->name;
2408 return subnet_entry;
2413 subnet_entry.mask = 0;
2414 subnet_entry.mask_length = 0;
2415 subnet_entry.name = NULL;
2417 return subnet_entry;
2420 /* Add a subnet-definition - name pair to the set.
2421 * The definition is taken by masking the address passed in with the mask of the
2425 subnet_entry_set(guint32 subnet_addr, const guint8 mask_length, const gchar* name)
2427 subnet_length_entry_t* entry;
2428 sub_net_hashipv4_t * tp;
2431 g_assert(mask_length > 0 && mask_length <= 32);
2433 entry = &subnet_length_entries[mask_length - 1];
2435 subnet_addr &= entry->mask;
2437 hash_idx = HASH_IPV4_ADDRESS(subnet_addr);
2439 if (NULL == entry->subnet_addresses) {
2440 entry->subnet_addresses = (sub_net_hashipv4_t**)wmem_alloc0(wmem_epan_scope(), sizeof(sub_net_hashipv4_t*) * HASHHOSTSIZE);
2443 if (NULL != (tp = entry->subnet_addresses[hash_idx])) {
2444 sub_net_hashipv4_t * new_tp;
2447 if (tp->addr == subnet_addr) {
2448 return; /* XXX provide warning that an address was repeated? */
2454 new_tp = wmem_new(wmem_epan_scope(), sub_net_hashipv4_t);
2458 tp = entry->subnet_addresses[hash_idx] = wmem_new(wmem_epan_scope(), sub_net_hashipv4_t);
2462 tp->addr = subnet_addr;
2463 g_strlcpy(tp->name, name, MAXNAMELEN); /* This is longer than subnet names can actually be */
2464 have_subnet_entry = TRUE;
2468 subnet_name_lookup_init(void)
2473 for(i = 0; i < SUBNETLENGTHSIZE; ++i) {
2474 guint32 length = i + 1;
2476 subnet_length_entries[i].subnet_addresses = NULL;
2477 subnet_length_entries[i].mask_length = length;
2478 subnet_length_entries[i].mask = g_htonl(ip_get_subnet_mask(length));
2481 /* Check profile directory before personal configuration */
2482 subnetspath = get_persconffile_path(ENAME_SUBNETS, TRUE);
2483 if (!read_subnets_file(subnetspath)) {
2484 if (errno != ENOENT) {
2485 report_open_failure(subnetspath, errno, FALSE);
2488 g_free(subnetspath);
2489 subnetspath = get_persconffile_path(ENAME_SUBNETS, FALSE);
2490 if (!read_subnets_file(subnetspath) && errno != ENOENT) {
2491 report_open_failure(subnetspath, errno, FALSE);
2494 g_free(subnetspath);
2497 * Load the global subnets file, if we have one.
2499 subnetspath = get_datafile_path(ENAME_SUBNETS);
2500 if (!read_subnets_file(subnetspath) && errno != ENOENT) {
2501 report_open_failure(subnetspath, errno, FALSE);
2503 g_free(subnetspath);
2506 /* SS7 PC Name Resolution Portion */
2507 static hashss7pc_t *
2508 new_ss7pc(const guint8 ni, const guint32 pc)
2510 hashss7pc_t *tp = wmem_new(wmem_epan_scope(), hashss7pc_t);
2511 tp->id = (ni<<24) + (pc&0xffffff);
2512 tp->pc_addr[0] = '\0';
2518 static hashss7pc_t *
2519 host_lookup_ss7pc(const guint8 ni, const guint32 pc)
2521 hashss7pc_t * volatile tp;
2524 id = (ni<<24) + (pc&0xffffff);
2526 tp = (hashss7pc_t *)wmem_map_lookup(ss7pc_hash_table, GUINT_TO_POINTER(id));
2528 tp = new_ss7pc(ni, pc);
2529 wmem_map_insert(ss7pc_hash_table, GUINT_TO_POINTER(id), tp);
2535 void fill_unresolved_ss7pc(const gchar * pc_addr, const guint8 ni, const guint32 pc)
2537 hashss7pc_t *tp = host_lookup_ss7pc(ni, pc);
2539 g_strlcpy(tp->pc_addr, pc_addr, MAXNAMELEN);
2543 get_hostname_ss7pc(const guint8 ni, const guint32 pc)
2545 hashss7pc_t *tp = host_lookup_ss7pc(ni, pc);
2547 /* never resolved yet*/
2548 if (tp->pc_addr[0] == '\0')
2551 /* Don't have name in file */
2552 if (tp->name[0] == '\0')
2555 if (!gbl_resolv_flags.ss7pc_name)
2562 add_ss7pc_name(const guint8 ni, guint32 pc, const gchar *name)
2567 if (!name || name[0] == '\0')
2570 id = (ni<<24) + (pc&0xffffff);
2571 tp = (hashss7pc_t *)wmem_map_lookup(ss7pc_hash_table, GUINT_TO_POINTER(id));
2573 tp = new_ss7pc(ni, pc);
2574 wmem_map_insert(ss7pc_hash_table, GUINT_TO_POINTER(id), tp);
2577 if (g_ascii_strcasecmp(tp->name, name)) {
2578 g_strlcpy(tp->name, name, MAXNAMELEN);
2583 read_ss7pcs_file(const char *ss7pcspath)
2586 char line[MAX_LINELEN];
2590 gboolean entry_found = FALSE;
2593 * File format is Network Indicator (decimal)<dash>Point Code (Decimal)<tab/space>Hostname
2595 if ((hf = ws_fopen(ss7pcspath, "r")) == NULL)
2598 while (fgetline(line, sizeof(line), hf) >= 0) {
2599 if ((cp = strchr(line, '#')))
2602 if ((cp = strtok(line, "-")) == NULL)
2603 continue; /*no ni-pc separator*/
2604 if (!ws_strtou8(cp, NULL, &ni))
2609 if ((cp = strtok(NULL, " \t")) == NULL)
2610 continue; /* no tokens for pc and name */
2611 if (!ws_strtou32(cp, NULL, &pc))
2616 if ((cp = strtok(NULL, " \t")) == NULL)
2617 continue; /* no host name */
2620 add_ss7pc_name(ni, pc, cp);
2624 return entry_found ? TRUE : FALSE;
2628 ss7pc_name_lookup_init(void)
2632 g_assert(ss7pc_hash_table == NULL);
2634 ss7pc_hash_table = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
2637 * Load the user's ss7pcs file
2639 ss7pcspath = get_persconffile_path(ENAME_SS7PCS, TRUE);
2640 if (!read_ss7pcs_file(ss7pcspath) && errno != ENOENT) {
2641 report_open_failure(ss7pcspath, errno, FALSE);
2646 /* SS7PC Name Resolution End*/
2650 * External Functions
2654 addr_resolve_pref_init(module_t *nameres)
2656 prefs_register_bool_preference(nameres, "mac_name",
2657 "Resolve MAC addresses",
2658 "Resolve Ethernet MAC addresses to host names from the preferences"
2659 " or system's Ethers file, or to a manufacturer based name.",
2660 &gbl_resolv_flags.mac_name);
2662 prefs_register_bool_preference(nameres, "transport_name",
2663 "Resolve transport names",
2664 "Resolve TCP/UDP ports into service names",
2665 &gbl_resolv_flags.transport_name);
2667 prefs_register_bool_preference(nameres, "network_name",
2668 "Resolve network (IP) addresses",
2669 "Resolve IPv4, IPv6, and IPX addresses into host names."
2670 " The next set of check boxes determines how name resolution should be performed."
2671 " If no other options are checked name resolution is made from Wireshark's host file"
2672 " and capture file name resolution blocks.",
2673 &gbl_resolv_flags.network_name);
2675 prefs_register_bool_preference(nameres, "dns_pkt_addr_resolution",
2676 "Use captured DNS packet data for address resolution",
2677 "Whether address/name pairs found in captured DNS packets should be used by Wireshark for name resolution.",
2678 &gbl_resolv_flags.dns_pkt_addr_resolution);
2681 prefs_register_bool_preference(nameres, "use_external_name_resolver",
2682 "Use an external network name resolver",
2683 "Use your system's configured name resolver"
2684 " (usually DNS) to resolve network names."
2685 " Only applies when network name resolution"
2687 &gbl_resolv_flags.use_external_net_name_resolver);
2689 prefs_register_obsolete_preference(nameres, "concurrent_dns");
2691 prefs_register_uint_preference(nameres, "name_resolve_concurrency",
2692 "Maximum concurrent requests",
2693 "The maximum number of DNS requests that may"
2694 " be active at any time. A large value (many"
2695 " thousands) might overload the network or make"
2696 " your DNS server behave badly.",
2698 &name_resolve_concurrency);
2700 prefs_register_static_text_preference(nameres, "use_external_name_resolver",
2701 "Use an external network name resolver: N/A",
2702 "Support for using a concurrent external name resolver was not"
2703 " compiled into this version of Wireshark");
2706 prefs_register_bool_preference(nameres, "hosts_file_handling",
2707 "Only use the profile \"hosts\" file",
2708 "By default \"hosts\" files will be loaded from multiple sources."
2709 " Checking this box only loads the \"hosts\" in the current profile.",
2710 &gbl_resolv_flags.load_hosts_file_from_profile_only);
2712 prefs_register_bool_preference(nameres, "vlan_name",
2714 "Resolve VLAN IDs to network names from the preferences \"vlans\" file."
2715 " Format of the file is: \"ID<Tab>Name\"."
2716 " One line per VLAN, e.g.: 1 Management",
2717 &gbl_resolv_flags.vlan_name);
2719 prefs_register_bool_preference(nameres, "ss7_pc_name",
2721 "Resolve SS7 Point Codes to node names from the profiles \"ss7pcs\" file."
2722 " Format of the file is: \"Network_Indicator<Dash>PC_Decimal<Tab>Name\"."
2723 " One line per Point Code, e.g.: 2-1234 MyPointCode1",
2724 &gbl_resolv_flags.ss7pc_name);
2729 disable_name_resolution(void) {
2730 gbl_resolv_flags.mac_name = FALSE;
2731 gbl_resolv_flags.network_name = FALSE;
2732 gbl_resolv_flags.transport_name = FALSE;
2733 gbl_resolv_flags.dns_pkt_addr_resolution = FALSE;
2734 gbl_resolv_flags.use_external_net_name_resolver = FALSE;
2735 gbl_resolv_flags.vlan_name = FALSE;
2736 gbl_resolv_flags.ss7pc_name = FALSE;
2741 host_name_lookup_process(void) {
2742 async_dns_queue_msg_t *caqm;
2743 struct timeval tv = { 0, 0 };
2746 gboolean nro = new_resolved_objects;
2747 wmem_list_frame_t* head;
2749 new_resolved_objects = FALSE;
2750 nro |= maxmind_db_lookup_process();
2752 if (!async_dns_initialized)
2753 /* c-ares not initialized. Bail out and cancel timers. */
2756 head = wmem_list_head(async_dns_queue_head);
2758 while (head != NULL && async_dns_in_flight <= name_resolve_concurrency) {
2759 caqm = (async_dns_queue_msg_t *)wmem_list_frame_data(head);
2760 wmem_list_remove_frame(async_dns_queue_head, head);
2761 if (caqm->family == AF_INET) {
2762 ares_gethostbyaddr(ghba_chan, &caqm->addr.ip4, sizeof(guint32), AF_INET,
2763 c_ares_ghba_cb, caqm);
2764 async_dns_in_flight++;
2765 } else if (caqm->family == AF_INET6) {
2766 ares_gethostbyaddr(ghba_chan, &caqm->addr.ip6, sizeof(ws_in6_addr),
2767 AF_INET6, c_ares_ghba_cb, caqm);
2768 async_dns_in_flight++;
2771 head = wmem_list_head(async_dns_queue_head);
2776 nfds = ares_fds(ghba_chan, &rfds, &wfds);
2778 if (select(nfds, &rfds, &wfds, NULL, &tv) == -1) { /* call to select() failed */
2779 fprintf(stderr, "Warning: call to select() failed, error is %s\n", g_strerror(errno));
2782 ares_process(ghba_chan, &rfds, &wfds);
2785 /* Any new entries? */
2790 _host_name_lookup_cleanup(void) {
2791 async_dns_queue_head = NULL;
2793 if (async_dns_initialized) {
2794 ares_destroy(ghba_chan);
2795 ares_destroy(ghbn_chan);
2797 #ifdef CARES_HAVE_ARES_LIBRARY_INIT
2798 ares_library_cleanup();
2800 async_dns_initialized = FALSE;
2806 host_name_lookup_process(void) {
2807 gboolean nro = new_resolved_objects;
2809 new_resolved_objects = FALSE;
2811 nro |= maxmind_db_lookup_process();
2817 _host_name_lookup_cleanup(void) {
2820 #endif /* HAVE_C_ARES */
2823 get_hostname(const guint addr)
2825 /* XXX why do we call this if we're not resolving? To create hash entries?
2828 hashipv4_t *tp = host_lookup(addr);
2830 if (!gbl_resolv_flags.network_name)
2833 tp->flags |= RESOLVED_ADDRESS_USED;
2838 /* -------------------------- */
2841 get_hostname6(const ws_in6_addr *addr)
2843 /* XXX why do we call this if we're not resolving? To create hash entries?
2846 hashipv6_t *tp = host_lookup6(addr);
2848 if (!gbl_resolv_flags.network_name)
2851 tp->flags |= RESOLVED_ADDRESS_USED;
2856 /* -------------------------- */
2858 add_ipv4_name(const guint addr, const gchar *name)
2863 * Don't add zero-length names; apparently, some resolvers will return
2864 * them if they get them from DNS.
2866 if (!name || name[0] == '\0')
2869 tp = (hashipv4_t *)wmem_map_lookup(ipv4_hash_table, GUINT_TO_POINTER(addr));
2871 tp = new_ipv4(addr);
2872 wmem_map_insert(ipv4_hash_table, GUINT_TO_POINTER(addr), tp);
2875 if (g_ascii_strcasecmp(tp->name, name)) {
2876 g_strlcpy(tp->name, name, MAXNAMELEN);
2877 new_resolved_objects = TRUE;
2879 tp->flags |= TRIED_RESOLVE_ADDRESS|NAME_RESOLVED;
2880 } /* add_ipv4_name */
2882 /* -------------------------- */
2884 add_ipv6_name(const ws_in6_addr *addrp, const gchar *name)
2889 * Don't add zero-length names; apparently, some resolvers will return
2890 * them if they get them from DNS.
2892 if (!name || name[0] == '\0')
2895 tp = (hashipv6_t *)wmem_map_lookup(ipv6_hash_table, addrp);
2897 ws_in6_addr *addr_key;
2899 addr_key = wmem_new(wmem_epan_scope(), ws_in6_addr);
2900 tp = new_ipv6(addrp);
2901 memcpy(addr_key, addrp, 16);
2902 wmem_map_insert(ipv6_hash_table, addr_key, tp);
2905 if (g_ascii_strcasecmp(tp->name, name)) {
2906 g_strlcpy(tp->name, name, MAXNAMELEN);
2907 new_resolved_objects = TRUE;
2909 tp->flags |= TRIED_RESOLVE_ADDRESS|NAME_RESOLVED;
2910 } /* add_ipv6_name */
2913 add_manually_resolved_ipv4(gpointer data, gpointer user_data _U_)
2915 resolved_ipv4_t *resolved_ipv4_entry = (resolved_ipv4_t *)data;
2917 add_ipv4_name(resolved_ipv4_entry->host_addr, resolved_ipv4_entry->name);
2921 add_manually_resolved_ipv6(gpointer data, gpointer user_data _U_)
2923 resolved_ipv6_t *resolved_ipv6_entry = (resolved_ipv6_t *)data;
2925 add_ipv6_name(&(resolved_ipv6_entry->ip6_addr), resolved_ipv6_entry->name);
2929 add_manually_resolved(void)
2931 if (manually_resolved_ipv4_list) {
2932 wmem_list_foreach(manually_resolved_ipv4_list, add_manually_resolved_ipv4, NULL);
2935 if (manually_resolved_ipv6_list) {
2936 wmem_list_foreach(manually_resolved_ipv6_list, add_manually_resolved_ipv6, NULL);
2941 host_name_lookup_init(void)
2946 g_assert(ipxnet_hash_table == NULL);
2947 ipxnet_hash_table = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
2949 g_assert(ipv4_hash_table == NULL);
2950 ipv4_hash_table = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
2952 g_assert(ipv6_hash_table == NULL);
2953 ipv6_hash_table = wmem_map_new(wmem_epan_scope(), ipv6_oat_hash, ipv6_equal);
2956 g_assert(async_dns_queue_head == NULL);
2957 async_dns_queue_head = wmem_list_new(wmem_epan_scope());
2960 if (manually_resolved_ipv4_list == NULL)
2961 manually_resolved_ipv4_list = wmem_list_new(wmem_epan_scope());
2963 if (manually_resolved_ipv6_list == NULL)
2964 manually_resolved_ipv6_list = wmem_list_new(wmem_epan_scope());
2967 * Load the global hosts file, if we have one.
2969 if (!gbl_resolv_flags.load_hosts_file_from_profile_only) {
2970 hostspath = get_datafile_path(ENAME_HOSTS);
2971 if (!read_hosts_file(hostspath, TRUE) && errno != ENOENT) {
2972 report_open_failure(hostspath, errno, FALSE);
2977 * Load the user's hosts file no matter what, if they have one.
2979 hostspath = get_persconffile_path(ENAME_HOSTS, TRUE);
2980 if (!read_hosts_file(hostspath, TRUE) && errno != ENOENT) {
2981 report_open_failure(hostspath, errno, FALSE);
2985 #ifdef CARES_HAVE_ARES_LIBRARY_INIT
2986 if (ares_library_init(ARES_LIB_INIT_ALL) == ARES_SUCCESS) {
2988 if (ares_init(&ghba_chan) == ARES_SUCCESS && ares_init(&ghbn_chan) == ARES_SUCCESS) {
2989 async_dns_initialized = TRUE;
2991 #ifdef CARES_HAVE_ARES_LIBRARY_INIT
2995 #endif /* HAVE_C_ARES */
2997 if (extra_hosts_files && !gbl_resolv_flags.load_hosts_file_from_profile_only) {
2998 for (i = 0; i < extra_hosts_files->len; i++) {
2999 read_hosts_file((const char *) g_ptr_array_index(extra_hosts_files, i), TRUE);
3003 subnet_name_lookup_init();
3005 add_manually_resolved();
3007 ss7pc_name_lookup_init();
3011 host_name_lookup_cleanup(void)
3014 sub_net_hashipv4_t *entry, *next_entry;
3016 _host_name_lookup_cleanup();
3018 ipxnet_hash_table = NULL;
3019 ipv4_hash_table = NULL;
3020 ipv6_hash_table = NULL;
3021 ss7pc_hash_table = NULL;
3023 for(i = 0; i < SUBNETLENGTHSIZE; ++i) {
3024 if (subnet_length_entries[i].subnet_addresses != NULL) {
3025 for (j = 0; j < HASHHOSTSIZE; j++) {
3026 for (entry = subnet_length_entries[i].subnet_addresses[j];
3027 entry != NULL; entry = next_entry) {
3028 next_entry = entry->next;
3029 wmem_free(wmem_epan_scope(), entry);
3032 wmem_free(wmem_epan_scope(), subnet_length_entries[i].subnet_addresses);
3033 subnet_length_entries[i].subnet_addresses = NULL;
3037 have_subnet_entry = FALSE;
3038 new_resolved_objects = FALSE;
3042 void host_name_lookup_reset(void)
3044 host_name_lookup_cleanup();
3045 host_name_lookup_init();
3049 manually_resolve_cleanup(void)
3051 if (manually_resolved_ipv4_list) {
3052 wmem_destroy_list(manually_resolved_ipv4_list);
3053 manually_resolved_ipv4_list = NULL;
3055 if (manually_resolved_ipv6_list) {
3056 wmem_destroy_list(manually_resolved_ipv6_list);
3057 manually_resolved_ipv6_list = NULL;
3062 udp_port_to_display(wmem_allocator_t *allocator, guint port)
3065 if (!gbl_resolv_flags.transport_name) {
3066 return wmem_utoa(allocator, port);
3069 return wmem_strdup(allocator, serv_name_lookup(PT_UDP, port));
3071 } /* udp_port_to_display */
3074 dccp_port_to_display(wmem_allocator_t *allocator, guint port)
3077 if (!gbl_resolv_flags.transport_name) {
3078 return wmem_utoa(allocator, port);
3081 return wmem_strdup(allocator, serv_name_lookup(PT_DCCP, port));
3083 } /* dccp_port_to_display */
3086 tcp_port_to_display(wmem_allocator_t *allocator, guint port)
3089 if (!gbl_resolv_flags.transport_name) {
3090 return wmem_utoa(allocator, port);
3093 return wmem_strdup(allocator, serv_name_lookup(PT_TCP, port));
3095 } /* tcp_port_to_display */
3098 sctp_port_to_display(wmem_allocator_t *allocator, guint port)
3101 if (!gbl_resolv_flags.transport_name) {
3102 return wmem_utoa(allocator, port);
3105 return wmem_strdup(allocator, serv_name_lookup(PT_SCTP, port));
3107 } /* sctp_port_to_display */
3110 port_with_resolution_to_str(wmem_allocator_t *scope, port_type proto, guint port)
3112 const gchar *port_str;
3114 if (!gbl_resolv_flags.transport_name || (proto == PT_NONE)) {
3115 /* No name resolution support, just return port string */
3116 return wmem_strdup_printf(scope, "%u", port);
3118 port_str = serv_name_lookup(proto, port);
3120 return wmem_strdup_printf(scope, "%s (%u)", port_str, port);
3124 port_with_resolution_to_str_buf(gchar *buf, gulong buf_size, port_type proto, guint port)
3126 const gchar *port_str;
3128 if (!gbl_resolv_flags.transport_name || (proto == PT_NONE)) {
3129 /* No name resolution support, just return port string */
3130 return g_snprintf(buf, buf_size, "%u", port);
3132 port_str = serv_name_lookup(proto, port);
3134 return g_snprintf(buf, buf_size, "%s (%u)", port_str, port);
3138 get_ether_name(const guint8 *addr)
3141 gboolean resolve = gbl_resolv_flags.mac_name;
3143 tp = eth_name_lookup(addr, resolve);
3145 return resolve ? tp->resolved_name : tp->hexaddr;
3147 } /* get_ether_name */
3150 tvb_get_ether_name(tvbuff_t *tvb, gint offset)
3152 return get_ether_name(tvb_get_ptr(tvb, offset, 6));
3155 /* Look for a (non-dummy) ether name in the hash, and return it if found.
3156 * If it's not found, simply return NULL.
3159 get_ether_name_if_known(const guint8 *addr)
3163 /* Initialize ether structs if we're the first
3164 * ether-related function called */
3165 if (!gbl_resolv_flags.mac_name)
3168 /* eth_name_lookup will create a (resolved) hash entry if it doesn't exist */
3169 tp = eth_name_lookup(addr, TRUE);
3170 g_assert(tp != NULL);
3172 if (tp->status == HASHETHER_STATUS_RESOLVED_NAME) {
3173 /* Name is from an ethers file */
3174 return tp->resolved_name;
3177 /* Name was created */
3183 add_ether_byip(const guint ip, const guint8 *eth)
3187 /* first check that IP address can be resolved */
3188 if (!gbl_resolv_flags.network_name)
3191 tp = host_lookup(ip);
3194 * Was this IP address resolved to a host name?
3196 if (tp->flags & NAME_RESOLVED) {
3198 * Yes, so add an entry in the ethers hashtable resolving
3199 * the MAC address to that name.
3201 add_eth_name(eth, tp->name);
3204 } /* add_ether_byip */
3207 ipxnet_to_str_punct(wmem_allocator_t *allocator, const guint32 ad, const char punct)
3209 gchar *buf = (gchar *)wmem_alloc(allocator, 12);
3211 *dword_to_hex_punct(buf, ad, punct) = '\0';
3216 get_ipxnet_name(wmem_allocator_t *allocator, const guint32 addr)
3219 if (!gbl_resolv_flags.network_name) {
3220 return ipxnet_to_str_punct(allocator, addr, '\0');
3223 return ipxnet_name_lookup(allocator, addr);
3225 } /* get_ipxnet_name */
3228 get_vlan_name(wmem_allocator_t *allocator, const guint16 id)
3231 if (!gbl_resolv_flags.vlan_name) {
3235 return wmem_strdup(allocator, vlan_name_lookup(id));
3237 } /* get_vlan_name */
3240 get_manuf_name(const guint8 *addr)
3242 hashmanuf_t *manuf_value;
3244 manuf_value = manuf_name_lookup(addr);
3245 if (gbl_resolv_flags.mac_name && manuf_value->status != HASHETHER_STATUS_UNRESOLVED)
3246 return manuf_value->resolved_name;
3248 return manuf_value->hexaddr;
3250 } /* get_manuf_name */
3253 tvb_get_manuf_name(tvbuff_t *tvb, gint offset)
3255 return get_manuf_name(tvb_get_ptr(tvb, offset, 3));
3259 get_manuf_name_if_known(const guint8 *addr)
3261 hashmanuf_t *manuf_value;
3265 /* manuf needs only the 3 most significant octets of the ethernet address */
3266 manuf_key = addr[0];
3267 manuf_key = manuf_key<<8;
3269 manuf_key = manuf_key | oct;
3270 manuf_key = manuf_key<<8;
3272 manuf_key = manuf_key | oct;
3274 manuf_value = (hashmanuf_t *)wmem_map_lookup(manuf_hashtable, GUINT_TO_POINTER(manuf_key));
3275 if ((manuf_value == NULL) || (manuf_value->status == HASHETHER_STATUS_UNRESOLVED)) {
3279 return manuf_value->resolved_longname;
3281 } /* get_manuf_name_if_known */
3284 uint_get_manuf_name_if_known(const guint manuf_key)
3286 hashmanuf_t *manuf_value;
3288 manuf_value = (hashmanuf_t *)wmem_map_lookup(manuf_hashtable, GUINT_TO_POINTER(manuf_key));
3289 if ((manuf_value == NULL) || (manuf_value->status == HASHETHER_STATUS_UNRESOLVED)) {
3293 return manuf_value->resolved_longname;
3297 tvb_get_manuf_name_if_known(tvbuff_t *tvb, gint offset)
3299 return get_manuf_name_if_known(tvb_get_ptr(tvb, offset, 3));
3302 char* get_hash_manuf_resolved_name(hashmanuf_t* manuf)
3304 return manuf->resolved_longname;
3308 eui64_to_display(wmem_allocator_t *allocator, const guint64 addr_eui64)
3310 guint8 *addr = (guint8 *)wmem_alloc(NULL, 8);
3311 hashmanuf_t *manuf_value;
3314 /* Copy and convert the address to network byte order. */
3315 *(guint64 *)(void *)(addr) = pntoh64(&(addr_eui64));
3317 manuf_value = manuf_name_lookup(addr);
3318 if (!gbl_resolv_flags.mac_name || (manuf_value->status == HASHETHER_STATUS_UNRESOLVED)) {
3319 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]);
3321 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]);
3324 wmem_free(NULL, addr);
3326 } /* eui64_to_display */
3329 #define GHI_TIMEOUT (250 * 1000)
3331 c_ares_ghi_cb(void *arg, int status, int timeouts _U_, struct hostent *hp) {
3333 * XXX - If we wanted to be really fancy we could cache results here and
3334 * look them up in get_host_ipaddr* below.
3336 async_hostent_t *ahp = (async_hostent_t *)arg;
3337 if (status == ARES_SUCCESS && hp && ahp && hp->h_length == ahp->addr_size) {
3338 memcpy(ahp->addrp, hp->h_addr, hp->h_length);
3339 ahp->copied = hp->h_length;
3342 #endif /* HAVE_C_ARES */
3344 /* Translate a string, assumed either to be a dotted-quad IPv4 address or
3345 * a host name, to a numeric IPv4 address. Return TRUE if we succeed and
3346 * set "*addrp" to that numeric IPv4 address; return FALSE if we fail. */
3348 get_host_ipaddr(const char *host, guint32 *addrp)
3351 struct timeval tv = { 0, GHI_TIMEOUT }, *tvp;
3354 async_hostent_t ahe;
3358 * XXX - are there places where this is used to translate something
3359 * that's *only* supposed to be an IPv4 address, and where it
3360 * *shouldn't* translate host names?
3362 if (!ws_inet_pton4(host, addrp)) {
3364 /* It's not a valid dotted-quad IP address; is it a valid
3368 /* If we're not allowed to do name resolution, don't do name
3371 if (!gbl_resolv_flags.network_name ||
3372 !gbl_resolv_flags.use_external_net_name_resolver) {
3377 if (!async_dns_initialized || name_resolve_concurrency < 1) {
3380 ahe.addr_size = (int) sizeof (struct in_addr);
3383 ares_gethostbyname(ghbn_chan, host, AF_INET, c_ares_ghi_cb, &ahe);
3386 nfds = ares_fds(ghbn_chan, &rfds, &wfds);
3388 tvp = ares_timeout(ghbn_chan, &tv, &tv);
3389 if (select(nfds, &rfds, &wfds, NULL, tvp) == -1) { /* call to select() failed */
3390 fprintf(stderr, "Warning: call to select() failed, error is %s\n", g_strerror(errno));
3393 ares_process(ghbn_chan, &rfds, &wfds);
3395 ares_cancel(ghbn_chan);
3396 if (ahe.addr_size == ahe.copied) {
3407 * Translate IPv6 numeric address or FQDN hostname into binary IPv6 address.
3408 * Return TRUE if we succeed and set "*addrp" to that numeric IPv6 address;
3409 * return FALSE if we fail.
3412 get_host_ipaddr6(const char *host, ws_in6_addr *addrp)
3415 struct timeval tv = { 0, GHI_TIMEOUT }, *tvp;
3418 async_hostent_t ahe;
3419 #endif /* HAVE_C_ARES */
3421 if (str_to_ip6(host, addrp))
3424 /* It's not a valid dotted-quad IP address; is it a valid
3427 * XXX - are there places where this is used to translate something
3428 * that's *only* supposed to be an IPv6 address, and where it
3429 * *shouldn't* translate host names?
3432 /* If we're not allowed to do name resolution, don't do name
3435 if (!gbl_resolv_flags.network_name ||
3436 !gbl_resolv_flags.use_external_net_name_resolver) {
3442 if (!async_dns_initialized || name_resolve_concurrency < 1) {
3445 ahe.addr_size = (int) sizeof (ws_in6_addr);
3448 ares_gethostbyname(ghbn_chan, host, AF_INET6, c_ares_ghi_cb, &ahe);
3451 nfds = ares_fds(ghbn_chan, &rfds, &wfds);
3453 tvp = ares_timeout(ghbn_chan, &tv, &tv);
3454 if (select(nfds, &rfds, &wfds, NULL, tvp) == -1) { /* call to select() failed */
3455 fprintf(stderr, "Warning: call to select() failed, error is %s\n", g_strerror(errno));
3458 ares_process(ghbn_chan, &rfds, &wfds);
3460 ares_cancel(ghbn_chan);
3461 if (ahe.addr_size == ahe.copied) {
3470 get_manuf_hashtable(void)
3472 return manuf_hashtable;
3476 get_wka_hashtable(void)
3478 return wka_hashtable;
3482 get_eth_hashtable(void)
3484 return eth_hashtable;
3488 get_serv_port_hashtable(void)
3490 return serv_port_hashtable;
3494 get_ipxnet_hash_table(void)
3496 return ipxnet_hash_table;
3500 get_vlan_hash_table(void)
3502 return vlan_hash_table;
3506 get_ipv4_hash_table(void)
3508 return ipv4_hash_table;
3512 get_ipv6_hash_table(void)
3514 return ipv6_hash_table;
3516 /* Initialize all the address resolution subsystems in this file */
3518 addr_resolv_init(void)
3520 initialize_services();
3521 initialize_ethers();
3522 initialize_ipxnets();
3524 initialize_enterprises();
3525 host_name_lookup_init();
3528 /* Clean up all the address resolution subsystems in this file */
3530 addr_resolv_cleanup(void)
3532 vlan_name_lookup_cleanup();
3533 service_name_lookup_cleanup();
3535 ipx_name_lookup_cleanup();
3536 enterprises_cleanup();
3537 host_name_lookup_cleanup();
3541 str_to_ip(const char *str, void *dst)
3543 return ws_inet_pton4(str, (guint32 *)dst);
3547 str_to_ip6(const char *str, void *dst)
3549 return ws_inet_pton6(str, (ws_in6_addr *)dst);
3553 * convert a 0-terminated string that contains an ethernet address into
3554 * the corresponding sequence of 6 bytes
3555 * eth_bytes is a buffer >= 6 bytes that was allocated by the caller
3558 str_to_eth(const char *str, char *eth_bytes)
3562 if (!parse_ether_address(str, ð, NULL, FALSE))
3565 memcpy(eth_bytes, eth.addr, sizeof(eth.addr));
3570 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3575 * indent-tabs-mode: nil
3578 * vi: set shiftwidth=4 tabstop=8 expandtab:
3579 * :indentSize=4:tabSize=8:noTabs=true: