RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

教你動手寫UDP協(xié)議?!狣NS報文解析

電子設(shè)計(jì) ? 來源:電子設(shè)計(jì) ? 作者:電子設(shè)計(jì) ? 2020-12-24 16:16 ? 次閱讀

教你動手寫UDP協(xié)議棧系列文章序號內(nèi)容1《教你動手寫UDP協(xié)議棧-UDP協(xié)議棧格式》2《教你動手寫UDP協(xié)議棧-DHCP報文解析》3《教你動手寫UDP協(xié)議棧-OTA上位機(jī)》4《教你動手寫UDP協(xié)議棧-DNS報文解析》背景因特網(wǎng)上的節(jié)點(diǎn)通過IP地址唯一標(biāo)識,并且能通過IP地址來識別參與分布式應(yīng)用的主機(jī)。但對于大多數(shù)人來說,這些地址太繁瑣而且難以使用和記憶(特別是IPV6地址)。因此互聯(lián)網(wǎng)支持使用主機(jī)名稱來識別包括客戶機(jī)和服務(wù)器在內(nèi)的主機(jī)。

為了使用如TCP和IP等協(xié)議,主機(jī)名稱可以通過稱為域名解析的過程轉(zhuǎn)換成IP地址。在互聯(lián)網(wǎng)中存在不同形式的名稱解析,但是最普遍、最重要的一種是采用分布式數(shù)據(jù)庫系統(tǒng),即我們熟知的域名系統(tǒng)(DNS),也是這篇文章的主角。DNS - 是一個分布式的客戶機(jī)-服務(wù)器網(wǎng)絡(luò)數(shù)據(jù)庫,TCP/IP應(yīng)用程序使用它來完成主機(jī)名稱和IP地址之間的映射,提供電子郵件路由信息、服務(wù)命名和其他服務(wù)。DNS使用TCP和UDP的端口--53。DNS - 為了可擴(kuò)展性,DNS名稱是分層的。每一級域名長度的限制是63個字符,域名總長度則不能超過253個字符。下面來介紹DNS報文的格式解析,以及如何將域名轉(zhuǎn)為IP地址的流程。準(zhǔn)備工具工具介紹WireShark網(wǎng)絡(luò)封包分析軟件,分析數(shù)據(jù)包CMDwindow 命令行DNS報文解析抓包分析打開CMD和WireShark工具。在WireShark中設(shè)置過濾信息,我們只抓取DNS報文。在CMD鍵入ping www.baidu.com,然后查看WireShark的抓包信息。

可以看到兩包DNS報文,一個是DNS發(fā)送報文,一個是DNS接收報文發(fā)送報文

接收報文

發(fā)送報文和接收報文格式是不一樣的,從上面截圖可以看到,接收報文多一個Answers字段。

DNS可以使用UDP與TCP兩種協(xié)議。這里我們主要以UDP進(jìn)行分析。

DNS報文字段解析DNS報文格式:

DNS字段格式:發(fā)送報文

接收報文

DNS報文頭部

字段說明字段說明Transaction ID辨別DNS應(yīng)答報文是哪個請求報文的響應(yīng)QRFlags字段,1為響應(yīng),0位查詢OpCodeFlags字段,查詢或響應(yīng)類型,0為標(biāo)準(zhǔn),1為反向,2為服務(wù)器狀態(tài)請求AAFlags字段,授權(quán)回答TCFlags字段,截斷,1表示超過512字節(jié)并已被截斷,0表示沒有發(fā)送截斷RDFlags字段,是否希望得到遞歸回答RAFlags字段,響應(yīng)報文中為1便是得到遞歸響應(yīng)ZFlags字段,0ADFlags字段,真是數(shù)據(jù)CDFlags字段,禁止校驗(yàn)RCODEFlags字段,返回碼:0-無差錯,1-格式錯誤,2-服務(wù)器失效,3-不存在域名,4-查詢類型不支持,5-被禁止,6-15保留QuestionsFlags字段,查詢數(shù)AnswerFlags字段,資源記錄數(shù)AuthorityFlags字段,授權(quán)資源記錄數(shù)AdditionalFlags字段,額外資源記錄數(shù)代碼實(shí)現(xiàn)/** DNS message header */PACK_STRUCT_BEGINstruct dns_h(yuǎn)eader { PACK_STRUCT_FIELD(uint16_t id); PACK_STRUCT_FIELD(uint8_t flags1); PACK_STRUCT_FIELD(uint8_t flags2); PACK_STRUCT_FIELD(uint16_t numquestions); PACK_STRUCT_FIELD(uint16_t numanswers); PACK_STRUCT_FIELD(uint16_t numauthrr); PACK_STRUCT_FIELD(uint16_t numextrarr);}PACK_STRUCT_STRUCT;PACK_STRUCT_ENDDNS報文問題字段

