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