Golang實現發送DNS請求

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

關於DNS協議的具體內容可以查看RFC1035,如果英語不太好我推薦下面這個人的譯文:

http://blog.csdn.net/tigerjibo/article/details/6827736 翻譯的足夠詳盡了。



那麼來看下Go的實現:

package mainimport ("bytes""encoding/binary""fmt""net""strings")type DNSHeader struct {ID            uint16Flag          uint16QuestionCount uint16AnswerRRs     uint16 //RRs is Resource RecordsAuthorityRRs  uint16AdditionalRRs uint16}func (header *DNSHeader) SetFlag(QR uint16, OperationCode uint16, AuthoritativeAnswer uint16, Truncation uint16, RecursionDesired uint16, RecursionAvailable uint16, ResponseCode uint16) {header.Flag = QR<<15 + OperationCode<<11 + AuthoritativeAnswer<<10 + Truncation<<9 + RecursionDesired<<8 + RecursionAvailable<<7 + ResponseCode}type DNSQuery struct {QuestionType  uint16QuestionClass uint16}func ParseDomainName(domain string) []byte {//要將網域名稱解析成相應的格式,例如://"www.google.com"會被解析成"0x03www0x06google0x03com0x00"//就是長度+內容,長度+內容……最後以0x00結尾var (buffer   bytes.Buffersegments []string = strings.Split(domain, "."))for _, seg := range segments {binary.Write(&buffer, binary.BigEndian, byte(len(seg)))binary.Write(&buffer, binary.BigEndian, []byte(seg))}binary.Write(&buffer, binary.BigEndian, byte(0x00))return buffer.Bytes()}func main() {var (dns_header   DNSHeaderdns_question DNSQuery)//填充dns首部dns_header.ID = 0xFFFFdns_header.SetFlag(0, 0, 0, 0, 1, 0, 0)dns_header.QuestionCount = 1dns_header.AnswerRRs = 0dns_header.AuthorityRRs = 0dns_header.AdditionalRRs = 0//填充dns查詢首部dns_question.QuestionType = 1  //IPv4dns_question.QuestionClass = 1  var (conn net.Connerr  errorbuffer bytes.Buffer)//DNS伺服器的連接埠一般是53,IP你自己ipconfig查一下//別忘了DNS是基於UDP協議的if conn, err = net.Dial("udp", "211.137.191.26:53"); err != nil {fmt.Println(err.Error())return}defer conn.Close()//buffer中是我們要發送的資料,裡面的內容是DNS首部+查詢內容+DNS查詢首部binary.Write(&buffer, binary.BigEndian, dns_header)binary.Write(&buffer, binary.BigEndian, ParseDomainName("www.baidu.com"))binary.Write(&buffer, binary.BigEndian, dns_question)fmt.Println(buffer.Bytes())if _, err := conn.Write(buffer.Bytes()); err != nil {fmt.Println(err.Error())return}fmt.Println("send success.")}



用Wireshark來檢查一下是否正確(截一張太長了不方便看,所以截成了兩段):




看看我們構造的DNS請求資料包:





如果轉載請註明出處:http://blog.csdn.net/gophers/article/details/22942457



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.