QUIC: Update IETF draft URL (draft-08)
[metze/wireshark/wip.git] / epan / addr_resolv.c
1 /* addr_resolv.c
2  * Routines for network object lookup
3  *
4  * Laurent Deniel <laurent.deniel@free.fr>
5  *
6  * Add option to resolv VLAN ID to describing name
7  * Uli Heilmeier, March 2016
8  *
9  * Wireshark - Network traffic analyzer
10  * By Gerald Combs <gerald@wireshark.org>
11  * Copyright 1998 Gerald Combs
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26  */
27
28 #include "config.h"
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <errno.h>
34
35 #include <wsutil/strtoi.h>
36
37 /*
38  * Win32 doesn't have SIGALRM (and it's the OS where name lookup calls
39  * are most likely to take a long time, given the way address-to-name
40  * lookups are done over NBNS).
41  *
42  * macOS does have SIGALRM, but if you longjmp() out of a name resolution
43  * call in a signal handler, you might crash, because the state of the
44  * resolution code that sends messages to lookupd might be inconsistent
45  * if you jump out of it in middle of a call.
46  *
47  * There's no guarantee that longjmp()ing out of name resolution calls
48  * will work on *any* platform; OpenBSD got rid of the alarm/longjmp
49  * code in tcpdump, to avoid those sorts of problems, and that was
50  * picked up by tcpdump.org tcpdump.
51  *
52  * So, for now, we do not use alarm() and SIGALRM to time out host name
53  * lookups.  If we get a lot of complaints about lookups taking a long time,
54  * we can reconsider that decision.  (Note that tcpdump originally added
55  * such a timeout mechanism that for the benefit of systems using NIS to
56  * look up host names; that might now be fixed in NIS implementations, for
57  * those sites still using NIS rather than DNS for that....  tcpdump no
58  * longer does that, for the same reasons that we don't.)
59  *
60  * If we're using an asynchronous DNS resolver, that shouldn't be an issue.
61  * If we're using a synchronous name lookup mechanism (which we'd do mainly
62  * to support resolving addresses and host names using more mechanisms than
63  * just DNS, such as NIS, NBNS, or Mr. Hosts File), we could do that in
64  * a separate thread, making it, in effect, asynchronous.
65  */
66
67 #ifdef HAVE_NETINET_IN_H
68 # include <netinet/in.h>
69 #endif
70
71 #ifdef HAVE_NETDB_H
72 #include <netdb.h>
73 #endif
74
75 #ifdef HAVE_SYS_SOCKET_H
76 #include <sys/socket.h>     /* needed to define AF_ values on UNIX */
77 #endif
78
79 #ifdef _WIN32
80 #include <winsock2.h>       /* needed to define AF_ values on Windows */
81 #include <ws2tcpip.h>
82 #endif
83
84 #ifdef HAVE_C_ARES
85 # ifdef _WIN32
86 #  define socklen_t unsigned int
87 # endif
88 # include <ares.h>
89 # include <ares_version.h>
90 #endif  /* HAVE_C_ARES */
91
92 #include <glib.h>
93
94 #include "packet.h"
95 #include "addr_and_mask.h"
96 #include "ipv6.h"
97 #include "addr_resolv.h"
98 #include "wsutil/filesystem.h"
99
100 #include <wsutil/report_message.h>
101 #include <wsutil/file_util.h>
102 #include <wsutil/pint.h>
103 #include <wsutil/inet_addr.h>
104
105 #include <epan/strutil.h>
106 #include <epan/to_str-int.h>
107 #include <epan/prefs.h>
108
109 #define ENAME_HOSTS     "hosts"
110 #define ENAME_SUBNETS   "subnets"
111 #define ENAME_ETHERS    "ethers"
112 #define ENAME_IPXNETS   "ipxnets"
113 #define ENAME_MANUF     "manuf"
114 #define ENAME_WKA       "wka"
115 #define ENAME_SERVICES  "services"
116 #define ENAME_VLANS     "vlans"
117 #define ENAME_SS7PCS    "ss7pcs"
118 #define ENAME_ENTERPRISES "enterprises.tsv"
119
120 #define HASHETHSIZE      2048
121 #define HASHHOSTSIZE     2048
122 #define HASHIPXNETSIZE    256
123 #define SUBNETLENGTHSIZE   32  /*1-32 inc.*/
124
125 /* hash table used for IPv4 lookup */
126
127 #define HASH_IPV4_ADDRESS(addr) (g_htonl(addr) & (HASHHOSTSIZE - 1))
128
129
130 typedef struct sub_net_hashipv4 {
131     guint             addr;
132     /* XXX: No longer needed?*/
133     guint8            flags;          /* B0 dummy_entry, B1 resolve, B2 If the address is used in the trace */
134     struct sub_net_hashipv4   *next;
135     gchar             name[MAXNAMELEN];
136 } sub_net_hashipv4_t;
137
138 /* Array of entries of subnets of different lengths */
139 typedef struct {
140     gsize        mask_length;      /*1-32*/
141     guint32      mask;             /* e.g. 255.255.255.*/
142     sub_net_hashipv4_t** subnet_addresses; /* Hash table of subnet addresses */
143 } subnet_length_entry_t;
144
145
146 /* hash table used for IPX network lookup */
147
148 /* XXX - check goodness of hash function */
149
150 #define HASH_IPX_NET(net)   ((net) & (HASHIPXNETSIZE - 1))
151
152 typedef struct hashipxnet {
153     guint               addr;
154     struct hashipxnet  *next;
155     gchar               name[MAXNAMELEN];
156 } hashipxnet_t;
157
158 typedef struct hashvlan {
159     guint               id;
160 /*    struct hashvlan     *next; */
161     gchar               name[MAXVLANNAMELEN];
162 } hashvlan_t;
163
164 typedef struct ss7pc {
165     guint32             id; /* 1st byte NI, 3 following bytes: Point Code */
166     gchar               pc_addr[MAXNAMELEN];
167     gchar               name[MAXNAMELEN];
168 } hashss7pc_t;
169
170 /* hash tables used for ethernet and manufacturer lookup */
171 #define HASHETHER_STATUS_UNRESOLVED     1
172 #define HASHETHER_STATUS_RESOLVED_DUMMY 2
173 #define HASHETHER_STATUS_RESOLVED_NAME  3
174
175 struct hashether {
176     guint             status;  /* (See above) */
177     guint8            addr[6];
178     char              hexaddr[6*3];
179     char              resolved_name[MAXNAMELEN];
180 };
181
182 struct hashmanuf {
183     guint             status;  /* (See above) */
184     guint8            addr[3];
185     char              hexaddr[3*3];
186     char              resolved_name[MAXNAMELEN];
187     char              resolved_longname[MAXNAMELEN];
188 };
189
190 /* internal ethernet type */
191 typedef struct _ether
192 {
193     guint8            addr[6];
194     char              name[MAXNAMELEN];
195     char              longname[MAXNAMELEN];
196 } ether_t;
197
198 /* internal ipxnet type */
199 typedef struct _ipxnet
200 {
201     guint             addr;
202     char              name[MAXNAMELEN];
203 } ipxnet_t;
204
205 /* internal vlan type */
206 typedef struct _vlan
207 {
208     guint             id;
209     char              name[MAXVLANNAMELEN];
210 } vlan_t;
211
212 static wmem_map_t *ipxnet_hash_table = NULL;
213 static wmem_map_t *ipv4_hash_table = NULL;
214 static wmem_map_t *ipv6_hash_table = NULL;
215 static wmem_map_t *vlan_hash_table = NULL;
216 static wmem_map_t *ss7pc_hash_table = NULL;
217
218 static wmem_list_t *manually_resolved_ipv4_list = NULL;
219 static wmem_list_t *manually_resolved_ipv6_list = NULL;
220
221 typedef struct _resolved_ipv4
222 {
223     guint32          host_addr;
224     char             name[MAXNAMELEN];
225 } resolved_ipv4_t;
226
227 typedef struct _resolved_ipv6
228 {
229     ws_in6_addr  ip6_addr;
230     char               name[MAXNAMELEN];
231 } resolved_ipv6_t;
232
233 static addrinfo_lists_t addrinfo_lists = { NULL, NULL};
234
235 struct cb_serv_data {
236     gchar       *service;
237     port_type    proto;
238 };
239
240 static wmem_map_t *manuf_hashtable = NULL;
241 static wmem_map_t *wka_hashtable = NULL;
242 static wmem_map_t *eth_hashtable = NULL;
243 static wmem_map_t *serv_port_hashtable = NULL;
244 static GHashTable *enterprises_hashtable = NULL;
245
246 static subnet_length_entry_t subnet_length_entries[SUBNETLENGTHSIZE]; /* Ordered array of entries */
247 static gboolean have_subnet_entry = FALSE;
248
249 static gboolean new_resolved_objects = FALSE;
250
251 static GPtrArray* extra_hosts_files = NULL;
252
253 static hashether_t *add_eth_name(const guint8 *addr, const gchar *name);
254 static void add_serv_port_cb(const guint32 port, gpointer ptr);
255
256
257 /* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx#existing
258  * One-at-a-Time hash
259  */
260 static guint32
261 ipv6_oat_hash(gconstpointer key)
262 {
263     int len = 16;
264     const unsigned char *p = (const unsigned char *)key;
265     guint32 h = 0;
266     int i;
267
268     for ( i = 0; i < len; i++ ) {
269         h += p[i];
270         h += ( h << 10 );
271         h ^= ( h >> 6 );
272     }
273
274     h += ( h << 3 );
275     h ^= ( h >> 11 );
276     h += ( h << 15 );
277
278     return h;
279 }
280
281 static gboolean
282 ipv6_equal(gconstpointer v1, gconstpointer v2)
283 {
284
285     if (memcmp(v1, v2, sizeof (ws_in6_addr)) == 0) {
286         return TRUE;
287     }
288
289     return FALSE;
290 }
291
292 /*
293  * Flag controlling what names to resolve.
294  */
295 e_addr_resolve gbl_resolv_flags = {
296     TRUE,   /* mac_name */
297     FALSE,  /* network_name */
298     FALSE,  /* transport_name */
299     TRUE,   /* dns_pkt_addr_resolution */
300     TRUE,   /* use_external_net_name_resolver */
301     FALSE,  /* load_hosts_file_from_profile_only */
302     FALSE,  /* vlan_name */
303     FALSE   /* ss7 point code names */
304 };
305 #ifdef HAVE_C_ARES
306 static guint name_resolve_concurrency = 500;
307 #endif
308
309 /*
310  *  Global variables (can be changed in GUI sections)
311  *  XXX - they could be changed in GUI code, but there's currently no
312  *  GUI code to change them.
313  */
314
315 gchar *g_ethers_path    = NULL;     /* global ethers file     */
316 gchar *g_pethers_path   = NULL;     /* personal ethers file   */
317 gchar *g_wka_path       = NULL;     /* global well-known-addresses file */
318 gchar *g_manuf_path     = NULL;     /* global manuf file      */
319 gchar *g_ipxnets_path   = NULL;     /* global ipxnets file    */
320 gchar *g_pipxnets_path  = NULL;     /* personal ipxnets file  */
321 gchar *g_services_path  = NULL;     /* global services file   */
322 gchar *g_pservices_path = NULL;     /* personal services file */
323 gchar *g_pvlan_path     = NULL;     /* personal vlans file    */
324 gchar *g_ss7pcs_path    = NULL;     /* personal ss7pcs file   */
325 gchar *g_enterprises_path = NULL;   /* global enterprises file   */
326 gchar *g_penterprises_path = NULL;  /* personal enterprises file */
327                                     /* first resolving call   */
328
329 /* c-ares */
330 #ifdef HAVE_C_ARES
331 /*
332  * Submitted queries trigger a callback (c_ares_ghba_cb()).
333  * Queries are added to c_ares_queue_head. During processing, queries are
334  * popped off the front of c_ares_queue_head and submitted using
335  * ares_gethostbyaddr().
336  * The callback processes the response, then frees the request.
337  */
338 typedef struct _async_dns_queue_msg
339 {
340     union {
341         guint32           ip4;
342         ws_in6_addr ip6;
343     } addr;
344     int                 family;
345 } async_dns_queue_msg_t;
346
347 typedef struct _async_hostent {
348     int addr_size;
349     int   copied;
350     void *addrp;
351 } async_hostent_t;
352
353 ares_channel ghba_chan; /* ares_gethostbyaddr -- Usually non-interactive, no timeout */
354 ares_channel ghbn_chan; /* ares_gethostbyname -- Usually interactive, timeout */
355
356 static  gboolean  async_dns_initialized = FALSE;
357 static  guint       async_dns_in_flight = 0;
358 static  wmem_list_t *async_dns_queue_head = NULL;
359
360 /* push a dns request */
361 static void
362 add_async_dns_ipv4(int type, guint32 addr)
363 {
364     async_dns_queue_msg_t *msg;
365
366     msg = wmem_new(wmem_epan_scope(), async_dns_queue_msg_t);
367     msg->family = type;
368     msg->addr.ip4 = addr;
369     wmem_list_append(async_dns_queue_head, (gpointer) msg);
370 }
371 #endif /* HAVE_C_ARES */
372
373 typedef struct {
374     guint32      mask;
375     gsize        mask_length;
376     const gchar* name; /* Shallow copy */
377 } subnet_entry_t;
378
379 /*
380  *  Miscellaneous functions
381  */
382
383 static int
384 fgetline(char **buf, int *size, FILE *fp)
385 {
386     int len;
387     int c;
388
389     if (fp == NULL || buf == NULL)
390         return -1;
391
392     if (*buf == NULL) {
393         if (*size == 0)
394             *size = BUFSIZ;
395
396         *buf = (char *)wmem_alloc(wmem_epan_scope(), *size);
397     }
398
399     g_assert(*buf);
400     g_assert(*size > 0);
401
402     if (feof(fp))
403         return -1;
404
405     len = 0;
406     while ((c = ws_getc_unlocked(fp)) != EOF && c != '\r' && c != '\n') {
407         if (len+1 >= *size) {
408             *buf = (char *)wmem_realloc(wmem_epan_scope(), *buf, *size += BUFSIZ);
409         }
410         (*buf)[len++] = c;
411     }
412
413     if (len == 0 && c == EOF)
414         return -1;
415
416     (*buf)[len] = '\0';
417
418     return len;
419
420 } /* fgetline */
421
422
423 /*
424  *  Local function definitions
425  */
426 static subnet_entry_t subnet_lookup(const guint32 addr);
427 static void subnet_entry_set(guint32 subnet_addr, const guint8 mask_length, const gchar* name);
428
429
430 static void
431 add_service_name(port_type proto, const guint port, const char *service_name)
432 {
433     serv_port_t *serv_port_table;
434     int *key;
435
436     key = (int *)wmem_new(wmem_epan_scope(), int);
437     *key = port;
438
439     serv_port_table = (serv_port_t *)wmem_map_lookup(serv_port_hashtable, &port);
440     if (serv_port_table == NULL) {
441         serv_port_table = wmem_new0(wmem_epan_scope(), serv_port_t);
442         wmem_map_insert(serv_port_hashtable, key, serv_port_table);
443     }
444     else {
445         wmem_free(wmem_epan_scope(), key);
446     }
447
448     switch(proto) {
449         case PT_TCP:
450             wmem_free(wmem_epan_scope(), serv_port_table->tcp_name);
451             serv_port_table->tcp_name = wmem_strdup(wmem_epan_scope(), service_name);
452             break;
453         case PT_UDP:
454             wmem_free(wmem_epan_scope(), serv_port_table->udp_name);
455             serv_port_table->udp_name = wmem_strdup(wmem_epan_scope(), service_name);
456             break;
457         case PT_SCTP:
458             wmem_free(wmem_epan_scope(), serv_port_table->sctp_name);
459             serv_port_table->sctp_name = wmem_strdup(wmem_epan_scope(), service_name);
460             break;
461         case PT_DCCP:
462             wmem_free(wmem_epan_scope(), serv_port_table->dccp_name);
463             serv_port_table->dccp_name = wmem_strdup(wmem_epan_scope(), service_name);
464             break;
465         default:
466             return;
467             /* Should not happen */
468     }
469
470     new_resolved_objects = TRUE;
471 }
472
473
474 static void
475 parse_service_line (char *line)
476 {
477     gchar *cp;
478     gchar *service;
479     gchar *port;
480     port_type proto;
481     struct cb_serv_data cb_data;
482     range_t *port_rng = NULL;
483
484     if ((cp = strchr(line, '#')))
485         *cp = '\0';
486
487     if ((cp = strtok(line, " \t")) == NULL)
488         return;
489
490     service = cp;
491
492     if ((cp = strtok(NULL, " \t")) == NULL)
493         return;
494
495     port = cp;
496
497     if (strtok(cp, "/") == NULL)
498         return;
499
500     if (range_convert_str(NULL, &port_rng, port, G_MAXUINT16) != CVT_NO_ERROR) {
501         wmem_free (NULL, port_rng);
502         return;
503     }
504
505     while ((cp = strtok(NULL, "/")) != NULL) {
506         if (strcmp(cp, "tcp") == 0) {
507             proto = PT_TCP;
508         }
509         else if (strcmp(cp, "udp") == 0) {
510             proto = PT_UDP;
511         }
512         else if (strcmp(cp, "sctp") == 0) {
513             proto = PT_SCTP;
514         }
515         else if (strcmp(cp, "dccp") == 0) {
516             proto = PT_DCCP;
517         }
518         else {
519             break;
520         }
521         cb_data.service = service;
522         cb_data.proto = proto;
523         range_foreach(port_rng, add_serv_port_cb, &cb_data);
524     }
525
526     wmem_free (NULL, port_rng);
527 } /* parse_service_line */
528
529
530 static void
531 add_serv_port_cb(const guint32 port, gpointer ptr)
532 {
533     struct cb_serv_data *cb_data = (struct cb_serv_data *)ptr;
534
535     if ( port ) {
536         add_service_name(cb_data->proto, port, cb_data->service);
537     }
538 }
539
540
541 static gboolean
542 parse_services_file(const char * path)
543 {
544     FILE *serv_p;
545     static int     size = 0;
546     static char   *buf = NULL;
547
548     /* services hash table initialization */
549     serv_p = ws_fopen(path, "r");
550
551     if (serv_p == NULL)
552         return FALSE;
553
554     while (fgetline(&buf, &size, serv_p) >= 0) {
555         parse_service_line(buf);
556     }
557
558     fclose(serv_p);
559     return TRUE;
560 }
561
562 /* -----------------
563  * unsigned integer to ascii
564  */
565 static gchar *
566 wmem_utoa(wmem_allocator_t *allocator, guint port)
567 {
568     gchar *bp = (gchar *)wmem_alloc(allocator, MAXNAMELEN);
569
570     /* XXX, guint32_to_str() ? */
571     guint32_to_str_buf(port, bp, MAXNAMELEN);
572     return bp;
573 }
574
575 static const gchar *
576 _serv_name_lookup(port_type proto, guint port, serv_port_t **value_ret)
577 {
578     serv_port_t *serv_port_table;
579
580     serv_port_table = (serv_port_t *)wmem_map_lookup(serv_port_hashtable, &port);
581
582     if (value_ret != NULL)
583         *value_ret = serv_port_table;
584
585     if (serv_port_table == NULL)
586         return NULL;
587
588     switch (proto) {
589         case PT_UDP:
590             return serv_port_table->udp_name;
591         case PT_TCP:
592             return serv_port_table->tcp_name;
593         case PT_SCTP:
594             return serv_port_table->sctp_name;
595         case PT_DCCP:
596             return serv_port_table->dccp_name;
597         default:
598             break;
599     }
600     return NULL;
601 }
602
603 const gchar *
604 try_serv_name_lookup(port_type proto, guint port)
605 {
606     return _serv_name_lookup(proto, port, NULL);
607 }
608
609 const gchar *
610 serv_name_lookup(port_type proto, guint port)
611 {
612     serv_port_t *serv_port_table = NULL;
613     const char *name;
614     guint *key;
615
616     name = _serv_name_lookup(proto, port, &serv_port_table);
617     if (name != NULL)
618         return name;
619
620     if (serv_port_table == NULL) {
621         key = (guint *)wmem_new(wmem_epan_scope(), guint);
622         *key = port;
623         serv_port_table = wmem_new0(wmem_epan_scope(), serv_port_t);
624         wmem_map_insert(serv_port_hashtable, key, serv_port_table);
625     }
626     if (serv_port_table->numeric == NULL) {
627         serv_port_table->numeric = wmem_strdup_printf(wmem_epan_scope(), "%u", port);
628     }
629
630     return serv_port_table->numeric;
631 }
632
633 static void
634 initialize_services(void)
635 {
636     gboolean parse_file = TRUE;
637     g_assert(serv_port_hashtable == NULL);
638     serv_port_hashtable = wmem_map_new(wmem_epan_scope(), g_int_hash, g_int_equal);
639
640     /* Compute the pathname of the services file. */
641     if (g_services_path == NULL) {
642         g_services_path = get_datafile_path(ENAME_SERVICES);
643     }
644     parse_services_file(g_services_path);
645
646     /* Compute the pathname of the personal services file */
647     if (g_pservices_path == NULL) {
648         /* Check profile directory before personal configuration */
649         g_pservices_path = get_persconffile_path(ENAME_SERVICES, TRUE);
650         if (!parse_services_file(g_pservices_path)) {
651             g_free(g_pservices_path);
652             g_pservices_path = get_persconffile_path(ENAME_SERVICES, FALSE);
653         } else {
654             parse_file = FALSE;
655         }
656     }
657     if (parse_file) {
658         parse_services_file(g_pservices_path);
659     }
660 }
661
662 static void
663 service_name_lookup_cleanup(void)
664 {
665     serv_port_hashtable = NULL;
666     g_free(g_services_path);
667     g_services_path = NULL;
668     g_free(g_pservices_path);
669     g_pservices_path = NULL;
670 }
671
672 static void
673 parse_enterprises_line (char *line)
674 {
675     char *tok, *dec_str, *org_str;
676     guint32 dec;
677
678     if ((tok = strchr(line, '#')))
679         *tok = '\0';
680     dec_str = strtok(line, " \t");
681     if (!dec_str)
682         return;
683     org_str = strtok(NULL, ""); /* everything else */
684     if (org_str)
685         org_str = g_strstrip(org_str);
686     if (!org_str)
687         return;
688     if (!ws_strtou32(dec_str, NULL, &dec))
689         return;
690     g_hash_table_replace(enterprises_hashtable, GUINT_TO_POINTER(dec), g_strdup(org_str));
691 }
692
693
694 static gboolean
695 parse_enterprises_file(const char * path)
696 {
697     FILE *fp;
698     static int size = 0;
699     static char *buf = NULL;
700
701     fp = ws_fopen(path, "r");
702     if (fp == NULL)
703         return FALSE;
704
705     while (fgetline(&buf, &size, fp) >= 0) {
706         parse_enterprises_line(buf);
707     }
708
709     fclose(fp);
710     return TRUE;
711 }
712
713 static void
714 initialize_enterprises(void)
715 {
716     g_assert(enterprises_hashtable == NULL);
717     enterprises_hashtable = g_hash_table_new_full(NULL, NULL, NULL, g_free);
718
719     if (g_enterprises_path == NULL) {
720         g_enterprises_path = get_datafile_path(ENAME_ENTERPRISES);
721     }
722     parse_enterprises_file(g_enterprises_path);
723
724     if (g_penterprises_path == NULL) {
725         g_penterprises_path = get_persconffile_path(ENAME_ENTERPRISES, FALSE);
726     }
727     parse_enterprises_file(g_penterprises_path);
728 }
729
730 const gchar *
731 try_enterprises_lookup(guint32 value)
732 {
733     return (const gchar *)g_hash_table_lookup(enterprises_hashtable, GUINT_TO_POINTER(value));
734 }
735
736 const gchar *
737 enterprises_lookup(guint32 value, const char *unknown_str)
738 {
739     const gchar *s;
740
741     s = try_enterprises_lookup(value);
742     if (s != NULL)
743         return s;
744     if (unknown_str != NULL)
745         return unknown_str;
746     return "<Unknown>";
747 }
748
749 void
750 enterprises_base_custom(char *buf, guint32 value)
751 {
752     const gchar *s;
753
754     if ((s = try_enterprises_lookup(value)) == NULL)
755         s = ITEM_LABEL_UNKNOWN_STR;
756     g_snprintf(buf, ITEM_LABEL_LENGTH, "%s (%u)", s, value);
757 }
758
759 static void
760 enterprises_cleanup(void)
761 {
762     g_assert(enterprises_hashtable);
763     g_hash_table_destroy(enterprises_hashtable);
764     enterprises_hashtable = NULL;
765     g_assert(g_enterprises_path);
766     g_free(g_enterprises_path);
767     g_enterprises_path = NULL;
768     if (g_pservices_path) {
769         g_free(g_pservices_path);
770         g_pservices_path = NULL;
771     }
772 }
773
774 /* Fill in an IP4 structure with info from subnets file or just with the
775  * string form of the address.
776  */
777 static void
778 fill_dummy_ip4(const guint addr, hashipv4_t* volatile tp)
779 {
780     subnet_entry_t subnet_entry;
781
782     /* Overwrite if we get async DNS reply */
783
784     /* Do we have a subnet for this address? */
785     subnet_entry = subnet_lookup(addr);
786     if (0 != subnet_entry.mask) {
787         /* Print name, then '.' then IP address after subnet mask */
788         guint32 host_addr;
789         gchar buffer[WS_INET_ADDRSTRLEN];
790         gchar* paddr;
791         gsize i;
792
793         host_addr = addr & (~(guint32)subnet_entry.mask);
794         ip_to_str_buf((guint8 *)&host_addr, buffer, WS_INET_ADDRSTRLEN);
795         paddr = buffer;
796
797         /* Skip to first octet that is not totally masked
798          * If length of mask is 32, we chomp the whole address.
799          * If the address string starts '.' (should not happen?),
800          * we skip that '.'.
801          */
802         i = subnet_entry.mask_length / 8;
803         while(*(paddr) != '\0' && i > 0) {
804             if (*(++paddr) == '.') {
805                 --i;
806             }
807         }
808
809         /* There are more efficient ways to do this, but this is safe if we
810          * trust g_snprintf and MAXNAMELEN
811          */
812         g_snprintf(tp->name, MAXNAMELEN, "%s%s", subnet_entry.name, paddr);
813     } else {
814         /* XXX: This means we end up printing "1.2.3.4 (1.2.3.4)" in many cases */
815         ip_to_str_buf((const guint8 *)&addr, tp->name, MAXNAMELEN);
816     }
817 }
818
819
820 /* Fill in an IP6 structure with the string form of the address.
821  */
822 static void
823 fill_dummy_ip6(hashipv6_t* volatile tp)
824 {
825     /* Overwrite if we get async DNS reply */
826     g_strlcpy(tp->name, tp->ip6, MAXNAMELEN);
827 }
828
829 #ifdef HAVE_C_ARES
830
831 static void
832 c_ares_ghba_cb(void *arg, int status, int timeouts _U_, struct hostent *he) {
833     async_dns_queue_msg_t *caqm = (async_dns_queue_msg_t *)arg;
834     char **p;
835
836     if (!caqm) return;
837     /* XXX, what to do if async_dns_in_flight == 0? */
838     async_dns_in_flight--;
839
840     if (status == ARES_SUCCESS) {
841         for (p = he->h_addr_list; *p != NULL; p++) {
842             switch(caqm->family) {
843                 case AF_INET:
844                     add_ipv4_name(caqm->addr.ip4, he->h_name);
845                     break;
846                 case AF_INET6:
847                     add_ipv6_name(&caqm->addr.ip6, he->h_name);
848                     break;
849                 default:
850                     /* Throw an exception? */
851                     break;
852             }
853         }
854     }
855     wmem_free(wmem_epan_scope(), caqm);
856 }
857 #endif /* HAVE_C_ARES */
858
859 /* --------------- */
860 static hashipv4_t *
861 new_ipv4(const guint addr)
862 {
863     hashipv4_t *tp = wmem_new(wmem_epan_scope(), hashipv4_t);
864     tp->addr = addr;
865     tp->flags = 0;
866     tp->name[0] = '\0';
867     ip_to_str_buf((const guint8 *)&addr, tp->ip, sizeof(tp->ip));
868     return tp;
869 }
870
871 static hashipv4_t *
872 host_lookup(const guint addr)
873 {
874     hashipv4_t * volatile tp;
875
876     tp = (hashipv4_t *)wmem_map_lookup(ipv4_hash_table, GUINT_TO_POINTER(addr));
877     if (tp == NULL) {
878         /*
879          * We don't already have an entry for this host name; create one,
880          * and then try to resolve it.
881          */
882         tp = new_ipv4(addr);
883         fill_dummy_ip4(addr, tp);
884         wmem_map_insert(ipv4_hash_table, GUINT_TO_POINTER(addr), tp);
885     } else if (tp->flags & TRIED_OR_RESOLVED_MASK) {
886         return tp;
887     }
888
889     /*
890      * This hasn't been resolved yet, and we haven't tried to
891      * resolve it already.
892      */
893
894     if (!gbl_resolv_flags.network_name)
895         return tp;
896
897     if (gbl_resolv_flags.use_external_net_name_resolver) {
898         tp->flags |= TRIED_RESOLVE_ADDRESS;
899
900 #ifdef HAVE_C_ARES
901         if (async_dns_initialized && name_resolve_concurrency > 0) {
902             add_async_dns_ipv4(AF_INET, addr);
903         }
904 #endif
905     }
906
907     return tp;
908
909 } /* host_lookup */
910
911 /* --------------- */
912 static hashipv6_t *
913 new_ipv6(const ws_in6_addr *addr)
914 {
915     hashipv6_t *tp = wmem_new(wmem_epan_scope(), hashipv6_t);
916     memcpy(tp->addr, addr->bytes, sizeof tp->addr);
917     tp->flags = 0;
918     tp->name[0] = '\0';
919     ip6_to_str_buf(addr, tp->ip6, sizeof(tp->ip6));
920     return tp;
921 }
922
923 /* ------------------------------------ */
924 static hashipv6_t *
925 host_lookup6(const ws_in6_addr *addr)
926 {
927     hashipv6_t * volatile tp;
928 #ifdef HAVE_C_ARES
929     async_dns_queue_msg_t *caqm;
930 #endif
931
932     tp = (hashipv6_t *)wmem_map_lookup(ipv6_hash_table, addr);
933     if (tp == NULL) {
934         /*
935          * We don't already have an entry for this host name; create one,
936          * and then try to resolve it.
937          */
938         ws_in6_addr *addr_key;
939
940         addr_key = wmem_new(wmem_epan_scope(), ws_in6_addr);
941         tp = new_ipv6(addr);
942         memcpy(addr_key, addr, 16);
943         fill_dummy_ip6(tp);
944         wmem_map_insert(ipv6_hash_table, addr_key, tp);
945     } else if (tp->flags & TRIED_OR_RESOLVED_MASK) {
946         return tp;
947     }
948
949     /*
950      * This hasn't been resolved yet, and we haven't tried to
951      * resolve it already.
952      */
953
954     if (!gbl_resolv_flags.network_name)
955         return tp;
956
957     if (gbl_resolv_flags.use_external_net_name_resolver) {
958         tp->flags |= TRIED_RESOLVE_ADDRESS;
959 #ifdef HAVE_C_ARES
960         if (async_dns_initialized && name_resolve_concurrency > 0) {
961             caqm = wmem_new(wmem_epan_scope(), async_dns_queue_msg_t);
962             caqm->family = AF_INET6;
963             memcpy(&caqm->addr.ip6, addr, sizeof(caqm->addr.ip6));
964             wmem_list_append(async_dns_queue_head, (gpointer) caqm);
965         }
966 #endif
967     }
968
969     return tp;
970
971 } /* host_lookup6 */
972
973 /*
974  * Ethernet / manufacturer resolution
975  *
976  * The following functions implement ethernet address resolution and
977  * ethers files parsing (see ethers(4)).
978  *
979  * The manuf file has the same format as ethers(4) except that names are
980  * truncated to MAXMANUFLEN-1 (8) characters and that an address contains
981  * only 3 bytes (instead of 6).
982  *
983  * Notes:
984  *
985  * I decide to not use the existing functions (see ethers(3) on some
986  * operating systems) for the following reasons:
987  * - performance gains (use of hash tables and some other enhancements),
988  * - use of two ethers files (system-wide and per user),
989  * - avoid the use of NIS maps,
990  * - lack of these functions on some systems.
991  *
992  * So the following functions do _not_ behave as the standard ones.
993  *
994  * -- Laurent.
995  */
996
997
998 /*
999  * If "accept_mask" is FALSE,  either 3 or 6 bytes are valid, but no other number of bytes is.
1000  * If "accept_mask" is TRUE, parse an up-to-6-byte sequence with an optional
1001  * mask.
1002  */
1003 static gboolean
1004 parse_ether_address(const char *cp, ether_t *eth, unsigned int *mask,
1005         const gboolean accept_mask)
1006 {
1007     int i;
1008     unsigned long num;
1009     char *p;
1010     char sep = '\0';
1011
1012     for (i = 0; i < 6; i++) {
1013         /* Get a hex number, 1 or 2 digits, no sign characters allowed. */
1014         if (!g_ascii_isxdigit(*cp))
1015             return FALSE;
1016         num = strtoul(cp, &p, 16);
1017         if (p == cp)
1018             return FALSE; /* failed */
1019         if (num > 0xFF)
1020             return FALSE; /* not a valid octet */
1021         eth->addr[i] = (guint8) num;
1022         cp = p;     /* skip past the number */
1023
1024         /* OK, what character terminated the octet? */
1025         if (*cp == '/') {
1026             /* "/" - this has a mask. */
1027             if (!accept_mask) {
1028                 /* Entries with masks are not allowed in this file. */
1029                 return FALSE;
1030             }
1031             cp++; /* skip past the '/' to get to the mask */
1032             if (!g_ascii_isdigit(*cp))
1033                 return FALSE;   /* no sign allowed */
1034             num = strtoul(cp, &p, 10);
1035             if (p == cp)
1036                 return FALSE;   /* failed */
1037             cp = p;   /* skip past the number */
1038             if (*cp != '\0' && !g_ascii_isspace(*cp))
1039                 return FALSE;   /* bogus terminator */
1040             if (num == 0 || num >= 48)
1041                 return FALSE;   /* bogus mask */
1042             /* Mask out the bits not covered by the mask */
1043             *mask = (int)num;
1044             for (i = 0; num >= 8; i++, num -= 8)
1045                 ;   /* skip octets entirely covered by the mask */
1046             /* Mask out the first masked octet */
1047             eth->addr[i] &= (0xFF << (8 - num));
1048             i++;
1049             /* Mask out completely-masked-out octets */
1050             for (; i < 6; i++)
1051                 eth->addr[i] = 0;
1052             return TRUE;
1053         }
1054         if (*cp == '\0') {
1055             /* We're at the end of the address, and there's no mask. */
1056             if (i == 2) {
1057                 /* We got 3 bytes, so this is a manufacturer ID. */
1058                 if (!accept_mask) {
1059                     /* Manufacturer IDs are not allowed in this file */
1060                     return FALSE;
1061                 }
1062                 /* Indicate that this is a manufacturer ID (0 is not allowed
1063                    as a mask). */
1064                 *mask = 0;
1065                 return TRUE;
1066             }
1067
1068             if (i == 5) {
1069                 /* We got 6 bytes, so this is a MAC address (48 is not allowed as a mask). */
1070                 if (accept_mask)
1071                     *mask = 48;
1072                 return TRUE;
1073             }
1074
1075             /* We didn't get 3 or 6 bytes, and there's no mask; this is
1076                illegal. */
1077             return FALSE;
1078         } else {
1079             if (sep == '\0') {
1080                 /* We don't know the separator used in this number; it can either
1081                    be ':', '-', or '.'. */
1082                 if (*cp != ':' && *cp != '-' && *cp != '.')
1083                     return FALSE;
1084                 sep = *cp;  /* subsequent separators must be the same */
1085             } else {
1086                 /* It has to be the same as the first separator */
1087                 if (*cp != sep)
1088                     return FALSE;
1089             }
1090         }
1091         cp++;
1092     }
1093
1094     return TRUE;
1095 }
1096
1097 static int
1098 parse_ether_line(char *line, ether_t *eth, unsigned int *mask,
1099         const gboolean accept_mask)
1100 {
1101     /*
1102      *  See the ethers(4) or ethers(5) man page for ethers file format
1103      *  (not available on all systems).
1104      *  We allow both ethernet address separators (':' and '-'),
1105      *  as well as Wireshark's '.' separator.
1106      */
1107
1108     gchar *cp;
1109
1110     line = g_strstrip(line);
1111     if (line[0] == '\0' || line[0] == '#')
1112         return -1;
1113
1114     if ((cp = strchr(line, '#'))) {
1115         cp--;
1116         while (g_ascii_isspace(*cp)) {
1117             cp--;
1118         }
1119         *cp = '\0';
1120     }
1121
1122     if ((cp = strtok(line, " \t")) == NULL)
1123         return -1;
1124
1125     if (!parse_ether_address(cp, eth, mask, accept_mask))
1126         return -1;
1127
1128     if ((cp = strtok(NULL, " \t")) == NULL)
1129         return -1;
1130
1131     g_strlcpy(eth->name, cp, MAXNAMELEN);
1132
1133     if ((cp = strtok(NULL, "")) != NULL)
1134     {
1135         g_strlcpy(eth->longname, cp, MAXNAMELEN);
1136     } else {
1137         /* Make the long name the short name */
1138         g_strlcpy(eth->longname, eth->name, MAXNAMELEN);
1139     }
1140
1141     return 0;
1142
1143 } /* parse_ether_line */
1144
1145 static FILE *eth_p = NULL;
1146
1147 static void
1148 set_ethent(char *path)
1149 {
1150     if (eth_p)
1151         rewind(eth_p);
1152     else
1153         eth_p = ws_fopen(path, "r");
1154 }
1155
1156 static void
1157 end_ethent(void)
1158 {
1159     if (eth_p) {
1160         fclose(eth_p);
1161         eth_p = NULL;
1162     }
1163 }
1164
1165 static ether_t *
1166 get_ethent(unsigned int *mask, const gboolean accept_mask)
1167 {
1168
1169     static ether_t eth;
1170     static int     size = 0;
1171     static char   *buf = NULL;
1172
1173     if (eth_p == NULL)
1174         return NULL;
1175
1176     while (fgetline(&buf, &size, eth_p) >= 0) {
1177         if (parse_ether_line(buf, &eth, mask, accept_mask) == 0) {
1178             return &eth;
1179         }
1180     }
1181
1182     return NULL;
1183
1184 } /* get_ethent */
1185
1186 static ether_t *
1187 get_ethbyaddr(const guint8 *addr)
1188 {
1189
1190     ether_t *eth;
1191
1192     set_ethent(g_pethers_path);
1193
1194     while (((eth = get_ethent(NULL, FALSE)) != NULL) && memcmp(addr, eth->addr, 6) != 0)
1195         ;
1196
1197     if (eth == NULL) {
1198         end_ethent();
1199
1200         set_ethent(g_ethers_path);
1201
1202         while (((eth = get_ethent(NULL, FALSE)) != NULL) && memcmp(addr, eth->addr, 6) != 0)
1203             ;
1204
1205         end_ethent();
1206     }
1207
1208     return eth;
1209
1210 } /* get_ethbyaddr */
1211
1212 static hashmanuf_t *
1213 manuf_hash_new_entry(const guint8 *addr, char* name, char* longname)
1214 {
1215     int    *manuf_key;
1216     hashmanuf_t *manuf_value;
1217     char *endp;
1218
1219     /* manuf needs only the 3 most significant octets of the ethernet address */
1220     manuf_key = (int *)wmem_new(wmem_epan_scope(), int);
1221     *manuf_key = (int)((addr[0] << 16) + (addr[1] << 8) + addr[2]);
1222     manuf_value = wmem_new(wmem_epan_scope(), hashmanuf_t);
1223
1224     memcpy(manuf_value->addr, addr, 3);
1225     if (name != NULL) {
1226         g_strlcpy(manuf_value->resolved_name, name, MAXNAMELEN);
1227         manuf_value->status = HASHETHER_STATUS_RESOLVED_NAME;
1228         if (longname != NULL) {
1229             g_strlcpy(manuf_value->resolved_longname, longname, MAXNAMELEN);
1230         }
1231         else {
1232             g_strlcpy(manuf_value->resolved_longname, name, MAXNAMELEN);
1233         }
1234     }
1235     else {
1236         manuf_value->status = HASHETHER_STATUS_UNRESOLVED;
1237         manuf_value->resolved_name[0] = '\0';
1238         manuf_value->resolved_longname[0] = '\0';
1239     }
1240     /* Values returned by bytes_to_hexstr_punct() are *not* null-terminated */
1241     endp = bytes_to_hexstr_punct(manuf_value->hexaddr, addr, sizeof(manuf_value->addr), ':');
1242     *endp = '\0';
1243
1244     wmem_map_insert(manuf_hashtable, manuf_key, manuf_value);
1245     return manuf_value;
1246 }
1247
1248 static void
1249 wka_hash_new_entry(const guint8 *addr, char* name)
1250 {
1251     guint8 *wka_key;
1252
1253     wka_key = (guint8 *)wmem_alloc(wmem_epan_scope(), 6);
1254     memcpy(wka_key, addr, 6);
1255
1256     wmem_map_insert(wka_hashtable, wka_key, wmem_strdup(wmem_epan_scope(), name));
1257 }
1258
1259 static void
1260 add_manuf_name(const guint8 *addr, unsigned int mask, gchar *name, gchar *longname)
1261 {
1262     switch (mask)
1263     {
1264     case 0:
1265         /* This is a manufacturer ID; add it to the manufacturer ID hash table */
1266         manuf_hash_new_entry(addr, name, longname);
1267         break;
1268
1269     case 48:
1270         /* This is a well-known MAC address; add it to the Ethernet hash table */
1271         add_eth_name(addr, name);
1272         break;
1273
1274     default:
1275         /* This is a range of well-known addresses; add it to the well-known-address table */
1276         wka_hash_new_entry(addr, name);
1277         break;
1278     }
1279 } /* add_manuf_name */
1280
1281 static hashmanuf_t *
1282 manuf_name_lookup(const guint8 *addr)
1283 {
1284     gint32       manuf_key = 0;
1285     guint8       oct;
1286     hashmanuf_t  *manuf_value;
1287
1288     /* manuf needs only the 3 most significant octets of the ethernet address */
1289     manuf_key = addr[0];
1290     manuf_key = manuf_key<<8;
1291     oct = addr[1];
1292     manuf_key = manuf_key | oct;
1293     manuf_key = manuf_key<<8;
1294     oct = addr[2];
1295     manuf_key = manuf_key | oct;
1296
1297
1298     /* first try to find a "perfect match" */
1299     manuf_value = (hashmanuf_t*)wmem_map_lookup(manuf_hashtable, &manuf_key);
1300     if (manuf_value != NULL) {
1301         return manuf_value;
1302     }
1303
1304     /* Mask out the broadcast/multicast flag but not the locally
1305      * administered flag as locally administered means: not assigned
1306      * by the IEEE but the local administrator instead.
1307      * 0x01 multicast / broadcast bit
1308      * 0x02 locally administered bit */
1309     if ((manuf_key & 0x00010000) != 0) {
1310         manuf_key &= 0x00FEFFFF;
1311         manuf_value = (hashmanuf_t*)wmem_map_lookup(manuf_hashtable, &manuf_key);
1312         if (manuf_value != NULL) {
1313             return manuf_value;
1314         }
1315     }
1316
1317     /* Add the address as a hex string */
1318     return manuf_hash_new_entry(addr, NULL, NULL);
1319
1320 } /* manuf_name_lookup */
1321
1322 static gchar *
1323 wka_name_lookup(const guint8 *addr, const unsigned int mask)
1324 {
1325     guint8     masked_addr[6];
1326     guint      num;
1327     gint       i;
1328     gchar     *name;
1329
1330     if (wka_hashtable == NULL) {
1331         return NULL;
1332     }
1333     /* Get the part of the address covered by the mask. */
1334     for (i = 0, num = mask; num >= 8; i++, num -= 8)
1335         masked_addr[i] = addr[i];   /* copy octets entirely covered by the mask */
1336     /* Mask out the first masked octet */
1337     masked_addr[i] = addr[i] & (0xFF << (8 - num));
1338     i++;
1339     /* Zero out completely-masked-out octets */
1340     for (; i < 6; i++)
1341         masked_addr[i] = 0;
1342
1343     name = (gchar *)wmem_map_lookup(wka_hashtable, masked_addr);
1344
1345     return name;
1346
1347 } /* wka_name_lookup */
1348
1349
1350 guint get_hash_ether_status(hashether_t* ether)
1351 {
1352     return ether->status;
1353 }
1354
1355 char* get_hash_ether_hexaddr(hashether_t* ether)
1356 {
1357     return ether->hexaddr;
1358 }
1359
1360 char* get_hash_ether_resolved_name(hashether_t* ether)
1361 {
1362     return ether->resolved_name;
1363 }
1364
1365 static guint
1366 eth_addr_hash(gconstpointer key)
1367 {
1368     return wmem_strong_hash((const guint8 *)key, 6);
1369 }
1370
1371 static gboolean
1372 eth_addr_cmp(gconstpointer a, gconstpointer b)
1373 {
1374     return (memcmp(a, b, 6) == 0);
1375 }
1376
1377 static void
1378 initialize_ethers(void)
1379 {
1380     ether_t *eth;
1381     guint    mask = 0;
1382
1383     /* hash table initialization */
1384     wka_hashtable   = wmem_map_new(wmem_epan_scope(), eth_addr_hash, eth_addr_cmp);
1385     manuf_hashtable = wmem_map_new(wmem_epan_scope(), g_int_hash, g_int_equal);
1386     eth_hashtable   = wmem_map_new(wmem_epan_scope(), eth_addr_hash, eth_addr_cmp);
1387
1388     /* Compute the pathname of the ethers file. */
1389     if (g_ethers_path == NULL) {
1390         g_ethers_path = g_build_filename(get_systemfile_dir(), ENAME_ETHERS, NULL);
1391     }
1392
1393     /* Set g_pethers_path here, but don't actually do anything
1394      * with it. It's used in get_ethbyaddr().
1395      */
1396     if (g_pethers_path == NULL)
1397         g_pethers_path = get_persconffile_path(ENAME_ETHERS, FALSE);
1398
1399     /* Compute the pathname of the manuf file */
1400     if (g_manuf_path == NULL)
1401         g_manuf_path = get_datafile_path(ENAME_MANUF);
1402
1403     /* Read it and initialize the hash table */
1404     set_ethent(g_manuf_path);
1405     while ((eth = get_ethent(&mask, TRUE))) {
1406         add_manuf_name(eth->addr, mask, eth->name, eth->longname);
1407     }
1408     end_ethent();
1409
1410     /* Compute the pathname of the wka file */
1411     if (g_wka_path == NULL)
1412         g_wka_path = get_datafile_path(ENAME_WKA);
1413
1414     /* Read it and initialize the hash table */
1415     set_ethent(g_wka_path);
1416     while ((eth = get_ethent(&mask, TRUE))) {
1417         add_manuf_name(eth->addr, mask, eth->name, eth->longname);
1418     }
1419     end_ethent();
1420
1421 } /* initialize_ethers */
1422
1423 static void
1424 ethers_cleanup(void)
1425 {
1426     g_free(g_ethers_path);
1427     g_ethers_path = NULL;
1428     g_free(g_pethers_path);
1429     g_pethers_path = NULL;
1430     g_free(g_manuf_path);
1431     g_manuf_path = NULL;
1432     g_free(g_wka_path);
1433     g_wka_path = NULL;
1434 }
1435
1436 /* Resolve ethernet address */
1437 static hashether_t *
1438 eth_addr_resolve(hashether_t *tp) {
1439     ether_t      *eth;
1440     hashmanuf_t *manuf_value;
1441     const guint8 *addr = tp->addr;
1442
1443     if ( (eth = get_ethbyaddr(addr)) != NULL) {
1444         g_strlcpy(tp->resolved_name, eth->name, MAXNAMELEN);
1445         tp->status = HASHETHER_STATUS_RESOLVED_NAME;
1446         return tp;
1447     } else {
1448         guint         mask;
1449         gchar        *name;
1450         address       ether_addr;
1451
1452         /* Unknown name.  Try looking for it in the well-known-address
1453            tables for well-known address ranges smaller than 2^24. */
1454         mask = 7;
1455         do {
1456             /* Only the topmost 5 bytes participate fully */
1457             if ((name = wka_name_lookup(addr, mask+40)) != NULL) {
1458                 g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x",
1459                         name, addr[5] & (0xFF >> mask));
1460                 tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1461                 return tp;
1462             }
1463         } while (mask--);
1464
1465         mask = 7;
1466         do {
1467             /* Only the topmost 4 bytes participate fully */
1468             if ((name = wka_name_lookup(addr, mask+32)) != NULL) {
1469                 g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x",
1470                         name, addr[4] & (0xFF >> mask), addr[5]);
1471                 tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1472                 return tp;
1473             }
1474         } while (mask--);
1475
1476         mask = 7;
1477         do {
1478             /* Only the topmost 3 bytes participate fully */
1479             if ((name = wka_name_lookup(addr, mask+24)) != NULL) {
1480                 g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x",
1481                         name, addr[3] & (0xFF >> mask), addr[4], addr[5]);
1482                 tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1483                 return tp;
1484             }
1485         } while (mask--);
1486
1487         /* Now try looking in the manufacturer table. */
1488         manuf_value = manuf_name_lookup(addr);
1489         if ((manuf_value != NULL) && (manuf_value->status != HASHETHER_STATUS_UNRESOLVED)) {
1490             g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x",
1491                     manuf_value->resolved_name, addr[3], addr[4], addr[5]);
1492             tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1493             return tp;
1494         }
1495
1496         /* Now try looking for it in the well-known-address
1497            tables for well-known address ranges larger than 2^24. */
1498         mask = 7;
1499         do {
1500             /* Only the topmost 2 bytes participate fully */
1501             if ((name = wka_name_lookup(addr, mask+16)) != NULL) {
1502                 g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x:%02x",
1503                         name, addr[2] & (0xFF >> mask), addr[3], addr[4],
1504                         addr[5]);
1505                 tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1506                 return tp;
1507             }
1508         } while (mask--);
1509
1510         mask = 7;
1511         do {
1512             /* Only the topmost byte participates fully */
1513             if ((name = wka_name_lookup(addr, mask+8)) != NULL) {
1514                 g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x:%02x:%02x",
1515                         name, addr[1] & (0xFF >> mask), addr[2], addr[3],
1516                         addr[4], addr[5]);
1517                 tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1518                 return tp;
1519             }
1520         } while (mask--);
1521
1522         mask = 7;
1523         do {
1524             /* Not even the topmost byte participates fully */
1525             if ((name = wka_name_lookup(addr, mask)) != NULL) {
1526                 g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x:%02x:%02x:%02x",
1527                         name, addr[0] & (0xFF >> mask), addr[1], addr[2],
1528                         addr[3], addr[4], addr[5]);
1529                 tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1530                 return tp;
1531             }
1532         } while (--mask); /* Work down to the last bit */
1533
1534         /* No match whatsoever. */
1535         set_address(&ether_addr, AT_ETHER, 6, addr);
1536         address_to_str_buf(&ether_addr, tp->resolved_name, MAXNAMELEN);
1537         tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
1538         return tp;
1539     }
1540     g_assert_not_reached();
1541 } /* eth_addr_resolve */
1542
1543 static hashether_t *
1544 eth_hash_new_entry(const guint8 *addr, const gboolean resolve)
1545 {
1546     hashether_t *tp;
1547     char *endp;
1548
1549     tp = wmem_new(wmem_epan_scope(), hashether_t);
1550     memcpy(tp->addr, addr, sizeof(tp->addr));
1551     tp->status = HASHETHER_STATUS_UNRESOLVED;
1552     /* Values returned by bytes_to_hexstr_punct() are *not* null-terminated */
1553     endp = bytes_to_hexstr_punct(tp->hexaddr, addr, sizeof(tp->addr), ':');
1554     *endp = '\0';
1555     tp->resolved_name[0] = '\0';
1556
1557     if (resolve)
1558         eth_addr_resolve(tp);
1559
1560     wmem_map_insert(eth_hashtable, tp->addr, tp);
1561
1562     return tp;
1563 } /* eth_hash_new_entry */
1564
1565 static hashether_t *
1566 add_eth_name(const guint8 *addr, const gchar *name)
1567 {
1568     hashether_t *tp;
1569
1570     tp = (hashether_t *)wmem_map_lookup(eth_hashtable, addr);
1571
1572     if (tp == NULL) {
1573         tp = eth_hash_new_entry(addr, FALSE);
1574     }
1575
1576     if (strcmp(tp->resolved_name, name) != 0) {
1577         g_strlcpy(tp->resolved_name, name, MAXNAMELEN);
1578         tp->status = HASHETHER_STATUS_RESOLVED_NAME;
1579         new_resolved_objects = TRUE;
1580     }
1581
1582     return tp;
1583 } /* add_eth_name */
1584
1585 static hashether_t *
1586 eth_name_lookup(const guint8 *addr, const gboolean resolve)
1587 {
1588     hashether_t  *tp;
1589
1590     tp = (hashether_t *)wmem_map_lookup(eth_hashtable, addr);
1591
1592     if (tp == NULL) {
1593         tp = eth_hash_new_entry(addr, resolve);
1594     } else {
1595         if (resolve && (tp->status == HASHETHER_STATUS_UNRESOLVED)) {
1596             eth_addr_resolve(tp); /* Found but needs to be resolved */
1597         }
1598     }
1599
1600     return tp;
1601
1602 } /* eth_name_lookup */
1603
1604
1605 /* IPXNETS */
1606 static int
1607 parse_ipxnets_line(char *line, ipxnet_t *ipxnet)
1608 {
1609     /*
1610      *  We allow three address separators (':', '-', and '.'),
1611      *  as well as no separators
1612      */
1613
1614     gchar     *cp;
1615     guint32   a, a0, a1, a2, a3;
1616     gboolean  found_single_number = FALSE;
1617
1618     if ((cp = strchr(line, '#')))
1619         *cp = '\0';
1620
1621     if ((cp = strtok(line, " \t\n")) == NULL)
1622         return -1;
1623
1624     /* Either fill a0,a1,a2,a3 and found_single_number is FALSE,
1625      * fill a and found_single_number is TRUE,
1626      * or return -1
1627      */
1628     if (sscanf(cp, "%x:%x:%x:%x", &a0, &a1, &a2, &a3) != 4) {
1629         if (sscanf(cp, "%x-%x-%x-%x", &a0, &a1, &a2, &a3) != 4) {
1630             if (sscanf(cp, "%x.%x.%x.%x", &a0, &a1, &a2, &a3) != 4) {
1631                 if (sscanf(cp, "%x", &a) == 1) {
1632                     found_single_number = TRUE;
1633                 }
1634                 else {
1635                     return -1;
1636                 }
1637             }
1638         }
1639     }
1640
1641     if ((cp = strtok(NULL, " \t\n")) == NULL)
1642         return -1;
1643
1644     if (found_single_number) {
1645         ipxnet->addr = a;
1646     }
1647     else {
1648         ipxnet->addr = (a0 << 24) | (a1 << 16) | (a2 << 8) | a3;
1649     }
1650
1651     g_strlcpy(ipxnet->name, cp, MAXNAMELEN);
1652
1653     return 0;
1654
1655 } /* parse_ipxnets_line */
1656
1657 static FILE *ipxnet_p = NULL;
1658
1659 static void
1660 set_ipxnetent(char *path)
1661 {
1662     if (ipxnet_p)
1663         rewind(ipxnet_p);
1664     else
1665         ipxnet_p = ws_fopen(path, "r");
1666 }
1667
1668 static void
1669 end_ipxnetent(void)
1670 {
1671     if (ipxnet_p) {
1672         fclose(ipxnet_p);
1673         ipxnet_p = NULL;
1674     }
1675 }
1676
1677 static ipxnet_t *
1678 get_ipxnetent(void)
1679 {
1680
1681     static ipxnet_t ipxnet;
1682     static int     size = 0;
1683     static char   *buf = NULL;
1684
1685     if (ipxnet_p == NULL)
1686         return NULL;
1687
1688     while (fgetline(&buf, &size, ipxnet_p) >= 0) {
1689         if (parse_ipxnets_line(buf, &ipxnet) == 0) {
1690             return &ipxnet;
1691         }
1692     }
1693
1694     return NULL;
1695
1696 } /* get_ipxnetent */
1697
1698 static ipxnet_t *
1699 get_ipxnetbyaddr(guint32 addr)
1700 {
1701     ipxnet_t *ipxnet;
1702
1703     set_ipxnetent(g_ipxnets_path);
1704
1705     while (((ipxnet = get_ipxnetent()) != NULL) && (addr != ipxnet->addr) ) ;
1706
1707     if (ipxnet == NULL) {
1708         end_ipxnetent();
1709
1710         set_ipxnetent(g_pipxnets_path);
1711
1712         while (((ipxnet = get_ipxnetent()) != NULL) && (addr != ipxnet->addr) )
1713             ;
1714
1715         end_ipxnetent();
1716     }
1717
1718     return ipxnet;
1719
1720 } /* get_ipxnetbyaddr */
1721
1722 static void
1723 initialize_ipxnets(void)
1724 {
1725     /* Compute the pathname of the ipxnets file.
1726      *
1727      * XXX - is there a notion of an "ipxnets file" in any flavor of
1728      * UNIX, or with any add-on Netware package for UNIX?  If not,
1729      * should the UNIX version of the ipxnets file be in the datafile
1730      * directory as well?
1731      */
1732     if (g_ipxnets_path == NULL) {
1733         g_ipxnets_path = wmem_strdup_printf(wmem_epan_scope(), "%s" G_DIR_SEPARATOR_S "%s",
1734                 get_systemfile_dir(), ENAME_IPXNETS);
1735     }
1736
1737     /* Set g_pipxnets_path here, but don't actually do anything
1738      * with it. It's used in get_ipxnetbyaddr().
1739      */
1740     if (g_pipxnets_path == NULL)
1741         g_pipxnets_path = get_persconffile_path(ENAME_IPXNETS, FALSE);
1742
1743 } /* initialize_ipxnets */
1744
1745 static void
1746 ipx_name_lookup_cleanup(void)
1747 {
1748     ipxnet_hash_table = NULL;
1749     g_free(g_pipxnets_path);
1750     g_pipxnets_path = NULL;
1751 }
1752
1753 static gchar *
1754 ipxnet_name_lookup(wmem_allocator_t *allocator, const guint addr)
1755 {
1756     hashipxnet_t *tp;
1757     ipxnet_t *ipxnet;
1758
1759     tp = (hashipxnet_t *)wmem_map_lookup(ipxnet_hash_table, &addr);
1760     if (tp == NULL) {
1761         int *key;
1762
1763         key = (int *)wmem_new(wmem_epan_scope(), int);
1764         *key = addr;
1765         tp = wmem_new(wmem_epan_scope(), hashipxnet_t);
1766         wmem_map_insert(ipxnet_hash_table, key, tp);
1767     } else {
1768         return wmem_strdup(allocator, tp->name);
1769     }
1770
1771     /* fill in a new entry */
1772
1773     tp->addr = addr;
1774
1775     if ( (ipxnet = get_ipxnetbyaddr(addr)) == NULL) {
1776         /* unknown name */
1777         g_snprintf(tp->name, MAXNAMELEN, "%X", addr);
1778
1779     } else {
1780         g_strlcpy(tp->name, ipxnet->name, MAXNAMELEN);
1781     }
1782
1783     return wmem_strdup(allocator, tp->name);
1784
1785 } /* ipxnet_name_lookup */
1786
1787 /* VLANS */
1788 static int
1789 parse_vlan_line(char *line, vlan_t *vlan)
1790 {
1791     gchar     *cp;
1792     guint16   id;
1793
1794     if ((cp = strchr(line, '#')))
1795         *cp = '\0';
1796
1797     if ((cp = strtok(line, " \t\n")) == NULL)
1798         return -1;
1799
1800     if (sscanf(cp, "%" G_GUINT16_FORMAT, &id) == 1) {
1801         vlan->id = id;
1802     }
1803     else {
1804         return -1;
1805     }
1806
1807     if ((cp = strtok(NULL, "\t\n")) == NULL)
1808         return -1;
1809
1810     g_strlcpy(vlan->name, cp, MAXVLANNAMELEN);
1811
1812     return 0;
1813
1814 } /* parse_vlan_line */
1815
1816 static FILE *vlan_p = NULL;
1817
1818 static void
1819 set_vlanent(char *path)
1820 {
1821     if (vlan_p)
1822         rewind(vlan_p);
1823     else
1824         vlan_p = ws_fopen(path, "r");
1825 }
1826
1827 static void
1828 end_vlanent(void)
1829 {
1830     if (vlan_p) {
1831         fclose(vlan_p);
1832         vlan_p = NULL;
1833     }
1834 }
1835
1836 static vlan_t *
1837 get_vlanent(void)
1838 {
1839
1840     static vlan_t vlan;
1841     static int     size = 0;
1842     static char   *buf = NULL;
1843
1844     if (vlan_p == NULL)
1845         return NULL;
1846
1847     while (fgetline(&buf, &size, vlan_p) >= 0) {
1848         if (parse_vlan_line(buf, &vlan) == 0) {
1849             return &vlan;
1850         }
1851     }
1852
1853     return NULL;
1854
1855 } /* get_vlanent */
1856
1857 static vlan_t *
1858 get_vlannamebyid(guint16 id)
1859 {
1860     vlan_t *vlan;
1861
1862     set_vlanent(g_pvlan_path);
1863
1864     while (((vlan = get_vlanent()) != NULL) && (id != vlan->id) ) ;
1865
1866     if (vlan == NULL) {
1867         end_vlanent();
1868
1869     }
1870
1871     return vlan;
1872
1873 } /* get_vlannamebyid */
1874
1875 static void
1876 initialize_vlans(void)
1877 {
1878     g_assert(vlan_hash_table == NULL);
1879     vlan_hash_table = wmem_map_new(wmem_epan_scope(), g_int_hash, g_int_equal);
1880
1881     /* Set g_pvlan_path here, but don't actually do anything
1882      * with it. It's used in get_vlannamebyid()
1883      */
1884     if (g_pvlan_path == NULL)
1885         g_pvlan_path = get_persconffile_path(ENAME_VLANS, FALSE);
1886
1887 } /* initialize_vlans */
1888
1889 static void
1890 vlan_name_lookup_cleanup(void)
1891 {
1892     vlan_hash_table = NULL;
1893     g_free(g_pvlan_path);
1894     g_pvlan_path = NULL;
1895 }
1896
1897 static const gchar *
1898 vlan_name_lookup(const guint id)
1899 {
1900     hashvlan_t *tp;
1901     vlan_t *vlan;
1902
1903     tp = (hashvlan_t *)wmem_map_lookup(vlan_hash_table, &id);
1904     if (tp == NULL) {
1905         int *key;
1906
1907         key = (int *)wmem_new(wmem_epan_scope(), int);
1908         *key = id;
1909         tp = wmem_new(wmem_epan_scope(), hashvlan_t);
1910         wmem_map_insert(vlan_hash_table, key, tp);
1911     } else {
1912         return tp->name;
1913     }
1914
1915     /* fill in a new entry */
1916
1917     tp->id = id;
1918
1919     if ( (vlan = get_vlannamebyid(id)) == NULL) {
1920         /* unknown name */
1921         g_snprintf(tp->name, MAXVLANNAMELEN, "<%u>", id);
1922
1923     } else {
1924         g_strlcpy(tp->name, vlan->name, MAXVLANNAMELEN);
1925     }
1926
1927     return tp->name;
1928
1929 } /* vlan_name_lookup */
1930 /* VLAN END */
1931
1932 static gboolean
1933 read_hosts_file (const char *hostspath, gboolean store_entries)
1934 {
1935     FILE *hf;
1936     char *line = NULL;
1937     int size = 0;
1938     gchar *cp;
1939     union {
1940         guint32 ip4_addr;
1941         ws_in6_addr ip6_addr;
1942     } host_addr;
1943     gboolean is_ipv6, entry_found = FALSE;
1944
1945     /*
1946      *  See the hosts(4) or hosts(5) man page for hosts file format
1947      *  (not available on all systems).
1948      */
1949     if ((hf = ws_fopen(hostspath, "r")) == NULL)
1950         return FALSE;
1951
1952     while (fgetline(&line, &size, hf) >= 0) {
1953         if ((cp = strchr(line, '#')))
1954             *cp = '\0';
1955
1956         if ((cp = strtok(line, " \t")) == NULL)
1957             continue; /* no tokens in the line */
1958
1959         if (ws_inet_pton6(cp, &host_addr.ip6_addr)) {
1960             /* Valid IPv6 */
1961             is_ipv6 = TRUE;
1962         } else if (ws_inet_pton4(cp, &host_addr.ip4_addr)) {
1963             /* Valid IPv4 */
1964             is_ipv6 = FALSE;
1965         } else {
1966             continue;
1967         }
1968
1969         if ((cp = strtok(NULL, " \t")) == NULL)
1970             continue; /* no host name */
1971
1972         entry_found = TRUE;
1973         if (store_entries) {
1974             if (is_ipv6) {
1975                 add_ipv6_name(&host_addr.ip6_addr, cp);
1976             } else {
1977                 add_ipv4_name(host_addr.ip4_addr, cp);
1978             }
1979         }
1980     }
1981     wmem_free(wmem_epan_scope(), line);
1982
1983     fclose(hf);
1984     return entry_found ? TRUE : FALSE;
1985 } /* read_hosts_file */
1986
1987 gboolean
1988 add_hosts_file (const char *hosts_file)
1989 {
1990     gboolean found = FALSE;
1991     guint i;
1992
1993     if (!hosts_file)
1994         return FALSE;
1995
1996     if (!extra_hosts_files)
1997         extra_hosts_files = g_ptr_array_new();
1998
1999     for (i = 0; i < extra_hosts_files->len; i++) {
2000         if (strcmp(hosts_file, (const char *) g_ptr_array_index(extra_hosts_files, i)) == 0)
2001             found = TRUE;
2002     }
2003
2004     if (!found) {
2005         g_ptr_array_add(extra_hosts_files, wmem_strdup(wmem_epan_scope(), hosts_file));
2006         return read_hosts_file (hosts_file, FALSE);
2007     }
2008     return TRUE;
2009 }
2010
2011 gboolean
2012 add_ip_name_from_string (const char *addr, const char *name)
2013 {
2014     union {
2015         guint32 ip4_addr;
2016         ws_in6_addr ip6_addr;
2017     } host_addr;
2018     gboolean is_ipv6;
2019     resolved_ipv4_t *resolved_ipv4_entry;
2020     resolved_ipv6_t *resolved_ipv6_entry;
2021
2022     if (ws_inet_pton6(addr, &host_addr.ip6_addr)) {
2023         is_ipv6 = TRUE;
2024     } else if (ws_inet_pton4(addr, &host_addr.ip4_addr)) {
2025         is_ipv6 = FALSE;
2026     } else {
2027         return FALSE;
2028     }
2029
2030     if (is_ipv6) {
2031         resolved_ipv6_entry = wmem_new(wmem_epan_scope(), resolved_ipv6_t);
2032         memcpy(&(resolved_ipv6_entry->ip6_addr), &host_addr.ip6_addr, 16);
2033         g_strlcpy(resolved_ipv6_entry->name, name, MAXNAMELEN);
2034         wmem_list_prepend(manually_resolved_ipv6_list, resolved_ipv6_entry);
2035     } else {
2036         resolved_ipv4_entry = wmem_new(wmem_epan_scope(), resolved_ipv4_t);
2037         resolved_ipv4_entry->host_addr = host_addr.ip4_addr;
2038         g_strlcpy(resolved_ipv4_entry->name, name, MAXNAMELEN);
2039         wmem_list_prepend(manually_resolved_ipv4_list, resolved_ipv4_entry);
2040     }
2041
2042     return TRUE;
2043 } /* add_ip_name_from_string */
2044
2045 /*
2046  * Add the resolved addresses that are in use to the list used to create the NRB
2047  */
2048 static void
2049 ipv4_hash_table_resolved_to_list(gpointer key _U_, gpointer value, gpointer user_data)
2050 {
2051     addrinfo_lists_t *lists = (addrinfo_lists_t*)user_data;
2052     hashipv4_t *ipv4_hash_table_entry = (hashipv4_t *)value;
2053
2054     if ((ipv4_hash_table_entry->flags & USED_AND_RESOLVED_MASK) == USED_AND_RESOLVED_MASK) {
2055         lists->ipv4_addr_list = g_list_prepend(lists->ipv4_addr_list, ipv4_hash_table_entry);
2056     }
2057
2058 }
2059
2060 /*
2061  * Add the resolved addresses that are in use to the list used to create the NRB
2062  */
2063
2064 static void
2065 ipv6_hash_table_resolved_to_list(gpointer key _U_, gpointer value, gpointer user_data)
2066 {
2067     addrinfo_lists_t *lists = (addrinfo_lists_t*)user_data;
2068     hashipv6_t *ipv6_hash_table_entry = (hashipv6_t *)value;
2069
2070     if ((ipv6_hash_table_entry->flags & USED_AND_RESOLVED_MASK) == USED_AND_RESOLVED_MASK) {
2071         lists->ipv6_addr_list = g_list_prepend (lists->ipv6_addr_list, ipv6_hash_table_entry);
2072     }
2073
2074 }
2075
2076 addrinfo_lists_t *
2077 get_addrinfo_list(void)
2078 {
2079     if (ipv4_hash_table) {
2080         wmem_map_foreach(ipv4_hash_table, ipv4_hash_table_resolved_to_list, &addrinfo_lists);
2081     }
2082
2083     if (ipv6_hash_table) {
2084         wmem_map_foreach(ipv6_hash_table, ipv6_hash_table_resolved_to_list, &addrinfo_lists);
2085     }
2086
2087     return &addrinfo_lists;
2088 }
2089
2090 /* Read in a list of subnet definition - name pairs.
2091  * <line> = <comment> | <entry> | <whitespace>
2092  * <comment> = <whitespace>#<any>
2093  * <entry> = <subnet_definition> <whitespace> <subnet_name> [<comment>|<whitespace><any>]
2094  * <subnet_definition> = <ipv4_address> / <subnet_mask_length>
2095  * <ipv4_address> is a full address; it will be masked to get the subnet-ID.
2096  * <subnet_mask_length> is a decimal 1-31
2097  * <subnet_name> is a string containing no whitespace.
2098  * <whitespace> = (space | tab)+
2099  * Any malformed entries are ignored.
2100  * Any trailing data after the subnet_name is ignored.
2101  *
2102  * XXX Support IPv6
2103  */
2104 static gboolean
2105 read_subnets_file (const char *subnetspath)
2106 {
2107     FILE *hf;
2108     char *line = NULL;
2109     int size = 0;
2110     gchar *cp, *cp2;
2111     guint32 host_addr; /* IPv4 ONLY */
2112     guint8 mask_length;
2113
2114     if ((hf = ws_fopen(subnetspath, "r")) == NULL)
2115         return FALSE;
2116
2117     while (fgetline(&line, &size, hf) >= 0) {
2118         if ((cp = strchr(line, '#')))
2119             *cp = '\0';
2120
2121         if ((cp = strtok(line, " \t")) == NULL)
2122             continue; /* no tokens in the line */
2123
2124
2125         /* Expected format is <IP4 address>/<subnet length> */
2126         cp2 = strchr(cp, '/');
2127         if (NULL == cp2) {
2128             /* No length */
2129             continue;
2130         }
2131         *cp2 = '\0'; /* Cut token */
2132         ++cp2    ;
2133
2134         /* Check if this is a valid IPv4 address */
2135         if (!str_to_ip(cp, &host_addr)) {
2136             continue; /* no */
2137         }
2138
2139         if (!ws_strtou8(cp2, NULL, &mask_length) || mask_length == 0 || mask_length > 32) {
2140             continue; /* invalid mask length */
2141         }
2142
2143         if ((cp = strtok(NULL, " \t")) == NULL)
2144             continue; /* no subnet name */
2145
2146         subnet_entry_set(host_addr, mask_length, cp);
2147     }
2148     wmem_free(wmem_epan_scope(), line);
2149
2150     fclose(hf);
2151     return TRUE;
2152 } /* read_subnets_file */
2153
2154 static subnet_entry_t
2155 subnet_lookup(const guint32 addr)
2156 {
2157     subnet_entry_t subnet_entry;
2158     guint32 i;
2159
2160     /* Search mask lengths linearly, longest first */
2161
2162     i = SUBNETLENGTHSIZE;
2163     while(have_subnet_entry && i > 0) {
2164         guint32 masked_addr;
2165         subnet_length_entry_t* length_entry;
2166
2167         /* Note that we run from 31 (length 32)  to 0 (length 1)  */
2168         --i;
2169         g_assert(i < SUBNETLENGTHSIZE);
2170
2171
2172         length_entry = &subnet_length_entries[i];
2173
2174         if (NULL != length_entry->subnet_addresses) {
2175             sub_net_hashipv4_t * tp;
2176             guint32 hash_idx;
2177
2178             masked_addr = addr & length_entry->mask;
2179             hash_idx = HASH_IPV4_ADDRESS(masked_addr);
2180
2181             tp = length_entry->subnet_addresses[hash_idx];
2182             while(tp != NULL && tp->addr != masked_addr) {
2183                 tp = tp->next;
2184             }
2185
2186             if (NULL != tp) {
2187                 subnet_entry.mask = length_entry->mask;
2188                 subnet_entry.mask_length = i + 1; /* Length is offset + 1 */
2189                 subnet_entry.name = tp->name;
2190                 return subnet_entry;
2191             }
2192         }
2193     }
2194
2195     subnet_entry.mask = 0;
2196     subnet_entry.mask_length = 0;
2197     subnet_entry.name = NULL;
2198
2199     return subnet_entry;
2200 }
2201
2202 /* Add a subnet-definition - name pair to the set.
2203  * The definition is taken by masking the address passed in with the mask of the
2204  * given length.
2205  */
2206 static void
2207 subnet_entry_set(guint32 subnet_addr, const guint8 mask_length, const gchar* name)
2208 {
2209     subnet_length_entry_t* entry;
2210     sub_net_hashipv4_t * tp;
2211     gsize hash_idx;
2212
2213     g_assert(mask_length > 0 && mask_length <= 32);
2214
2215     entry = &subnet_length_entries[mask_length - 1];
2216
2217     subnet_addr &= entry->mask;
2218
2219     hash_idx = HASH_IPV4_ADDRESS(subnet_addr);
2220
2221     if (NULL == entry->subnet_addresses) {
2222         entry->subnet_addresses = (sub_net_hashipv4_t**)wmem_alloc0(wmem_epan_scope(), sizeof(sub_net_hashipv4_t*) * HASHHOSTSIZE);
2223     }
2224
2225     if (NULL != (tp = entry->subnet_addresses[hash_idx])) {
2226         sub_net_hashipv4_t * new_tp;
2227
2228         while (tp->next) {
2229             if (tp->addr == subnet_addr) {
2230                 return; /* XXX provide warning that an address was repeated? */
2231             } else {
2232                 tp = tp->next;
2233             }
2234         }
2235
2236         new_tp = wmem_new(wmem_epan_scope(), sub_net_hashipv4_t);
2237         tp->next = new_tp;
2238         tp = new_tp;
2239     } else {
2240         tp = entry->subnet_addresses[hash_idx] = wmem_new(wmem_epan_scope(), sub_net_hashipv4_t);
2241     }
2242
2243     tp->next = NULL;
2244     tp->addr = subnet_addr;
2245     g_strlcpy(tp->name, name, MAXNAMELEN); /* This is longer than subnet names can actually be */
2246     have_subnet_entry = TRUE;
2247 }
2248
2249 static void
2250 subnet_name_lookup_init(void)
2251 {
2252     gchar* subnetspath;
2253     guint32 i;
2254
2255     for(i = 0; i < SUBNETLENGTHSIZE; ++i) {
2256         guint32 length = i + 1;
2257
2258         subnet_length_entries[i].subnet_addresses  = NULL;
2259         subnet_length_entries[i].mask_length  = length;
2260         subnet_length_entries[i].mask = g_htonl(ip_get_subnet_mask(length));
2261     }
2262
2263     /* Check profile directory before personal configuration */
2264     subnetspath = get_persconffile_path(ENAME_SUBNETS, TRUE);
2265     if (!read_subnets_file(subnetspath)) {
2266         if (errno != ENOENT) {
2267             report_open_failure(subnetspath, errno, FALSE);
2268         }
2269
2270         g_free(subnetspath);
2271         subnetspath = get_persconffile_path(ENAME_SUBNETS, FALSE);
2272         if (!read_subnets_file(subnetspath) && errno != ENOENT) {
2273             report_open_failure(subnetspath, errno, FALSE);
2274         }
2275     }
2276     g_free(subnetspath);
2277
2278     /*
2279      * Load the global subnets file, if we have one.
2280      */
2281     subnetspath = get_datafile_path(ENAME_SUBNETS);
2282     if (!read_subnets_file(subnetspath) && errno != ENOENT) {
2283         report_open_failure(subnetspath, errno, FALSE);
2284     }
2285     g_free(subnetspath);
2286 }
2287
2288 /* SS7 PC Name Resolution Portion */
2289 static hashss7pc_t *
2290 new_ss7pc(const guint8 ni, const guint32 pc)
2291 {
2292     hashss7pc_t *tp = wmem_new(wmem_epan_scope(), hashss7pc_t);
2293     tp->id = (ni<<24) + (pc&0xffffff);
2294     tp->pc_addr[0] = '\0';
2295     tp->name[0] = '\0';
2296
2297     return tp;
2298 }
2299
2300 static hashss7pc_t *
2301 host_lookup_ss7pc(const guint8 ni, const guint32 pc)
2302 {
2303     hashss7pc_t * volatile tp;
2304     guint32 id;
2305
2306     id = (ni<<24) + (pc&0xffffff);
2307
2308     tp = (hashss7pc_t *)wmem_map_lookup(ss7pc_hash_table, GUINT_TO_POINTER(id));
2309     if (tp == NULL) {
2310         tp = new_ss7pc(ni, pc);
2311         wmem_map_insert(ss7pc_hash_table, GUINT_TO_POINTER(id), tp);
2312     }
2313
2314     return tp;
2315 }
2316
2317 void fill_unresolved_ss7pc(const gchar * pc_addr, const guint8 ni, const guint32 pc)
2318 {
2319     hashss7pc_t *tp = host_lookup_ss7pc(ni, pc);
2320
2321     g_strlcpy(tp->pc_addr, pc_addr, MAXNAMELEN);
2322 }
2323
2324 const gchar *
2325 get_hostname_ss7pc(const guint8 ni, const guint32 pc)
2326 {
2327     hashss7pc_t *tp = host_lookup_ss7pc(ni, pc);
2328
2329     /* never resolved yet*/
2330     if (tp->pc_addr[0] == '\0')
2331         return tp->pc_addr;
2332
2333     /* Don't have name in file */
2334     if (tp->name[0] == '\0')
2335         return tp->pc_addr;
2336
2337     if (!gbl_resolv_flags.ss7pc_name)
2338         return tp->pc_addr;
2339
2340     return tp->name;
2341 }
2342
2343 static void
2344 add_ss7pc_name(const guint8 ni, guint32 pc, const gchar *name)
2345 {
2346     hashss7pc_t *tp;
2347     guint32 id;
2348
2349     if (!name || name[0] == '\0')
2350         return;
2351
2352     id = (ni<<24) + (pc&0xffffff);
2353     tp = (hashss7pc_t *)wmem_map_lookup(ss7pc_hash_table, GUINT_TO_POINTER(id));
2354     if (!tp) {
2355         tp = new_ss7pc(ni, pc);
2356         wmem_map_insert(ss7pc_hash_table, GUINT_TO_POINTER(id), tp);
2357     }
2358
2359     if (g_ascii_strcasecmp(tp->name, name)) {
2360         g_strlcpy(tp->name, name, MAXNAMELEN);
2361     }
2362 }
2363
2364 static gboolean
2365 read_ss7pcs_file(const char *ss7pcspath)
2366 {
2367     FILE *hf;
2368     char *line = NULL;
2369     int size = 0;
2370     gchar *cp;
2371     guint8 ni;
2372     guint32 pc;
2373     gboolean entry_found = FALSE;
2374
2375     /*
2376     *  File format is Network Indicator (decimal)<dash>Point Code (Decimal)<tab/space>Hostname
2377     */
2378     if ((hf = ws_fopen(ss7pcspath, "r")) == NULL)
2379         return FALSE;
2380
2381     while (fgetline(&line, &size, hf) >= 0) {
2382         if ((cp = strchr(line, '#')))
2383             *cp = '\0';
2384
2385         if ((cp = strtok(line, "-")) == NULL)
2386             continue; /*no ni-pc separator*/
2387         if (!ws_strtou8(cp, NULL, &ni))
2388             continue;
2389         if (ni > 3)
2390              continue;
2391
2392         if ((cp = strtok(NULL, " \t")) == NULL)
2393             continue; /* no tokens for pc and name */
2394         if (!ws_strtou32(cp, NULL, &pc))
2395             continue;
2396         if (pc >> 24 > 0)
2397             continue;
2398
2399         if ((cp = strtok(NULL, " \t")) == NULL)
2400             continue; /* no host name */
2401
2402         entry_found = TRUE;
2403         add_ss7pc_name(ni, pc, cp);
2404     }
2405     wmem_free(wmem_epan_scope(), line);
2406
2407     fclose(hf);
2408     return entry_found ? TRUE : FALSE;
2409 }
2410
2411 static void
2412 ss7pc_name_lookup_init(void)
2413 {
2414     char *ss7pcspath;
2415
2416     g_assert(ss7pc_hash_table == NULL);
2417
2418     ss7pc_hash_table = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
2419
2420     /*
2421      * Load the user's ss7pcs file
2422      */
2423     ss7pcspath = get_persconffile_path(ENAME_SS7PCS, TRUE);
2424     if (!read_ss7pcs_file(ss7pcspath) && errno != ENOENT) {
2425         report_open_failure(ss7pcspath, errno, FALSE);
2426     }
2427     g_free(ss7pcspath);
2428 }
2429
2430 /* SS7PC Name Resolution End*/
2431
2432
2433 /*
2434  *  External Functions
2435  */
2436
2437 void
2438 addr_resolve_pref_init(module_t *nameres)
2439 {
2440     prefs_register_bool_preference(nameres, "mac_name",
2441             "Resolve MAC addresses",
2442             "Resolve Ethernet MAC addresses to host names from the preferences"
2443             " or system's Ethers file, or to a manufacturer based name.",
2444             &gbl_resolv_flags.mac_name);
2445
2446     prefs_register_bool_preference(nameres, "transport_name",
2447             "Resolve transport names",
2448             "Resolve TCP/UDP ports into service names",
2449             &gbl_resolv_flags.transport_name);
2450
2451     prefs_register_bool_preference(nameres, "network_name",
2452             "Resolve network (IP) addresses",
2453             "Resolve IPv4, IPv6, and IPX addresses into host names."
2454             " The next set of check boxes determines how name resolution should be performed."
2455             " If no other options are checked name resolution is made from Wireshark's host file,"
2456             " capture file name resolution blocks and DNS packets in the capture.",
2457             &gbl_resolv_flags.network_name);
2458
2459     prefs_register_bool_preference(nameres, "dns_pkt_addr_resolution",
2460             "Use captured DNS packet data for address resolution",
2461             "Whether address/name pairs found in captured DNS packets should be used by Wireshark for name resolution.",
2462             &gbl_resolv_flags.dns_pkt_addr_resolution);
2463
2464 #ifdef HAVE_C_ARES
2465     prefs_register_bool_preference(nameres, "use_external_name_resolver",
2466             "Use an external network name resolver",
2467             "Use your system's configured name resolver"
2468             " (usually DNS) to resolve network names."
2469             " Only applies when network name resolution"
2470             " is enabled.",
2471             &gbl_resolv_flags.use_external_net_name_resolver);
2472
2473     prefs_register_obsolete_preference(nameres, "concurrent_dns");
2474
2475     prefs_register_uint_preference(nameres, "name_resolve_concurrency",
2476             "Maximum concurrent requests",
2477             "The maximum number of DNS requests that may"
2478             " be active at any time. A large value (many"
2479             " thousands) might overload the network or make"
2480             " your DNS server behave badly.",
2481             10,
2482             &name_resolve_concurrency);
2483 #else
2484     prefs_register_static_text_preference(nameres, "use_external_name_resolver",
2485             "Use an external network name resolver: N/A",
2486             "Support for using a concurrent external name resolver was not"
2487             " compiled into this version of Wireshark");
2488 #endif
2489
2490     prefs_register_bool_preference(nameres, "hosts_file_handling",
2491             "Only use the profile \"hosts\" file",
2492             "By default \"hosts\" files will be loaded from multiple sources."
2493             " Checking this box only loads the \"hosts\" in the current profile.",
2494             &gbl_resolv_flags.load_hosts_file_from_profile_only);
2495
2496     prefs_register_bool_preference(nameres, "vlan_name",
2497             "Resolve VLAN IDs",
2498             "Resolve VLAN IDs to network names from the preferences \"vlans\" file."
2499             " Format of the file is: \"ID<Tab>Name\"."
2500             " One line per VLAN, e.g.: 1 Management",
2501             &gbl_resolv_flags.vlan_name);
2502
2503     prefs_register_bool_preference(nameres, "ss7_pc_name",
2504             "Resolve SS7 PCs",
2505             "Resolve SS7 Point Codes to node names from the profiles \"ss7pcs\" file."
2506             " Format of the file is: \"Network_Indicator<Dash>PC_Decimal<Tab>Name\"."
2507             " One line per Point Code, e.g.: 2-1234 MyPointCode1",
2508             &gbl_resolv_flags.ss7pc_name);
2509
2510 }
2511
2512 void
2513 disable_name_resolution(void) {
2514     gbl_resolv_flags.mac_name                           = FALSE;
2515     gbl_resolv_flags.network_name                       = FALSE;
2516     gbl_resolv_flags.transport_name                     = FALSE;
2517     gbl_resolv_flags.dns_pkt_addr_resolution            = FALSE;
2518     gbl_resolv_flags.use_external_net_name_resolver     = FALSE;
2519     gbl_resolv_flags.vlan_name                          = FALSE;
2520     gbl_resolv_flags.ss7pc_name                         = FALSE;
2521 }
2522
2523 #ifdef HAVE_C_ARES
2524 gboolean
2525 host_name_lookup_process(void) {
2526     async_dns_queue_msg_t *caqm;
2527     struct timeval tv = { 0, 0 };
2528     int nfds;
2529     fd_set rfds, wfds;
2530     gboolean nro = new_resolved_objects;
2531     wmem_list_frame_t* head;
2532
2533     new_resolved_objects = FALSE;
2534
2535     if (!async_dns_initialized)
2536         /* c-ares not initialized. Bail out and cancel timers. */
2537         return nro;
2538
2539     head = wmem_list_head(async_dns_queue_head);
2540
2541     while (head != NULL && async_dns_in_flight <= name_resolve_concurrency) {
2542         caqm = (async_dns_queue_msg_t *)wmem_list_frame_data(head);
2543         wmem_list_remove_frame(async_dns_queue_head, head);
2544         if (caqm->family == AF_INET) {
2545             ares_gethostbyaddr(ghba_chan, &caqm->addr.ip4, sizeof(guint32), AF_INET,
2546                     c_ares_ghba_cb, caqm);
2547             async_dns_in_flight++;
2548         } else if (caqm->family == AF_INET6) {
2549             ares_gethostbyaddr(ghba_chan, &caqm->addr.ip6, sizeof(ws_in6_addr),
2550                     AF_INET6, c_ares_ghba_cb, caqm);
2551             async_dns_in_flight++;
2552         }
2553
2554         head = wmem_list_head(async_dns_queue_head);
2555     }
2556
2557     FD_ZERO(&rfds);
2558     FD_ZERO(&wfds);
2559     nfds = ares_fds(ghba_chan, &rfds, &wfds);
2560     if (nfds > 0) {
2561         if (select(nfds, &rfds, &wfds, NULL, &tv) == -1) { /* call to select() failed */
2562             fprintf(stderr, "Warning: call to select() failed, error is %s\n", g_strerror(errno));
2563             return nro;
2564         }
2565         ares_process(ghba_chan, &rfds, &wfds);
2566     }
2567
2568     /* Any new entries? */
2569     return nro;
2570 }
2571
2572 static void
2573 _host_name_lookup_cleanup(void) {
2574     async_dns_queue_head = NULL;
2575
2576     if (async_dns_initialized) {
2577         ares_destroy(ghba_chan);
2578         ares_destroy(ghbn_chan);
2579     }
2580 #ifdef CARES_HAVE_ARES_LIBRARY_INIT
2581     ares_library_cleanup();
2582 #endif
2583     async_dns_initialized = FALSE;
2584 }
2585
2586 #else
2587
2588 gboolean
2589 host_name_lookup_process(void) {
2590     gboolean nro = new_resolved_objects;
2591
2592     new_resolved_objects = FALSE;
2593
2594     return nro;
2595 }
2596
2597 static void
2598 _host_name_lookup_cleanup(void) {
2599 }
2600
2601 #endif /* HAVE_C_ARES */
2602
2603 const gchar *
2604 get_hostname(const guint addr)
2605 {
2606     /* XXX why do we call this if we're not resolving? To create hash entries?
2607      * Why?
2608      */
2609     hashipv4_t *tp = host_lookup(addr);
2610
2611     if (!gbl_resolv_flags.network_name)
2612         return tp->ip;
2613
2614     tp->flags |= RESOLVED_ADDRESS_USED;
2615
2616     return tp->name;
2617 }
2618
2619 /* -------------------------- */
2620
2621 const gchar *
2622 get_hostname6(const ws_in6_addr *addr)
2623 {
2624     /* XXX why do we call this if we're not resolving? To create hash entries?
2625      * Why?
2626      */
2627     hashipv6_t *tp = host_lookup6(addr);
2628
2629     if (!gbl_resolv_flags.network_name)
2630         return tp->ip6;
2631
2632     tp->flags |= RESOLVED_ADDRESS_USED;
2633
2634     return tp->name;
2635 }
2636
2637 /* -------------------------- */
2638 void
2639 add_ipv4_name(const guint addr, const gchar *name)
2640 {
2641     hashipv4_t *tp;
2642
2643     /*
2644      * Don't add zero-length names; apparently, some resolvers will return
2645      * them if they get them from DNS.
2646      */
2647     if (!name || name[0] == '\0')
2648         return;
2649
2650     tp = (hashipv4_t *)wmem_map_lookup(ipv4_hash_table, GUINT_TO_POINTER(addr));
2651     if (!tp) {
2652         tp = new_ipv4(addr);
2653         wmem_map_insert(ipv4_hash_table, GUINT_TO_POINTER(addr), tp);
2654     }
2655
2656     if (g_ascii_strcasecmp(tp->name, name)) {
2657         g_strlcpy(tp->name, name, MAXNAMELEN);
2658         new_resolved_objects = TRUE;
2659     }
2660     tp->flags |= TRIED_RESOLVE_ADDRESS|NAME_RESOLVED;
2661 } /* add_ipv4_name */
2662
2663 /* -------------------------- */
2664 void
2665 add_ipv6_name(const ws_in6_addr *addrp, const gchar *name)
2666 {
2667     hashipv6_t *tp;
2668
2669     /*
2670      * Don't add zero-length names; apparently, some resolvers will return
2671      * them if they get them from DNS.
2672      */
2673     if (!name || name[0] == '\0')
2674         return;
2675
2676     tp = (hashipv6_t *)wmem_map_lookup(ipv6_hash_table, addrp);
2677     if (!tp) {
2678         ws_in6_addr *addr_key;
2679
2680         addr_key = wmem_new(wmem_epan_scope(), ws_in6_addr);
2681         tp = new_ipv6(addrp);
2682         memcpy(addr_key, addrp, 16);
2683         wmem_map_insert(ipv6_hash_table, addr_key, tp);
2684     }
2685
2686     if (g_ascii_strcasecmp(tp->name, name)) {
2687         g_strlcpy(tp->name, name, MAXNAMELEN);
2688         new_resolved_objects = TRUE;
2689     }
2690     tp->flags |= TRIED_RESOLVE_ADDRESS|NAME_RESOLVED;
2691 } /* add_ipv6_name */
2692
2693 static void
2694 add_manually_resolved_ipv4(gpointer data, gpointer user_data _U_)
2695 {
2696     resolved_ipv4_t *resolved_ipv4_entry = (resolved_ipv4_t *)data;
2697
2698     add_ipv4_name(resolved_ipv4_entry->host_addr, resolved_ipv4_entry->name);
2699 }
2700
2701 static void
2702 add_manually_resolved_ipv6(gpointer data, gpointer user_data _U_)
2703 {
2704     resolved_ipv6_t *resolved_ipv6_entry = (resolved_ipv6_t *)data;
2705
2706     add_ipv6_name(&(resolved_ipv6_entry->ip6_addr), resolved_ipv6_entry->name);
2707 }
2708
2709 static void
2710 add_manually_resolved(void)
2711 {
2712     if (manually_resolved_ipv4_list) {
2713         wmem_list_foreach(manually_resolved_ipv4_list, add_manually_resolved_ipv4, NULL);
2714     }
2715
2716     if (manually_resolved_ipv6_list) {
2717         wmem_list_foreach(manually_resolved_ipv6_list, add_manually_resolved_ipv6, NULL);
2718     }
2719 }
2720
2721 void
2722 host_name_lookup_init(void)
2723 {
2724     char *hostspath;
2725     guint i;
2726
2727     g_assert(ipxnet_hash_table == NULL);
2728     ipxnet_hash_table = wmem_map_new(wmem_epan_scope(), g_int_hash, g_int_equal);
2729
2730     g_assert(ipv4_hash_table == NULL);
2731     ipv4_hash_table = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
2732
2733     g_assert(ipv6_hash_table == NULL);
2734     ipv6_hash_table = wmem_map_new(wmem_epan_scope(), ipv6_oat_hash, ipv6_equal);
2735
2736 #ifdef HAVE_C_ARES
2737     g_assert(async_dns_queue_head == NULL);
2738     async_dns_queue_head = wmem_list_new(wmem_epan_scope());
2739 #endif
2740
2741     if (manually_resolved_ipv4_list == NULL)
2742         manually_resolved_ipv4_list = wmem_list_new(wmem_epan_scope());
2743
2744     if (manually_resolved_ipv6_list == NULL)
2745         manually_resolved_ipv6_list = wmem_list_new(wmem_epan_scope());
2746
2747     /*
2748      * Load the global hosts file, if we have one.
2749      */
2750     if (!gbl_resolv_flags.load_hosts_file_from_profile_only) {
2751         hostspath = get_datafile_path(ENAME_HOSTS);
2752         if (!read_hosts_file(hostspath, TRUE) && errno != ENOENT) {
2753             report_open_failure(hostspath, errno, FALSE);
2754         }
2755         g_free(hostspath);
2756     }
2757     /*
2758      * Load the user's hosts file no matter what, if they have one.
2759      */
2760     hostspath = get_persconffile_path(ENAME_HOSTS, TRUE);
2761     if (!read_hosts_file(hostspath, TRUE) && errno != ENOENT) {
2762         report_open_failure(hostspath, errno, FALSE);
2763     }
2764     g_free(hostspath);
2765 #ifdef HAVE_C_ARES
2766 #ifdef CARES_HAVE_ARES_LIBRARY_INIT
2767     if (ares_library_init(ARES_LIB_INIT_ALL) == ARES_SUCCESS) {
2768 #endif
2769         if (ares_init(&ghba_chan) == ARES_SUCCESS && ares_init(&ghbn_chan) == ARES_SUCCESS) {
2770             async_dns_initialized = TRUE;
2771         }
2772 #ifdef CARES_HAVE_ARES_LIBRARY_INIT
2773     }
2774 #endif
2775 #else
2776 #endif /* HAVE_C_ARES */
2777
2778     if (extra_hosts_files && !gbl_resolv_flags.load_hosts_file_from_profile_only) {
2779         for (i = 0; i < extra_hosts_files->len; i++) {
2780             read_hosts_file((const char *) g_ptr_array_index(extra_hosts_files, i), TRUE);
2781         }
2782     }
2783
2784     subnet_name_lookup_init();
2785
2786     add_manually_resolved();
2787
2788     ss7pc_name_lookup_init();
2789 }
2790
2791 void
2792 host_name_lookup_cleanup(void)
2793 {
2794     guint32 i, j;
2795     sub_net_hashipv4_t *entry, *next_entry;
2796
2797     _host_name_lookup_cleanup();
2798
2799     ipxnet_hash_table = NULL;
2800     ipv4_hash_table = NULL;
2801     ipv6_hash_table = NULL;
2802     ss7pc_hash_table = NULL;
2803
2804     for(i = 0; i < SUBNETLENGTHSIZE; ++i) {
2805         if (subnet_length_entries[i].subnet_addresses != NULL) {
2806             for (j = 0; j < HASHHOSTSIZE; j++) {
2807                 for (entry = subnet_length_entries[i].subnet_addresses[j];
2808                      entry != NULL; entry = next_entry) {
2809                     next_entry = entry->next;
2810                     wmem_free(wmem_epan_scope(), entry);
2811                 }
2812             }
2813             wmem_free(wmem_epan_scope(), subnet_length_entries[i].subnet_addresses);
2814             subnet_length_entries[i].subnet_addresses = NULL;
2815         }
2816     }
2817
2818     have_subnet_entry = FALSE;
2819     new_resolved_objects = FALSE;
2820 }
2821
2822 void
2823 manually_resolve_cleanup(void)
2824 {
2825     wmem_destroy_list(manually_resolved_ipv4_list);
2826     manually_resolved_ipv4_list = NULL;
2827     wmem_destroy_list(manually_resolved_ipv6_list);
2828     manually_resolved_ipv6_list = NULL;
2829 }
2830
2831 gchar *
2832 udp_port_to_display(wmem_allocator_t *allocator, guint port)
2833 {
2834
2835     if (!gbl_resolv_flags.transport_name) {
2836         return wmem_utoa(allocator, port);
2837     }
2838
2839     return wmem_strdup(allocator, serv_name_lookup(PT_UDP, port));
2840
2841 } /* udp_port_to_display */
2842
2843 gchar *
2844 dccp_port_to_display(wmem_allocator_t *allocator, guint port)
2845 {
2846
2847     if (!gbl_resolv_flags.transport_name) {
2848         return wmem_utoa(allocator, port);
2849     }
2850
2851     return wmem_strdup(allocator, serv_name_lookup(PT_DCCP, port));
2852
2853 } /* dccp_port_to_display */
2854
2855 gchar *
2856 tcp_port_to_display(wmem_allocator_t *allocator, guint port)
2857 {
2858
2859     if (!gbl_resolv_flags.transport_name) {
2860         return wmem_utoa(allocator, port);
2861     }
2862
2863     return wmem_strdup(allocator, serv_name_lookup(PT_TCP, port));
2864
2865 } /* tcp_port_to_display */
2866
2867 gchar *
2868 sctp_port_to_display(wmem_allocator_t *allocator, guint port)
2869 {
2870
2871     if (!gbl_resolv_flags.transport_name) {
2872         return wmem_utoa(allocator, port);
2873     }
2874
2875     return wmem_strdup(allocator, serv_name_lookup(PT_SCTP, port));
2876
2877 } /* sctp_port_to_display */
2878
2879 gchar *
2880 port_with_resolution_to_str(wmem_allocator_t *scope, port_type proto, guint port)
2881 {
2882     const gchar *port_str;
2883
2884     if (!gbl_resolv_flags.transport_name || (proto == PT_NONE)) {
2885         /* No name resolution support, just return port string */
2886         return wmem_strdup_printf(scope, "%u", port);
2887     }
2888     port_str = serv_name_lookup(proto, port);
2889     g_assert(port_str);
2890     return wmem_strdup_printf(scope, "%s (%u)", port_str, port);
2891 }
2892
2893 int
2894 port_with_resolution_to_str_buf(gchar *buf, gulong buf_size, port_type proto, guint port)
2895 {
2896     const gchar *port_str;
2897
2898     if (!gbl_resolv_flags.transport_name || (proto == PT_NONE)) {
2899         /* No name resolution support, just return port string */
2900         return g_snprintf(buf, buf_size, "%u", port);
2901     }
2902     port_str = serv_name_lookup(proto, port);
2903     g_assert(port_str);
2904     return g_snprintf(buf, buf_size, "%s (%u)", port_str, port);
2905 }
2906
2907 const gchar *
2908 get_ether_name(const guint8 *addr)
2909 {
2910     hashether_t *tp;
2911     gboolean resolve = gbl_resolv_flags.mac_name;
2912
2913     tp = eth_name_lookup(addr, resolve);
2914
2915     return resolve ? tp->resolved_name : tp->hexaddr;
2916
2917 } /* get_ether_name */
2918
2919 const gchar *
2920 tvb_get_ether_name(tvbuff_t *tvb, gint offset)
2921 {
2922     return get_ether_name(tvb_get_ptr(tvb, offset, 6));
2923 }
2924
2925 /* Look for a (non-dummy) ether name in the hash, and return it if found.
2926  * If it's not found, simply return NULL.
2927  */
2928 const gchar *
2929 get_ether_name_if_known(const guint8 *addr)
2930 {
2931     hashether_t *tp;
2932
2933     /* Initialize ether structs if we're the first
2934      * ether-related function called */
2935     if (!gbl_resolv_flags.mac_name)
2936         return NULL;
2937
2938     /* eth_name_lookup will create a (resolved) hash entry if it doesn't exist */
2939     tp = eth_name_lookup(addr, TRUE);
2940     g_assert(tp != NULL);
2941
2942     if (tp->status == HASHETHER_STATUS_RESOLVED_NAME) {
2943         /* Name is from an ethers file */
2944         return tp->resolved_name;
2945     }
2946     else {
2947         /* Name was created */
2948         return NULL;
2949     }
2950 }
2951
2952 void
2953 add_ether_byip(const guint ip, const guint8 *eth)
2954 {
2955     hashipv4_t *tp;
2956
2957     /* first check that IP address can be resolved */
2958     if (!gbl_resolv_flags.network_name)
2959         return;
2960
2961     tp = host_lookup(ip);
2962
2963     /*
2964      * Was this IP address resolved to a host name?
2965      */
2966     if (tp->flags & NAME_RESOLVED) {
2967         /*
2968          * Yes, so add an entry in the ethers hashtable resolving
2969          * the MAC address to that name.
2970          */
2971         add_eth_name(eth, tp->name);
2972     }
2973
2974 } /* add_ether_byip */
2975
2976 gchar *
2977 ipxnet_to_str_punct(wmem_allocator_t *allocator, const guint32 ad, const char punct)
2978 {
2979     gchar *buf = (gchar *)wmem_alloc(allocator, 12);
2980
2981     *dword_to_hex_punct(buf, ad, punct) = '\0';
2982     return buf;
2983 }
2984
2985 gchar *
2986 get_ipxnet_name(wmem_allocator_t *allocator, const guint32 addr)
2987 {
2988
2989     if (!gbl_resolv_flags.network_name) {
2990         return ipxnet_to_str_punct(allocator, addr, '\0');
2991     }
2992
2993     return ipxnet_name_lookup(allocator, addr);
2994
2995 } /* get_ipxnet_name */
2996
2997 gchar *
2998 get_vlan_name(wmem_allocator_t *allocator, const guint16 id)
2999 {
3000
3001     if (!gbl_resolv_flags.vlan_name) {
3002         return NULL;
3003     }
3004
3005     return wmem_strdup(allocator, vlan_name_lookup(id));
3006
3007 } /* get_vlan_name */
3008
3009 const gchar *
3010 get_manuf_name(const guint8 *addr)
3011 {
3012     hashmanuf_t *manuf_value;
3013
3014     manuf_value = manuf_name_lookup(addr);
3015     if (gbl_resolv_flags.mac_name && manuf_value->status != HASHETHER_STATUS_UNRESOLVED)
3016         return manuf_value->resolved_name;
3017
3018     return manuf_value->hexaddr;
3019
3020 } /* get_manuf_name */
3021
3022 const gchar *
3023 tvb_get_manuf_name(tvbuff_t *tvb, gint offset)
3024 {
3025     return get_manuf_name(tvb_get_ptr(tvb, offset, 3));
3026 }
3027
3028 const gchar *
3029 get_manuf_name_if_known(const guint8 *addr)
3030 {
3031     hashmanuf_t *manuf_value;
3032     int manuf_key;
3033     guint8 oct;
3034
3035     /* manuf needs only the 3 most significant octets of the ethernet address */
3036     manuf_key = addr[0];
3037     manuf_key = manuf_key<<8;
3038     oct = addr[1];
3039     manuf_key = manuf_key | oct;
3040     manuf_key = manuf_key<<8;
3041     oct = addr[2];
3042     manuf_key = manuf_key | oct;
3043
3044     manuf_value = (hashmanuf_t *)wmem_map_lookup(manuf_hashtable, &manuf_key);
3045     if ((manuf_value == NULL) || (manuf_value->status == HASHETHER_STATUS_UNRESOLVED)) {
3046         return NULL;
3047     }
3048
3049     return manuf_value->resolved_longname;
3050
3051 } /* get_manuf_name_if_known */
3052
3053 const gchar *
3054 uint_get_manuf_name_if_known(const guint manuf_key)
3055 {
3056     hashmanuf_t *manuf_value;
3057
3058     manuf_value = (hashmanuf_t *)wmem_map_lookup(manuf_hashtable, &manuf_key);
3059     if ((manuf_value == NULL) || (manuf_value->status == HASHETHER_STATUS_UNRESOLVED)) {
3060         return NULL;
3061     }
3062
3063     return manuf_value->resolved_longname;
3064 }
3065
3066 const gchar *
3067 tvb_get_manuf_name_if_known(tvbuff_t *tvb, gint offset)
3068 {
3069     return get_manuf_name_if_known(tvb_get_ptr(tvb, offset, 3));
3070 }
3071
3072 char* get_hash_manuf_resolved_name(hashmanuf_t* manuf)
3073 {
3074     return manuf->resolved_longname;
3075 }
3076
3077 gchar *
3078 eui64_to_display(wmem_allocator_t *allocator, const guint64 addr_eui64)
3079 {
3080     guint8 *addr = (guint8 *)wmem_alloc(NULL, 8);
3081     hashmanuf_t *manuf_value;
3082     gchar *ret;
3083
3084     /* Copy and convert the address to network byte order. */
3085     *(guint64 *)(void *)(addr) = pntoh64(&(addr_eui64));
3086
3087     manuf_value = manuf_name_lookup(addr);
3088     if (!gbl_resolv_flags.mac_name || (manuf_value->status == HASHETHER_STATUS_UNRESOLVED)) {
3089         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]);
3090     } else {
3091         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]);
3092     }
3093
3094     wmem_free(NULL, addr);
3095     return ret;
3096 } /* eui64_to_display */
3097
3098 #ifdef HAVE_C_ARES
3099 #define GHI_TIMEOUT (250 * 1000)
3100 static void
3101 c_ares_ghi_cb(void *arg, int status, int timeouts _U_, struct hostent *hp) {
3102     /*
3103      * XXX - If we wanted to be really fancy we could cache results here and
3104      * look them up in get_host_ipaddr* below.
3105      */
3106     async_hostent_t *ahp = (async_hostent_t *)arg;
3107     if (status == ARES_SUCCESS && hp && ahp && hp->h_length == ahp->addr_size) {
3108         memcpy(ahp->addrp, hp->h_addr, hp->h_length);
3109         ahp->copied = hp->h_length;
3110     }
3111 }
3112 #endif /* HAVE_C_ARES */
3113
3114 /* Translate a string, assumed either to be a dotted-quad IPv4 address or
3115  * a host name, to a numeric IPv4 address.  Return TRUE if we succeed and
3116  * set "*addrp" to that numeric IPv4 address; return FALSE if we fail. */
3117 gboolean
3118 get_host_ipaddr(const char *host, guint32 *addrp)
3119 {
3120 #ifdef HAVE_C_ARES
3121     struct timeval tv = { 0, GHI_TIMEOUT }, *tvp;
3122     int nfds;
3123     fd_set rfds, wfds;
3124     async_hostent_t ahe;
3125 #endif
3126
3127     /*
3128      * XXX - are there places where this is used to translate something
3129      * that's *only* supposed to be an IPv4 address, and where it
3130      * *shouldn't* translate host names?
3131      */
3132     if (!ws_inet_pton4(host, addrp)) {
3133
3134         /* It's not a valid dotted-quad IP address; is it a valid
3135          * host name?
3136          */
3137
3138         /* If we're not allowed to do name resolution, don't do name
3139          * resolution...
3140          */
3141         if (!gbl_resolv_flags.network_name ||
3142                 !gbl_resolv_flags.use_external_net_name_resolver) {
3143             return FALSE;
3144         }
3145
3146 #ifdef HAVE_C_ARES
3147         if (!async_dns_initialized || name_resolve_concurrency < 1) {
3148             return FALSE;
3149         }
3150         ahe.addr_size = (int) sizeof (struct in_addr);
3151         ahe.copied = 0;
3152         ahe.addrp = addrp;
3153         ares_gethostbyname(ghbn_chan, host, AF_INET, c_ares_ghi_cb, &ahe);
3154         FD_ZERO(&rfds);
3155         FD_ZERO(&wfds);
3156         nfds = ares_fds(ghbn_chan, &rfds, &wfds);
3157         if (nfds > 0) {
3158             tvp = ares_timeout(ghbn_chan, &tv, &tv);
3159             if (select(nfds, &rfds, &wfds, NULL, tvp) == -1) { /* call to select() failed */
3160                 fprintf(stderr, "Warning: call to select() failed, error is %s\n", g_strerror(errno));
3161                 return FALSE;
3162             }
3163             ares_process(ghbn_chan, &rfds, &wfds);
3164         }
3165         ares_cancel(ghbn_chan);
3166         if (ahe.addr_size == ahe.copied) {
3167             return TRUE;
3168         }
3169         return FALSE;
3170 #endif
3171     }
3172
3173     return TRUE;
3174 }
3175
3176 /*
3177  * Translate IPv6 numeric address or FQDN hostname into binary IPv6 address.
3178  * Return TRUE if we succeed and set "*addrp" to that numeric IPv6 address;
3179  * return FALSE if we fail.
3180  */
3181 gboolean
3182 get_host_ipaddr6(const char *host, ws_in6_addr *addrp)
3183 {
3184 #ifdef HAVE_C_ARES
3185     struct timeval tv = { 0, GHI_TIMEOUT }, *tvp;
3186     int nfds;
3187     fd_set rfds, wfds;
3188     async_hostent_t ahe;
3189 #endif /* HAVE_C_ARES */
3190
3191     if (str_to_ip6(host, addrp))
3192         return TRUE;
3193
3194     /* It's not a valid dotted-quad IP address; is it a valid
3195      * host name?
3196      *
3197      * XXX - are there places where this is used to translate something
3198      * that's *only* supposed to be an IPv6 address, and where it
3199      * *shouldn't* translate host names?
3200      */
3201
3202     /* If we're not allowed to do name resolution, don't do name
3203      * resolution...
3204      */
3205     if (!gbl_resolv_flags.network_name ||
3206             !gbl_resolv_flags.use_external_net_name_resolver) {
3207         return FALSE;
3208     }
3209
3210     /* try FQDN */
3211 #ifdef HAVE_C_ARES
3212     if (!async_dns_initialized || name_resolve_concurrency < 1) {
3213         return FALSE;
3214     }
3215     ahe.addr_size = (int) sizeof (ws_in6_addr);
3216     ahe.copied = 0;
3217     ahe.addrp = addrp;
3218     ares_gethostbyname(ghbn_chan, host, AF_INET6, c_ares_ghi_cb, &ahe);
3219     FD_ZERO(&rfds);
3220     FD_ZERO(&wfds);
3221     nfds = ares_fds(ghbn_chan, &rfds, &wfds);
3222     if (nfds > 0) {
3223         tvp = ares_timeout(ghbn_chan, &tv, &tv);
3224         if (select(nfds, &rfds, &wfds, NULL, tvp) == -1) { /* call to select() failed */
3225             fprintf(stderr, "Warning: call to select() failed, error is %s\n", g_strerror(errno));
3226             return FALSE;
3227         }
3228         ares_process(ghbn_chan, &rfds, &wfds);
3229     }
3230     ares_cancel(ghbn_chan);
3231     if (ahe.addr_size == ahe.copied) {
3232         return TRUE;
3233     }
3234 #endif
3235
3236     return FALSE;
3237 }
3238
3239 wmem_map_t *
3240 get_manuf_hashtable(void)
3241 {
3242     return manuf_hashtable;
3243 }
3244
3245 wmem_map_t *
3246 get_wka_hashtable(void)
3247 {
3248     return wka_hashtable;
3249 }
3250
3251 wmem_map_t *
3252 get_eth_hashtable(void)
3253 {
3254     return eth_hashtable;
3255 }
3256
3257 wmem_map_t *
3258 get_serv_port_hashtable(void)
3259 {
3260     return serv_port_hashtable;
3261 }
3262
3263 wmem_map_t *
3264 get_ipxnet_hash_table(void)
3265 {
3266         return ipxnet_hash_table;
3267 }
3268
3269 wmem_map_t *
3270 get_vlan_hash_table(void)
3271 {
3272         return vlan_hash_table;
3273 }
3274
3275 wmem_map_t *
3276 get_ipv4_hash_table(void)
3277 {
3278         return ipv4_hash_table;
3279 }
3280
3281 wmem_map_t *
3282 get_ipv6_hash_table(void)
3283 {
3284         return ipv6_hash_table;
3285 }
3286 /* Initialize all the address resolution subsystems in this file */
3287 void
3288 addr_resolv_init(void)
3289 {
3290     initialize_services();
3291     initialize_ethers();
3292     initialize_ipxnets();
3293     initialize_vlans();
3294     initialize_enterprises();
3295     /* host name initialization is done on a per-capture-file basis */
3296     /*host_name_lookup_init();*/
3297 }
3298
3299 /* Clean up all the address resolution subsystems in this file */
3300 void
3301 addr_resolv_cleanup(void)
3302 {
3303     vlan_name_lookup_cleanup();
3304     service_name_lookup_cleanup();
3305     ethers_cleanup();
3306     ipx_name_lookup_cleanup();
3307     enterprises_cleanup();
3308     /* host name initialization is done on a per-capture-file basis */
3309     /*host_name_lookup_cleanup();*/
3310 }
3311
3312 gboolean
3313 str_to_ip(const char *str, void *dst)
3314 {
3315     return ws_inet_pton4(str, (guint32 *)dst);
3316 }
3317
3318 gboolean
3319 str_to_ip6(const char *str, void *dst)
3320 {
3321     return ws_inet_pton6(str, (ws_in6_addr *)dst);
3322 }
3323
3324 /*
3325  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
3326  *
3327  * Local variables:
3328  * c-basic-offset: 4
3329  * tab-width: 8
3330  * indent-tabs-mode: nil
3331  * End:
3332  *
3333  * vi: set shiftwidth=4 tabstop=8 expandtab:
3334  * :indentSize=4:tabSize=8:noTabs=true:
3335  */