1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
#ifndef RESOLVER_HH
#define RESOLVER_HH
#include <stdio.h>
#include <unistd.h>
#include <map>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
class Resolver {
private:
bool verbose;
struct ltstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
}
};
struct ltip
{
bool operator()(const in_addr i1,
const in_addr i2) const
{
return i1.s_addr<i2.s_addr;
}
};
/* Caches */
typedef std::map<const in_addr, char *, ltip> reverse_cache_t;
typedef std::map<const char *, in_addr, ltstr> forward_cache_t;
reverse_cache_t reverse_cache;
forward_cache_t forward_cache;
public:
Resolver(bool be_verbose) {
verbose = be_verbose;
}
~Resolver() {
reverse_cache.clear();
forward_cache.clear();
}
/* Returns a pointer to a statically allocated string
* containing the DNS name for the requested address, or
* NULL if no name is available. */
char *get_name(const in_addr addr) {
/* Use cached name if available */
reverse_cache_t::iterator name;
name = reverse_cache.find(addr);
if (name != reverse_cache.end()) {
if (verbose)
fprintf(stderr, "Using cached name "
"for %s\n",
inet_ntoa(addr));
return reverse_cache[addr];
}
/* Otherwise look it up */
struct hostent *h;
if ((h=gethostbyaddr((char *)&addr, sizeof(in_addr),
AF_INET))==NULL) {
if (verbose)
fprintf(stderr, "Unable to resolve "
"address: %s\n",
inet_ntoa(addr));
return NULL;
} else {
/* Put it into our cache */
reverse_cache[addr] = strdup(h->h_name);
if (verbose)
fprintf(stderr, "Cached hostname "
"(%s) for %s\n", h->h_name,
inet_ntoa(addr));
}
return reverse_cache[addr];
}
/* Retrieves the IP Address for the specified hostname and
* returns it via the inp parameter. Returns 0 if an ip
* address was successfully returned, returns non zero
* otherwise */
int get_ip(const char *name, in_addr *inp) {
/* Used cached ip if available */
forward_cache_t::iterator tmp;
tmp = forward_cache.find(name);
if (tmp != forward_cache.end()) {
if (verbose)
fprintf(stderr, "Using cached ip (%s) "
"address for %s\n",
inet_ntoa(forward_cache[name]),
name);
memcpy(inp, &(*tmp).second, sizeof(in_addr));
return 0;
}
char *tname = strdup(name);
/* Otherwise look it up */
struct hostent *h;
if ((h=gethostbyname(tname))==NULL) {
if (verbose)
fprintf(stderr, "Unable to resolve "
"name: %s\n", tname);
inp = NULL;
free(tname);
return 1;
} else {
/* Put it into our cache */
in_addr t_addr;
memcpy(&t_addr, h->h_addr, sizeof(in_addr));
forward_cache[tname] = t_addr;
if (verbose)
fprintf(stderr, "Cached ip address "
"(%s) for %s\n",
inet_ntoa(forward_cache[tname]),
tname);
memcpy(inp, &t_addr, sizeof(in_addr));
}
return 0;
}
};
#endif
|