PageRenderTime 66ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/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

Large files files are truncated, but you can click here to view the full file

  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. * a…

Large files files are truncated, but you can click here to view the full file