2012-11-18 44 views
0

Possible Duplicate:
C - byte array to structure (dns query)Ç - DNS查詢來構建

我有這些結構:

typedef struct dnsQuery { 
    char header[12]; 
    struct dnsQuerySection *querySection; 
} TdnsQuery; 

typedef struct dnsQuerySection { 
    unsigned char *name; 
    struct dnsQueryQuestion *question; 
} TdnsQuerySection; 

typedef struct dnsQueryQuestion { 
    unsigned short qtype; 
    unsigned short qclass; 
} TdnsQueryQuestion; 

我有從recvfrom字節數組buf的DNS查詢。我想從字節數組像這樣得到的結構:

TdnsQuery* dnsQuery = (TdnsQuery*)buf; 

當我試圖訪問QTYPE是這樣的:

printf("%u", dnsQuery->querySection->question.qtype); 

我得到賽格故障11

誰能幫我這些結構?他們怎麼了?我試圖添加結構:

typedef struct udpPacket { 
    char header[8]; 
    structr dnsQuery query; 
} 

並將此結構映射到字節數組,但它沒有幫助。有人可以幫助我建立這些結構嗎?他們應該如何使用UDP協議進行DNS查詢?

編輯:我的結構,現在看起來是這樣的:

typedef struct { 
     unsigned short qtype; 
     unsigned short qclass; 
} dnsQueryQuestion; 

typedef struct { 

     dnsQueryQuestion *question; 
     unsigned char *data[0]; 
} dnsQuerySection; 

typedef struct { 
     char header[12]; 
     dnsQuerySection querySection[0]; 
} dnsQuery; 

typedef struct udpPacket { 
     char header[8]; 
     dnsQuery query[0]; 
} TudpPacket; 

我加解析功能:

void parse(unsigned char *data, unsigned short *qtype, unsigned short *qclass) { 
    int i = 0; 
    while (data[i]) { 
     int len = data[i]; 
     i += len + 1; 
    } 
    *qtype = (unsigned short) data[i+1]; 
    *qclass = (unsigned short) data[i+3]; 
    return; 
} 

,並試圖解析:

TudpPacket udpPack = (TudpPacket)buf; 
parse(udpPack.query.querySection.data, &(udpPack.query.querySection.question.qtype), &(udpPack.query.querySection.question.qclass)); 
printf("%u\n", udpPack.query.querySection.question.qtype); 
+0

什麼是'buf'?它從何而來?它真的指向你的結構的一個實例嗎? – Mat

+0

Buf是來自'recvfrom'的字節數組。 –

+0

'struct dnsQuerySection * querySection;'< - 您不會從'recvfrom'獲得有效的指針。它不分配內存,將相關數據複製到那裏並將指針存儲在結構中。如果您接收到的消息包含_pointer_值,那麼這些值對您沒有用處,因爲他們會說出原始系統上的內容。 –

回答

3

首先,你可以開始通過將dnsQuery更改爲:

typedef struct dnsQuery { 
    char header[12]; 
    struct dnsQuerySection querySection[0]; 
} TdnsQuery; 

見零長度數組這裏的用法:http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

然而,由於QNAME部分在DNS的問題是變長的,你可能不能夠從QTYPEQCLASS分別做直接使用struct。例如,

Header 

00 01 - ID = 1 
01 00 - RD = 1 
00 01 - QD = 1 
00 00 - AN 
00 00 - NS 
00 00 - NR 

    Question for www.google.com 

    03 77 - 3 w 
    77 77 - w w 
    06 67 - 6 g 
    6f 6f - o o 
    67 6c - g l 
    65 03 - e 3 
    63 6f - c o 
    6d 00 - m 0 
    00 01 - QTYPE 
    00 01 - QCLASS 

如果你能保證有隻一個在傳入的請求的問題,試試這個:

typedef struct dnsQuerySection { 
    unsigned char *data[0]; 
} TdnsQuerySection; 

,並編寫一個函數來分析它。

編輯:下面是解析函數的草圖,只是爲了您的方便。

char* parse(unsigned char *data, unsigned short *qtype, unsigned short *qclass) { 
    int i = 0; 
    while (data[i]) { 
     int len = data[i]; 
     i += len + 1; 
    } 
    /* data[i] == 0 */ 
    /* you may need to loop data[] again and do strcpy to get the domain name */ 
    *qtype = (unsigned short) data[i+1]; 
    *qclass = (unsigned short) data[i+3]; 
    return /* domain name */; 
} 
+0

感謝這和解析功能,但我有零長度數組的問題。我得到錯誤:「數組類型具有不完整的元素類型」。 –

+0

@Bibo也許這有助於:http://stackoverflow.com/questions/6957766/array-type-has-incomplete-element-type –

+0

是的,它有幫助。我上面編輯了我的問題,但仍然遇到了seg錯誤。當編譯時,我得到錯誤:「從不兼容的指針類型」和「ISO C禁止零大小的數組」中傳遞'parse'的參數1「。你能幫助我嗎?現在我不需要域名,所以我從解析器中刪除它。 –