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
2090 if len(name)+(endOff-currOff) >= nonEncodedNameMax {
2091 return off, errNameTooLong
2092 }
2093 name = append(name, msg[currOff:endOff]...)
2094 name = append(name, '.')
2095 currOff = endOff
2096 case 0xC0:
2097 if currOff >= len(msg) {
2098 return off, errInvalidPtr
2099 }
2100 c1 := msg[currOff]
2101 currOff++
2102 if ptr == 0 {
2103 newOff = currOff
2104 }
2105
2106 if ptr++; ptr > 10 {
2107 return off, errTooManyPtr
2108 }
2109 currOff = (c^0xC0)<<8 | int(c1)
2110 default:
2111
2112 return off, errReserved
2113 }
2114 }
2115 if len(name) == 0 {
2116 name = append(name, '.')
2117 }
2118 n.Length = uint8(len(name))
2119 if ptr == 0 {
2120 newOff = currOff
2121 }
2122 return newOff, nil
2123 }
2124
2125 func skipName(msg []byte, off int) (int, error) {
2126
2127
2128
2129 newOff := off
2130
2131 Loop:
2132 for {
2133 if newOff >= len(msg) {
2134 return off, errBaseLen
2135 }
2136 c := int(msg[newOff])
2137 newOff++
2138 switch c & 0xC0 {
2139 case 0x00:
2140 if c == 0x00 {
2141
2142 break Loop
2143 }
2144
2145 newOff += c
2146 if newOff > len(msg) {
2147 return off, errCalcLen
2148 }
2149 case 0xC0:
2150
2151
2152
2153 newOff++
2154
2155
2156 break Loop
2157 default:
2158
2159 return off, errReserved
2160 }
2161 }
2162
2163 return newOff, nil
2164 }
2165
2166
2167 type Question struct {
2168 Name Name
2169 Type Type
2170 Class Class
2171 }
2172
2173
2174 func (q *Question) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2175 msg, err := q.Name.pack(msg, compression, compressionOff)
2176 if err != nil {
2177 return msg, &nestedError{"Name", err}
2178 }
2179 msg = packType(msg, q.Type)
2180 return packClass(msg, q.Class), nil
2181 }
2182
2183
2184 func (q *Question) GoString() string {
2185 return "dnsmessage.Question{" +
2186 "Name: " + q.Name.GoString() + ", " +
2187 "Type: " + q.Type.GoString() + ", " +
2188 "Class: " + q.Class.GoString() + "}"
2189 }
2190
2191 func unpackResourceBody(msg []byte, off int, hdr ResourceHeader) (ResourceBody, int, error) {
2192 var (
2193 r ResourceBody
2194 err error
2195 name string
2196 )
2197 switch hdr.Type {
2198 case TypeA:
2199 var rb AResource
2200 rb, err = unpackAResource(msg, off)
2201 r = &rb
2202 name = "A"
2203 case TypeNS:
2204 var rb NSResource
2205 rb, err = unpackNSResource(msg, off)
2206 r = &rb
2207 name = "NS"
2208 case TypeCNAME:
2209 var rb CNAMEResource
2210 rb, err = unpackCNAMEResource(msg, off)
2211 r = &rb
2212 name = "CNAME"
2213 case TypeSOA:
2214 var rb SOAResource
2215 rb, err = unpackSOAResource(msg, off)
2216 r = &rb
2217 name = "SOA"
2218 case TypePTR:
2219 var rb PTRResource
2220 rb, err = unpackPTRResource(msg, off)
2221 r = &rb
2222 name = "PTR"
2223 case TypeMX:
2224 var rb MXResource
2225 rb, err = unpackMXResource(msg, off)
2226 r = &rb
2227 name = "MX"
2228 case TypeTXT:
2229 var rb TXTResource
2230 rb, err = unpackTXTResource(msg, off, hdr.Length)
2231 r = &rb
2232 name = "TXT"
2233 case TypeAAAA:
2234 var rb AAAAResource
2235 rb, err = unpackAAAAResource(msg, off)
2236 r = &rb
2237 name = "AAAA"
2238 case TypeSRV:
2239 var rb SRVResource
2240 rb, err = unpackSRVResource(msg, off)
2241 r = &rb
2242 name = "SRV"
2243 case TypeSVCB:
2244 var rb SVCBResource
2245 rb, err = unpackSVCBResource(msg, off, hdr.Length)
2246 r = &rb
2247 name = "SVCB"
2248 case TypeHTTPS:
2249 var rb HTTPSResource
2250 rb.SVCBResource, err = unpackSVCBResource(msg, off, hdr.Length)
2251 r = &rb
2252 name = "HTTPS"
2253 case TypeOPT:
2254 var rb OPTResource
2255 rb, err = unpackOPTResource(msg, off, hdr.Length)
2256 r = &rb
2257 name = "OPT"
2258 default:
2259 var rb UnknownResource
2260 rb, err = unpackUnknownResource(hdr.Type, msg, off, hdr.Length)
2261 r = &rb
2262 name = "Unknown"
2263 }
2264 if err != nil {
2265 return nil, off, &nestedError{name + " record", err}
2266 }
2267 return r, off + int(hdr.Length), nil
2268 }
2269
2270
2271 type CNAMEResource struct {
2272 CNAME Name
2273 }
2274
2275 func (r *CNAMEResource) realType() Type {
2276 return TypeCNAME
2277 }
2278
2279
2280 func (r *CNAMEResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2281 return r.CNAME.pack(msg, compression, compressionOff)
2282 }
2283
2284
2285 func (r *CNAMEResource) GoString() string {
2286 return "dnsmessage.CNAMEResource{CNAME: " + r.CNAME.GoString() + "}"
2287 }
2288
2289 func unpackCNAMEResource(msg []byte, off int) (CNAMEResource, error) {
2290 var cname Name
2291 if _, err := cname.unpack(msg, off); err != nil {
2292 return CNAMEResource{}, err
2293 }
2294 return CNAMEResource{cname}, nil
2295 }
2296
2297
2298 type MXResource struct {
2299 Pref uint16
2300 MX Name
2301 }
2302
2303 func (r *MXResource) realType() Type {
2304 return TypeMX
2305 }
2306
2307
2308 func (r *MXResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2309 oldMsg := msg
2310 msg = packUint16(msg, r.Pref)
2311 msg, err := r.MX.pack(msg, compression, compressionOff)
2312 if err != nil {
2313 return oldMsg, &nestedError{"MXResource.MX", err}
2314 }
2315 return msg, nil
2316 }
2317
2318
2319 func (r *MXResource) GoString() string {
2320 return "dnsmessage.MXResource{" +
2321 "Pref: " + printUint16(r.Pref) + ", " +
2322 "MX: " + r.MX.GoString() + "}"
2323 }
2324
2325 func unpackMXResource(msg []byte, off int) (MXResource, error) {
2326 pref, off, err := unpackUint16(msg, off)
2327 if err != nil {
2328 return MXResource{}, &nestedError{"Pref", err}
2329 }
2330 var mx Name
2331 if _, err := mx.unpack(msg, off); err != nil {
2332 return MXResource{}, &nestedError{"MX", err}
2333 }
2334 return MXResource{pref, mx}, nil
2335 }
2336
2337
2338 type NSResource struct {
2339 NS Name
2340 }
2341
2342 func (r *NSResource) realType() Type {
2343 return TypeNS
2344 }
2345
2346
2347 func (r *NSResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2348 return r.NS.pack(msg, compression, compressionOff)
2349 }
2350
2351
2352 func (r *NSResource) GoString() string {
2353 return "dnsmessage.NSResource{NS: " + r.NS.GoString() + "}"
2354 }
2355
2356 func unpackNSResource(msg []byte, off int) (NSResource, error) {
2357 var ns Name
2358 if _, err := ns.unpack(msg, off); err != nil {
2359 return NSResource{}, err
2360 }
2361 return NSResource{ns}, nil
2362 }
2363
2364
2365 type PTRResource struct {
2366 PTR Name
2367 }
2368
2369 func (r *PTRResource) realType() Type {
2370 return TypePTR
2371 }
2372
2373
2374 func (r *PTRResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2375 return r.PTR.pack(msg, compression, compressionOff)
2376 }
2377
2378
2379 func (r *PTRResource) GoString() string {
2380 return "dnsmessage.PTRResource{PTR: " + r.PTR.GoString() + "}"
2381 }
2382
2383 func unpackPTRResource(msg []byte, off int) (PTRResource, error) {
2384 var ptr Name
2385 if _, err := ptr.unpack(msg, off); err != nil {
2386 return PTRResource{}, err
2387 }
2388 return PTRResource{ptr}, nil
2389 }
2390
2391
2392 type SOAResource struct {
2393 NS Name
2394 MBox Name
2395 Serial uint32
2396 Refresh uint32
2397 Retry uint32
2398 Expire uint32
2399
2400
2401
2402
2403 MinTTL uint32
2404 }
2405
2406 func (r *SOAResource) realType() Type {
2407 return TypeSOA
2408 }
2409
2410
2411 func (r *SOAResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2412 oldMsg := msg
2413 msg, err := r.NS.pack(msg, compression, compressionOff)
2414 if err != nil {
2415 return oldMsg, &nestedError{"SOAResource.NS", err}
2416 }
2417 msg, err = r.MBox.pack(msg, compression, compressionOff)
2418 if err != nil {
2419 return oldMsg, &nestedError{"SOAResource.MBox", err}
2420 }
2421 msg = packUint32(msg, r.Serial)
2422 msg = packUint32(msg, r.Refresh)
2423 msg = packUint32(msg, r.Retry)
2424 msg = packUint32(msg, r.Expire)
2425 return packUint32(msg, r.MinTTL), nil
2426 }
2427
2428
2429 func (r *SOAResource) GoString() string {
2430 return "dnsmessage.SOAResource{" +
2431 "NS: " + r.NS.GoString() + ", " +
2432 "MBox: " + r.MBox.GoString() + ", " +
2433 "Serial: " + printUint32(r.Serial) + ", " +
2434 "Refresh: " + printUint32(r.Refresh) + ", " +
2435 "Retry: " + printUint32(r.Retry) + ", " +
2436 "Expire: " + printUint32(r.Expire) + ", " +
2437 "MinTTL: " + printUint32(r.MinTTL) + "}"
2438 }
2439
2440 func unpackSOAResource(msg []byte, off int) (SOAResource, error) {
2441 var ns Name
2442 off, err := ns.unpack(msg, off)
2443 if err != nil {
2444 return SOAResource{}, &nestedError{"NS", err}
2445 }
2446 var mbox Name
2447 if off, err = mbox.unpack(msg, off); err != nil {
2448 return SOAResource{}, &nestedError{"MBox", err}
2449 }
2450 serial, off, err := unpackUint32(msg, off)
2451 if err != nil {
2452 return SOAResource{}, &nestedError{"Serial", err}
2453 }
2454 refresh, off, err := unpackUint32(msg, off)
2455 if err != nil {
2456 return SOAResource{}, &nestedError{"Refresh", err}
2457 }
2458 retry, off, err := unpackUint32(msg, off)
2459 if err != nil {
2460 return SOAResource{}, &nestedError{"Retry", err}
2461 }
2462 expire, off, err := unpackUint32(msg, off)
2463 if err != nil {
2464 return SOAResource{}, &nestedError{"Expire", err}
2465 }
2466 minTTL, _, err := unpackUint32(msg, off)
2467 if err != nil {
2468 return SOAResource{}, &nestedError{"MinTTL", err}
2469 }
2470 return SOAResource{ns, mbox, serial, refresh, retry, expire, minTTL}, nil
2471 }
2472
2473
2474 type TXTResource struct {
2475 TXT []string
2476 }
2477
2478 func (r *TXTResource) realType() Type {
2479 return TypeTXT
2480 }
2481
2482
2483 func (r *TXTResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2484 oldMsg := msg
2485 for _, s := range r.TXT {
2486 var err error
2487 msg, err = packText(msg, s)
2488 if err != nil {
2489 return oldMsg, err
2490 }
2491 }
2492 return msg, nil
2493 }
2494
2495
2496 func (r *TXTResource) GoString() string {
2497 s := "dnsmessage.TXTResource{TXT: []string{"
2498 if len(r.TXT) == 0 {
2499 return s + "}}"
2500 }
2501 s += `"` + printString([]byte(r.TXT[0]))
2502 for _, t := range r.TXT[1:] {
2503 s += `", "` + printString([]byte(t))
2504 }
2505 return s + `"}}`
2506 }
2507
2508 func unpackTXTResource(msg []byte, off int, length uint16) (TXTResource, error) {
2509 txts := make([]string, 0, 1)
2510 for n := uint16(0); n < length; {
2511 var t string
2512 var err error
2513 if t, off, err = unpackText(msg, off); err != nil {
2514 return TXTResource{}, &nestedError{"text", err}
2515 }
2516
2517 if length-n < uint16(len(t))+1 {
2518 return TXTResource{}, errCalcLen
2519 }
2520 n += uint16(len(t)) + 1
2521 txts = append(txts, t)
2522 }
2523 return TXTResource{txts}, nil
2524 }
2525
2526
2527 type SRVResource struct {
2528 Priority uint16
2529 Weight uint16
2530 Port uint16
2531 Target Name
2532 }
2533
2534 func (r *SRVResource) realType() Type {
2535 return TypeSRV
2536 }
2537
2538
2539 func (r *SRVResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2540 oldMsg := msg
2541 msg = packUint16(msg, r.Priority)
2542 msg = packUint16(msg, r.Weight)
2543 msg = packUint16(msg, r.Port)
2544 msg, err := r.Target.pack(msg, nil, compressionOff)
2545 if err != nil {
2546 return oldMsg, &nestedError{"SRVResource.Target", err}
2547 }
2548 return msg, nil
2549 }
2550
2551
2552 func (r *SRVResource) GoString() string {
2553 return "dnsmessage.SRVResource{" +
2554 "Priority: " + printUint16(r.Priority) + ", " +
2555 "Weight: " + printUint16(r.Weight) + ", " +
2556 "Port: " + printUint16(r.Port) + ", " +
2557 "Target: " + r.Target.GoString() + "}"
2558 }
2559
2560 func unpackSRVResource(msg []byte, off int) (SRVResource, error) {
2561 priority, off, err := unpackUint16(msg, off)
2562 if err != nil {
2563 return SRVResource{}, &nestedError{"Priority", err}
2564 }
2565 weight, off, err := unpackUint16(msg, off)
2566 if err != nil {
2567 return SRVResource{}, &nestedError{"Weight", err}
2568 }
2569 port, off, err := unpackUint16(msg, off)
2570 if err != nil {
2571 return SRVResource{}, &nestedError{"Port", err}
2572 }
2573 var target Name
2574 if _, err := target.unpack(msg, off); err != nil {
2575 return SRVResource{}, &nestedError{"Target", err}
2576 }
2577 return SRVResource{priority, weight, port, target}, nil
2578 }
2579
2580
2581 type AResource struct {
2582 A [4]byte
2583 }
2584
2585 func (r *AResource) realType() Type {
2586 return TypeA
2587 }
2588
2589
2590 func (r *AResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2591 return packBytes(msg, r.A[:]), nil
2592 }
2593
2594
2595 func (r *AResource) GoString() string {
2596 return "dnsmessage.AResource{" +
2597 "A: [4]byte{" + printByteSlice(r.A[:]) + "}}"
2598 }
2599
2600 func unpackAResource(msg []byte, off int) (AResource, error) {
2601 var a [4]byte
2602 if _, err := unpackBytes(msg, off, a[:]); err != nil {
2603 return AResource{}, err
2604 }
2605 return AResource{a}, nil
2606 }
2607
2608
2609 type AAAAResource struct {
2610 AAAA [16]byte
2611 }
2612
2613 func (r *AAAAResource) realType() Type {
2614 return TypeAAAA
2615 }
2616
2617
2618 func (r *AAAAResource) GoString() string {
2619 return "dnsmessage.AAAAResource{" +
2620 "AAAA: [16]byte{" + printByteSlice(r.AAAA[:]) + "}}"
2621 }
2622
2623
2624 func (r *AAAAResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2625 return packBytes(msg, r.AAAA[:]), nil
2626 }
2627
2628 func unpackAAAAResource(msg []byte, off int) (AAAAResource, error) {
2629 var aaaa [16]byte
2630 if _, err := unpackBytes(msg, off, aaaa[:]); err != nil {
2631 return AAAAResource{}, err
2632 }
2633 return AAAAResource{aaaa}, nil
2634 }
2635
2636
2637
2638
2639
2640 type OPTResource struct {
2641 Options []Option
2642 }
2643
2644
2645
2646
2647
2648 type Option struct {
2649 Code uint16
2650 Data []byte
2651 }
2652
2653
2654 func (o *Option) GoString() string {
2655 return "dnsmessage.Option{" +
2656 "Code: " + printUint16(o.Code) + ", " +
2657 "Data: []byte{" + printByteSlice(o.Data) + "}}"
2658 }
2659
2660 func (r *OPTResource) realType() Type {
2661 return TypeOPT
2662 }
2663
2664 func (r *OPTResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2665 for _, opt := range r.Options {
2666 msg = packUint16(msg, opt.Code)
2667 l := uint16(len(opt.Data))
2668 msg = packUint16(msg, l)
2669 msg = packBytes(msg, opt.Data)
2670 }
2671 return msg, nil
2672 }
2673
2674
2675 func (r *OPTResource) GoString() string {
2676 s := "dnsmessage.OPTResource{Options: []dnsmessage.Option{"
2677 if len(r.Options) == 0 {
2678 return s + "}}"
2679 }
2680 s += r.Options[0].GoString()
2681 for _, o := range r.Options[1:] {
2682 s += ", " + o.GoString()
2683 }
2684 return s + "}}"
2685 }
2686
2687 func unpackOPTResource(msg []byte, off int, length uint16) (OPTResource, error) {
2688 var opts []Option
2689 for oldOff := off; off < oldOff+int(length); {
2690 var err error
2691 var o Option
2692 o.Code, off, err = unpackUint16(msg, off)
2693 if err != nil {
2694 return OPTResource{}, &nestedError{"Code", err}
2695 }
2696 var l uint16
2697 l, off, err = unpackUint16(msg, off)
2698 if err != nil {
2699 return OPTResource{}, &nestedError{"Data", err}
2700 }
2701 o.Data = make([]byte, l)
2702 if copy(o.Data, msg[off:]) != int(l) {
2703 return OPTResource{}, &nestedError{"Data", errCalcLen}
2704 }
2705 off += int(l)
2706 opts = append(opts, o)
2707 }
2708 return OPTResource{opts}, nil
2709 }
2710
2711
2712 type UnknownResource struct {
2713 Type Type
2714 Data []byte
2715 }
2716
2717 func (r *UnknownResource) realType() Type {
2718 return r.Type
2719 }
2720
2721
2722 func (r *UnknownResource) pack(msg []byte, compression map[string]uint16, compressionOff int) ([]byte, error) {
2723 return packBytes(msg, r.Data[:]), nil
2724 }
2725
2726
2727 func (r *UnknownResource) GoString() string {
2728 return "dnsmessage.UnknownResource{" +
2729 "Type: " + r.Type.GoString() + ", " +
2730 "Data: []byte{" + printByteSlice(r.Data) + "}}"
2731 }
2732
2733 func unpackUnknownResource(recordType Type, msg []byte, off int, length uint16) (UnknownResource, error) {
2734 parsed := UnknownResource{
2735 Type: recordType,
2736 Data: make([]byte, length),
2737 }
2738 if _, err := unpackBytes(msg, off, parsed.Data); err != nil {
2739 return UnknownResource{}, err
2740 }
2741 return parsed, nil
2742 }
2743
View as plain text