字段說明查詢名稱格式:

字段說明name查詢名稱,不定長type查詢類型class查詢類代碼實(shí)現(xiàn)(由于名字是不定長,另作處理)PACK_STRUCT_BEGINstruct dns_query { PACK_STRUCT_FIELD(uint16_t type); PACK_STRUCT_FIELD(uint16_t class);}PACK_STRUCT_STRUCT;PACK_STRUCT_ENDDNS報文應(yīng)答字段

字段說明(此字段只有應(yīng)答包才有)字段說明name查詢名稱,不定長type查詢類型class查詢類TTL該資源記錄的生命周期data length資源數(shù)據(jù)長度address返回的IP地址,即域名轉(zhuǎn)換的IP地址代碼實(shí)現(xiàn)struct dns_answer { PACK_STRUCT_FIELD(uint16_t name); PACK_STRUCT_FIELD(uint16_t type); PACK_STRUCT_FIELD(uint16_t class); PACK_STRUCT_FIELD(uint32_t ttl); PACK_STRUCT_FIELD(uint16_t len); PACK_STRUCT_FIELD(struct ip_addr server_ip);}PACK_STRUCT_STRUCT;PACK_STRUCT_ENDDNS報文發(fā)送實(shí)現(xiàn)代碼實(shí)現(xiàn)static void dns_packet_output(uint8_t *host_name){ struct dns_h(yuǎn)eader dns_h(yuǎn)dr = {0}; struct dns_query dns_qry = {0}; struct dest_device_info dest_info = {0}; uint8_t *dns_packet = NULL; uint8_t *dns_name = NULL; uint16_t query_index = 0; uint16_t label_len = 0; uint16_t dns_name_len = strlen(host_name) + 2;
dns_packet = malloc(DNS_HDR_SIZE + dns_name_len + DNS_QUERY_SIZE); dns_name = malloc(strlen(host_name) + 2);
if(dns_packet != NULL && dns_name ?。絅ULL) { //打包DNS header memset(&dns_h(yuǎn)dr, 0, DNS_HDR_SIZE); dns_h(yuǎn)dr.id = mu_h(yuǎn)tons(TRANSACTION_ID); dns_h(yuǎn)dr.flags1 = DNS_FLAG1_RD; dns_h(yuǎn)dr.numquestions = mu_h(yuǎn)tons(1); memcpy(dns_packet, &dns_h(yuǎn)dr, DNS_HDR_SIZE);
//將域名轉(zhuǎn)換DNS數(shù)據(jù)包格式 change_to_dns_name(dns_name, host_name);
memcpy(dns_packet + DNS_HDR_SIZE, dns_name, dns_name_len);
dns_qry.type = mu_h(yuǎn)tons(DNS_RRTYPE_A); dns_qry.class = mu_h(yuǎn)tons(DNS_RRCLASS_IN); //打包DNS query memcpy(dns_packet + DNS_HDR_SIZE + dns_name_len, &dns_qry, DNS_QUERY_SIZE);
memcpy(&dest_info.dest_mac, get_gw_mac(), MAC_ADDR_SIZE); memcpy(&dest_info.dest_ip, get_dns_server(), IP_ADDR_SIZE); dest_info.src_port = DNS_CLIENT_PORT; dest_info.dest_port = DNS_SERVER_PORT; //通過UDP報文發(fā)送 mini_udp_output(&dest_info, dns_packet, (DNS_HDR_SIZE + dns_name_len + DNS_QUERY_SIZE)); }
if(dns_packet ?。?NULL) { free(dns_packet); } if(dns_name != NULL) { free(dns_name); }}驗(yàn)證代碼結(jié)果,我們通過查詢CSDN的IP地址,CSDN的域名:www.csdn.net

通過wireshark抓包,可以看到我們DNS報文已發(fā)送成功,并且有應(yīng)答包

DNS報文接收實(shí)現(xiàn)代碼實(shí)現(xiàn)static void dns_packet_input(void *dns_packet_data){ struct dns_h(yuǎn)eader *dns_h(yuǎn)dr = {0}; struct dns_answer *dns_ans = {0}; uint16_t dns_name_len = strlen("www.csdn.net") + 2; uint8_t *server_dns_name = malloc(strlen("www.csdn.net") + 2);
if(server_dns_name == NULL) { LOG_E("malloc fail?。。ⅲ? return; }
dns_h(yuǎn)dr = dns_packet_data; if(dns_h(yuǎn)dr->id == mu_ntohs(TRANSACTION_ID) && (dns_h(yuǎn)dr->numanswers > 1)) { change_to_dns_name(server_dns_name, "www.csdn.net");
if(strncmp(dns_packet_data + DNS_HDR_SIZE, server_dns_name, dns_name_len) == 0) { dns_ans = dns_packet_data + DNS_HDR_SIZE + dns_name_len + DNS_QUERY_SIZE;
printf("CSDN IP: %d:%d:%d:%d ", dns_ans->server_ip.a(chǎn)ddr[0], dns_ans->server_ip.a(chǎn)ddr[1], dns_ans->server_ip.a(chǎn)ddr[2], dns_ans->server_ip.a(chǎn)ddr[3]); } } free(server_dns_name);}通過wireshark抓包的IP與代碼捕獲的IP一致:

審核編輯:符乾江


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • DNS
    DNS
    +關(guān)注

    關(guān)注

    0

    文章

    218

    瀏覽量

    19828
  • UDP協(xié)議棧
    +關(guān)注

    關(guān)注

    0

    文章

    4

    瀏覽量

    1111
收藏 人收藏

    評論

    相關(guān)推薦

    UDP丟包的原因和解決方案

    每個 UDP 報文分為 UDP 報頭和 UDP 數(shù)據(jù)區(qū)兩部分。報頭由 4 個 16 位長(2 字節(jié))字段組成,分別說明該報文的源端口、目的端
    的頭像 發(fā)表于 10-22 14:38 ?1274次閱讀
    <b class='flag-5'>UDP</b>丟包的原因和解決方案

    解析的高防DNS是什么?高防DNS有什么作用?

    DNS解析手段在應(yīng)對攻擊時只能采取被動防守的策略,導(dǎo)致線路擁堵、服務(wù)器宕機(jī)、域名劫持等情況的時有發(fā)生。云解析作為一種更智能、更安全的解析技術(shù),其高防
    的頭像 發(fā)表于 09-26 17:31 ?288次閱讀

    Linux網(wǎng)絡(luò)協(xié)議的實(shí)現(xiàn)

    網(wǎng)絡(luò)協(xié)議是操作系統(tǒng)核心的一個重要組成部分,負(fù)責(zé)管理網(wǎng)絡(luò)通信中的數(shù)據(jù)包處理。在 Linux 操作系統(tǒng)中,網(wǎng)絡(luò)協(xié)議(Network Stack)負(fù)責(zé)實(shí)現(xiàn) TCP/IP
    的頭像 發(fā)表于 09-10 09:51 ?299次閱讀
    Linux網(wǎng)絡(luò)<b class='flag-5'>協(xié)議</b><b class='flag-5'>棧</b>的實(shí)現(xiàn)

    深度解析TCP與UDP協(xié)議

    計(jì)算機(jī)與網(wǎng)絡(luò)設(shè)備要相互通信,它們必須遵循一種共同的方法或標(biāo)準(zhǔn)。對于不同硬件平臺和操作系統(tǒng)之間的交互而言,這種共同遵循的規(guī)范尤為關(guān)鍵。我們將這一系列指導(dǎo)通信過程的規(guī)則稱為“協(xié)議”。TCP 和 UDP
    的頭像 發(fā)表于 09-02 14:53 ?383次閱讀
    深度<b class='flag-5'>解析</b>TCP與<b class='flag-5'>UDP</b><b class='flag-5'>協(xié)議</b>

    IEC101、IEC103、IEC104、Modbus報文解析工具

    IEC101\IEC104\IEC103\Modebus報文解析軟件,可有效解析上述協(xié)議的各種類型報文
    的頭像 發(fā)表于 09-02 09:56 ?1090次閱讀
    IEC101、IEC103、IEC104、Modbus<b class='flag-5'>報文</b><b class='flag-5'>解析</b>工具

    IP地址與DNS的關(guān)系

    IP地址和DNS是網(wǎng)絡(luò)架構(gòu)中的重要組成部分。IP地址是計(jì)算機(jī)網(wǎng)絡(luò)中用于標(biāo)識設(shè)備的唯一地址,而DNS則是負(fù)責(zé)將域名解析為IP地址的系統(tǒng)。記下來將講述DNS的構(gòu)成與IP地址的共同協(xié)作。
    的頭像 發(fā)表于 08-12 17:40 ?457次閱讀

    DNS的結(jié)構(gòu)和工作原理

    DNS 代表域名系統(tǒng)或域名服務(wù)器。DNS 將IP 地址解析為主機(jī)名,反之亦然。
    的頭像 發(fā)表于 08-05 15:23 ?514次閱讀
    <b class='flag-5'>DNS</b>的結(jié)構(gòu)和工作原理

    調(diào)試ESP8266集成LWIP協(xié)議UDP方式發(fā)送數(shù)據(jù)時,無法正常發(fā)送數(shù)據(jù)是哪里的問題?

    我在調(diào)試8266集成LWIP協(xié)議UDP方式發(fā)送數(shù)據(jù)時,參考別的環(huán)境的UDP例程,發(fā)現(xiàn)無法正常發(fā)送數(shù)據(jù),反復(fù)檢查了,并確認(rèn)8266已經(jīng)通過WIFI連上網(wǎng)了,但是使用LWIP
    發(fā)表于 07-12 07:44

    長時間發(fā)送344個字節(jié)的UDP報文,出現(xiàn)overflow the heap_size并導(dǎo)致系統(tǒng)異常重啟怎么解決?

    Jan8 2013,rst cause:2, boot mode:(3,0) 請問這個協(xié)議有問題??什么原因?qū)е逻@個問題??? 另外的現(xiàn)象,就是sendto的地方掛死。 之前在sendto地方加了一個select 判斷是否能夠發(fā)送
    發(fā)表于 07-11 07:55

    ESP32C6 WiFi報文出現(xiàn)大量重傳是什么原因?qū)е碌模?/a>

    使用ESP32C6作為AP與另一設(shè)備通信,傳輸層使用UDP協(xié)議,C6每隔100ms會發(fā)送一幀UDP報文,通過wireshark捕獲報文發(fā)現(xiàn),
    發(fā)表于 06-06 07:55

    ESP32C6作為UDP Server,使用recvfrom無法及時收到第一幀報文的原因?如何解決?

    我使用esp32-c6作為WiFi AP,當(dāng)有STA接入且通過DHCP為其分配了IP地址后,AP會創(chuàng)建一個udp socket作為server等待接收來自客戶端的UDP報文,AP成功創(chuàng)建socket
    發(fā)表于 06-06 07:34

    udp是什么協(xié)議udp協(xié)議介紹

    UDP(User Datagram Protocol,用戶數(shù)據(jù)報協(xié)議)是一種無連接的傳輸層協(xié)議,不保證數(shù)據(jù)傳輸?shù)目煽啃?,只?fù)責(zé)把數(shù)據(jù)包發(fā)送給目標(biāo)地址。它提供了簡單、高效的數(shù)據(jù)傳輸方式,適合對傳輸質(zhì)量
    的頭像 發(fā)表于 04-19 15:57 ?1361次閱讀

    ethernetif_input和tcpip協(xié)議線程的作用

    tcpip協(xié)議線程是lwIP協(xié)議的核心線程,負(fù)責(zé)處理TCP/IP協(xié)議的各種功能,包括TCP
    的頭像 發(fā)表于 03-20 10:01 ?1316次閱讀

    通信必備知識!TCP與UDP協(xié)議介紹及使用

    協(xié)議,它在數(shù)據(jù)傳輸之前不需要建立連接。發(fā)送端可以直接將數(shù)據(jù)報文(數(shù)據(jù)段)扔到網(wǎng)絡(luò)上,而接收端則從網(wǎng)絡(luò)中接收數(shù)據(jù),并從消息隊(duì)列中讀取數(shù)據(jù)段。UDP不提供可靠性和順序
    的頭像 發(fā)表于 03-15 08:19 ?1862次閱讀
    通信必備知識!TCP與<b class='flag-5'>UDP</b><b class='flag-5'>協(xié)議</b>介紹及使用

    通信網(wǎng)絡(luò)協(xié)議UDP協(xié)議技術(shù)解析

    在通常的網(wǎng)絡(luò)協(xié)議中,TCP/IP協(xié)議是一個常見的示例,其中UDP和TCP都是傳輸層協(xié)議。傳輸
    發(fā)表于 02-01 11:00 ?970次閱讀
    通信網(wǎng)絡(luò)<b class='flag-5'>協(xié)議</b><b class='flag-5'>棧</b>之<b class='flag-5'>UDP</b><b class='flag-5'>協(xié)議</b>技術(shù)<b class='flag-5'>解析</b>
    RM新时代网站-首页