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
|
#include <stdlib.h>
#include <string.h>
#include <event2/dns.h>
#include <event2/util.h>
#include <event2/event.h>
#include <libglouglou.h>
/*
* For dns with libevent, see
* http://www.wangafu.net/~nickm/libevent-2.0/doxygen/html/dns_8h.html
* http://www.wangafu.net/~nickm/libevent-book/Ref9_dns.html
* spike/evdns_chrooted.c
* spike/evdns.c
*/
static void _cb_evdns_reverse(int, char, int, int, void *, void *);
struct req_reverse {
LIST_ENTRY(req_reverse) entry;
struct evdns_request *ereq;
struct in_addr ip;
void (*cb_usr)(struct in_addr *, char *, void *);
void *data;
};
struct event_base *_ev_base;
struct evdns_base *_evdns_base;
int _req_reverse_pending = 0;
LIST_HEAD(, req_reverse) _req_reverse_list; /* XXX for now unused. remove ? */
int
ggsniff_dns_init(struct event_base *ev_base)
{
_ev_base = ev_base;
_evdns_base = evdns_base_new(ev_base, 1);
if (!_evdns_base)
return 0;
return 1;
}
void
ggsniff_dns_shutdown(void)
{
evdns_base_free(_evdns_base, 1);
}
int
ggsniff_dns_reverse(struct in_addr *ip,
void (*cb_usr)(struct in_addr *, char *, void *),
void *data)
{
struct evutil_addrinfo hints;
struct req_reverse *req;
struct evdns_request *ereq;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_flags = EVUTIL_AI_CANONNAME;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
req = xmalloc(sizeof(struct req_reverse));
memcpy(&req->ip, ip, sizeof(struct in_addr));
req->cb_usr = cb_usr;
req->data = data;
LIST_INSERT_HEAD(&_req_reverse_list, req, entry);
_req_reverse_pending++;
ereq = evdns_base_resolve_reverse(_evdns_base, ip, 0, _cb_evdns_reverse, req);
if (ereq == NULL) {
gg_log_warn("gg_sniff dns request for %d returned immediately]\n",
ip->s_addr);
/* remove req from list and free it happened in the callback. */
return 0;
}
req->ereq = ereq;
return 1;
}
static void
_cb_evdns_reverse(int result, char type, int count,
int ttl, void *addresses, void *arg)
{
struct req_reverse *req;
req = arg;
if (type != DNS_PTR) {
gg_log_warn("gg_sniff dns reverse received non DNS_PTR record !");
goto free;
}
req->cb_usr(&req->ip, addresses, req->data);
free:
LIST_REMOVE(req, entry);
_req_reverse_pending--;
free(req);
}
|