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