2010-11-19 179 views
1

我在解析DNS響應時遇到了一些麻煩。以下是我的代碼。以下是結構。我在printf()中遇到了分段錯誤,我嘗試打印QNAME。解析DNS響應

我是非常業餘的,當談到C編程,所以即時通訊不確定哪裏會出錯。任何幫助/提示或鏈接到有用的資源/教程,將不勝感激。函數verfify_header()可以正常工作。我不確定HEADER爲什麼使用memcpy()正確提取。而其他領域則沒有。

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!!!!! 

} 

感謝, 錢德爾

+1

你不需要* on * rname – 2010-11-19 21:44:53

+0

我得到一個NULL值。此外,我試圖使用memmove()無論使用memcpy,但仍然是相同的結果 – 2010-11-19 21:54:04

回答

2

的問題是,你要使用C語言結構,從通過網絡分析數據。如果你的機器是big endian,並且你的編譯器按照你想要的順序排列位域,這可能會工作正常(直到你看到指針字段......),但它非常脆弱。您應該將數據包解析爲unsigned char的數組。

現在,看看這個:

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

這是這是8或16個字節的結構(根據您的平臺),沒有像可變長度字段中的實際DNS數據包。而且,你絕對沒有辦法從網絡中的數據中獲取有效的指針(這對本機和進程的地址空間是本地的)。