C++ 从名称服务器回复c++;

C++ 从名称服务器回复c++;,c++,dns,mail-server,nslookup,C++,Dns,Mail Server,Nslookup,我试图使用以下代码获取低优先级MX记录的主机名,但无法从给定的名称服务器应答中解析所需的详细信息(主机名、ttl、优先级) u_char nsbuf[4096], dispbuf[4096]; ns_msg msg; ns_rr rr; int i, j, l; std::string domain("gmail.com"); l = res_query(domain.c_str(), ns_c_any, ns_t_mx, nsbuf, sizeof (nsbuf)); ns_init

我试图使用以下代码获取低优先级MX记录的主机名,但无法从给定的名称服务器应答中解析所需的详细信息(主机名、ttl、优先级)

u_char nsbuf[4096], dispbuf[4096];
ns_msg msg;
ns_rr rr;
int i, j, l;
std::string domain("gmail.com");
l = res_query(domain.c_str(), ns_c_any, ns_t_mx, nsbuf, sizeof (nsbuf));

    ns_initparse(nsbuf, l, &msg);
    printf("%s :\n", domain.c_str());
    l = ns_msg_count(msg, ns_s_an);
    for (j = 0; j < l; j++)
    {
        int prr = ns_parserr(&msg, ns_s_an, j, &rr);


        ns_sprintrr(&msg, &rr, NULL, NULL, reinterpret_cast<char*> (dispbuf), sizeof (dispbuf));

        printf("%s\n", dispbuf);
    }
