簡體   English   中英

通過C套接字發送結構

[英]Sending structs over a C socket

我正在編寫DNS查詢客戶端,但無法理解我的數據如何發送以及如何使其正常工作。

在Wireshark中,我收到了許多帶有MALFORMED PACKET警告的隨機數據,而正在測試的DNS服務器沒有響應。 (當前是Google的DNS ... 8.8.8.8)

一段...

typedef struct DNS_HEADER {

    // id to identify the request
    int16_t id;

    // query or response flag; default is 0
    uint8_t qr :1;

    // type of query; default is 0
    uint8_t opcode :4;

    // authoritative answer
    uint8_t aa :1;

    // message was truncated
    uint8_t tc :1;

    // recursion desired; default is yes
    uint8_t rd :1;

    // recursion available
    uint8_t ra :1;

    // unused
    uint8_t z :1;

    // response code
    uint8_t rcode :4;

    // entries in the question section; default is 1
    uint16_t qdcount;

    // resource records
    uint16_t ancount;

    // server resource records (in the authority section)
    uint16_t nscount;

    // resource records (in addl. section)
    uint16_t arcount;

} dns_h;

header->qr = 0;
header->opcode = 0;
...
header->qdcount = htons(1);
...

還有我的信箱

char buffer[sizeof(*header) * sizeof(*question) * 2];
int offset = 0;
memcpy(buffer, header, sizeof(*header));
offset += sizeof(*header);
memcpy(buffer + offset, question, sizeof(*question)); 

ssize_t sent = sendto(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)addr, sizeof(*addr));

我究竟做錯了什么? 這是通過套接字發送結構的推薦方法嗎? 我已將標題中的大多數字段設置為0,並將任何我設置為1的內容都使用了htons

標頭結構有兩個問題:

  • z字段是3位,而不是1。因此, rcode字段在應保留的位置還剩兩位。
  • 您完全使用位域的事實。 為了實現這一目標,您需要在編譯時知道字節序,並且沒有可移植的方法來執行此操作。 您最好為所有內容聲明一個16位字段(或2個8位字段),並進行位移以讀取/寫入適當的值。

您沒有在頭文件的創建位置顯示代碼,而是在設置字段時確保使用htons ,以使值以網絡字節順序排列。

另外,請仔細查看Wireshark中數據包中的二進制數據。 將其與您輸入的值進行比較,看看有什么地方不對。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM