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