2010-11-19 23 views
1

DNS応答の解析に問題があります。以下は私のコードです。以下はその構造です。私はprintf()でセグメント化エラーを取得しています。ここではQNAMEを印刷しようとしています。DNS応答の解析

私はかなりプログラミングに興味があるので、私は間違っています。任意のヘルプ/ヒントや有用なリソース/チュートリアルへのリンク、ありがとうございます。関数verfify_header()は正しく動作します。 memcpy()を使用してHEADERが正しく抽出された理由がわかりません。他のフィールドはそうではありません。

struct HEADER{  
    unsigned short ID;  
    unsigned char RD:1;  
    unsigned char TC:1;  
    unsigned char AA:1;  
    unsigned char Opcode:4;  
    unsigned char QR:1;  
    unsigned char RCODE:4;  
    unsigned char Z:3;  
    unsigned char RA:1;  
    unsigned short QDCOUNT;  
    unsigned short ANCOUNT;  
    unsigned short NSCOUNT;  
    unsigned short ARCOUNT;  
}; 

struct REQ_DATA{ 
unsigned short qtype; 
unsigned short qclass; 
}; 

struct QUESTION{ 
    char* qname; 
    struct REQ_DATA field; 
}; 

struct RES_DATA{  
    unsigned short type;  
    unsigned short class;  
    unsigned int ttl;  
    unsigned short rdlength;  
}; 

struct RESPONSE{ 
    char* name;  
    struct RES_DATA field;  
    char* rdata;  
}; 

以下は、dns応答を解析する機能です。

void parse_response(char *recvbuf, struct result *res)  
{ 
    struct HEADER *rechd = (struct HEADER*) malloc(sizeof(struct HEADER));  
    struct QUESTION qst;  
    struct RESPONSE *rp = (struct RESPONSE*) malloc(sizeof(struct RESPONSE));  
    struct RES_DATA fld; 

    char* rname = (char*)malloc(sizeof(char));  
    int hlen,qlen,rlen; 
    hlen = sizeof(struct HEADER); 

    memcpy(rechd,recvbuf,hlen); 

    verify_header(rechd); //This function works correctly 
    qlen = sizeof(struct QUESTION); 

    //RESPONSE is after QUESTION and HEADER 
    rlen = sizeof(struct RESPONSE); 

    int length = hlen + qlen; 
    rp = (struct RESPONSE*)(recvbuf + length); 
//memcpy(rp, recbbuf + length, sizeof(struct RESPONSE)); 

    memcpy(rname, rp, strlen(rname) + 1); 

    printf("QNAME: %s\n", *rname); //Segmentation Fault occurs over here!!!!! 

} 

おかげで、 のChander

+1

* on * rnameは不要です –

+0

私はNULL値を取得しています。また、私はmemcpyを使用してみましたが、memcpyを使用していましたが、同じ結果が残っています –

答えて

2

問題は、ネットワーク上のデータを解析するC構造体を使用しようとしているということです。あなたのマシンがビッグエンディアンで、コンパイラが命令したい方法でビットフィールドを注文すると、これはうまくいくかもしれません(ポインタフィールドに到達するまで...)、非常に壊れやすいものです。あなたはunsigned charの配列としてパケットを解析する必要があります。

今、これを見て:

struct QUESTION{ 
    char* qname; 
    struct REQ_DATA field; 
}; 

これは、8または16バイト(プラットフォームに応じて)だ構造、実際のDNSパケット内の可変長フィールドのような何もないです。また、ネットワークからのデータから有効なポインタ(自分のマシンとプロセスのアドレス空間に対してローカルになる)を取得する方法はありません。

関連する問題