u_char nsbuf[4096],dispbuf[4096];
味精;
ns_rr;
int i,j,l;
std::字符串域(“gmail.com”);
l=resu查询(domain.c_str(),ns_c_any,ns_t_mx,nsbuf,sizeof(nsbuf));
ns_initparse(nsbuf、l和msg);
printf(“%s:\n”,domain.c_str());
l=ns_msg_计数(msg,ns_s_an);
对于(j=0;j
上面的代码给出了如下结果:

gmail.com。15米MX 30 alt3.gmail-smtp-in.l.google.com

是否有任何可用的函数可以在下面这样的单独缓冲区中获取主机名、优先级、ttl等

主机->alt3.gmail-smtp-in.l.google.com

优先级->30

ttl->15米

如果我们手动检查优先级较高的记录, 或者是否有任何实用功能或代码可以满足要求

编辑:

我尝试了以下代码来提取数据

#include <cstdlib>
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <resolv.h>
#include <cstring>
#include <string>
#include <string.h>

using namespace std;
int main(int argc, char** argv) {

    u_char nsbuf[4096];
    u_char dispbuf[4096];
    ns_msg msg;
    ns_rr rr;
    int i, j, l;
    std::string domain("gmail.com");
    l = res_query(domain.c_str(), ns_c_any, ns_t_mx, nsbuf, sizeof (nsbuf));
    if (l < 0) {
        perror(domain.c_str());
    } else {
#ifdef USE_PQUERY
        res_pquery(&_res, nsbuf, l, stdout);
#else
        ns_initparse(nsbuf, l, &msg);
        l = ns_msg_count(msg, ns_s_an);
        for (j = 0; j < l; j++) {
            int prr = ns_parserr(&msg, ns_s_an, j, &rr);

            //BLOCK 1
            char *cp;
            cp = (char *) ns_rr_name(rr);
            printf("CP->%s\n", (char *) cp);
            int i1 = ns_rr_type(rr);
            printf("Type->%d\n", i1);
            int i2 = ns_rr_class(rr);
            printf("Class->%d\n", i2);
            int i3 = ns_rr_ttl(rr);
            printf("TTL->%d\n", i3);
            int i4 = ns_rr_rdlen(rr);
            printf("DataLength->%d\n", i4);

            //BLOCK 2
            const u_char *rdata = ns_rr_rdata(rr) +1;
            printf("DataU_char-> %s\n", reinterpret_cast<const char*> (rdata));

            int len = strlen(reinterpret_cast<const char*> (rdata));
            printf("len->%d\n", len);

            char rdatatemp[1024];
            strncpy(rdatatemp, reinterpret_cast<const char*> (rdata), sizeof (rdatatemp));
            printf("DataChar->%s\n", rdatatemp);

            ns_sprintrr(&msg, &rr, NULL, NULL, reinterpret_cast<char*> (dispbuf), sizeof (dispbuf));
            printf("FullRecord->%s\n", dispbuf);
            printf("\n");
        }
#endif
    }
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
int main(int argc,字符**argv){
u_char nsbuf[4096];
u_char dispbuf[4096];
味精;
ns_rr;
int i,j,l;
std::字符串域(“gmail.com”);
l=resu查询(domain.c_str(),ns_c_any,ns_t_mx,nsbuf,sizeof(nsbuf));
if(l<0){
perror(domain.c_str());
}否则{
#ifdef使用查询
调查(&U res,nsbuf,l,stdout);
#否则
ns_initparse(nsbuf、l和msg);
l=ns_msg_计数(msg,ns_s_an);
对于(j=0;j%s\n”,(char*)CP);
int i1=ns_rr_类型(rr);
printf(“类型->%d\n”,i1);
int i2=ns_rr_类(rr);
printf(“类->%d\n”,i2);
int i3=ns_rr_ttl(rr);
printf(“TTL->%d\n”,i3);
int i4=ns_rr_rdlen(rr);
printf(“数据长度->%d\n”,i4);
//第2区
常量u_char*rdata=ns_rr_rdata(rr)+1;
printf(“数据字符->%s\n”,重新解释数据类型(rdata));
int len=strlen(重新解释铸造(rdata));
printf(“len->%d\n”,len);
char rdatatemp[1024];
strncpy(RDATATTEMP、重新解释铸件(rdata)、尺寸(RDATATTEMP));
printf(“DataChar->%s\n”,rdatatemp);
ns_sprintrr(&msg,&rr,NULL,NULL,reinterpret_cast(dispbuf),sizeof(dispbuf));
printf(“完整记录->%s\n”,dispbuf);
printf(“\n”);
}
#恩迪夫
}
返回0;
}
上面的代码对于txt记录很有效,但是对于mx记录,它没有被正确解析,结果如下

输出:

CP->gmail.com
类型->15
类别->1
TTL->130
数据长度->32
DataU_char->gmail smtp在谷歌��
len->33
DataChar->gmail smtp在谷歌��
FullRecord->gmail.com。在.l.google.com的MX 30 alt3.gmail smtp中安装2m10s。

CP->gmail.com
类型->15
类别->1
TTL->130
数据长度->9
DataU_char->alt2�.�
len->10
DataChar->alt2�.�
FullRecord->gmail.com。MX 20 alt2.gmail-smtp-IN.l.google.com中的2m10s

因此,在DataChar和DataU_char中,会打印特殊符号
“alt2�.�' 是打印的,而不是“alt2.gmail smtp in.l.google.com”。
数据长度值也是错误的。
此外,我无法获得记录的优先级。

我在这里漏掉了什么东西,还是C++库本身的错误?

<代码>代码> LBISRESV< <代码>没有公开的功能来打开特定的资源记录类型,但是里面有一些函数帮助你自己做。 特别是,看看
dn_expand
,它可以读取一个(压缩的)域名和
ns_get16
,它将从记录中读取一个大端双八位字节字段,因此在您的情况下:

char exchange[NS_MAXDNAME];

const u_char *rdata = ns_rr_rdata(rr);

const uint16_t pri = ns_get16(rdata);
int len = dn_expand(nsbuf, nsbuf + msg_len, rdata + 2, exchange, sizeof(exchange));

printf("Pri->%d\n", pri);
printf("Exchange->%s\n", exchange);
其中
msg_len
替换覆盖的
l
变量,该变量包含所接收数据包的长度


调用
dn_expand()
中的
rdata+2
跳过了16位优先级字段。

我刚刚尝试了答案中的内容,获得了正确的优先级,但exchange是空的。变量len是-1,我不知道msg_len.@fury.slay在您的原始代码中是什么,您分配了
l=res_query(…)
,但随后您用
ns_msg_count()
的结果覆盖了该变量。您需要将
l
的原始值存储在
msg_len
中,我们应该手动检查哪个优先级最低并使用该记录,还是有任何api用于该记录?libresolv中没有api来选择应该使用哪个MX记录。另外,不要忘记,在没有任何MX记录的情况下,
A
AAAA
记录应被视为优先级为0的MX。