2016-12-29 14 views
1

다음 코드를 사용하여 우선 순위가 낮은 MX 레코드의 호스트 이름을 가져 오려고하지만 필요한 세부 정보 (호스트 이름, ttl, 우선 순위)를 구문 분석 할 수 없습니다. 주어진 네임 서버 응답으로부터.네임 서버 응답에서 DNS 레코드 (MX) 세부 정보를 추출합니다. C++

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); 
    } 

위 코드

gmail.com

같은 결과를 제공한다. 15M IN MX 30 alt3.gmail-smtp-in.l.google.com.

아래와 같이 별도의 버퍼에 호스트 이름, 우선 순위, ttl 등을 가져 오는 기능이 있습니까?

호스트 -> alt3.gmail-smtp-in.l.google.com

우선 순위 -> 30

TTL -> 15M

, 우리가 수동으로 확인해야합니다 우선 순위가 높은 레코드 인 이거나 요구 사항을 수행 할 수있는 유틸리티 기능 또는 코드가 있습니까?

편집 :

나는 위의 코드는 TXT 레코드 잘 작동하지만 MX 레코드에 대해 제대로 분석되지 않고 다음은 데이터

#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; 
} 

를 추출하려면 다음 코드를 시도 결과

출력 :

C P-> gmail.com
붙이> DataLength-
> 32 DataU_char-
>의 Gmail-SMTP-inlgoogle len-
> 33

클래스 -> 1, TTL
> 130 15 DataChar-> gmail-smtp-inlgoogle
FullRecord-> gmail.com. IN MX 30 alt3.gmail-smtp-in.l.google.com에서 2 분 10 초.

CP-> gmail.com
형 -> 15
클래스 -> 1, TTL
> 130 DataLength-
> 9 DataU_char-
> ALT2. len-
> 10
DataChar-> alt2 .
FullRecord-> gmail.com. IN MX 20 alt2.gmail-smtp-in.l.google.com에서 2 분 10 초.

DataChar &에서 DataU_char 특수 기호가 인쇄됩니다.
'alt2.gmail-smtp-in.l.google.com'대신 'alt2 . '이 인쇄됩니다.
또한 DataLength 값이 잘못되었습니다.
또한 레코드의 우선 순위를 얻을 수 없습니다.
여기에 뭔가가 누락되었거나 C++ 라이브러리 자체의 오류입니까?

답변

1

libresolv에는 특정 리소스 레코드 유형의 압축을 해제 할 수있는 공개 기능이 없지만 은 사용자가 직접 할 수 있도록 도와주는 기능입니다. 특히

는 기록에서 빅 endian 두 옥텟 필드를 읽어 이는 (압축) 도메인 이름을 읽을 수 dn_expandns_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 비트 우선 순위 필드를 건너 뜁니다.

+0

답변에있는 것을 시도해 보았고 우선 순위가 좋았지 만 교환은 비어있었습니다. 변수 len은 -1이고 msg_len이 무엇인지 알 수 없습니다. –

+1

@ fury.slay 원래 코드에서'l = res_query (...)'를 할당하지만 그 변수를'ns_msg_count()'의 결과로 덮어 씁니다. msg_len에 원래 값'l'을 저장해야합니다. – Alnitak

+0

어떤 레코드가 가장 우선 순위가 낮고 레코드를 사용하는지 수동으로 선택해야합니까, 아니면 어떤 API가 있습니까? –