GolangはDNS要求の送信を実現する
3433 ワード
DNSプロトコルの具体的な内容についてはRFC 1035を参照してください.英語があまり上手でなければ、次の人の訳文をお勧めします.
http://blog.csdn.net/tigerjibo/article/details/6827736翻訳は十分詳しくなった.
ではGoの実現を見てみましょう
Wiresharkで正しいかどうかをチェックします(1枚切るのが長すぎて見にくいので2段に切りました):
DNSリクエストパケットを構築してみましょう.
転載する場合は出典を明記してください.http://blog.csdn.net/gophers/article/details/22942457
http://blog.csdn.net/tigerjibo/article/details/6827736翻訳は十分詳しくなった.
ではGoの実現を見てみましょう
package main
import (
"bytes"
"encoding/binary"
"fmt"
"net"
"strings"
)
type DNSHeader struct {
ID uint16
Flag uint16
QuestionCount uint16
AnswerRRs uint16 //RRs is Resource Records
AuthorityRRs uint16
AdditionalRRs 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 uint16
QuestionClass uint16
}
func ParseDomainName(domain string) []byte {
// , :
//"www.google.com" "0x03www0x06google0x03com0x00"
// + , + …… 0x00
var (
buffer bytes.Buffer
segments []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 DNSHeader
dns_question DNSQuery
)
// dns
dns_header.ID = 0xFFFF
dns_header.SetFlag(0, 0, 0, 0, 1, 0, 0)
dns_header.QuestionCount = 1
dns_header.AnswerRRs = 0
dns_header.AuthorityRRs = 0
dns_header.AdditionalRRs = 0
// dns
dns_question.QuestionType = 1 //IPv4
dns_question.QuestionClass = 1
var (
conn net.Conn
err error
buffer 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で正しいかどうかをチェックします(1枚切るのが長すぎて見にくいので2段に切りました):
DNSリクエストパケットを構築してみましょう.
転載する場合は出典を明記してください.http://blog.csdn.net/gophers/article/details/22942457