|
1 | 1 | package header
|
2 | 2 |
|
| 3 | +import ( |
| 4 | + "bytes" |
| 5 | + "encoding/binary" |
| 6 | + "strings" |
| 7 | +) |
| 8 | + |
3 | 9 | //DNSResourceType resource type 表示资源类型
|
4 | 10 | type DNSResourceType uint16
|
5 | 11 |
|
6 |
| -const ( |
7 |
| - A DNSResourceType = iota + 1 // name = hostname value = ipaddress |
8 |
| - NS //name = ,value = dns hostname |
9 |
| - MD |
10 |
| - MF |
11 |
| - CNAME //name = hostname |
12 |
| - SOA |
13 |
| - MB |
14 |
| - MG |
15 |
| - MR |
16 |
| - NULL |
17 |
| - WKS |
18 |
| - PTR |
19 |
| - HINFO |
20 |
| - MINFO |
21 |
| - MX |
22 |
| -) |
23 |
| - |
24 | 12 | //DNSop 表示dns header 操作码
|
25 | 13 | type DNSop uint16
|
26 | 14 |
|
27 |
| -//1(QR)+4(OPCODE)+1(AA)+1(TC)+1(RD)+1(RA)+3(Z)+4(RCODE) |
28 |
| -const ( |
29 |
| - //dns请求 |
30 |
| - DNSRequest DNSop = 0 |
31 |
| - //dns应答 |
32 |
| - DNSReply DNSop = 1 |
| 15 | +//ADCOUNT question 实体数量占2个字节 |
| 16 | +//ANCOUNT answer 资源数量占2个字节 |
| 17 | +//NSCOUNT authority 部分包含的资源数量 2byte |
| 18 | +//ARCOUNT additional 部分包含的资源梳理 2byte |
| 19 | + |
33 | 20 |
|
34 |
| - //opcode 标准请求 |
35 |
| - DNSOpcodeQ DNSop = 0 << 1 |
36 |
| - //opcode 反转查询 |
37 |
| - DNSOpcodeR DNSop = 1 << 1 |
38 |
| - //opcode 服务器状态查询 |
39 |
| - DNSOpcodeS DNSop = 2 << 1 |
| 21 | +const ( |
| 22 | + ID = 0 |
| 23 | + OP = 2 |
| 24 | + QDCOUNT = 4 |
| 25 | + ANCOUNT = 6 |
| 26 | + NSCOUNT = 8 |
| 27 | + QACOUNT = 10 |
40 | 28 |
|
41 |
| - //权威应答 |
42 |
| - DNSAaN DNSop = 0 << 5 |
43 |
| - DNSAaY DNSop = 1 << 5 |
| 29 | + DOMAIN = 12 |
| 30 | +) |
44 | 31 |
|
45 |
| - //截断 |
46 |
| - DNSTcN DNSop = 0 << 6 |
47 |
| - DNSTcY DNSop = 1 << 6 |
| 32 | +type DNSQuestion struct { |
| 33 | + QuestionType uint16 |
| 34 | + QuestionClass uint16 |
| 35 | +} |
48 | 36 |
|
49 |
| - //期望递归 |
50 |
| - DNSRdN DNSop = 0 << 7 |
51 |
| - DNSRdY DNSop = 1 << 7 |
| 37 | +//DNS 报文的封装 |
| 38 | +type DNS []byte |
52 | 39 |
|
53 |
| - //递归可用性 |
54 |
| - DNSRaN DNSop = 0 << 8 |
55 |
| - DNSRaY DNSop = 1 << 8 |
| 40 | +//Setheader |
| 41 | +func (d DNS) Setheader(id uint16){ |
| 42 | + d.setID(id) |
| 43 | + d.setFlag(0,0,0,0,1,0,0) |
| 44 | +} |
| 45 | +//SetID |
| 46 | +func (d DNS)setID(id uint16){ |
| 47 | + //set id |
| 48 | + binary.BigEndian.PutUint16(d[ID:], id) |
| 49 | +} |
| 50 | +//SetQdcount |
| 51 | +func (d DNS)SetQdcount(qd uint16){ |
56 | 52 |
|
57 |
| - //保留备用 占3位 + 3 |
| 53 | + binary.BigEndian.PutUint16(d[QDCOUNT:], qd) |
| 54 | +} |
| 55 | +//SetAncount |
| 56 | +func (d DNS)SetAncount(an uint16){ |
| 57 | + binary.BigEndian.PutUint16(d[ANCOUNT:] ,an) |
| 58 | +} |
| 59 | +//SetNscount |
| 60 | +func (d DNS)SetNscount(ns uint16){ |
| 61 | + binary.BigEndian.PutUint16(d[NSCOUNT:],ns) |
| 62 | +} |
| 63 | +//SetQAcount |
| 64 | +func (d DNS)SetQAcount(qa uint16){ |
| 65 | + binary.BigEndian.PutUint16(d[QACOUNT:],qa) |
| 66 | +} |
| 67 | +//SetDomain |
| 68 | +func (d *DNS)SetDomain(domain string) { |
| 69 | + var ( |
| 70 | + buffer bytes.Buffer |
| 71 | + segments []string = strings.Split(domain, ".") |
| 72 | + ) |
| 73 | + binary.Write(&buffer,binary.BigEndian,*d) |
58 | 74 |
|
59 |
| - //RCODE 响应code 占4位 |
60 |
| - DNSRocdeN DNSop = 0 << 12 |
61 |
| - DNSRocdeF DNSop = 1 << 12 |
62 |
| - DNSRocdeS DNSop = 2 << 12 |
63 |
| - DNSRocdeNa DNSop = 3 << 12 |
64 |
| - DNSRocdeNot DNSop = 4 << 12 |
65 |
| - DNSRocdeRef DNSop = 5 << 12 |
66 |
| -) |
| 75 | + for _, seg := range segments { |
| 76 | + binary.Write(&buffer, binary.BigEndian, byte(len(seg))) |
| 77 | + binary.Write(&buffer, binary.BigEndian, []byte(seg)) |
| 78 | + } |
| 79 | + binary.Write(&buffer, binary.BigEndian, byte(0x00)) |
67 | 80 |
|
68 |
| -//ADCOUNT question 实体数量占2个字节 |
69 |
| -//ANCOUNT answer 资源数量占2个字节 |
70 |
| -//NSCOUNT authority 部分包含的资源数量 2byte |
71 |
| -//ARCOUNT additional 部分包含的资源梳理 2byte |
| 81 | + *d = buffer.Bytes() |
| 82 | + //return buffer.Bytes() |
| 83 | +} |
| 84 | +func (d *DNS)SetQuestion(qtype,qclass uint16){ |
| 85 | + q := DNSQuestion{ |
| 86 | + QuestionType: qtype, |
| 87 | + QuestionClass: qclass, |
| 88 | + } |
| 89 | + var buffer bytes.Buffer |
| 90 | + binary.Write(&buffer,binary.BigEndian,*d) |
| 91 | + binary.Write(&buffer,binary.BigEndian,q) |
| 92 | + *d = buffer.Bytes() |
| 93 | +} |
72 | 94 |
|
73 |
| -//DNS 报文的封装 |
74 |
| -type DNS []byte |
| 95 | +//SetFlag |
| 96 | +//QR 表示请求还是响应 |
| 97 | +//OPCODE 1表示反转查询;2表示服务器状态查询。3~15目前保留,以备将来使用 |
| 98 | +//AA 表示响应的服务器是否是权威DNS服务器。只在响应消息中有效。 |
| 99 | +//TC 指示消息是否因为传输大小限制而被截断 |
| 100 | +//RD 该值在请求消息中被设置,响应消息复用该值。如果被设置,表示希望服务器递归查询。但服务器不一定支持递归查询 |
| 101 | +//RA 。该值在响应消息中被设置或被清除,以表明服务器是否支持递归查询。 |
| 102 | +//Z 保留备用 |
| 103 | +//RCODE: 该值在响应消息中被设置。取值及含义如下: |
| 104 | +//0:No error condition,没有错误条件; |
| 105 | +//1:Format error,请求格式有误,服务器无法解析请求; |
| 106 | +//2:Server failure,服务器出错。 |
| 107 | +//3:Name Error,只在权威DNS服务器的响应中有意义,表示请求中的域名不存在。 |
| 108 | +//4:Not Implemented,服务器不支持该请求类型。 |
| 109 | +//5:Refused,服务器拒绝执行请求操作。 |
| 110 | +//6~15:保留备用 |
| 111 | +func (d DNS) setFlag(QR uint16, OPCODE uint16, AA uint16, TC uint16, RD uint16, RA uint16, RCODE uint16) { |
| 112 | + //set flag |
| 113 | + op := QR<<15 + OPCODE<<11 + AA<<10 + TC<<9 + RD<<8 + RA<<7 + RCODE |
| 114 | + binary.BigEndian.PutUint16(d[OP:],op) |
| 115 | +} |
0 commit comments