package dns import "fmt" // https://datatracker.ietf.org/doc/html/rfc6891#section-4.1 type Option struct { Code uint16 Data []byte } type OPT struct { // https://datatracker.ietf.org/doc/html/rfc6891#section-4.3 UDPSize uint16 ExtRCode uint8 Version uint8 DO bool Z uint16 Options []Option } func (o *OPT) Type() uint16 { return TypeOPT } func (o *OPT) Pack(p *packer) error { for _, opt := range o.Options { p.writeUint16(opt.Code) p.writeUint16(uint16(len(opt.Data))) p.buf = append(p.buf, opt.Data...) } return nil } func (o *OPT) Unpack(u *unpacker, length uint16) error { end := u.off + int(length) for u.off < end { code, err := u.readUint16() if err != nil { return err } optLen, err := u.readUint16() if err != nil { return err } if u.off+int(optLen) > end { return fmt.Errorf("dns: opt data overflow") } o.Options = append(o.Options, Option{ Code: code, Data: append([]byte(nil), u.buf[u.off:u.off+int(optLen)]...), }) u.off += int(optLen) } return nil } func (o *OPT) String() string { return fmt.Sprintf("OPT udpsize=%d extrcode=%d version=%d do=%t", o.UDPSize, o.ExtRCode, o.Version, o.DO) }