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