1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package net
25
26 import (
27 "fmt"
28 "os"
29 "reflect"
30 )
31
32
33
34
35 const (
36
37 dnsTypeA = 1
38 dnsTypeNS = 2
39 dnsTypeMD = 3
40 dnsTypeMF = 4
41 dnsTypeCNAME = 5
42 dnsTypeSOA = 6
43 dnsTypeMB = 7
44 dnsTypeMG = 8
45 dnsTypeMR = 9
46 dnsTypeNULL = 10
47 dnsTypeWKS = 11
48 dnsTypePTR = 12
49 dnsTypeHINFO = 13
50 dnsTypeMINFO = 14
51 dnsTypeMX = 15
52 dnsTypeTXT = 16
53 dnsTypeAAAA = 28
54 dnsTypeSRV = 33
55
56
57 dnsTypeAXFR = 252
58 dnsTypeMAILB = 253
59 dnsTypeMAILA = 254
60 dnsTypeALL = 255
61
62
63 dnsClassINET = 1
64 dnsClassCSNET = 2
65 dnsClassCHAOS = 3
66 dnsClassHESIOD = 4
67 dnsClassANY = 255
68
69
70 dnsRcodeSuccess = 0
71 dnsRcodeFormatError = 1
72 dnsRcodeServerFailure = 2
73 dnsRcodeNameError = 3
74 dnsRcodeNotImplemented = 4
75 dnsRcodeRefused = 5
76 )
77
78
79 type dnsHeader struct {
80 Id uint16
81 Bits uint16
82 Qdcount, Ancount, Nscount, Arcount uint16
83 }
84
85 const (
86
87 _QR = 1 << 15
88 _AA = 1 << 10
89 _TC = 1 << 9
90 _RD = 1 << 8
91 _RA = 1 << 7
92 )
93
94
95 type dnsQuestion struct {
96 Name string `net:"domain-name"`
97 Qtype uint16
98 Qclass uint16
99 }
100
101
102
103
104 type dnsRR_Header struct {
105 Name string `net:"domain-name"`
106 Rrtype uint16
107 Class uint16
108 Ttl uint32
109 Rdlength uint16
110 }
111
112 func (h *dnsRR_Header) Header() *dnsRR_Header {
113 return h
114 }
115
116 type dnsRR interface {
117 Header() *dnsRR_Header
118 }
119
120
121
122 type dnsRR_CNAME struct {
123 Hdr dnsRR_Header
124 Cname string `net:"domain-name"`
125 }
126
127 func (rr *dnsRR_CNAME) Header() *dnsRR_Header {
128 return &rr.Hdr
129 }
130
131 type dnsRR_HINFO struct {
132 Hdr dnsRR_Header
133 Cpu string
134 Os string
135 }
136
137 func (rr *dnsRR_HINFO) Header() *dnsRR_Header {
138 return &rr.Hdr
139 }
140
141 type dnsRR_MB struct {
142 Hdr dnsRR_Header
143 Mb string `net:"domain-name"`
144 }
145
146 func (rr *dnsRR_MB) Header() *dnsRR_Header {
147 return &rr.Hdr
148 }
149
150 type dnsRR_MG struct {
151 Hdr dnsRR_Header
152 Mg string `net:"domain-name"`
153 }
154
155 func (rr *dnsRR_MG) Header() *dnsRR_Header {
156 return &rr.Hdr
157 }
158
159 type dnsRR_MINFO struct {
160 Hdr dnsRR_Header
161 Rmail string `net:"domain-name"`
162 Email string `net:"domain-name"`
163 }
164
165 func (rr *dnsRR_MINFO) Header() *dnsRR_Header {
166 return &rr.Hdr
167 }
168
169 type dnsRR_MR struct {
170 Hdr dnsRR_Header
171 Mr string `net:"domain-name"`
172 }
173
174 func (rr *dnsRR_MR) Header() *dnsRR_Header {
175 return &rr.Hdr
176 }
177
178 type dnsRR_MX struct {
179 Hdr dnsRR_Header
180 Pref uint16
181 Mx string `net:"domain-name"`
182 }
183
184 func (rr *dnsRR_MX) Header() *dnsRR_Header {
185 return &rr.Hdr
186 }
187
188 type dnsRR_NS struct {
189 Hdr dnsRR_Header
190 Ns string `net:"domain-name"`
191 }
192
193 func (rr *dnsRR_NS) Header() *dnsRR_Header {
194 return &rr.Hdr
195 }
196
197 type dnsRR_PTR struct {
198 Hdr dnsRR_Header
199 Ptr string `net:"domain-name"`
200 }
201
202 func (rr *dnsRR_PTR) Header() *dnsRR_Header {
203 return &rr.Hdr
204 }
205
206 type dnsRR_SOA struct {
207 Hdr dnsRR_Header
208 Ns string `net:"domain-name"`
209 Mbox string `net:"domain-name"`
210 Serial uint32
211 Refresh uint32
212 Retry uint32
213 Expire uint32
214 Minttl uint32
215 }
216
217 func (rr *dnsRR_SOA) Header() *dnsRR_Header {
218 return &rr.Hdr
219 }
220
221 type dnsRR_TXT struct {
222 Hdr dnsRR_Header
223 Txt string
224 }
225
226 func (rr *dnsRR_TXT) Header() *dnsRR_Header {
227 return &rr.Hdr
228 }
229
230 type dnsRR_SRV struct {
231 Hdr dnsRR_Header
232 Priority uint16
233 Weight uint16
234 Port uint16
235 Target string `net:"domain-name"`
236 }
237
238 func (rr *dnsRR_SRV) Header() *dnsRR_Header {
239 return &rr.Hdr
240 }
241
242 type dnsRR_A struct {
243 Hdr dnsRR_Header
244 A uint32 `net:"ipv4"`
245 }
246
247 func (rr *dnsRR_A) Header() *dnsRR_Header {
248 return &rr.Hdr
249 }
250
251 type dnsRR_AAAA struct {
252 Hdr dnsRR_Header
253 AAAA [16]byte `net:"ipv6"`
254 }
255
256 func (rr *dnsRR_AAAA) Header() *dnsRR_Header {
257 return &rr.Hdr
258 }
259
260
261
262
263
264
265
266
267
268
269 var rr_mk = map[int]func() dnsRR{
270 dnsTypeCNAME: func() dnsRR { return new(dnsRR_CNAME) },
271 dnsTypeHINFO: func() dnsRR { return new(dnsRR_HINFO) },
272 dnsTypeMB: func() dnsRR { return new(dnsRR_MB) },
273 dnsTypeMG: func() dnsRR { return new(dnsRR_MG) },
274 dnsTypeMINFO: func() dnsRR { return new(dnsRR_MINFO) },
275 dnsTypeMR: func() dnsRR { return new(dnsRR_MR) },
276 dnsTypeMX: func() dnsRR { return new(dnsRR_MX) },
277 dnsTypeNS: func() dnsRR { return new(dnsRR_NS) },
278 dnsTypePTR: func() dnsRR { return new(dnsRR_PTR) },
279 dnsTypeSOA: func() dnsRR { return new(dnsRR_SOA) },
280 dnsTypeTXT: func() dnsRR { return new(dnsRR_TXT) },
281 dnsTypeSRV: func() dnsRR { return new(dnsRR_SRV) },
282 dnsTypeA: func() dnsRR { return new(dnsRR_A) },
283 dnsTypeAAAA: func() dnsRR { return new(dnsRR_AAAA) },
284 }
285
286
287
288
289 func packDomainName(s string, msg []byte, off int) (off1 int, ok bool) {
290
291 if n := len(s); n == 0 || s[n-1] != '.' {
292 s += "."
293 }
294
295
296
297
298
299 tot := len(s) + 1
300 if off+tot > len(msg) {
301 return len(msg), false
302 }
303
304
305 begin := 0
306 for i := 0; i < len(s); i++ {
307 if s[i] == '.' {
308 if i-begin >= 1<<6 {
309 return len(msg), false
310 }
311 msg[off] = byte(i - begin)
312 off++
313 for j := begin; j < i; j++ {
314 msg[off] = s[j]
315 off++
316 }
317 begin = i + 1
318 }
319 }
320 msg[off] = 0
321 off++
322 return off, true
323 }
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338 func unpackDomainName(msg []byte, off int) (s string, off1 int, ok bool) {
339 s = ""
340 ptr := 0
341 Loop:
342 for {
343 if off >= len(msg) {
344 return "", len(msg), false
345 }
346 c := int(msg[off])
347 off++
348 switch c & 0xC0 {
349 case 0x00:
350 if c == 0x00 {
351
352 break Loop
353 }
354
355 if off+c > len(msg) {
356 return "", len(msg), false
357 }
358 s += string(msg[off:off+c]) + "."
359 off += c
360 case 0xC0:
361
362
363
364
365
366 if off >= len(msg) {
367 return "", len(msg), false
368 }
369 c1 := msg[off]
370 off++
371 if ptr == 0 {
372 off1 = off
373 }
374 if ptr++; ptr > 10 {
375 return "", len(msg), false
376 }
377 off = (c^0xC0)<<8 | int(c1)
378 default:
379
380 return "", len(msg), false
381 }
382 }
383 if ptr == 0 {
384 off1 = off
385 }
386 return s, off1, true
387 }
388
389
390
391
392 func packStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok bool) {
393 for i := 0; i < val.NumField(); i++ {
394 f := val.Type().Field(i)
395 switch fv := val.Field(i); fv.Kind() {
396 default:
397 fmt.Fprintf(os.Stderr, "net: dns: unknown packing type %v", f.Type)
398 return len(msg), false
399 case reflect.Struct:
400 off, ok = packStructValue(fv, msg, off)
401 case reflect.Uint16:
402 if off+2 > len(msg) {
403 return len(msg), false
404 }
405 i := fv.Uint()
406 msg[off] = byte(i >> 8)
407 msg[off+1] = byte(i)
408 off += 2
409 case reflect.Uint32:
410 if off+4 > len(msg) {
411 return len(msg), false
412 }
413 i := fv.Uint()
414 msg[off] = byte(i >> 24)
415 msg[off+1] = byte(i >> 16)
416 msg[off+2] = byte(i >> 8)
417 msg[off+3] = byte(i)
418 off += 4
419 case reflect.Array:
420 if fv.Type().Elem().Kind() != reflect.Uint8 {
421 fmt.Fprintf(os.Stderr, "net: dns: unknown packing type %v", f.Type)
422 return len(msg), false
423 }
424 n := fv.Len()
425 if off+n > len(msg) {
426 return len(msg), false
427 }
428 reflect.Copy(reflect.ValueOf(msg[off:off+n]), fv)
429 off += n
430 case reflect.String:
431
432
433 s := fv.String()
434 switch f.Tag {
435 default:
436 fmt.Fprintf(os.Stderr, "net: dns: unknown string tag %v", f.Tag)
437 return len(msg), false
438 case `net:"domain-name"`:
439 off, ok = packDomainName(s, msg, off)
440 if !ok {
441 return len(msg), false
442 }
443 case "":
444
445 if len(s) > 255 || off+1+len(s) > len(msg) {
446 return len(msg), false
447 }
448 msg[off] = byte(len(s))
449 off++
450 off += copy(msg[off:], s)
451 }
452 }
453 }
454 return off, true
455 }
456
457 func structValue(any interface{}) reflect.Value {
458 return reflect.ValueOf(any).Elem()
459 }
460
461 func packStruct(any interface{}, msg []byte, off int) (off1 int, ok bool) {
462 off, ok = packStructValue(structValue(any), msg, off)
463 return off, ok
464 }
465
466
467
468
469 func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok bool) {
470 for i := 0; i < val.NumField(); i++ {
471 f := val.Type().Field(i)
472 switch fv := val.Field(i); fv.Kind() {
473 default:
474 fmt.Fprintf(os.Stderr, "net: dns: unknown packing type %v", f.Type)
475 return len(msg), false
476 case reflect.Struct:
477 off, ok = unpackStructValue(fv, msg, off)
478 case reflect.Uint16:
479 if off+2 > len(msg) {
480 return len(msg), false
481 }
482 i := uint16(msg[off])<<8 | uint16(msg[off+1])
483 fv.SetUint(uint64(i))
484 off += 2
485 case reflect.Uint32:
486 if off+4 > len(msg) {
487 return len(msg), false
488 }
489 i := uint32(msg[off])<<24 | uint32(msg[off+1])<<16 | uint32(msg[off+2])<<8 | uint32(msg[off+3])
490 fv.SetUint(uint64(i))
491 off += 4
492 case reflect.Array:
493 if fv.Type().Elem().Kind() != reflect.Uint8 {
494 fmt.Fprintf(os.Stderr, "net: dns: unknown packing type %v", f.Type)
495 return len(msg), false
496 }
497 n := fv.Len()
498 if off+n > len(msg) {
499 return len(msg), false
500 }
501 reflect.Copy(fv, reflect.ValueOf(msg[off:off+n]))
502 off += n
503 case reflect.String:
504 var s string
505 switch f.Tag {
506 default:
507 fmt.Fprintf(os.Stderr, "net: dns: unknown string tag %v", f.Tag)
508 return len(msg), false
509 case `net:"domain-name"`:
510 s, off, ok = unpackDomainName(msg, off)
511 if !ok {
512 return len(msg), false
513 }
514 case "":
515 if off >= len(msg) || off+1+int(msg[off]) > len(msg) {
516 return len(msg), false
517 }
518 n := int(msg[off])
519 off++
520 b := make([]byte, n)
521 for i := 0; i < n; i++ {
522 b[i] = msg[off+i]
523 }
524 off += n
525 s = string(b)
526 }
527 fv.SetString(s)
528 }
529 }
530 return off, true
531 }
532
533 func unpackStruct(any interface{}, msg []byte, off int) (off1 int, ok bool) {
534 off, ok = unpackStructValue(structValue(any), msg, off)
535 return off, ok
536 }
537
538
539
540
541
542
543 func printStructValue(val reflect.Value) string {
544 s := "{"
545 for i := 0; i < val.NumField(); i++ {
546 if i > 0 {
547 s += ", "
548 }
549 f := val.Type().Field(i)
550 if !f.Anonymous {
551 s += f.Name + "="
552 }
553 fval := val.Field(i)
554 if fv := fval; fv.Kind() == reflect.Struct {
555 s += printStructValue(fv)
556 } else if fv := fval; (fv.Kind() == reflect.Uint || fv.Kind() == reflect.Uint8 || fv.Kind() == reflect.Uint16 || fv.Kind() == reflect.Uint32 || fv.Kind() == reflect.Uint64 || fv.Kind() == reflect.Uintptr) && f.Tag == `net:"ipv4"` {
557 i := fv.Uint()
558 s += IPv4(byte(i>>24), byte(i>>16), byte(i>>8), byte(i)).String()
559 } else if fv := fval; fv.Kind() == reflect.Array && f.Tag == `net:"ipv6"` {
560 i := fv.Interface().([]byte)
561 s += IP(i).String()
562 } else {
563 s += fmt.Sprint(fval.Interface())
564 }
565 }
566 s += "}"
567 return s
568 }
569
570 func printStruct(any interface{}) string { return printStructValue(structValue(any)) }
571
572
573 func packRR(rr dnsRR, msg []byte, off int) (off2 int, ok bool) {
574 var off1 int
575
576
577
578
579
580 off1, ok = packStruct(rr.Header(), msg, off)
581 off2, ok = packStruct(rr, msg, off)
582 if !ok {
583 return len(msg), false
584 }
585
586 rr.Header().Rdlength = uint16(off2 - off1)
587 packStruct(rr.Header(), msg, off)
588 return off2, true
589 }
590
591
592 func unpackRR(msg []byte, off int) (rr dnsRR, off1 int, ok bool) {
593
594 var h dnsRR_Header
595 off0 := off
596 if off, ok = unpackStruct(&h, msg, off); !ok {
597 return nil, len(msg), false
598 }
599 end := off + int(h.Rdlength)
600
601
602
603 mk, known := rr_mk[int(h.Rrtype)]
604 if !known {
605 return &h, end, true
606 }
607 rr = mk()
608 off, ok = unpackStruct(rr, msg, off0)
609 if off != end {
610 return &h, end, true
611 }
612 return rr, off, ok
613 }
614
615
616
617
618
619 type dnsMsgHdr struct {
620 id uint16
621 response bool
622 opcode int
623 authoritative bool
624 truncated bool
625 recursion_desired bool
626 recursion_available bool
627 rcode int
628 }
629
630 type dnsMsg struct {
631 dnsMsgHdr
632 question []dnsQuestion
633 answer []dnsRR
634 ns []dnsRR
635 extra []dnsRR
636 }
637
638 func (dns *dnsMsg) Pack() (msg []byte, ok bool) {
639 var dh dnsHeader
640
641
642 dh.Id = dns.id
643 dh.Bits = uint16(dns.opcode)<<11 | uint16(dns.rcode)
644 if dns.recursion_available {
645 dh.Bits |= _RA
646 }
647 if dns.recursion_desired {
648 dh.Bits |= _RD
649 }
650 if dns.truncated {
651 dh.Bits |= _TC
652 }
653 if dns.authoritative {
654 dh.Bits |= _AA
655 }
656 if dns.response {
657 dh.Bits |= _QR
658 }
659
660
661 question := dns.question
662 answer := dns.answer
663 ns := dns.ns
664 extra := dns.extra
665
666 dh.Qdcount = uint16(len(question))
667 dh.Ancount = uint16(len(answer))
668 dh.Nscount = uint16(len(ns))
669 dh.Arcount = uint16(len(extra))
670
671
672
673
674 msg = make([]byte, 2000)
675
676
677 off := 0
678 off, ok = packStruct(&dh, msg, off)
679 for i := 0; i < len(question); i++ {
680 off, ok = packStruct(&question[i], msg, off)
681 }
682 for i := 0; i < len(answer); i++ {
683 off, ok = packRR(answer[i], msg, off)
684 }
685 for i := 0; i < len(ns); i++ {
686 off, ok = packRR(ns[i], msg, off)
687 }
688 for i := 0; i < len(extra); i++ {
689 off, ok = packRR(extra[i], msg, off)
690 }
691 if !ok {
692 return nil, false
693 }
694 return msg[0:off], true
695 }
696
697 func (dns *dnsMsg) Unpack(msg []byte) bool {
698
699 var dh dnsHeader
700 off := 0
701 var ok bool
702 if off, ok = unpackStruct(&dh, msg, off); !ok {
703 return false
704 }
705 dns.id = dh.Id
706 dns.response = (dh.Bits & _QR) != 0
707 dns.opcode = int(dh.Bits>>11) & 0xF
708 dns.authoritative = (dh.Bits & _AA) != 0
709 dns.truncated = (dh.Bits & _TC) != 0
710 dns.recursion_desired = (dh.Bits & _RD) != 0
711 dns.recursion_available = (dh.Bits & _RA) != 0
712 dns.rcode = int(dh.Bits & 0xF)
713
714
715 dns.question = make([]dnsQuestion, dh.Qdcount)
716 dns.answer = make([]dnsRR, 0, dh.Ancount)
717 dns.ns = make([]dnsRR, 0, dh.Nscount)
718 dns.extra = make([]dnsRR, 0, dh.Arcount)
719
720 var rec dnsRR
721
722 for i := 0; i < len(dns.question); i++ {
723 off, ok = unpackStruct(&dns.question[i], msg, off)
724 }
725 for i := 0; i < int(dh.Ancount); i++ {
726 rec, off, ok = unpackRR(msg, off)
727 if !ok {
728 return false
729 }
730 dns.answer = append(dns.answer, rec)
731 }
732 for i := 0; i < int(dh.Nscount); i++ {
733 rec, off, ok = unpackRR(msg, off)
734 if !ok {
735 return false
736 }
737 dns.ns = append(dns.ns, rec)
738 }
739 for i := 0; i < int(dh.Arcount); i++ {
740 rec, off, ok = unpackRR(msg, off)
741 if !ok {
742 return false
743 }
744 dns.extra = append(dns.extra, rec)
745 }
746
747
748
749 return true
750 }
751
752 func (dns *dnsMsg) String() string {
753 s := "DNS: " + printStruct(&dns.dnsMsgHdr) + "\n"
754 if len(dns.question) > 0 {
755 s += "-- Questions\n"
756 for i := 0; i < len(dns.question); i++ {
757 s += printStruct(&dns.question[i]) + "\n"
758 }
759 }
760 if len(dns.answer) > 0 {
761 s += "-- Answers\n"
762 for i := 0; i < len(dns.answer); i++ {
763 s += printStruct(dns.answer[i]) + "\n"
764 }
765 }
766 if len(dns.ns) > 0 {
767 s += "-- Name servers\n"
768 for i := 0; i < len(dns.ns); i++ {
769 s += printStruct(dns.ns[i]) + "\n"
770 }
771 }
772 if len(dns.extra) > 0 {
773 s += "-- Extra\n"
774 for i := 0; i < len(dns.extra); i++ {
775 s += printStruct(dns.extra[i]) + "\n"
776 }
777 }
778 return s
779 }