【转】adns解析库——域名解析实例(C++、linux)
转自:http://blog.csdn.net/fty8788/article/details/7480334
adns是一个开源的dns解析库
官方文档:http://www.chiark.greenend.org.uk/~ian/adns/
1. 初始化
adns_state adns; adns_query query; adns_answer *answer; 函数原型: int adns_init(adns_state *newstate_r, adns_initflags flags, FILE *diagfile /*0=>stderr*/); 举例: adns_init(&adns, adns_if_noenv, 0);
2. 提交待解析的域名
函数原型: int adns_submit(adns_state ads, const char *owner, adns_rrtype type, adns_queryflags flags, void *context, adns_query *query_r); 举例: adns_submit(adns, argv[1], adns_r_a, (adns_queryflags) 0, NULL, &query);
3. 检测是否有域名已检测完成
函数原型: int adns_check(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r); 例:adns_check(adns, &query, &answer, NULL);
4.
函数原型: int adns_wait(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r); 例:adns_wait(adns, &query, &answer, NULL);
5. 检测是否已完成所有提交的域名的解析
函数原型: void adns_finish(adns_state ads); 例:adns_finish(adns);
6. 范例代码(解析IPv4地址可使用adns v1.2或adns v1.4,解析IPv6地址请使用adns v1.6)
可从此处下载:https://github.com/sunada/adns_example/tree/71c9bf8555b67199c6b94c83027fb71eaa0c0241
#include "adns.h" #include <sys/errno.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int test_dns(char *host) { adns_state ads; adns_initflags flags; flags = adns_if_nosigpipe | adns_if_noerrprint; adns_init(&ads, flags, NULL); adns_query quer = NULL; adns_submit(ads, host, (adns_rrtype) adns_r_a, (adns_queryflags) 0, NULL, &quer); int tryCount = -1; int adns_cname = 0; while(tryCount < 32) { tryCount += 1; adns_answer *ans; int res = adns_check(ads, &quer, &ans, NULL); if(res == 0) { if (ans->status == adns_s_prohibitedcname) { char cname[128]; strncpy(cname, ans->cname, 127); cname[strlen(ans->cname)] = '\0'; adns_query quer = NULL; adns_submit(ads, cname, (adns_rrtype) adns_r_addr, (adns_queryflags) 0, NULL, &quer); adns_cname = 1; } else { //resolve IPv4 address /* * if(adns_cname) * printf("ip: %s\n", ans->status == adns_s_ok ? inet_ntoa(ans->rrs.addr->addr.inet.sin_addr) : "no"); * else * printf("ip: %s\n", ans->status == adns_s_ok ? inet_ntoa(*(ans->rrs.inaddr)) : "no"); */ //resolve IPv6 address if(adns_cname){ if(ans->status == adns_s_ok){ char buf[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &ans->rrs.addr->addr.inet6.sin6_addr, buf, sizeof(buf)); printf("ip: %s\n", buf); } else{ printf("no\n"); } } else{ if(ans->status == adns_s_ok){ char buf[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, ans->rrs.in6addr, buf, sizeof(buf)); printf("ip: %s\n", buf); } else{ printf("no\n"); } } adns_finish(ads); break; } } else if (res == ESRCH || res == EAGAIN) { sleep(1); } else { printf("host(%s) is err!\n", host); } } return 0; } int main(int argc, char *argv[]) { char host[128]; while(1) { scanf("%s", host); if(strlen(host) == 3 && strcmp(host, "eof")) break; test_dns(host); } return 0; }
Makefile
CFLAGS= -g TARGETS=libadns.a LIBOBJS=types.o event.o query.o reply.o general.o setup.o transmit.om parse.o poll.o check.o all: testdns testdns: testdns.c libadns.a libadns.a: $(LIBOBJS) rm -f $@ $(AR) cq $@ $(LIBOBJS) clean: rm -f $(LIBOBJS) libadns.a *~ config.status distclean: clean rm -f config.h .depend $(LIBOBJS): adns.h internal.h config.h