2016-12-29 8 views
1

次のコードを使用してMXレコードのホスト名を取得しようとしましたが、必要な詳細(ホスト名、ttl、優先順位)与えられたネームサーバの返信から。ネームサーバreplyからの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。

hostname、priority、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
タイプ - > 15
クラス - > 1
にTTL> 130
DataLength-> 32
DataU_char-> Gmailの-SMTP-inlgoogle
len-> 33
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。

DataChar & DataU_charの特殊記号が印刷されています。
'alt2.gmail-smtp-in.l.google.com'の代わりに 'alt2 . 'が印刷されています。
また、DataLength値が間違っています。
また、私はレコードの優先順位を得ることができません。
ここで何かが見つからないのですか、それともC++ライブラリ自体のエラーですか?

答えて

1

libresolvには特定のリソースレコードタイプを解凍するためのパブリック関数はありませんが、はその中にという機能があり、あなた自身でそれを行うのに役立ちます。

特に

、レコードからビッグエンディアン2オクテットフィールドを読んであろう(圧縮)ドメイン名とns_get16を読むことができるdn_expandを見て、あなたのケースではそう:

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がありますか? –

関連する問題