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