1package dns 2 3import ( 4 "encoding/base32" 5 "encoding/base64" 6 "encoding/binary" 7 "encoding/hex" 8 "net" 9 "sort" 10 "strings" 11) 12 13// helper functions called from the generated zmsg.go 14 15// These function are named after the tag to help pack/unpack, if there is no tag it is the name 16// of the type they pack/unpack (string, int, etc). We prefix all with unpackData or packData, so packDataA or 17// packDataDomainName. 18 19func unpackDataA(msg []byte, off int) (net.IP, int, error) { 20 if off+net.IPv4len > len(msg) { 21 return nil, len(msg), &Error{err: "overflow unpacking a"} 22 } 23 a := append(make(net.IP, 0, net.IPv4len), msg[off:off+net.IPv4len]...) 24 off += net.IPv4len 25 return a, off, nil 26} 27 28func packDataA(a net.IP, msg []byte, off int) (int, error) { 29 switch len(a) { 30 case net.IPv4len, net.IPv6len: 31 // It must be a slice of 4, even if it is 16, we encode only the first 4 32 if off+net.IPv4len > len(msg) { 33 return len(msg), &Error{err: "overflow packing a"} 34 } 35 36 copy(msg[off:], a.To4()) 37 off += net.IPv4len 38 case 0: 39 // Allowed, for dynamic updates. 40 default: 41 return len(msg), &Error{err: "overflow packing a"} 42 } 43 return off, nil 44} 45 46func unpackDataAAAA(msg []byte, off int) (net.IP, int, error) { 47 if off+net.IPv6len > len(msg) { 48 return nil, len(msg), &Error{err: "overflow unpacking aaaa"} 49 } 50 aaaa := append(make(net.IP, 0, net.IPv6len), msg[off:off+net.IPv6len]...) 51 off += net.IPv6len 52 return aaaa, off, nil 53} 54 55func packDataAAAA(aaaa net.IP, msg []byte, off int) (int, error) { 56 switch len(aaaa) { 57 case net.IPv6len: 58 if off+net.IPv6len > len(msg) { 59 return len(msg), &Error{err: "overflow packing aaaa"} 60 } 61 62 copy(msg[off:], aaaa) 63 off += net.IPv6len 64 case 0: 65 // Allowed, dynamic updates. 66 default: 67 return len(msg), &Error{err: "overflow packing aaaa"} 68 } 69 return off, nil 70} 71 72// unpackHeader unpacks an RR header, returning the offset to the end of the header and a 73// re-sliced msg according to the expected length of the RR. 74func unpackHeader(msg []byte, off int) (rr RR_Header, off1 int, truncmsg []byte, err error) { 75 hdr := RR_Header{} 76 if off == len(msg) { 77 return hdr, off, msg, nil 78 } 79 80 hdr.Name, off, err = UnpackDomainName(msg, off) 81 if err != nil { 82 return hdr, len(msg), msg, err 83 } 84 hdr.Rrtype, off, err = unpackUint16(msg, off) 85 if err != nil { 86 return hdr, len(msg), msg, err 87 } 88 hdr.Class, off, err = unpackUint16(msg, off) 89 if err != nil { 90 return hdr, len(msg), msg, err 91 } 92 hdr.Ttl, off, err = unpackUint32(msg, off) 93 if err != nil { 94 return hdr, len(msg), msg, err 95 } 96 hdr.Rdlength, off, err = unpackUint16(msg, off) 97 if err != nil { 98 return hdr, len(msg), msg, err 99 } 100 msg, err = truncateMsgFromRdlength(msg, off, hdr.Rdlength) 101 return hdr, off, msg, err 102} 103 104// packHeader packs an RR header, returning the offset to the end of the header. 105// See PackDomainName for documentation about the compression. 106func (hdr RR_Header) packHeader(msg []byte, off int, compression compressionMap, compress bool) (int, error) { 107 if off == len(msg) { 108 return off, nil 109 } 110 111 off, err := packDomainName(hdr.Name, msg, off, compression, compress) 112 if err != nil { 113 return len(msg), err 114 } 115 off, err = packUint16(hdr.Rrtype, msg, off) 116 if err != nil { 117 return len(msg), err 118 } 119 off, err = packUint16(hdr.Class, msg, off) 120 if err != nil { 121 return len(msg), err 122 } 123 off, err = packUint32(hdr.Ttl, msg, off) 124 if err != nil { 125 return len(msg), err 126 } 127 off, err = packUint16(0, msg, off) // The RDLENGTH field will be set later in packRR. 128 if err != nil { 129 return len(msg), err 130 } 131 return off, nil 132} 133 134// helper helper functions. 135 136// truncateMsgFromRdLength truncates msg to match the expected length of the RR. 137// Returns an error if msg is smaller than the expected size. 138func truncateMsgFromRdlength(msg []byte, off int, rdlength uint16) (truncmsg []byte, err error) { 139 lenrd := off + int(rdlength) 140 if lenrd > len(msg) { 141 return msg, &Error{err: "overflowing header size"} 142 } 143 return msg[:lenrd], nil 144} 145 146var base32HexNoPadEncoding = base32.HexEncoding.WithPadding(base32.NoPadding) 147 148func fromBase32(s []byte) (buf []byte, err error) { 149 for i, b := range s { 150 if b >= 'a' && b <= 'z' { 151 s[i] = b - 32 152 } 153 } 154 buflen := base32HexNoPadEncoding.DecodedLen(len(s)) 155 buf = make([]byte, buflen) 156 n, err := base32HexNoPadEncoding.Decode(buf, s) 157 buf = buf[:n] 158 return 159} 160 161func toBase32(b []byte) string { 162 return base32HexNoPadEncoding.EncodeToString(b) 163} 164 165func fromBase64(s []byte) (buf []byte, err error) { 166 buflen := base64.StdEncoding.DecodedLen(len(s)) 167 buf = make([]byte, buflen) 168 n, err := base64.StdEncoding.Decode(buf, s) 169 buf = buf[:n] 170 return 171} 172 173func toBase64(b []byte) string { return base64.StdEncoding.EncodeToString(b) } 174 175// dynamicUpdate returns true if the Rdlength is zero. 176func noRdata(h RR_Header) bool { return h.Rdlength == 0 } 177 178func unpackUint8(msg []byte, off int) (i uint8, off1 int, err error) { 179 if off+1 > len(msg) { 180 return 0, len(msg), &Error{err: "overflow unpacking uint8"} 181 } 182 return msg[off], off + 1, nil 183} 184 185func packUint8(i uint8, msg []byte, off int) (off1 int, err error) { 186 if off+1 > len(msg) { 187 return len(msg), &Error{err: "overflow packing uint8"} 188 } 189 msg[off] = i 190 return off + 1, nil 191} 192 193func unpackUint16(msg []byte, off int) (i uint16, off1 int, err error) { 194 if off+2 > len(msg) { 195 return 0, len(msg), &Error{err: "overflow unpacking uint16"} 196 } 197 return binary.BigEndian.Uint16(msg[off:]), off + 2, nil 198} 199 200func packUint16(i uint16, msg []byte, off int) (off1 int, err error) { 201 if off+2 > len(msg) { 202 return len(msg), &Error{err: "overflow packing uint16"} 203 } 204 binary.BigEndian.PutUint16(msg[off:], i) 205 return off + 2, nil 206} 207 208func unpackUint32(msg []byte, off int) (i uint32, off1 int, err error) { 209 if off+4 > len(msg) { 210 return 0, len(msg), &Error{err: "overflow unpacking uint32"} 211 } 212 return binary.BigEndian.Uint32(msg[off:]), off + 4, nil 213} 214 215func packUint32(i uint32, msg []byte, off int) (off1 int, err error) { 216 if off+4 > len(msg) { 217 return len(msg), &Error{err: "overflow packing uint32"} 218 } 219 binary.BigEndian.PutUint32(msg[off:], i) 220 return off + 4, nil 221} 222 223func unpackUint48(msg []byte, off int) (i uint64, off1 int, err error) { 224 if off+6 > len(msg) { 225 return 0, len(msg), &Error{err: "overflow unpacking uint64 as uint48"} 226 } 227 // Used in TSIG where the last 48 bits are occupied, so for now, assume a uint48 (6 bytes) 228 i = uint64(msg[off])<<40 | uint64(msg[off+1])<<32 | uint64(msg[off+2])<<24 | uint64(msg[off+3])<<16 | 229 uint64(msg[off+4])<<8 | uint64(msg[off+5]) 230 off += 6 231 return i, off, nil 232} 233 234func packUint48(i uint64, msg []byte, off int) (off1 int, err error) { 235 if off+6 > len(msg) { 236 return len(msg), &Error{err: "overflow packing uint64 as uint48"} 237 } 238 msg[off] = byte(i >> 40) 239 msg[off+1] = byte(i >> 32) 240 msg[off+2] = byte(i >> 24) 241 msg[off+3] = byte(i >> 16) 242 msg[off+4] = byte(i >> 8) 243 msg[off+5] = byte(i) 244 off += 6 245 return off, nil 246} 247 248func unpackUint64(msg []byte, off int) (i uint64, off1 int, err error) { 249 if off+8 > len(msg) { 250 return 0, len(msg), &Error{err: "overflow unpacking uint64"} 251 } 252 return binary.BigEndian.Uint64(msg[off:]), off + 8, nil 253} 254 255func packUint64(i uint64, msg []byte, off int) (off1 int, err error) { 256 if off+8 > len(msg) { 257 return len(msg), &Error{err: "overflow packing uint64"} 258 } 259 binary.BigEndian.PutUint64(msg[off:], i) 260 off += 8 261 return off, nil 262} 263 264func unpackString(msg []byte, off int) (string, int, error) { 265 if off+1 > len(msg) { 266 return "", off, &Error{err: "overflow unpacking txt"} 267 } 268 l := int(msg[off]) 269 off++ 270 if off+l > len(msg) { 271 return "", off, &Error{err: "overflow unpacking txt"} 272 } 273 var s strings.Builder 274 consumed := 0 275 for i, b := range msg[off : off+l] { 276 switch { 277 case b == '"' || b == '\\': 278 if consumed == 0 { 279 s.Grow(l * 2) 280 } 281 s.Write(msg[off+consumed : off+i]) 282 s.WriteByte('\\') 283 s.WriteByte(b) 284 consumed = i + 1 285 case b < ' ' || b > '~': // unprintable 286 if consumed == 0 { 287 s.Grow(l * 2) 288 } 289 s.Write(msg[off+consumed : off+i]) 290 s.WriteString(escapeByte(b)) 291 consumed = i + 1 292 } 293 } 294 if consumed == 0 { // no escaping needed 295 return string(msg[off : off+l]), off + l, nil 296 } 297 s.Write(msg[off+consumed : off+l]) 298 return s.String(), off + l, nil 299} 300 301func packString(s string, msg []byte, off int) (int, error) { 302 txtTmp := make([]byte, 256*4+1) 303 off, err := packTxtString(s, msg, off, txtTmp) 304 if err != nil { 305 return len(msg), err 306 } 307 return off, nil 308} 309 310func unpackStringBase32(msg []byte, off, end int) (string, int, error) { 311 if end > len(msg) { 312 return "", len(msg), &Error{err: "overflow unpacking base32"} 313 } 314 s := toBase32(msg[off:end]) 315 return s, end, nil 316} 317 318func packStringBase32(s string, msg []byte, off int) (int, error) { 319 b32, err := fromBase32([]byte(s)) 320 if err != nil { 321 return len(msg), err 322 } 323 if off+len(b32) > len(msg) { 324 return len(msg), &Error{err: "overflow packing base32"} 325 } 326 copy(msg[off:off+len(b32)], b32) 327 off += len(b32) 328 return off, nil 329} 330 331func unpackStringBase64(msg []byte, off, end int) (string, int, error) { 332 // Rest of the RR is base64 encoded value, so we don't need an explicit length 333 // to be set. Thus far all RR's that have base64 encoded fields have those as their 334 // last one. What we do need is the end of the RR! 335 if end > len(msg) { 336 return "", len(msg), &Error{err: "overflow unpacking base64"} 337 } 338 s := toBase64(msg[off:end]) 339 return s, end, nil 340} 341 342func packStringBase64(s string, msg []byte, off int) (int, error) { 343 b64, err := fromBase64([]byte(s)) 344 if err != nil { 345 return len(msg), err 346 } 347 if off+len(b64) > len(msg) { 348 return len(msg), &Error{err: "overflow packing base64"} 349 } 350 copy(msg[off:off+len(b64)], b64) 351 off += len(b64) 352 return off, nil 353} 354 355func unpackStringHex(msg []byte, off, end int) (string, int, error) { 356 // Rest of the RR is hex encoded value, so we don't need an explicit length 357 // to be set. NSEC and TSIG have hex fields with a length field. 358 // What we do need is the end of the RR! 359 if end > len(msg) { 360 return "", len(msg), &Error{err: "overflow unpacking hex"} 361 } 362 363 s := hex.EncodeToString(msg[off:end]) 364 return s, end, nil 365} 366 367func packStringHex(s string, msg []byte, off int) (int, error) { 368 h, err := hex.DecodeString(s) 369 if err != nil { 370 return len(msg), err 371 } 372 if off+len(h) > len(msg) { 373 return len(msg), &Error{err: "overflow packing hex"} 374 } 375 copy(msg[off:off+len(h)], h) 376 off += len(h) 377 return off, nil 378} 379 380func unpackStringAny(msg []byte, off, end int) (string, int, error) { 381 if end > len(msg) { 382 return "", len(msg), &Error{err: "overflow unpacking anything"} 383 } 384 return string(msg[off:end]), end, nil 385} 386 387func packStringAny(s string, msg []byte, off int) (int, error) { 388 if off+len(s) > len(msg) { 389 return len(msg), &Error{err: "overflow packing anything"} 390 } 391 copy(msg[off:off+len(s)], s) 392 off += len(s) 393 return off, nil 394} 395 396func unpackStringTxt(msg []byte, off int) ([]string, int, error) { 397 txt, off, err := unpackTxt(msg, off) 398 if err != nil { 399 return nil, len(msg), err 400 } 401 return txt, off, nil 402} 403 404func packStringTxt(s []string, msg []byte, off int) (int, error) { 405 txtTmp := make([]byte, 256*4+1) // If the whole string consists out of \DDD we need this many. 406 off, err := packTxt(s, msg, off, txtTmp) 407 if err != nil { 408 return len(msg), err 409 } 410 return off, nil 411} 412 413func unpackDataOpt(msg []byte, off int) ([]EDNS0, int, error) { 414 var edns []EDNS0 415Option: 416 var code uint16 417 if off+4 > len(msg) { 418 return nil, len(msg), &Error{err: "overflow unpacking opt"} 419 } 420 code = binary.BigEndian.Uint16(msg[off:]) 421 off += 2 422 optlen := binary.BigEndian.Uint16(msg[off:]) 423 off += 2 424 if off+int(optlen) > len(msg) { 425 return nil, len(msg), &Error{err: "overflow unpacking opt"} 426 } 427 e := makeDataOpt(code) 428 if err := e.unpack(msg[off : off+int(optlen)]); err != nil { 429 return nil, len(msg), err 430 } 431 edns = append(edns, e) 432 off += int(optlen) 433 434 if off < len(msg) { 435 goto Option 436 } 437 438 return edns, off, nil 439} 440 441func packDataOpt(options []EDNS0, msg []byte, off int) (int, error) { 442 for _, el := range options { 443 b, err := el.pack() 444 if err != nil || off+4 > len(msg) { 445 return len(msg), &Error{err: "overflow packing opt"} 446 } 447 binary.BigEndian.PutUint16(msg[off:], el.Option()) // Option code 448 binary.BigEndian.PutUint16(msg[off+2:], uint16(len(b))) // Length 449 off += 4 450 if off+len(b) > len(msg) { 451 return len(msg), &Error{err: "overflow packing opt"} 452 } 453 // Actual data 454 copy(msg[off:off+len(b)], b) 455 off += len(b) 456 } 457 return off, nil 458} 459 460func unpackStringOctet(msg []byte, off int) (string, int, error) { 461 s := string(msg[off:]) 462 return s, len(msg), nil 463} 464 465func packStringOctet(s string, msg []byte, off int) (int, error) { 466 txtTmp := make([]byte, 256*4+1) 467 off, err := packOctetString(s, msg, off, txtTmp) 468 if err != nil { 469 return len(msg), err 470 } 471 return off, nil 472} 473 474func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) { 475 var nsec []uint16 476 length, window, lastwindow := 0, 0, -1 477 for off < len(msg) { 478 if off+2 > len(msg) { 479 return nsec, len(msg), &Error{err: "overflow unpacking nsecx"} 480 } 481 window = int(msg[off]) 482 length = int(msg[off+1]) 483 off += 2 484 if window <= lastwindow { 485 // RFC 4034: Blocks are present in the NSEC RR RDATA in 486 // increasing numerical order. 487 return nsec, len(msg), &Error{err: "out of order NSEC block"} 488 } 489 if length == 0 { 490 // RFC 4034: Blocks with no types present MUST NOT be included. 491 return nsec, len(msg), &Error{err: "empty NSEC block"} 492 } 493 if length > 32 { 494 return nsec, len(msg), &Error{err: "NSEC block too long"} 495 } 496 if off+length > len(msg) { 497 return nsec, len(msg), &Error{err: "overflowing NSEC block"} 498 } 499 500 // Walk the bytes in the window and extract the type bits 501 for j, b := range msg[off : off+length] { 502 // Check the bits one by one, and set the type 503 if b&0x80 == 0x80 { 504 nsec = append(nsec, uint16(window*256+j*8+0)) 505 } 506 if b&0x40 == 0x40 { 507 nsec = append(nsec, uint16(window*256+j*8+1)) 508 } 509 if b&0x20 == 0x20 { 510 nsec = append(nsec, uint16(window*256+j*8+2)) 511 } 512 if b&0x10 == 0x10 { 513 nsec = append(nsec, uint16(window*256+j*8+3)) 514 } 515 if b&0x8 == 0x8 { 516 nsec = append(nsec, uint16(window*256+j*8+4)) 517 } 518 if b&0x4 == 0x4 { 519 nsec = append(nsec, uint16(window*256+j*8+5)) 520 } 521 if b&0x2 == 0x2 { 522 nsec = append(nsec, uint16(window*256+j*8+6)) 523 } 524 if b&0x1 == 0x1 { 525 nsec = append(nsec, uint16(window*256+j*8+7)) 526 } 527 } 528 off += length 529 lastwindow = window 530 } 531 return nsec, off, nil 532} 533 534// typeBitMapLen is a helper function which computes the "maximum" length of 535// a the NSEC Type BitMap field. 536func typeBitMapLen(bitmap []uint16) int { 537 var l int 538 var lastwindow, lastlength uint16 539 for _, t := range bitmap { 540 window := t / 256 541 length := (t-window*256)/8 + 1 542 if window > lastwindow && lastlength != 0 { // New window, jump to the new offset 543 l += int(lastlength) + 2 544 lastlength = 0 545 } 546 if window < lastwindow || length < lastlength { 547 // packDataNsec would return Error{err: "nsec bits out of order"} here, but 548 // when computing the length, we want do be liberal. 549 continue 550 } 551 lastwindow, lastlength = window, length 552 } 553 l += int(lastlength) + 2 554 return l 555} 556 557func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) { 558 if len(bitmap) == 0 { 559 return off, nil 560 } 561 var lastwindow, lastlength uint16 562 for _, t := range bitmap { 563 window := t / 256 564 length := (t-window*256)/8 + 1 565 if window > lastwindow && lastlength != 0 { // New window, jump to the new offset 566 off += int(lastlength) + 2 567 lastlength = 0 568 } 569 if window < lastwindow || length < lastlength { 570 return len(msg), &Error{err: "nsec bits out of order"} 571 } 572 if off+2+int(length) > len(msg) { 573 return len(msg), &Error{err: "overflow packing nsec"} 574 } 575 // Setting the window # 576 msg[off] = byte(window) 577 // Setting the octets length 578 msg[off+1] = byte(length) 579 // Setting the bit value for the type in the right octet 580 msg[off+1+int(length)] |= byte(1 << (7 - t%8)) 581 lastwindow, lastlength = window, length 582 } 583 off += int(lastlength) + 2 584 return off, nil 585} 586 587func unpackDataSVCB(msg []byte, off int) ([]SVCBKeyValue, int, error) { 588 var xs []SVCBKeyValue 589 var code uint16 590 var length uint16 591 var err error 592 for off < len(msg) { 593 code, off, err = unpackUint16(msg, off) 594 if err != nil { 595 return nil, len(msg), &Error{err: "overflow unpacking SVCB"} 596 } 597 length, off, err = unpackUint16(msg, off) 598 if err != nil || off+int(length) > len(msg) { 599 return nil, len(msg), &Error{err: "overflow unpacking SVCB"} 600 } 601 e := makeSVCBKeyValue(SVCBKey(code)) 602 if e == nil { 603 return nil, len(msg), &Error{err: "bad SVCB key"} 604 } 605 if err := e.unpack(msg[off : off+int(length)]); err != nil { 606 return nil, len(msg), err 607 } 608 if len(xs) > 0 && e.Key() <= xs[len(xs)-1].Key() { 609 return nil, len(msg), &Error{err: "SVCB keys not in strictly increasing order"} 610 } 611 xs = append(xs, e) 612 off += int(length) 613 } 614 return xs, off, nil 615} 616 617func packDataSVCB(pairs []SVCBKeyValue, msg []byte, off int) (int, error) { 618 pairs = append([]SVCBKeyValue(nil), pairs...) 619 sort.Slice(pairs, func(i, j int) bool { 620 return pairs[i].Key() < pairs[j].Key() 621 }) 622 prev := svcb_RESERVED 623 for _, el := range pairs { 624 if el.Key() == prev { 625 return len(msg), &Error{err: "repeated SVCB keys are not allowed"} 626 } 627 prev = el.Key() 628 packed, err := el.pack() 629 if err != nil { 630 return len(msg), err 631 } 632 off, err = packUint16(uint16(el.Key()), msg, off) 633 if err != nil { 634 return len(msg), &Error{err: "overflow packing SVCB"} 635 } 636 off, err = packUint16(uint16(len(packed)), msg, off) 637 if err != nil || off+len(packed) > len(msg) { 638 return len(msg), &Error{err: "overflow packing SVCB"} 639 } 640 copy(msg[off:off+len(packed)], packed) 641 off += len(packed) 642 } 643 return off, nil 644} 645 646func unpackDataDomainNames(msg []byte, off, end int) ([]string, int, error) { 647 var ( 648 servers []string 649 s string 650 err error 651 ) 652 if end > len(msg) { 653 return nil, len(msg), &Error{err: "overflow unpacking domain names"} 654 } 655 for off < end { 656 s, off, err = UnpackDomainName(msg, off) 657 if err != nil { 658 return servers, len(msg), err 659 } 660 servers = append(servers, s) 661 } 662 return servers, off, nil 663} 664 665func packDataDomainNames(names []string, msg []byte, off int, compression compressionMap, compress bool) (int, error) { 666 var err error 667 for _, name := range names { 668 off, err = packDomainName(name, msg, off, compression, compress) 669 if err != nil { 670 return len(msg), err 671 } 672 } 673 return off, nil 674} 675 676func packDataApl(data []APLPrefix, msg []byte, off int) (int, error) { 677 var err error 678 for i := range data { 679 off, err = packDataAplPrefix(&data[i], msg, off) 680 if err != nil { 681 return len(msg), err 682 } 683 } 684 return off, nil 685} 686 687func packDataAplPrefix(p *APLPrefix, msg []byte, off int) (int, error) { 688 if len(p.Network.IP) != len(p.Network.Mask) { 689 return len(msg), &Error{err: "address and mask lengths don't match"} 690 } 691 692 var err error 693 prefix, _ := p.Network.Mask.Size() 694 addr := p.Network.IP.Mask(p.Network.Mask)[:(prefix+7)/8] 695 696 switch len(p.Network.IP) { 697 case net.IPv4len: 698 off, err = packUint16(1, msg, off) 699 case net.IPv6len: 700 off, err = packUint16(2, msg, off) 701 default: 702 err = &Error{err: "unrecognized address family"} 703 } 704 if err != nil { 705 return len(msg), err 706 } 707 708 off, err = packUint8(uint8(prefix), msg, off) 709 if err != nil { 710 return len(msg), err 711 } 712 713 var n uint8 714 if p.Negation { 715 n = 0x80 716 } 717 718 // trim trailing zero bytes as specified in RFC3123 Sections 4.1 and 4.2. 719 i := len(addr) - 1 720 for ; i >= 0 && addr[i] == 0; i-- { 721 } 722 addr = addr[:i+1] 723 724 adflen := uint8(len(addr)) & 0x7f 725 off, err = packUint8(n|adflen, msg, off) 726 if err != nil { 727 return len(msg), err 728 } 729 730 if off+len(addr) > len(msg) { 731 return len(msg), &Error{err: "overflow packing APL prefix"} 732 } 733 off += copy(msg[off:], addr) 734 735 return off, nil 736} 737 738func unpackDataApl(msg []byte, off int) ([]APLPrefix, int, error) { 739 var result []APLPrefix 740 for off < len(msg) { 741 prefix, end, err := unpackDataAplPrefix(msg, off) 742 if err != nil { 743 return nil, len(msg), err 744 } 745 off = end 746 result = append(result, prefix) 747 } 748 return result, off, nil 749} 750 751func unpackDataAplPrefix(msg []byte, off int) (APLPrefix, int, error) { 752 family, off, err := unpackUint16(msg, off) 753 if err != nil { 754 return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL prefix"} 755 } 756 prefix, off, err := unpackUint8(msg, off) 757 if err != nil { 758 return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL prefix"} 759 } 760 nlen, off, err := unpackUint8(msg, off) 761 if err != nil { 762 return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL prefix"} 763 } 764 765 var ip []byte 766 switch family { 767 case 1: 768 ip = make([]byte, net.IPv4len) 769 case 2: 770 ip = make([]byte, net.IPv6len) 771 default: 772 return APLPrefix{}, len(msg), &Error{err: "unrecognized APL address family"} 773 } 774 if int(prefix) > 8*len(ip) { 775 return APLPrefix{}, len(msg), &Error{err: "APL prefix too long"} 776 } 777 afdlen := int(nlen & 0x7f) 778 if afdlen > len(ip) { 779 return APLPrefix{}, len(msg), &Error{err: "APL length too long"} 780 } 781 if off+afdlen > len(msg) { 782 return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL address"} 783 } 784 off += copy(ip, msg[off:off+afdlen]) 785 if afdlen > 0 { 786 last := ip[afdlen-1] 787 if last == 0 { 788 return APLPrefix{}, len(msg), &Error{err: "extra APL address bits"} 789 } 790 } 791 ipnet := net.IPNet{ 792 IP: ip, 793 Mask: net.CIDRMask(int(prefix), 8*len(ip)), 794 } 795 network := ipnet.IP.Mask(ipnet.Mask) 796 if !network.Equal(ipnet.IP) { 797 return APLPrefix{}, len(msg), &Error{err: "invalid APL address length"} 798 } 799 800 return APLPrefix{ 801 Negation: (nlen & 0x80) != 0, 802 Network: ipnet, 803 }, off, nil 804} 805