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