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