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