PageRenderTime 32ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/epan/addr_resolv.c

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