From ae5fbf492f2ba43f05063179a583f4711ddfec20 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 5 Nov 2009 22:24:21 +0000 Subject: [PATCH] Actually add the new dns-example.c code. :p svn:r1512 --- sample/dns-example.c | 169 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 sample/dns-example.c diff --git a/sample/dns-example.c b/sample/dns-example.c new file mode 100644 index 00000000..7757dd48 --- /dev/null +++ b/sample/dns-example.c @@ -0,0 +1,169 @@ + +#include + +#ifdef WIN32 +#include +#include +#else +#include +#include +#include +#endif + +#include +#include +#include +#include + +#ifdef _EVENT_HAVE_NETINET_IN6_H +#include +#endif + +#include +#include +#include + +#define u32 ev_uint32_t +#define u8 ev_uint8_t + +static const char * +debug_ntoa(u32 address) +{ + static char buf[32]; + u32 a = ntohl(address); + evutil_snprintf(buf, sizeof(buf), "%d.%d.%d.%d", + (int)(u8)((a>>24)&0xff), + (int)(u8)((a>>16)&0xff), + (int)(u8)((a>>8 )&0xff), + (int)(u8)((a )&0xff)); + return buf; +} + +static void +main_callback(int result, char type, int count, int ttl, + void *addrs, void *orig) { + char *n = (char*)orig; + int i; + for (i = 0; i < count; ++i) { + if (type == DNS_IPv4_A) { + printf("%s: %s\n", n, debug_ntoa(((u32*)addrs)[i])); + } else if (type == DNS_PTR) { + printf("%s: %s\n", n, ((char**)addrs)[i]); + } + } + if (!count) { + printf("%s: No answer (%d)\n", n, result); + } + fflush(stdout); +} + +static void +evdns_server_callback(struct evdns_server_request *req, void *data) +{ + int i, r; + (void)data; + /* dummy; give 192.168.11.11 as an answer for all A questions, + * give foo.bar.example.com as an answer for all PTR questions. */ + for (i = 0; i < req->nquestions; ++i) { + u32 ans = htonl(0xc0a80b0bUL); + if (req->questions[i]->type == EVDNS_TYPE_A && + req->questions[i]->dns_question_class == EVDNS_CLASS_INET) { + printf(" -- replying for %s (A)\n", req->questions[i]->name); + r = evdns_server_request_add_a_reply(req, req->questions[i]->name, + 1, &ans, 10); + if (r<0) + printf("eeep, didn't work.\n"); + } else if (req->questions[i]->type == EVDNS_TYPE_PTR && + req->questions[i]->dns_question_class == EVDNS_CLASS_INET) { + printf(" -- replying for %s (PTR)\n", req->questions[i]->name); + r = evdns_server_request_add_ptr_reply(req, NULL, req->questions[i]->name, + "foo.bar.example.com", 10); + } else { + printf(" -- skipping %s [%d %d]\n", req->questions[i]->name, + req->questions[i]->type, req->questions[i]->dns_question_class); + } + } + + r = evdns_server_request_respond(req, 0); + if (r<0) + printf("eeek, couldn't send reply.\n"); +} + +static int verbose = 0; + +static void +logfn(int is_warn, const char *msg) { + if (!is_warn && !verbose) + return; + fprintf(stderr, "%s: %s\n", is_warn?"WARN":"INFO", msg); +} + +int +main(int c, char **v) { + int idx; + int reverse = 0, servertest = 0; + struct event_base *event_base = NULL; + struct evdns_base *evdns_base = NULL; + if (c<2) { + fprintf(stderr, "syntax: %s [-x] [-v] hostname\n", v[0]); + fprintf(stderr, "syntax: %s [-servertest]\n", v[0]); + return 1; + } + idx = 1; + while (idx < c && v[idx][0] == '-') { + if (!strcmp(v[idx], "-x")) + reverse = 1; + else if (!strcmp(v[idx], "-v")) + verbose = 1; + else if (!strcmp(v[idx], "-servertest")) + servertest = 1; + else + fprintf(stderr, "Unknown option %s\n", v[idx]); + ++idx; + } + + event_base = event_base_new(); + evdns_base = evdns_base_new(event_base, 0); + evdns_set_log_fn(logfn); + + if (servertest) { + int sock; + struct sockaddr_in my_addr; + sock = socket(PF_INET, SOCK_DGRAM, 0); + evutil_make_socket_nonblocking(sock); + my_addr.sin_family = AF_INET; + my_addr.sin_port = htons(10053); + my_addr.sin_addr.s_addr = INADDR_ANY; + if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr))<0) { + perror("bind"); + exit(1); + } + evdns_add_server_port_with_base(event_base, sock, 0, evdns_server_callback, NULL); + } + if (idx < c) { +#ifdef WIN32 + evdns_base_config_windows_nameservers(evdns_base); +#else + evdns_base_resolv_conf_parse(evdns_base, DNS_OPTION_NAMESERVERS, + "/etc/resolv.conf"); +#endif + } + for (; idx < c; ++idx) { + if (reverse) { + struct in_addr addr; + if (!inet_aton(v[idx], &addr)) { + fprintf(stderr, "Skipping non-IP %s\n", v[idx]); + continue; + } + fprintf(stderr, "resolving %s...\n",v[idx]); + evdns_base_resolve_reverse(evdns_base, &addr, 0, main_callback, v[idx]); + } else { + fprintf(stderr, "resolving (fwd) %s...\n",v[idx]); + evdns_base_resolve_ipv4(evdns_base, v[idx], 0, main_callback, v[idx]); + } + } + fflush(stdout); + event_base_dispatch(event_base); + return 0; +} + -- 2.40.0