diff options
-rw-r--r-- | gg_sniff/dns.c | 77 | ||||
-rw-r--r-- | gg_sniff/gg_sniff.h | 4 |
2 files changed, 77 insertions, 4 deletions
diff --git a/gg_sniff/dns.c b/gg_sniff/dns.c index a3f35e7..f04f5ea 100644 --- a/gg_sniff/dns.c +++ b/gg_sniff/dns.c @@ -1,7 +1,12 @@ +#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 @@ -10,20 +15,86 @@ * 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_resolv(char *name, void (*cb)(char *name, char *ip)) +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) { - return -1; + 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); } diff --git a/gg_sniff/gg_sniff.h b/gg_sniff/gg_sniff.h index 9e0aeba..e20eb21 100644 --- a/gg_sniff/gg_sniff.h +++ b/gg_sniff/gg_sniff.h @@ -8,4 +8,6 @@ void ggsniff_pcap_shutdown(void); int ggsniff_dns_init(struct event_base *); void ggsniff_dns_shutdown(void); -int ggsniff_resolv(char *, void (*cb)(char *, char *)); +int ggsniff_dns_reverse(struct in_addr *, + void (*cb_usr)(struct in_addr *, char *, void *), + void *); |