在c程序中使用lresolv和res\n send从根DNS服务器获得权威答案
我试图用c编写一个程序,从根服务器遍历给定域的权威NS记录 我编写的当前代码收到正确的回复,然后丢弃它(然后重试,放弃,失败)。我试图弄明白为什么它忽视了它所得到的答案 当尝试查找“slashdot.net”时,它正确地给出了gtld服务器的列表在c程序中使用lresolv和res\n send从根DNS服务器获得权威答案,c,dns,bind,libresolv,C,Dns,Bind,Libresolv,我试图用c编写一个程序,从根服务器遍历给定域的权威NS记录 我编写的当前代码收到正确的回复,然后丢弃它(然后重试,放弃,失败)。我试图弄明白为什么它忽视了它所得到的答案 当尝试查找“slashdot.net”时,它正确地给出了gtld服务器的列表 ./res_query slashdot.net. 198.41.0.4 reply length is: 487, errno is: 0 AR Records: a.gtld-servers.net. 2D IN A 192.5.6.30
./res_query slashdot.net. 198.41.0.4
reply length is: 487, errno is: 0
AR Records: a.gtld-servers.net. 2D IN A 192.5.6.30
AR Records: b.gtld-servers.net. 2D IN A 192.33.14.30
AR Records: c.gtld-servers.net. 2D IN A 192.26.92.30
....... (cut)
选择其中一个名称服务器…我们应该能够给出相同的查询,它应该提供名称服务器,但我得到一个超时
./res_query slashdot.net. 192.5.6.30
reply length is: -1, errno is: 0
./res_query Connection timed out
令人沮丧的是,运行数据包捕获。。。我可以看到正确的答案,但程序忽略了它
20544 NS? slashdot.net. (30)
20544- q: NS? slashdot.net. 0/4/0 ns: slashdot.net. [2d] NS ns1.dnsmadeeasy.com., slashdot.net. [2d] NS ns4.dnsmadeeasy.com., slashdot.net. [2d] NS ns3.dnsmadeeasy.com., slashdot.net. [2d] NS ns2.dnsmadeeasy.com. (117)
手动查找输出
> server 192.5.6.30
Default server: 192.5.6.30
Address: 192.5.6.30#53
> set type=ns
> slashdot.net
Server: 192.5.6.30
Address: 192.5.6.30#53
Non-authoritative answer:
Can't find slashdot.net: No answer
Authoritative answers can be found from:
slashdot.net nameserver = ns1.dnsmadeeasy.com.
slashdot.net nameserver = ns4.dnsmadeeasy.com.
slashdot.net nameserver = ns3.dnsmadeeasy.com.
slashdot.net nameserver = ns2.dnsmadeeasy.com.
整个程序的代码(添加了-lresolv进行编译):
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
u_char nsbuf[4096];
u_char响应[4096];
char dispbuf[4096];
国际响应;
char*nameserver=argv[2];
味精;
ns_rr;
int i,j,l;
结构状态资源;
内槲皮素;
如果(argc<2){
printf(“用法:%s[…]\n”,argv[0]);
出口(1);
}
char-str[512];
res_ninit(&res);
/*我们手动设置服务器的名称*/
res.nscount=1;
res.nsaddr\u list[0]。sin\u family=AF\u INET;
res.nsaddr\u list[0]。sin\u addr.s\u addr=inet\u addr(名称服务器);
res.nsaddr_list[0].sin_port=htons(53);
/*关闭递归请求*/
res.options&=~res\u递归;
queryLen=res\u nmkquery&res,
N______查询,
argv[1],,
纳苏·库恩,
嗯,嗯,,
(u_char*)空,
0,
(u_char*)空,
nsbuf,
sizeof(nsbuf));
responseLen=res\u n发送(&res),
nsbuf,
克利伦,
(u_char*)和响应,
sizeof(响应));
printf(“回复长度为:%d,错误号为:%d\n”,responseLen,res.res\u h\u errno);
如果(响应小于0)
{
perror(argv[0]);
}
其他的
{
ns_initparse(response、responseLen和msg);
/*ns_s_an(回答部分)当查看递归服务器时,ns_s_ar(附加部分
记录部分)查看权威*/
l=ns_msg_计数(msg,ns_s_an);
对于(j=0;j
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <resolv.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
int main (int argc, char *argv[])
{
u_char nsbuf[4096];
u_char response[4096];
char dispbuf[4096];
int responseLen;
char *nameserver = argv[2];
ns_msg msg;
ns_rr rr;
int i, j, l;
struct __res_state res;
int queryLen;
if (argc < 2) {
printf ("Usage: %s <domain>[...]\n", argv[0]);
exit (1);
}
char str[512];
res_ninit(&res);
/* We manually set the name server*/
res.nscount = 1;
res.nsaddr_list[0].sin_family = AF_INET;
res.nsaddr_list[0].sin_addr.s_addr = inet_addr(nameserver);
res.nsaddr_list[0].sin_port = htons(53);
/*turn off the request for recursion*/
res.options &= ~RES_RECURSE;
queryLen = res_nmkquery(&res,
ns_o_query,
argv[1],
ns_c_in,
ns_t_ns,
(u_char *)NULL,
0,
(u_char *)NULL,
nsbuf,
sizeof(nsbuf));
responseLen = res_nsend(&res,
nsbuf,
queryLen,
(u_char *)&response,
sizeof(response));
printf("reply length is: %d, errno is: %d\n",responseLen,res.res_h_errno);
if (responseLen < 0)
{
perror (argv[0]);
}
else
{
ns_initparse (response, responseLen, &msg);
/*ns_s_an (answer section) when looking at a recursive server, ns_s_ar (additional
records section) when looking at an authoritative */
l = ns_msg_count (msg, ns_s_an);
for (j = 0; j < l; j++)
{
ns_parserr (&msg, ns_s_an, j, &rr);
ns_sprintrr (&msg, &rr, NULL, NULL, dispbuf, sizeof (dispbuf));
printf ("AN Records: %s\n", dispbuf);
}
l = ns_msg_count (msg, ns_s_ar);
for (j = 0; j < l; j++)
{
ns_parserr (&msg, ns_s_ar, j, &rr);
ns_sprintrr (&msg, &rr, NULL, NULL, dispbuf, sizeof (dispbuf));
printf ("AR Records: %s\n", dispbuf);
}
}
exit (0);
}