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