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