From 6411a3107aabdcd24a4b5c25ea97292ab8b25535 Mon Sep 17 00:00:00 2001 From: Laurent Ghigonis Date: Sat, 15 Dec 2012 03:09:01 +0100 Subject: integrate gg_sniff dns handling into libggnet it can be enabled in ggnet by calling ggnet_set_dns(), or can be used independently by including an calling ggnet_dns_new(), ggnet_dns_free() and ggnet_dns_reverse() WARNING: not tested yet, only compiles --- libglouglou/libggnet_dns.c | 113 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 libglouglou/libggnet_dns.c (limited to 'libglouglou/libggnet_dns.c') diff --git a/libglouglou/libggnet_dns.c b/libglouglou/libggnet_dns.c new file mode 100644 index 0000000..9685cde --- /dev/null +++ b/libglouglou/libggnet_dns.c @@ -0,0 +1,113 @@ +#include +#include + +#include "libggnet_dns.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 ggnet_dns *ggdns; + struct evdns_request *ereq; + struct in_addr ip; + void (*cb_usr)(struct in_addr *, char *, void *); + void *data; +}; + +struct ggnet_dns * +ggnet_dns_new(struct event_base *ev_base) +{ + struct ggnet_dns *dns = NULL; + + dns = calloc(1, sizeof(struct ggnet_dns)); + if (!dns) { + printf("could not allocate ggnet_dns\n"); + exit(1); + } + dns->ev_base = ev_base; + dns->evdns_base = evdns_base_new(ev_base, 1); + if (!dns->evdns_base) + goto err; + return dns; + +err: + if (dns) + free(dns); + return NULL; +} + +void +ggnet_dns_free(struct ggnet_dns *dns) +{ + evdns_base_free(dns->evdns_base, 1); + free(dns); +} + +int +ggnet_dns_reverse(struct ggnet_dns *dns, + 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 = malloc(sizeof(struct req_reverse)); + if (!req) { + printf("could not allocate req_reverse\n"); + exit(1); + } + req->ggdns = dns; + memcpy(&req->ip, ip, sizeof(struct in_addr)); + req->cb_usr = cb_usr; + req->data = data; + + LIST_INSERT_HEAD(&dns->req_reverse_list, req, entry); + dns->req_reverse_pending++; + ereq = evdns_base_resolve_reverse(dns->evdns_base, ip, 0, + _cb_evdns_reverse, req); + if (ereq == NULL) { + printf("libggnet_dns WARNING: 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) { + printf("libggnet_dns WARNING: dns reverse for %d received non DNS_PTR\n", + req->ip.s_addr); + goto free; + } + req->cb_usr(&req->ip, addresses, req->data); + +free: + LIST_REMOVE(req, entry); + req->ggdns->req_reverse_pending--; + free(req); +} -- cgit v1.2.3-59-g8ed1b