1
2
3
4
5
6
7
8
9
10
11
12
13 package dnsmessage
14
15 import (
16 "errors"
17 )
18
19
20
21
22 type Type uint16
23
24 const (
25
26 TypeA Type = 1
27 TypeNS Type = 2
28 TypeCNAME Type = 5
29 TypeSOA Type = 6
30 TypePTR Type = 12
31 TypeMX Type = 15
32 TypeTXT Type = 16
33 TypeAAAA Type = 28
34 TypeSRV Type = 33
35 TypeOPT Type = 41
36
37
38 TypeWKS Type = 11
39 TypeHINFO Type = 13
40 TypeMINFO Type = 14
41 TypeAXFR Type = 252
42 TypeALL Type = 255
43 )
44
45 var typeNames = map[Type]string{
46 TypeA: "TypeA",
47 TypeNS: "TypeNS",
48 TypeCNAME: "TypeCNAME",
49 TypeSOA: "TypeSOA",
50 TypePTR: "TypePTR",
51 TypeMX: "TypeMX",
52 TypeTXT: "TypeTXT",
53 TypeAAAA: "TypeAAAA",
54 TypeSRV: "TypeSRV",
55 TypeOPT: "TypeOPT",
56 TypeWKS: "TypeWKS",
57 TypeHINFO: "TypeHINFO",
58 TypeMINFO: "TypeMINFO",
59 TypeAXFR: "TypeAXFR",
60 TypeALL: "TypeALL",
61 }
62
63
64 func (t Type) String() string {
65 if n, ok := typeNames[t]; ok {
66 return n
67 }
68 return printUint16(uint16(t))
69 }
70
71
72 func (t Type) GoString() string {
73 if n, ok := typeNames[t]; ok {
74 return "dnsmessage." + n
75 }
76 return printUint16(uint16(t))
77 }
78
79
80 type Class uint16
81
82 const (
83
84 ClassINET Class = 1
85 ClassCSNET Class = 2
86 ClassCHAOS Class = 3
87 ClassHESIOD Class = 4
88
89
90 ClassANY Class = 255
91 )
92
93 var classNames = map[Class]string{
94 ClassINET: "ClassINET",
95 ClassCSNET: "ClassCSNET",
96 ClassCHAOS: "ClassCHAOS",
97 ClassHESIOD: "ClassHESIOD",
98 ClassANY: "ClassANY",
99 }
100
101
102 func (c Class) String() string {
103 if n, ok := classNames[c]; ok {
104 return n
105 }
106 return printUint16(uint16(c))
107 }
108
109
110 func (c Class) GoString() string {
111 if n, ok := classNames[c]; ok {
112 return "dnsmessage." + n
113 }
114 return printUint16(uint16(c))
115 }
116
117
118 type OpCode uint16
119
120
121 func (o OpCode) GoString() string {
122 return printUint16(uint16(o))
123 }
124
125
126 type RCode uint16
127
128
129 const (
130 RCodeSuccess RCode = 0
131 RCodeFormatError RCode = 1
132 RCodeServerFailure RCode = 2
133 RCodeNameError RCode = 3
134 RCodeNotImplemented RCode = 4
135 RCodeRefused RCode = 5
136 )
137
138 var rCodeNames = map[RCode]string{
139 RCodeSuccess: "RCodeSuccess",
140 RCodeFormatError: "RCodeFormatError",
141 RCodeServerFailure: "RCodeServerFailure",
142 RCodeNameError: "RCodeNameError",
143 RCodeNotImplemented: "RCodeNotImplemented",
144 RCodeRefused: "RCodeRefused",
145 }
146
147
148 func (r RCode) String() string {
149 if n, ok := rCodeNames[r]; ok {
150 return n
151 }
152 return printUint16(uint16(r))
153 }
154
155
156 func (r RCode) GoString() string {
157 if n, ok := rCodeNames[r]; ok {
158 return "dnsmessage." + n
159 }
160 return printUint16(uint16(r))
161 }
162
163 func printPaddedUint8(i uint8) string {
164 b := byte(i)
165 return string([]byte{
166 b/100 + '0',
167 b/10%10 + '0',
168 b%10 + '0',
169 })
170 }
171
172 func printUint8Bytes(buf []byte, i uint8) []byte {
173 b := byte(i)
174 if i >= 100 {
175 buf = append(buf, b/100+'0')
176 }
177 if i >= 10 {
178 buf = append(buf, b/10%10+'0')
179 }
180 return append(buf, b%10+'0')
181 }
182
183 func printByteSlice(b []byte) string {
184 if len(b) == 0 {
185 return ""
186 }
187 buf := make([]byte, 0, 5*len(b))
188 buf = printUint8Bytes(buf, uint8(b[0]))
189 for _, n := range b[1:] {
190 buf = append(buf, ',', ' ')
191 buf = printUint8Bytes(buf, uint8(n))
192 }
193 return string(buf)
194 }
195
196 const hexDigits = "0123456789abcdef"
197
198 func printString(str []byte) string {
199 buf := make([]byte, 0, len(str))
200 for i := 0; i < len(str); i++ {
201 c := str[i]
202 if c == '.' || c == '-' || c == ' ' ||
203 'A' <= c && c <= 'Z' ||
204 'a' <= c && c <= 'z' ||
205 '0' <= c && c <= '9' {
206 buf = append(buf, c)
207 continue
208 }
209
210 upper := c >> 4
211 lower := (c << 4) >> 4
212 buf = append(
213 buf,
214 '\\',
215 'x',
216 hexDigits[upper],
217 hexDigits[lower],
218 )
219 }
220 return string(buf)
221 }
222
223 func printUint16(i uint16) string {
224 return printUint32(uint32(i))
225 }
226
227 func printUint32(i uint32) string {
228
229 buf := make([]byte, 10)
230 for b, d := buf, uint32(1000000000); d > 0; d /= 10 {
231 b[0] = byte(i/d%10 + '0')
232 if b[0] == '0' && len(b) == len(buf) && len(buf) > 1 {
233 buf = buf[1:]
234 }
235 b = b[1:]
236 i %= d
237 }
238 return string(buf)
239 }
240
241 func printBool(b bool) string {
242 if b {
243 return "true"
244 }
245 return "false"
246 }
247
248 var (
249
250
251
252 ErrNotStarted = errors.New("parsing/packing of this type isn't available yet")
253
254
255
256 ErrSectionDone = errors.New("parsing/packing of this section has completed")
257
258 errBaseLen = errors.New("insufficient data for base length type")
259 errCalcLen = errors.New("insufficient data for calculated length type")
260 errReserved = errors.New("segment prefix is reserved")
261 errTooManyPtr = errors.New("too many pointers (>10)")
262 errInvalidPtr = errors.New("invalid pointer")
263 errInvalidName = errors.New("invalid dns name")
264 errNilResouceBody = errors.New("nil resource body")
265 errResourceLen = errors.New("insufficient data for resource body length")
266 errSegTooLong = errors.New("segment length too long")
267 errNameTooLong = errors.New("name too long")
268 errZeroSegLen = errors.New("zero length segment")
269 errResTooLong = errors.New("resource length too long")
270 errTooManyQuestions = errors.New("too many Questions to pack (>65535)")
271 errTooManyAnswers = errors.New("too many Answers to pack (>65535)")
272 errTooManyAuthorities = errors.New("too many Authorities to pack (>65535)")
273 errTooManyAdditionals = errors.New("too many Additionals to pack (>65535)")
274 errNonCanonicalName = errors.New("name is not in canonical format (it must end with a .)")
275 errStringTooLong = errors.New("character string exceeds maximum length (255)")
276 errCompressedSRV = errors.New("compressed name in SRV resource data")
277 )
278
279
280 const (
281
282
283
284
285
286 packStartingCap = 512
287
288
289 uint16Len = 2
290
291
292 uint32Len = 4
293
294
295
296
297 headerLen = 6 * uint16Len
298 )
299
300 type nestedError struct {
301
302 s string
303
304
305 err error
306 }
307
308
309 func (e *nestedError) Error() string {
310 return e.s + ": " + e.err.Error()
311 }
312
313
314 type Header struct {
315 ID uint16
316 Response bool
317 OpCode OpCode
318 Authoritative bool
319 Truncated bool
320 RecursionDesired bool
321 RecursionAvailable bool
322 AuthenticData bool
323 CheckingDisabled bool
324 RCode RCode
325 }
326
327 func (m *Header) pack() (id uint16, bits uint16) {
328 id = m.ID
329 bits = uint16(m.OpCode)<<11 | uint16(m.RCode)
330 if m.RecursionAvailable {
331 bits |= headerBitRA
332 }
333 if m.RecursionDesired {
334 bits |= headerBitRD
335 }
336 if m.Truncated {
337 bits |= headerBitTC
338 }
339 if m.Authoritative {
340 bits |= headerBitAA
341 }
342 if m.Response {
343 bits |= headerBitQR
344 }
345 if m.AuthenticData {
346 bits |= headerBitAD
347 }
348 if m.CheckingDisabled {
349 bits |= headerBitCD
350 }
351 return
352 }
353
354
355 func (m *Header) GoString() string {
356 return "dnsmessage.Header{" +
357 "ID: " + printUint16(m.ID) + ", " +
358 "Response: " + printBool(m.Response) + ", " +
359 "OpCode: " + m.OpCode.GoString() + ", " +
360 "Authoritative: " + printBool(m.Authoritative) + ", " +
361 "Truncated: " + printBool(m.Truncated) + ", " +
362 "RecursionDesired: " + printBool(m.RecursionDesired) + ", " +
363 "RecursionAvailable: " + printBool(m.RecursionAvailable) + ", " +
364 "AuthenticData: " + printBool(m.AuthenticData) + ", " +
365 "CheckingDisabled: " + printBool(m.CheckingDisabled) + ", " +
366 "RCode: " + m.RCode.GoString() + "}"
367 }
368
369
370 type Message struct {
371 Header
372 Questions []Question
373 Answers []Resource
374 Authorities []Resource
375 Additionals []Resource
376 }
377
378 type section uint8
379
380 const (
381 sectionNotStarted section = iota
382 sectionHeader
383 sectionQuestions
384 sectionAnswers
385 sectionAuthorities
386 sectionAdditionals
387 sectionDone
388
389 headerBitQR = 1 << 15
390 headerBitAA = 1 << 10
391 headerBitTC = 1 << 9
392 headerBitRD = 1 << 8
393 headerBitRA = 1 << 7
394 headerBitAD = 1 << 5
395 headerBitCD = 1 << 4
396 )
397
398 var sectionNames = map[section]string{
399 sectionHeader: "header",
400 sectionQuestions: "Question",
401 sectionAnswers: "Answer",
402 sectionAuthorities: "Authority",
403 sectionAdditionals: "Additional",
404 }
405
406
407 type header struct {
408 id uint16
409 bits uint16
410 questions uint16
411 answers uint16
412 authorities uint16
413 additionals uint16
414 }
415
416 func (h *header) count(sec section) uint16 {
417 switch sec {
418 case sectionQuestions:
419 return h.questions
420 case sectionAnswers:
421 return h.answers
422 case sectionAuthorities:
423 return h.authorities
424 case sectionAdditionals:
425 return h.additionals
426 }
427 return 0
428 }
429
430
431 func (h *header) pack(msg []byte) []byte {
432 msg = packUint16(msg, h.id)
433 msg = packUint16(msg, h.bits)
434 msg = packUint16(msg, h.questions)
435 msg = packUint16(msg, h.answers)
436 msg = packUint16(msg, h.authorities)
437 return packUint16(msg, h.additionals)
438 }
439
440 func (h *header) unpack(msg []byte, off int) (int, error) {
441 newOff := off
442 var err error
443 if h.id, newOff, err = unpackUint16(msg, newOff); err != nil {
444 return off, &nestedError{"id", err}
445 }
446 if h.bits, newOff, err = unpackUint16(msg, newOff); err != nil {
447 return off, &nestedError{"bits", err}
448 }
449 if h.questions, newOff, err = unpackUint16(msg, newOff); err != nil {
450 return off, &nestedError{"questions", err}
451 }
452 if h.answers, newOff, err = unpackUint16(msg, newOff); err != nil {
453 return off, &nestedError{"answers", err}
454 }
455 if h.authorities, newOff, err = unpackUint16(msg, newOff); err != nil {
456 return off, &nestedError{"authorities", err}
457 }
458 if h.additionals, newOff, err = unpackUint16(msg, newOff); err != nil {
459 return off, &nestedError{"additionals", err}
460 }
461 return newOff, nil
462 }
463
464 func (h *header) header() Header {
465 return Header{
466 ID: h.id,
467 Response: (h.bits & headerBitQR) != 0,
468 OpCode: OpCode(h.bits>>11) & 0xF,
469 Authoritative: (h.bits & headerBitAA) != 0,
470 Truncated: (h.bits & headerBitTC) != 0,
471 RecursionDesired: (h.bits & headerBitRD) != 0,
472 RecursionAvailable: (h.bits & headerBitRA) != 0,
473 AuthenticData: (h.bits & headerBitAD) != 0,
474 CheckingDisabled: (h.bits & headerBitCD) != 0,
475 RCode: RCode(h.bits & 0xF),
476 }
477 }
478
479
480 type Resource struct {
481 Header ResourceHeader
482 Body ResourceBody
483 }
484
485 func (r *Resource) GoString() string {
486 return "dnsmessage.Resource{" +
487 "Header: " + r.Header.GoString() +
488 ", Body: &" + r.Body.GoString() +
489 "}"
490 }
491
492
493 type ResourceBody interface {
494
495 pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error)
496
497
498
499 realType() Type
500
501
502 GoString() string
503 }
504
505
506 func (r *Resource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
507 if r.Body == nil {
508 return msg, errNilResouceBody
509 }
510 oldMsg := msg
511 r.Header.Type = r.Body.realType()
512 msg, lenOff, err := r.Header.pack(msg, compression, compressionOff)
513 if err != nil {
514 return msg, &nestedError{"ResourceHeader", err}
515 }
516 preLen := len(msg)
517 msg, err = r.Body.pack(msg, compression, compressionOff)
518 if err != nil {
519 return msg, &nestedError{"content", err}
520 }
521 if err := r.Header.fixLen(msg, lenOff, preLen); err != nil {
522 return oldMsg, err
523 }
524 return msg, nil
525 }
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541 type Parser struct {
542 msg []byte
543 header header
544
545 section section
546 off int
547 index int
548 resHeaderValid bool
549 resHeaderOffset int
550 resHeaderType Type
551 resHeaderLength uint16
552 }
553
554
555 func (p *Parser) Start(msg []byte) (Header, error) {
556 if p.msg != nil {
557 *p = Parser{}
558 }
559 p.msg = msg
560 var err error
561 if p.off, err = p.header.unpack(msg, 0); err != nil {
562 return Header{}, &nestedError{"unpacking header", err}
563 }
564 p.section = sectionQuestions
565 return p.header.header(), nil
566 }
567
568 func (p *Parser) checkAdvance(sec section) error {
569 if p.section < sec {
570 return ErrNotStarted
571 }
572 if p.section > sec {
573 return ErrSectionDone
574 }
575 p.resHeaderValid = false
576 if p.index == int(p.header.count(sec)) {
577 p.index = 0
578 p.section++
579 return ErrSectionDone
580 }
581 return nil
582 }
583
584 func (p *Parser) resource(sec section) (Resource, error) {
585 var r Resource
586 var err error
587 r.Header, err = p.resourceHeader(sec)
588 if err != nil {
589 return r, err
590 }
591 p.resHeaderValid = false
592 r.Body, p.off, err = unpackResourceBody(p.msg, p.off, r.Header)
593 if err != nil {
594 return Resource{}, &nestedError{"unpacking " + sectionNames[sec], err}
595 }
596 p.index++
597 return r, nil
598 }
599
600 func (p *Parser) resourceHeader(sec section) (ResourceHeader, error) {
601 if p.resHeaderValid {
602 p.off = p.resHeaderOffset
603 }
604
605 if err := p.checkAdvance(sec); err != nil {
606 return ResourceHeader{}, err
607 }
608 var hdr ResourceHeader
609 off, err := hdr.unpack(p.msg, p.off)
610 if err != nil {
611 return ResourceHeader{}, err
612 }
613 p.resHeaderValid = true
614 p.resHeaderOffset = p.off
615 p.resHeaderType = hdr.Type
616 p.resHeaderLength = hdr.Length
617 p.off = off
618 return hdr, nil
619 }
620
621 func (p *Parser) skipResource(sec section) error {
622 if p.resHeaderValid && p.section == sec {
623 newOff := p.off + int(p.resHeaderLength)
624 if newOff > len(p.msg) {
625 return errResourceLen
626 }
627 p.off = newOff
628 p.resHeaderValid = false
629 p.index++
630 return nil
631 }
632 if err := p.checkAdvance(sec); err != nil {
633 return err
634 }
635 var err error
636 p.off, err = skipResource(p.msg, p.off)
637 if err != nil {
638 return &nestedError{"skipping: " + sectionNames[sec], err}
639 }
640 p.index++
641 return nil
642 }
643
644
645 func (p *Parser) Question() (Question, error) {
646 if err := p.checkAdvance(sectionQuestions); err != nil {
647 return Question{}, err
648 }
649 var name Name
650 off, err := name.unpack(p.msg, p.off)
651 if err != nil {
652 return Question{}, &nestedError{"unpacking Question.Name", err}
653 }
654 typ, off, err := unpackType(p.msg, off)
655 if err != nil {
656 return Question{}, &nestedError{"unpacking Question.Type", err}
657 }
658 class, off, err := unpackClass(p.msg, off)
659 if err != nil {
660 return Question{}, &nestedError{"unpacking Question.Class", err}
661 }
662 p.off = off
663 p.index++
664 return Question{name, typ, class}, nil
665 }
666
667
668 func (p *Parser) AllQuestions() ([]Question, error) {
669
670
671
672
673
674
675 qs := []Question{}
676 for {
677 q, err := p.Question()
678 if err == ErrSectionDone {
679 return qs, nil
680 }
681 if err != nil {
682 return nil, err
683 }
684 qs = append(qs, q)
685 }
686 }
687
688
689 func (p *Parser) SkipQuestion() error {
690 if err := p.checkAdvance(sectionQuestions); err != nil {
691 return err
692 }
693 off, err := skipName(p.msg, p.off)
694 if err != nil {
695 return &nestedError{"skipping Question Name", err}
696 }
697 if off, err = skipType(p.msg, off); err != nil {
698 return &nestedError{"skipping Question Type", err}
699 }
700 if off, err = skipClass(p.msg, off); err != nil {
701 return &nestedError{"skipping Question Class", err}
702 }
703 p.off = off
704 p.index++
705 return nil
706 }
707
708
709 func (p *Parser) SkipAllQuestions() error {
710 for {
711 if err := p.SkipQuestion(); err == ErrSectionDone {
712 return nil
713 } else if err != nil {
714 return err
715 }
716 }
717 }
718
719
720 func (p *Parser) AnswerHeader() (ResourceHeader, error) {
721 return p.resourceHeader(sectionAnswers)
722 }
723
724
725 func (p *Parser) Answer() (Resource, error) {
726 return p.resource(sectionAnswers)
727 }
728
729
730 func (p *Parser) AllAnswers() ([]Resource, error) {
731
732
733
734
735
736 n := int(p.header.answers)
737 if n > 20 {
738 n = 20
739 }
740 as := make([]Resource, 0, n)
741 for {
742 a, err := p.Answer()
743 if err == ErrSectionDone {
744 return as, nil
745 }
746 if err != nil {
747 return nil, err
748 }
749 as = append(as, a)
750 }
751 }
752
753
754
755
756
757 func (p *Parser) SkipAnswer() error {
758 return p.skipResource(sectionAnswers)
759 }
760
761
762 func (p *Parser) SkipAllAnswers() error {
763 for {
764 if err := p.SkipAnswer(); err == ErrSectionDone {
765 return nil
766 } else if err != nil {
767 return err
768 }
769 }
770 }
771
772
773 func (p *Parser) AuthorityHeader() (ResourceHeader, error) {
774 return p.resourceHeader(sectionAuthorities)
775 }
776
777
778 func (p *Parser) Authority() (Resource, error) {
779 return p.resource(sectionAuthorities)
780 }
781
782
783 func (p *Parser) AllAuthorities() ([]Resource, error) {
784
785
786
787
788
789 n := int(p.header.authorities)
790 if n > 10 {
791 n = 10
792 }
793 as := make([]Resource, 0, n)
794 for {
795 a, err := p.Authority()
796 if err == ErrSectionDone {
797 return as, nil
798 }
799 if err != nil {
800 return nil, err
801 }
802 as = append(as, a)
803 }
804 }
805
806
807
808
809
810 func (p *Parser) SkipAuthority() error {
811 return p.skipResource(sectionAuthorities)
812 }
813
814
815 func (p *Parser) SkipAllAuthorities() error {
816 for {
817 if err := p.SkipAuthority(); err == ErrSectionDone {
818 return nil
819 } else if err != nil {
820 return err
821 }
822 }
823 }
824
825
826 func (p *Parser) AdditionalHeader() (ResourceHeader, error) {
827 return p.resourceHeader(sectionAdditionals)
828 }
829
830
831 func (p *Parser) Additional() (Resource, error) {
832 return p.resource(sectionAdditionals)
833 }
834
835
836 func (p *Parser) AllAdditionals() ([]Resource, error) {
837
838
839
840
841
842 n := int(p.header.additionals)
843 if n > 10 {
844 n = 10
845 }
846 as := make([]Resource, 0, n)
847 for {
848 a, err := p.Additional()
849 if err == ErrSectionDone {
850 return as, nil
851 }
852 if err != nil {
853 return nil, err
854 }
855 as = append(as, a)
856 }
857 }
858
859
860
861
862
863 func (p *Parser) SkipAdditional() error {
864 return p.skipResource(sectionAdditionals)
865 }
866
867
868 func (p *Parser) SkipAllAdditionals() error {
869 for {
870 if err := p.SkipAdditional(); err == ErrSectionDone {
871 return nil
872 } else if err != nil {
873 return err
874 }
875 }
876 }
877
878
879
880
881
882 func (p *Parser) CNAMEResource() (CNAMEResource, error) {
883 if !p.resHeaderValid || p.resHeaderType != TypeCNAME {
884 return CNAMEResource{}, ErrNotStarted
885 }
886 r, err := unpackCNAMEResource(p.msg, p.off)
887 if err != nil {
888 return CNAMEResource{}, err
889 }
890 p.off += int(p.resHeaderLength)
891 p.resHeaderValid = false
892 p.index++
893 return r, nil
894 }
895
896
897
898
899
900 func (p *Parser) MXResource() (MXResource, error) {
901 if !p.resHeaderValid || p.resHeaderType != TypeMX {
902 return MXResource{}, ErrNotStarted
903 }
904 r, err := unpackMXResource(p.msg, p.off)
905 if err != nil {
906 return MXResource{}, err
907 }
908 p.off += int(p.resHeaderLength)
909 p.resHeaderValid = false
910 p.index++
911 return r, nil
912 }
913
914
915
916
917
918 func (p *Parser) NSResource() (NSResource, error) {
919 if !p.resHeaderValid || p.resHeaderType != TypeNS {
920 return NSResource{}, ErrNotStarted
921 }
922 r, err := unpackNSResource(p.msg, p.off)
923 if err != nil {
924 return NSResource{}, err
925 }
926 p.off += int(p.resHeaderLength)
927 p.resHeaderValid = false
928 p.index++
929 return r, nil
930 }
931
932
933
934
935
936 func (p *Parser) PTRResource() (PTRResource, error) {
937 if !p.resHeaderValid || p.resHeaderType != TypePTR {
938 return PTRResource{}, ErrNotStarted
939 }
940 r, err := unpackPTRResource(p.msg, p.off)
941 if err != nil {
942 return PTRResource{}, err
943 }
944 p.off += int(p.resHeaderLength)
945 p.resHeaderValid = false
946 p.index++
947 return r, nil
948 }
949
950
951
952
953
954 func (p *Parser) SOAResource() (SOAResource, error) {
955 if !p.resHeaderValid || p.resHeaderType != TypeSOA {
956 return SOAResource{}, ErrNotStarted
957 }
958 r, err := unpackSOAResource(p.msg, p.off)
959 if err != nil {
960 return SOAResource{}, err
961 }
962 p.off += int(p.resHeaderLength)
963 p.resHeaderValid = false
964 p.index++
965 return r, nil
966 }
967
968
969
970
971
972 func (p *Parser) TXTResource() (TXTResource, error) {
973 if !p.resHeaderValid || p.resHeaderType != TypeTXT {
974 return TXTResource{}, ErrNotStarted
975 }
976 r, err := unpackTXTResource(p.msg, p.off, p.resHeaderLength)
977 if err != nil {
978 return TXTResource{}, err
979 }
980 p.off += int(p.resHeaderLength)
981 p.resHeaderValid = false
982 p.index++
983 return r, nil
984 }
985
986
987
988
989
990 func (p *Parser) SRVResource() (SRVResource, error) {
991 if !p.resHeaderValid || p.resHeaderType != TypeSRV {
992 return SRVResource{}, ErrNotStarted
993 }
994 r, err := unpackSRVResource(p.msg, p.off)
995 if err != nil {
996 return SRVResource{}, err
997 }
998 p.off += int(p.resHeaderLength)
999 p.resHeaderValid = false
1000 p.index++
1001 return r, nil
1002 }
1003
1004
1005
1006
1007
1008 func (p *Parser) AResource() (AResource, error) {
1009 if !p.resHeaderValid || p.resHeaderType != TypeA {
1010 return AResource{}, ErrNotStarted
1011 }
1012 r, err := unpackAResource(p.msg, p.off)
1013 if err != nil {
1014 return AResource{}, err
1015 }
1016 p.off += int(p.resHeaderLength)
1017 p.resHeaderValid = false
1018 p.index++
1019 return r, nil
1020 }
1021
1022
1023
1024
1025
1026 func (p *Parser) AAAAResource() (AAAAResource, error) {
1027 if !p.resHeaderValid || p.resHeaderType != TypeAAAA {
1028 return AAAAResource{}, ErrNotStarted
1029 }
1030 r, err := unpackAAAAResource(p.msg, p.off)
1031 if err != nil {
1032 return AAAAResource{}, err
1033 }
1034 p.off += int(p.resHeaderLength)
1035 p.resHeaderValid = false
1036 p.index++
1037 return r, nil
1038 }
1039
1040
1041
1042
1043
1044 func (p *Parser) OPTResource() (OPTResource, error) {
1045 if !p.resHeaderValid || p.resHeaderType != TypeOPT {
1046 return OPTResource{}, ErrNotStarted
1047 }
1048 r, err := unpackOPTResource(p.msg, p.off, p.resHeaderLength)
1049 if err != nil {
1050 return OPTResource{}, err
1051 }
1052 p.off += int(p.resHeaderLength)
1053 p.resHeaderValid = false
1054 p.index++
1055 return r, nil
1056 }
1057
1058
1059
1060
1061
1062 func (p *Parser) UnknownResource() (UnknownResource, error) {
1063 if !p.resHeaderValid {
1064 return UnknownResource{}, ErrNotStarted
1065 }
1066 r, err := unpackUnknownResource(p.resHeaderType, p.msg, p.off, p.resHeaderLength)
1067 if err != nil {
1068 return UnknownResource{}, err
1069 }
1070 p.off += int(p.resHeaderLength)
1071 p.resHeaderValid = false
1072 p.index++
1073 return r, nil
1074 }
1075
1076
1077 func (m *Message) Unpack(msg []byte) error {
1078 var p Parser
1079 var err error
1080 if m.Header, err = p.Start(msg); err != nil {
1081 return err
1082 }
1083 if m.Questions, err = p.AllQuestions(); err != nil {
1084 return err
1085 }
1086 if m.Answers, err = p.AllAnswers(); err != nil {
1087 return err
1088 }
1089 if m.Authorities, err = p.AllAuthorities(); err != nil {
1090 return err
1091 }
1092 if m.Additionals, err = p.AllAdditionals(); err != nil {
1093 return err
1094 }
1095 return nil
1096 }
1097
1098
1099 func (m *Message) Pack() ([]byte, error) {
1100 return m.AppendPack(make([]byte, 0, packStartingCap))
1101 }
1102
1103
1104
1105 func (m *Message) AppendPack(b []byte) ([]byte, error) {
1106
1107
1108
1109 if len(m.Questions) > int(^uint16(0)) {
1110 return nil, errTooManyQuestions
1111 }
1112 if len(m.Answers) > int(^uint16(0)) {
1113 return nil, errTooManyAnswers
1114 }
1115 if len(m.Authorities) > int(^uint16(0)) {
1116 return nil, errTooManyAuthorities
1117 }
1118 if len(m.Additionals) > int(^uint16(0)) {
1119 return nil, errTooManyAdditionals
1120 }
1121
1122 var h header
1123 h.id, h.bits = m.Header.pack()
1124
1125 h.questions = uint16(len(m.Questions))
1126 h.answers = uint16(len(m.Answers))
1127 h.authorities = uint16(len(m.Authorities))
1128 h.additionals = uint16(len(m.Additionals))
1129
1130 compressionOff := len(b)
1131 msg := h.pack(b)
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141 compression := map[string]uint16{}
1142
1143 for i := range m.Questions {
1144 var err error
1145 if msg, err = m.Questions[i].pack(msg, compression, compressionOff); err != nil {
1146 return nil, &nestedError{"packing Question", err}
1147 }
1148 }
1149 for i := range m.Answers {
1150 var err error
1151 if msg, err = m.Answers[i].pack(msg, compression, compressionOff); err != nil {
1152 return nil, &nestedError{"packing Answer", err}
1153 }
1154 }
1155 for i := range m.Authorities {
1156 var err error
1157 if msg, err = m.Authorities[i].pack(msg, compression, compressionOff); err != nil {
1158 return nil, &nestedError{"packing Authority", err}
1159 }
1160 }
1161 for i := range m.Additionals {
1162 var err error
1163 if msg, err = m.Additionals[i].pack(msg, compression, compressionOff); err != nil {
1164 return nil, &nestedError{"packing Additional", err}
1165 }
1166 }
1167
1168 return msg, nil
1169 }
1170
1171
1172 func (m *Message) GoString() string {
1173 s := "dnsmessage.Message{Header: " + m.Header.GoString() + ", " +
1174 "Questions: []dnsmessage.Question{"
1175 if len(m.Questions) > 0 {
1176 s += m.Questions[0].GoString()
1177 for _, q := range m.Questions[1:] {
1178 s += ", " + q.GoString()
1179 }
1180 }
1181 s += "}, Answers: []dnsmessage.Resource{"
1182 if len(m.Answers) > 0 {
1183 s += m.Answers[0].GoString()
1184 for _, a := range m.Answers[1:] {
1185 s += ", " + a.GoString()
1186 }
1187 }
1188 s += "}, Authorities: []dnsmessage.Resource{"
1189 if len(m.Authorities) > 0 {
1190 s += m.Authorities[0].GoString()
1191 for _, a := range m.Authorities[1:] {
1192 s += ", " + a.GoString()
1193 }
1194 }
1195 s += "}, Additionals: []dnsmessage.Resource{"
1196 if len(m.Additionals) > 0 {
1197 s += m.Additionals[0].GoString()
1198 for _, a := range m.Additionals[1:] {
1199 s += ", " + a.GoString()
1200 }
1201 }
1202 return s + "}}"
1203 }
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216 type Builder struct {
1217
1218 msg []byte
1219
1220
1221 section section
1222
1223
1224
1225 header header
1226
1227
1228 start int
1229
1230
1231
1232 compression map[string]uint16
1233 }
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245 func NewBuilder(buf []byte, h Header) Builder {
1246 if buf == nil {
1247 buf = make([]byte, 0, packStartingCap)
1248 }
1249 b := Builder{msg: buf, start: len(buf)}
1250 b.header.id, b.header.bits = h.pack()
1251 var hb [headerLen]byte
1252 b.msg = append(b.msg, hb[:]...)
1253 b.section = sectionHeader
1254 return b
1255 }
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268 func (b *Builder) EnableCompression() {
1269 b.compression = map[string]uint16{}
1270 }
1271
1272 func (b *Builder) startCheck(s section) error {
1273 if b.section <= sectionNotStarted {
1274 return ErrNotStarted
1275 }
1276 if b.section > s {
1277 return ErrSectionDone
1278 }
1279 return nil
1280 }
1281
1282
1283 func (b *Builder) StartQuestions() error {
1284 if err := b.startCheck(sectionQuestions); err != nil {
1285 return err
1286 }
1287 b.section = sectionQuestions
1288 return nil
1289 }
1290
1291
1292 func (b *Builder) StartAnswers() error {
1293 if err := b.startCheck(sectionAnswers); err != nil {
1294 return err
1295 }
1296 b.section = sectionAnswers
1297 return nil
1298 }
1299
1300
1301 func (b *Builder) StartAuthorities() error {
1302 if err := b.startCheck(sectionAuthorities); err != nil {
1303 return err
1304 }
1305 b.section = sectionAuthorities
1306 return nil
1307 }
1308
1309
1310 func (b *Builder) StartAdditionals() error {
1311 if err := b.startCheck(sectionAdditionals); err != nil {
1312 return err
1313 }
1314 b.section = sectionAdditionals
1315 return nil
1316 }
1317
1318 func (b *Builder) incrementSectionCount() error {
1319 var count *uint16
1320 var err error
1321 switch b.section {
1322 case sectionQuestions:
1323 count = &b.header.questions
1324 err = errTooManyQuestions
1325 case sectionAnswers:
1326 count = &b.header.answers
1327 err = errTooManyAnswers
1328 case sectionAuthorities:
1329 count = &b.header.authorities
1330 err = errTooManyAuthorities
1331 case sectionAdditionals:
1332 count = &b.header.additionals
1333 err = errTooManyAdditionals
1334 }
1335 if *count == ^uint16(0) {
1336 return err
1337 }
1338 *count++
1339 return nil
1340 }
1341
1342
1343 func (b *Builder) Question(q Question) error {
1344 if b.section < sectionQuestions {
1345 return ErrNotStarted
1346 }
1347 if b.section > sectionQuestions {
1348 return ErrSectionDone
1349 }
1350 msg, err := q.pack(b.msg, b.compression, b.start)
1351 if err != nil {
1352 return err
1353 }
1354 if err := b.incrementSectionCount(); err != nil {
1355 return err
1356 }
1357 b.msg = msg
1358 return nil
1359 }
1360
1361 func (b *Builder) checkResourceSection() error {
1362 if b.section < sectionAnswers {
1363 return ErrNotStarted
1364 }
1365 if b.section > sectionAdditionals {
1366 return ErrSectionDone
1367 }
1368 return nil
1369 }
1370
1371
1372 func (b *Builder) CNAMEResource(h ResourceHeader, r CNAMEResource) error {
1373 if err := b.checkResourceSection(); err != nil {
1374 return err
1375 }
1376 h.Type = r.realType()
1377 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1378 if err != nil {
1379 return &nestedError{"ResourceHeader", err}
1380 }
1381 preLen := len(msg)
1382 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1383 return &nestedError{"CNAMEResource body", err}
1384 }
1385 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1386 return err
1387 }
1388 if err := b.incrementSectionCount(); err != nil {
1389 return err
1390 }
1391 b.msg = msg
1392 return nil
1393 }
1394
1395
1396 func (b *Builder) MXResource(h ResourceHeader, r MXResource) error {
1397 if err := b.checkResourceSection(); err != nil {
1398 return err
1399 }
1400 h.Type = r.realType()
1401 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1402 if err != nil {
1403 return &nestedError{"ResourceHeader", err}
1404 }
1405 preLen := len(msg)
1406 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1407 return &nestedError{"MXResource body", err}
1408 }
1409 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1410 return err
1411 }
1412 if err := b.incrementSectionCount(); err != nil {
1413 return err
1414 }
1415 b.msg = msg
1416 return nil
1417 }
1418
1419
1420 func (b *Builder) NSResource(h ResourceHeader, r NSResource) error {
1421 if err := b.checkResourceSection(); err != nil {
1422 return err
1423 }
1424 h.Type = r.realType()
1425 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1426 if err != nil {
1427 return &nestedError{"ResourceHeader", err}
1428 }
1429 preLen := len(msg)
1430 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1431 return &nestedError{"NSResource body", err}
1432 }
1433 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1434 return err
1435 }
1436 if err := b.incrementSectionCount(); err != nil {
1437 return err
1438 }
1439 b.msg = msg
1440 return nil
1441 }
1442
1443
1444 func (b *Builder) PTRResource(h ResourceHeader, r PTRResource) error {
1445 if err := b.checkResourceSection(); err != nil {
1446 return err
1447 }
1448 h.Type = r.realType()
1449 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1450 if err != nil {
1451 return &nestedError{"ResourceHeader", err}
1452 }
1453 preLen := len(msg)
1454 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1455 return &nestedError{"PTRResource body", err}
1456 }
1457 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1458 return err
1459 }
1460 if err := b.incrementSectionCount(); err != nil {
1461 return err
1462 }
1463 b.msg = msg
1464 return nil
1465 }
1466
1467
1468 func (b *Builder) SOAResource(h ResourceHeader, r SOAResource) error {
1469 if err := b.checkResourceSection(); err != nil {
1470 return err
1471 }
1472 h.Type = r.realType()
1473 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1474 if err != nil {
1475 return &nestedError{"ResourceHeader", err}
1476 }
1477 preLen := len(msg)
1478 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1479 return &nestedError{"SOAResource body", err}
1480 }
1481 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1482 return err
1483 }
1484 if err := b.incrementSectionCount(); err != nil {
1485 return err
1486 }
1487 b.msg = msg
1488 return nil
1489 }
1490
1491
1492 func (b *Builder) TXTResource(h ResourceHeader, r TXTResource) error {
1493 if err := b.checkResourceSection(); err != nil {
1494 return err
1495 }
1496 h.Type = r.realType()
1497 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1498 if err != nil {
1499 return &nestedError{"ResourceHeader", err}
1500 }
1501 preLen := len(msg)
1502 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1503 return &nestedError{"TXTResource body", err}
1504 }
1505 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1506 return err
1507 }
1508 if err := b.incrementSectionCount(); err != nil {
1509 return err
1510 }
1511 b.msg = msg
1512 return nil
1513 }
1514
1515
1516 func (b *Builder) SRVResource(h ResourceHeader, r SRVResource) error {
1517 if err := b.checkResourceSection(); err != nil {
1518 return err
1519 }
1520 h.Type = r.realType()
1521 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1522 if err != nil {
1523 return &nestedError{"ResourceHeader", err}
1524 }
1525 preLen := len(msg)
1526 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1527 return &nestedError{"SRVResource body", err}
1528 }
1529 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1530 return err
1531 }
1532 if err := b.incrementSectionCount(); err != nil {
1533 return err
1534 }
1535 b.msg = msg
1536 return nil
1537 }
1538
1539
1540 func (b *Builder) AResource(h ResourceHeader, r AResource) error {
1541 if err := b.checkResourceSection(); err != nil {
1542 return err
1543 }
1544 h.Type = r.realType()
1545 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1546 if err != nil {
1547 return &nestedError{"ResourceHeader", err}
1548 }
1549 preLen := len(msg)
1550 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1551 return &nestedError{"AResource body", err}
1552 }
1553 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1554 return err
1555 }
1556 if err := b.incrementSectionCount(); err != nil {
1557 return err
1558 }
1559 b.msg = msg
1560 return nil
1561 }
1562
1563
1564 func (b *Builder) AAAAResource(h ResourceHeader, r AAAAResource) error {
1565 if err := b.checkResourceSection(); err != nil {
1566 return err
1567 }
1568 h.Type = r.realType()
1569 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1570 if err != nil {
1571 return &nestedError{"ResourceHeader", err}
1572 }
1573 preLen := len(msg)
1574 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1575 return &nestedError{"AAAAResource body", err}
1576 }
1577 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1578 return err
1579 }
1580 if err := b.incrementSectionCount(); err != nil {
1581 return err
1582 }
1583 b.msg = msg
1584 return nil
1585 }
1586
1587
1588 func (b *Builder) OPTResource(h ResourceHeader, r OPTResource) error {
1589 if err := b.checkResourceSection(); err != nil {
1590 return err
1591 }
1592 h.Type = r.realType()
1593 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1594 if err != nil {
1595 return &nestedError{"ResourceHeader", err}
1596 }
1597 preLen := len(msg)
1598 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1599 return &nestedError{"OPTResource body", err}
1600 }
1601 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1602 return err
1603 }
1604 if err := b.incrementSectionCount(); err != nil {
1605 return err
1606 }
1607 b.msg = msg
1608 return nil
1609 }
1610
1611
1612 func (b *Builder) UnknownResource(h ResourceHeader, r UnknownResource) error {
1613 if err := b.checkResourceSection(); err != nil {
1614 return err
1615 }
1616 h.Type = r.realType()
1617 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1618 if err != nil {
1619 return &nestedError{"ResourceHeader", err}
1620 }
1621 preLen := len(msg)
1622 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1623 return &nestedError{"UnknownResource body", err}
1624 }
1625 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1626 return err
1627 }
1628 if err := b.incrementSectionCount(); err != nil {
1629 return err
1630 }
1631 b.msg = msg
1632 return nil
1633 }
1634
1635
1636 func (b *Builder) Finish() ([]byte, error) {
1637 if b.section < sectionHeader {
1638 return nil, ErrNotStarted
1639 }
1640 b.section = sectionDone
1641
1642 b.header.pack(b.msg[b.start:b.start])
1643 return b.msg, nil
1644 }
1645
1646
1647
1648 type ResourceHeader struct {
1649
1650 Name Name
1651
1652
1653
1654
1655 Type Type
1656
1657
1658
1659 Class Class
1660
1661
1662
1663
1664 TTL uint32
1665
1666
1667
1668
1669 Length uint16
1670 }
1671
1672
1673 func (h *ResourceHeader) GoString() string {
1674 return "dnsmessage.ResourceHeader{" +
1675 "Name: " + h.Name.GoString() + ", " +
1676 "Type: " + h.Type.GoString() + ", " +
1677 "Class: " + h.Class.GoString() + ", " +
1678 "TTL: " + printUint32(h.TTL) + ", " +
1679 "Length: " + printUint16(h.Length) + "}"
1680 }
1681
1682
1683
1684
1685 func (h *ResourceHeader) pack(oldMsg []byte, compression map[string]uint16, compressionOff int) (msg []byte, lenOff int, err error) {
1686 msg = oldMsg
1687 if msg, err = h.Name.pack(msg, compression, compressionOff); err != nil {
1688 return oldMsg, 0, &nestedError{"Name", err}
1689 }
1690 msg = packType(msg, h.Type)
1691 msg = packClass(msg, h.Class)
1692 msg = packUint32(msg, h.TTL)
1693 lenOff = len(msg)
1694 msg = packUint16(msg, h.Length)
1695 return msg, lenOff, nil
1696 }
1697
1698 func (h *ResourceHeader) unpack(msg []byte, off int) (int, error) {
1699 newOff := off
1700 var err error
1701 if newOff, err = h.Name.unpack(msg, newOff); err != nil {
1702 return off, &nestedError{"Name", err}
1703 }
1704 if h.Type, newOff, err = unpackType(msg, newOff); err != nil {
1705 return off, &nestedError{"Type", err}
1706 }
1707 if h.Class, newOff, err = unpackClass(msg, newOff); err != nil {
1708 return off, &nestedError{"Class", err}
1709 }
1710 if h.TTL, newOff, err = unpackUint32(msg, newOff); err != nil {
1711 return off, &nestedError{"TTL", err}
1712 }
1713 if h.Length, newOff, err = unpackUint16(msg, newOff); err != nil {
1714 return off, &nestedError{"Length", err}
1715 }
1716 return newOff, nil
1717 }
1718
1719
1720
1721
1722
1723
1724
1725 func (h *ResourceHeader) fixLen(msg []byte, lenOff int, preLen int) error {
1726 conLen := len(msg) - preLen
1727 if conLen > int(^uint16(0)) {
1728 return errResTooLong
1729 }
1730
1731
1732 packUint16(msg[lenOff:lenOff], uint16(conLen))
1733 h.Length = uint16(conLen)
1734
1735 return nil
1736 }
1737
1738
1739 const (
1740 edns0Version = 0
1741
1742 edns0DNSSECOK = 0x00008000
1743 ednsVersionMask = 0x00ff0000
1744 edns0DNSSECOKMask = 0x00ff8000
1745 )
1746
1747
1748
1749
1750 func (h *ResourceHeader) SetEDNS0(udpPayloadLen int, extRCode RCode, dnssecOK bool) error {
1751 h.Name = Name{Data: [255]byte{'.'}, Length: 1}
1752 h.Type = TypeOPT
1753 h.Class = Class(udpPayloadLen)
1754 h.TTL = uint32(extRCode) >> 4 << 24
1755 if dnssecOK {
1756 h.TTL |= edns0DNSSECOK
1757 }
1758 return nil
1759 }
1760
1761
1762 func (h *ResourceHeader) DNSSECAllowed() bool {
1763 return h.TTL&edns0DNSSECOKMask == edns0DNSSECOK
1764 }
1765
1766
1767
1768
1769 func (h *ResourceHeader) ExtendedRCode(rcode RCode) RCode {
1770 if h.TTL&ednsVersionMask == edns0Version {
1771 return RCode(h.TTL>>24<<4) | rcode
1772 }
1773 return rcode
1774 }
1775
1776 func skipResource(msg []byte, off int) (int, error) {
1777 newOff, err := skipName(msg, off)
1778 if err != nil {
1779 return off, &nestedError{"Name", err}
1780 }
1781 if newOff, err = skipType(msg, newOff); err != nil {
1782 return off, &nestedError{"Type", err}
1783 }
1784 if newOff, err = skipClass(msg, newOff); err != nil {
1785 return off, &nestedError{"Class", err}
1786 }
1787 if newOff, err = skipUint32(msg, newOff); err != nil {
1788 return off, &nestedError{"TTL", err}
1789 }
1790 length, newOff, err := unpackUint16(msg, newOff)
1791 if err != nil {
1792 return off, &nestedError{"Length", err}
1793 }
1794 if newOff += int(length); newOff > len(msg) {
1795 return off, errResourceLen
1796 }
1797 return newOff, nil
1798 }
1799
1800
1801 func packUint16(msg []byte, field uint16) []byte {
1802 return append(msg, byte(field>>8), byte(field))
1803 }
1804
1805 func unpackUint16(msg []byte, off int) (uint16, int, error) {
1806 if off+uint16Len > len(msg) {
1807 return 0, off, errBaseLen
1808 }
1809 return uint16(msg[off])<<8 | uint16(msg[off+1]), off + uint16Len, nil
1810 }
1811
1812 func skipUint16(msg []byte, off int) (int, error) {
1813 if off+uint16Len > len(msg) {
1814 return off, errBaseLen
1815 }
1816 return off + uint16Len, nil
1817 }
1818
1819
1820 func packType(msg []byte, field Type) []byte {
1821 return packUint16(msg, uint16(field))
1822 }
1823
1824 func unpackType(msg []byte, off int) (Type, int, error) {
1825 t, o, err := unpackUint16(msg, off)
1826 return Type(t), o, err
1827 }
1828
1829 func skipType(msg []byte, off int) (int, error) {
1830 return skipUint16(msg, off)
1831 }
1832
1833
1834 func packClass(msg []byte, field Class) []byte {
1835 return packUint16(msg, uint16(field))
1836 }
1837
1838 func unpackClass(msg []byte, off int) (Class, int, error) {
1839 c, o, err := unpackUint16(msg, off)
1840 return Class(c), o, err
1841 }
1842
1843 func skipClass(msg []byte, off int) (int, error) {
1844 return skipUint16(msg, off)
1845 }
1846
1847
1848 func packUint32(msg []byte, field uint32) []byte {
1849 return append(
1850 msg,
1851 byte(field>>24),
1852 byte(field>>16),
1853 byte(field>>8),
1854 byte(field),
1855 )
1856 }
1857
1858 func unpackUint32(msg []byte, off int) (uint32, int, error) {
1859 if off+uint32Len > len(msg) {
1860 return 0, off, errBaseLen
1861 }
1862 v := uint32(msg[off])<<24 | uint32(msg[off+1])<<16 | uint32(msg[off+2])<<8 | uint32(msg[off+3])
1863 return v, off + uint32Len, nil
1864 }
1865
1866 func skipUint32(msg []byte, off int) (int, error) {
1867 if off+uint32Len > len(msg) {
1868 return off, errBaseLen
1869 }
1870 return off + uint32Len, nil
1871 }
1872
1873
1874 func packText(msg []byte, field string) ([]byte, error) {
1875 l := len(field)
1876 if l > 255 {
1877 return nil, errStringTooLong
1878 }
1879 msg = append(msg, byte(l))
1880 msg = append(msg, field...)
1881
1882 return msg, nil
1883 }
1884
1885 func unpackText(msg []byte, off int) (string, int, error) {
1886 if off >= len(msg) {
1887 return "", off, errBaseLen
1888 }
1889 beginOff := off + 1
1890 endOff := beginOff + int(msg[off])
1891 if endOff > len(msg) {
1892 return "", off, errCalcLen
1893 }
1894 return string(msg[beginOff:endOff]), endOff, nil
1895 }
1896
1897
1898 func packBytes(msg []byte, field []byte) []byte {
1899 return append(msg, field...)
1900 }
1901
1902 func unpackBytes(msg []byte, off int, field []byte) (int, error) {
1903 newOff := off + len(field)
1904 if newOff > len(msg) {
1905 return off, errBaseLen
1906 }
1907 copy(field, msg[off:newOff])
1908 return newOff, nil
1909 }
1910
1911 const nonEncodedNameMax = 254
1912
1913
1914
1915 type Name struct {
1916 Data [255]byte
1917 Length uint8
1918 }
1919
1920
1921 func NewName(name string) (Name, error) {
1922 n := Name{Length: uint8(len(name))}
1923 if len(name) > len(n.Data) {
1924 return Name{}, errCalcLen
1925 }
1926 copy(n.Data[:], name)
1927 return n, nil
1928 }
1929
1930
1931 func MustNewName(name string) Name {
1932 n, err := NewName(name)
1933 if err != nil {
1934 panic("creating name: " + err.Error())
1935 }
1936 return n
1937 }
1938
1939
1940
1941
1942 func (n Name) String() string {
1943 return string(n.Data[:n.Length])
1944 }
1945
1946
1947 func (n *Name) GoString() string {
1948 return `dnsmessage.MustNewName("` + printString(n.Data[:n.Length]) + `")`
1949 }
1950
1951
1952
1953
1954
1955
1956
1957
1958 func (n *Name) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
1959 oldMsg := msg
1960
1961 if n.Length > nonEncodedNameMax {
1962 return nil, errNameTooLong
1963 }
1964
1965
1966 if n.Length == 0 || n.Data[n.Length-1] != '.' {
1967 return oldMsg, errNonCanonicalName
1968 }
1969
1970
1971 if n.Data[0] == '.' && n.Length == 1 {
1972 return append(msg, 0), nil
1973 }
1974
1975 var nameAsStr string
1976
1977
1978 for i, begin := 0, 0; i < int(n.Length); i++ {
1979
1980 if n.Data[i] == '.' {
1981
1982
1983
1984 if i-begin >= 1<<6 {
1985 return oldMsg, errSegTooLong
1986 }
1987
1988
1989 if i-begin == 0 {
1990 return oldMsg, errZeroSegLen
1991 }
1992
1993 msg = append(msg, byte(i-begin))
1994
1995 for j := begin; j < i; j++ {
1996 msg = append(msg, n.Data[j])
1997 }
1998
1999 begin = i + 1
2000 continue
2001 }
2002
2003
2004
2005
2006 if (i == 0 || n.Data[i-1] == '.') && compression != nil {
2007 if ptr, ok := compression[string(n.Data[i:n.Length])]; ok {
2008
2009
2010 return append(msg, byte(ptr>>8|0xC0), byte(ptr)), nil
2011 }
2012
2013
2014
2015 newPtr := len(msg) - compressionOff
2016 if newPtr <= int(^uint16(0)>>2) {
2017 if nameAsStr == "" {
2018
2019
2020 nameAsStr = string(n.Data[:n.Length])
2021 }
2022 compression[nameAsStr[i:]] = uint16(newPtr)
2023 }
2024 }
2025 }
2026 return append(msg, 0), nil
2027 }
2028
2029
2030 func (n *Name) unpack(msg []byte, off int) (int, error) {
2031 return n.unpackCompressed(msg, off, true )
2032 }
2033
2034 func (n *Name) unpackCompressed(msg []byte, off int, allowCompression bool) (int, error) {
2035
2036 currOff := off
2037
2038
2039
2040
2041 newOff := off
2042
2043
2044 var ptr int
2045
2046
2047 name := n.Data[:0]
2048
2049 Loop:
2050 for {
2051 if currOff >= len(msg) {
2052 return off, errBaseLen
2053 }
2054 c := int(msg[currOff])
2055 currOff++
2056 switch c & 0xC0 {
2057 case 0x00:
2058 if c == 0x00 {
2059
2060 break Loop
2061 }
2062 endOff := currOff + c
2063 if endOff > len(msg) {
2064 return off, errCalcLen
2065 }
2066
2067
2068
2069 for _, v := range msg[currOff:endOff] {
2070 if v == '.' {
2071 return off, errInvalidName
2072 }
2073 }
2074
2075 name = append(name, msg[currOff:endOff]...)
2076 name = append(name, '.')
2077 currOff = endOff
2078 case 0xC0:
2079 if !allowCompression {
2080 return off, errCompressedSRV
2081 }
2082 if currOff >= len(msg) {
2083 return off, errInvalidPtr
2084 }
2085 c1 := msg[currOff]
2086 currOff++
2087 if ptr == 0 {
2088 newOff = currOff
2089 }
2090
2091 if ptr++; ptr > 10 {
2092 return off, errTooManyPtr
2093 }
2094 currOff = (c^0xC0)<<8 | int(c1)
2095 default:
2096
2097 return off, errReserved
2098 }
2099 }
2100 if len(name) == 0 {
2101 name = append(name, '.')
2102 }
2103 if len(name) > nonEncodedNameMax {
2104 return off, errNameTooLong
2105 }
2106 n.Length = uint8(len(name))
2107 if ptr == 0 {
2108 newOff = currOff
2109 }
2110 return newOff, nil
2111 }
2112
2113 func skipName(msg []byte, off int) (int, error) {
2114
2115
2116
2117 newOff := off
2118
2119 Loop:
2120 for {
2121 if newOff >= len(msg) {
2122 return off, errBaseLen
2123 }
2124 c := int(msg[newOff])
2125 newOff++
2126 switch c & 0xC0 {
2127 case 0x00:
2128 if c == 0x00 {
2129
2130 break Loop
2131 }
2132
2133 newOff += c
2134 if newOff > len(msg) {
2135 return off, errCalcLen
2136 }
2137 case 0xC0:
2138
2139
2140
2141 newOff++
2142
2143
2144 break Loop
2145 default:
2146
2147 return off, errReserved
2148 }
2149 }
2150
2151 return newOff, nil
2152 }
2153
2154
2155 type Question struct {
2156 Name Name
2157 Type Type
2158 Class Class
2159 }
2160
2161
2162 func (q *Question) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2163 msg, err := q.Name.pack(msg, compression, compressionOff)
2164 if err != nil {
2165 return msg, &nestedError{"Name", err}
2166 }
2167 msg = packType(msg, q.Type)
2168 return packClass(msg, q.Class), nil
2169 }
2170
2171
2172 func (q *Question) GoString() string {
2173 return "dnsmessage.Question{" +
2174 "Name: " + q.Name.GoString() + ", " +
2175 "Type: " + q.Type.GoString() + ", " +
2176 "Class: " + q.Class.GoString() + "}"
2177 }
2178
2179 func unpackResourceBody(msg []byte, off int, hdr ResourceHeader) (ResourceBody, int, error) {
2180 var (
2181 r ResourceBody
2182 err error
2183 name string
2184 )
2185 switch hdr.Type {
2186 case TypeA:
2187 var rb AResource
2188 rb, err = unpackAResource(msg, off)
2189 r = &rb
2190 name = "A"
2191 case TypeNS:
2192 var rb NSResource
2193 rb, err = unpackNSResource(msg, off)
2194 r = &rb
2195 name = "NS"
2196 case TypeCNAME:
2197 var rb CNAMEResource
2198 rb, err = unpackCNAMEResource(msg, off)
2199 r = &rb
2200 name = "CNAME"
2201 case TypeSOA:
2202 var rb SOAResource
2203 rb, err = unpackSOAResource(msg, off)
2204 r = &rb
2205 name = "SOA"
2206 case TypePTR:
2207 var rb PTRResource
2208 rb, err = unpackPTRResource(msg, off)
2209 r = &rb
2210 name = "PTR"
2211 case TypeMX:
2212 var rb MXResource
2213 rb, err = unpackMXResource(msg, off)
2214 r = &rb
2215 name = "MX"
2216 case TypeTXT:
2217 var rb TXTResource
2218 rb, err = unpackTXTResource(msg, off, hdr.Length)
2219 r = &rb
2220 name = "TXT"
2221 case TypeAAAA:
2222 var rb AAAAResource
2223 rb, err = unpackAAAAResource(msg, off)
2224 r = &rb
2225 name = "AAAA"
2226 case TypeSRV:
2227 var rb SRVResource
2228 rb, err = unpackSRVResource(msg, off)
2229 r = &rb
2230 name = "SRV"
2231 case TypeOPT:
2232 var rb OPTResource
2233 rb, err = unpackOPTResource(msg, off, hdr.Length)
2234 r = &rb
2235 name = "OPT"
2236 default:
2237 var rb UnknownResource
2238 rb, err = unpackUnknownResource(hdr.Type, msg, off, hdr.Length)
2239 r = &rb
2240 name = "Unknown"
2241 }
2242 if err != nil {
2243 return nil, off, &nestedError{name + " record", err}
2244 }
2245 return r, off + int(hdr.Length), nil
2246 }
2247
2248
2249 type CNAMEResource struct {
2250 CNAME Name
2251 }
2252
2253 func (r *CNAMEResource) realType() Type {
2254 return TypeCNAME
2255 }
2256
2257
2258 func (r *CNAMEResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2259 return r.CNAME.pack(msg, compression, compressionOff)
2260 }
2261
2262
2263 func (r *CNAMEResource) GoString() string {
2264 return "dnsmessage.CNAMEResource{CNAME: " + r.CNAME.GoString() + "}"
2265 }
2266
2267 func unpackCNAMEResource(msg []byte, off int) (CNAMEResource, error) {
2268 var cname Name
2269 if _, err := cname.unpack(msg, off); err != nil {
2270 return CNAMEResource{}, err
2271 }
2272 return CNAMEResource{cname}, nil
2273 }
2274
2275
2276 type MXResource struct {
2277 Pref uint16
2278 MX Name
2279 }
2280
2281 func (r *MXResource) realType() Type {
2282 return TypeMX
2283 }
2284
2285
2286 func (r *MXResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2287 oldMsg := msg
2288 msg = packUint16(msg, r.Pref)
2289 msg, err := r.MX.pack(msg, compression, compressionOff)
2290 if err != nil {
2291 return oldMsg, &nestedError{"MXResource.MX", err}
2292 }
2293 return msg, nil
2294 }
2295
2296
2297 func (r *MXResource) GoString() string {
2298 return "dnsmessage.MXResource{" +
2299 "Pref: " + printUint16(r.Pref) + ", " +
2300 "MX: " + r.MX.GoString() + "}"
2301 }
2302
2303 func unpackMXResource(msg []byte, off int) (MXResource, error) {
2304 pref, off, err := unpackUint16(msg, off)
2305 if err != nil {
2306 return MXResource{}, &nestedError{"Pref", err}
2307 }
2308 var mx Name
2309 if _, err := mx.unpack(msg, off); err != nil {
2310 return MXResource{}, &nestedError{"MX", err}
2311 }
2312 return MXResource{pref, mx}, nil
2313 }
2314
2315
2316 type NSResource struct {
2317 NS Name
2318 }
2319
2320 func (r *NSResource) realType() Type {
2321 return TypeNS
2322 }
2323
2324
2325 func (r *NSResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2326 return r.NS.pack(msg, compression, compressionOff)
2327 }
2328
2329
2330 func (r *NSResource) GoString() string {
2331 return "dnsmessage.NSResource{NS: " + r.NS.GoString() + "}"
2332 }
2333
2334 func unpackNSResource(msg []byte, off int) (NSResource, error) {
2335 var ns Name
2336 if _, err := ns.unpack(msg, off); err != nil {
2337 return NSResource{}, err
2338 }
2339 return NSResource{ns}, nil
2340 }
2341
2342
2343 type PTRResource struct {
2344 PTR Name
2345 }
2346
2347 func (r *PTRResource) realType() Type {
2348 return TypePTR
2349 }
2350
2351
2352 func (r *PTRResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2353 return r.PTR.pack(msg, compression, compressionOff)
2354 }
2355
2356
2357 func (r *PTRResource) GoString() string {
2358 return "dnsmessage.PTRResource{PTR: " + r.PTR.GoString() + "}"
2359 }
2360
2361 func unpackPTRResource(msg []byte, off int) (PTRResource, error) {
2362 var ptr Name
2363 if _, err := ptr.unpack(msg, off); err != nil {
2364 return PTRResource{}, err
2365 }
2366 return PTRResource{ptr}, nil
2367 }
2368
2369
2370 type SOAResource struct {
2371 NS Name
2372 MBox Name
2373 Serial uint32
2374 Refresh uint32
2375 Retry uint32
2376 Expire uint32
2377
2378
2379
2380
2381 MinTTL uint32
2382 }
2383
2384 func (r *SOAResource) realType() Type {
2385 return TypeSOA
2386 }
2387
2388
2389 func (r *SOAResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2390 oldMsg := msg
2391 msg, err := r.NS.pack(msg, compression, compressionOff)
2392 if err != nil {
2393 return oldMsg, &nestedError{"SOAResource.NS", err}
2394 }
2395 msg, err = r.MBox.pack(msg, compression, compressionOff)
2396 if err != nil {
2397 return oldMsg, &nestedError{"SOAResource.MBox", err}
2398 }
2399 msg = packUint32(msg, r.Serial)
2400 msg = packUint32(msg, r.Refresh)
2401 msg = packUint32(msg, r.Retry)
2402 msg = packUint32(msg, r.Expire)
2403 return packUint32(msg, r.MinTTL), nil
2404 }
2405
2406
2407 func (r *SOAResource) GoString() string {
2408 return "dnsmessage.SOAResource{" +
2409 "NS: " + r.NS.GoString() + ", " +
2410 "MBox: " + r.MBox.GoString() + ", " +
2411 "Serial: " + printUint32(r.Serial) + ", " +
2412 "Refresh: " + printUint32(r.Refresh) + ", " +
2413 "Retry: " + printUint32(r.Retry) + ", " +
2414 "Expire: " + printUint32(r.Expire) + ", " +
2415 "MinTTL: " + printUint32(r.MinTTL) + "}"
2416 }
2417
2418 func unpackSOAResource(msg []byte, off int) (SOAResource, error) {
2419 var ns Name
2420 off, err := ns.unpack(msg, off)
2421 if err != nil {
2422 return SOAResource{}, &nestedError{"NS", err}
2423 }
2424 var mbox Name
2425 if off, err = mbox.unpack(msg, off); err != nil {
2426 return SOAResource{}, &nestedError{"MBox", err}
2427 }
2428 serial, off, err := unpackUint32(msg, off)
2429 if err != nil {
2430 return SOAResource{}, &nestedError{"Serial", err}
2431 }
2432 refresh, off, err := unpackUint32(msg, off)
2433 if err != nil {
2434 return SOAResource{}, &nestedError{"Refresh", err}
2435 }
2436 retry, off, err := unpackUint32(msg, off)
2437 if err != nil {
2438 return SOAResource{}, &nestedError{"Retry", err}
2439 }
2440 expire, off, err := unpackUint32(msg, off)
2441 if err != nil {
2442 return SOAResource{}, &nestedError{"Expire", err}
2443 }
2444 minTTL, _, err := unpackUint32(msg, off)
2445 if err != nil {
2446 return SOAResource{}, &nestedError{"MinTTL", err}
2447 }
2448 return SOAResource{ns, mbox, serial, refresh, retry, expire, minTTL}, nil
2449 }
2450
2451
2452 type TXTResource struct {
2453 TXT []string
2454 }
2455
2456 func (r *TXTResource) realType() Type {
2457 return TypeTXT
2458 }
2459
2460
2461 func (r *TXTResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2462 oldMsg := msg
2463 for _, s := range r.TXT {
2464 var err error
2465 msg, err = packText(msg, s)
2466 if err != nil {
2467 return oldMsg, err
2468 }
2469 }
2470 return msg, nil
2471 }
2472
2473
2474 func (r *TXTResource) GoString() string {
2475 s := "dnsmessage.TXTResource{TXT: []string{"
2476 if len(r.TXT) == 0 {
2477 return s + "}}"
2478 }
2479 s += `"` + printString([]byte(r.TXT[0]))
2480 for _, t := range r.TXT[1:] {
2481 s += `", "` + printString([]byte(t))
2482 }
2483 return s + `"}}`
2484 }
2485
2486 func unpackTXTResource(msg []byte, off int, length uint16) (TXTResource, error) {
2487 txts := make([]string, 0, 1)
2488 for n := uint16(0); n < length; {
2489 var t string
2490 var err error
2491 if t, off, err = unpackText(msg, off); err != nil {
2492 return TXTResource{}, &nestedError{"text", err}
2493 }
2494
2495 if length-n < uint16(len(t))+1 {
2496 return TXTResource{}, errCalcLen
2497 }
2498 n += uint16(len(t)) + 1
2499 txts = append(txts, t)
2500 }
2501 return TXTResource{txts}, nil
2502 }
2503
2504
2505 type SRVResource struct {
2506 Priority uint16
2507 Weight uint16
2508 Port uint16
2509 Target Name
2510 }
2511
2512 func (r *SRVResource) realType() Type {
2513 return TypeSRV
2514 }
2515
2516
2517 func (r *SRVResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2518 oldMsg := msg
2519 msg = packUint16(msg, r.Priority)
2520 msg = packUint16(msg, r.Weight)
2521 msg = packUint16(msg, r.Port)
2522 msg, err := r.Target.pack(msg, nil, compressionOff)
2523 if err != nil {
2524 return oldMsg, &nestedError{"SRVResource.Target", err}
2525 }
2526 return msg, nil
2527 }
2528
2529
2530 func (r *SRVResource) GoString() string {
2531 return "dnsmessage.SRVResource{" +
2532 "Priority: " + printUint16(r.Priority) + ", " +
2533 "Weight: " + printUint16(r.Weight) + ", " +
2534 "Port: " + printUint16(r.Port) + ", " +
2535 "Target: " + r.Target.GoString() + "}"
2536 }
2537
2538 func unpackSRVResource(msg []byte, off int) (SRVResource, error) {
2539 priority, off, err := unpackUint16(msg, off)
2540 if err != nil {
2541 return SRVResource{}, &nestedError{"Priority", err}
2542 }
2543 weight, off, err := unpackUint16(msg, off)
2544 if err != nil {
2545 return SRVResource{}, &nestedError{"Weight", err}
2546 }
2547 port, off, err := unpackUint16(msg, off)
2548 if err != nil {
2549 return SRVResource{}, &nestedError{"Port", err}
2550 }
2551 var target Name
2552 if _, err := target.unpackCompressed(msg, off, false ); err != nil {
2553 return SRVResource{}, &nestedError{"Target", err}
2554 }
2555 return SRVResource{priority, weight, port, target}, nil
2556 }
2557
2558
2559 type AResource struct {
2560 A [4]byte
2561 }
2562
2563 func (r *AResource) realType() Type {
2564 return TypeA
2565 }
2566
2567
2568 func (r *AResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2569 return packBytes(msg, r.A[:]), nil
2570 }
2571
2572
2573 func (r *AResource) GoString() string {
2574 return "dnsmessage.AResource{" +
2575 "A: [4]byte{" + printByteSlice(r.A[:]) + "}}"
2576 }
2577
2578 func unpackAResource(msg []byte, off int) (AResource, error) {
2579 var a [4]byte
2580 if _, err := unpackBytes(msg, off, a[:]); err != nil {
2581 return AResource{}, err
2582 }
2583 return AResource{a}, nil
2584 }
2585
2586
2587 type AAAAResource struct {
2588 AAAA [16]byte
2589 }
2590
2591 func (r *AAAAResource) realType() Type {
2592 return TypeAAAA
2593 }
2594
2595
2596 func (r *AAAAResource) GoString() string {
2597 return "dnsmessage.AAAAResource{" +
2598 "AAAA: [16]byte{" + printByteSlice(r.AAAA[:]) + "}}"
2599 }
2600
2601
2602 func (r *AAAAResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2603 return packBytes(msg, r.AAAA[:]), nil
2604 }
2605
2606 func unpackAAAAResource(msg []byte, off int) (AAAAResource, error) {
2607 var aaaa [16]byte
2608 if _, err := unpackBytes(msg, off, aaaa[:]); err != nil {
2609 return AAAAResource{}, err
2610 }
2611 return AAAAResource{aaaa}, nil
2612 }
2613
2614
2615
2616
2617
2618 type OPTResource struct {
2619 Options []Option
2620 }
2621
2622
2623
2624
2625
2626 type Option struct {
2627 Code uint16
2628 Data []byte
2629 }
2630
2631
2632 func (o *Option) GoString() string {
2633 return "dnsmessage.Option{" +
2634 "Code: " + printUint16(o.Code) + ", " +
2635 "Data: []byte{" + printByteSlice(o.Data) + "}}"
2636 }
2637
2638 func (r *OPTResource) realType() Type {
2639 return TypeOPT
2640 }
2641
2642 func (r *OPTResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2643 for _, opt := range r.Options {
2644 msg = packUint16(msg, opt.Code)
2645 l := uint16(len(opt.Data))
2646 msg = packUint16(msg, l)
2647 msg = packBytes(msg, opt.Data)
2648 }
2649 return msg, nil
2650 }
2651
2652
2653 func (r *OPTResource) GoString() string {
2654 s := "dnsmessage.OPTResource{Options: []dnsmessage.Option{"
2655 if len(r.Options) == 0 {
2656 return s + "}}"
2657 }
2658 s += r.Options[0].GoString()
2659 for _, o := range r.Options[1:] {
2660 s += ", " + o.GoString()
2661 }
2662 return s + "}}"
2663 }
2664
2665 func unpackOPTResource(msg []byte, off int, length uint16) (OPTResource, error) {
2666 var opts []Option
2667 for oldOff := off; off < oldOff+int(length); {
2668 var err error
2669 var o Option
2670 o.Code, off, err = unpackUint16(msg, off)
2671 if err != nil {
2672 return OPTResource{}, &nestedError{"Code", err}
2673 }
2674 var l uint16
2675 l, off, err = unpackUint16(msg, off)
2676 if err != nil {
2677 return OPTResource{}, &nestedError{"Data", err}
2678 }
2679 o.Data = make([]byte, l)
2680 if copy(o.Data, msg[off:]) != int(l) {
2681 return OPTResource{}, &nestedError{"Data", errCalcLen}
2682 }
2683 off += int(l)
2684 opts = append(opts, o)
2685 }
2686 return OPTResource{opts}, nil
2687 }
2688
2689
2690 type UnknownResource struct {
2691 Type Type
2692 Data []byte
2693 }
2694
2695 func (r *UnknownResource) realType() Type {
2696 return r.Type
2697 }
2698
2699
2700 func (r *UnknownResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2701 return packBytes(msg, r.Data[:]), nil
2702 }
2703
2704
2705 func (r *UnknownResource) GoString() string {
2706 return "dnsmessage.UnknownResource{" +
2707 "Type: " + r.Type.GoString() + ", " +
2708 "Data: []byte{" + printByteSlice(r.Data) + "}}"
2709 }
2710
2711 func unpackUnknownResource(recordType Type, msg []byte, off int, length uint16) (UnknownResource, error) {
2712 parsed := UnknownResource{
2713 Type: recordType,
2714 Data: make([]byte, length),
2715 }
2716 if _, err := unpackBytes(msg, off, parsed.Data); err != nil {
2717 return UnknownResource{}, err
2718 }
2719 return parsed, nil
2720 }
2721
View as plain text