msg_helpers.go (22565B)
1 package dns 2 3 import ( 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 19 func 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 28 func 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 46 func 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 55 func 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. 74 func 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. 106 func (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. 138 func 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 146 var base32HexNoPadEncoding = base32.HexEncoding.WithPadding(base32.NoPadding) 147 148 func 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 161 func toBase32(b []byte) string { 162 return base32HexNoPadEncoding.EncodeToString(b) 163 } 164 165 func 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 173 func toBase64(b []byte) string { return base64.StdEncoding.EncodeToString(b) } 174 175 // dynamicUpdate returns true if the Rdlength is zero. 176 func noRdata(h RR_Header) bool { return h.Rdlength == 0 } 177 178 func 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 185 func 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 193 func 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 200 func 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 208 func 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 215 func 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 223 func 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 234 func 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 248 func 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 255 func 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 264 func 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 301 func packString(s string, msg []byte, off int) (int, error) { 302 off, err := packTxtString(s, msg, off) 303 if err != nil { 304 return len(msg), err 305 } 306 return off, nil 307 } 308 309 func unpackStringBase32(msg []byte, off, end int) (string, int, error) { 310 if end > len(msg) { 311 return "", len(msg), &Error{err: "overflow unpacking base32"} 312 } 313 s := toBase32(msg[off:end]) 314 return s, end, nil 315 } 316 317 func packStringBase32(s string, msg []byte, off int) (int, error) { 318 b32, err := fromBase32([]byte(s)) 319 if err != nil { 320 return len(msg), err 321 } 322 if off+len(b32) > len(msg) { 323 return len(msg), &Error{err: "overflow packing base32"} 324 } 325 copy(msg[off:off+len(b32)], b32) 326 off += len(b32) 327 return off, nil 328 } 329 330 func unpackStringBase64(msg []byte, off, end int) (string, int, error) { 331 // Rest of the RR is base64 encoded value, so we don't need an explicit length 332 // to be set. Thus far all RR's that have base64 encoded fields have those as their 333 // last one. What we do need is the end of the RR! 334 if end > len(msg) { 335 return "", len(msg), &Error{err: "overflow unpacking base64"} 336 } 337 s := toBase64(msg[off:end]) 338 return s, end, nil 339 } 340 341 func packStringBase64(s string, msg []byte, off int) (int, error) { 342 b64, err := fromBase64([]byte(s)) 343 if err != nil { 344 return len(msg), err 345 } 346 if off+len(b64) > len(msg) { 347 return len(msg), &Error{err: "overflow packing base64"} 348 } 349 copy(msg[off:off+len(b64)], b64) 350 off += len(b64) 351 return off, nil 352 } 353 354 func unpackStringHex(msg []byte, off, end int) (string, int, error) { 355 // Rest of the RR is hex encoded value, so we don't need an explicit length 356 // to be set. NSEC and TSIG have hex fields with a length field. 357 // What we do need is the end of the RR! 358 if end > len(msg) { 359 return "", len(msg), &Error{err: "overflow unpacking hex"} 360 } 361 362 s := hex.EncodeToString(msg[off:end]) 363 return s, end, nil 364 } 365 366 func packStringHex(s string, msg []byte, off int) (int, error) { 367 h, err := hex.DecodeString(s) 368 if err != nil { 369 return len(msg), err 370 } 371 if off+len(h) > len(msg) { 372 return len(msg), &Error{err: "overflow packing hex"} 373 } 374 copy(msg[off:off+len(h)], h) 375 off += len(h) 376 return off, nil 377 } 378 379 func unpackStringAny(msg []byte, off, end int) (string, int, error) { 380 if end > len(msg) { 381 return "", len(msg), &Error{err: "overflow unpacking anything"} 382 } 383 return string(msg[off:end]), end, nil 384 } 385 386 func packStringAny(s string, msg []byte, off int) (int, error) { 387 if off+len(s) > len(msg) { 388 return len(msg), &Error{err: "overflow packing anything"} 389 } 390 copy(msg[off:off+len(s)], s) 391 off += len(s) 392 return off, nil 393 } 394 395 func unpackStringTxt(msg []byte, off int) ([]string, int, error) { 396 txt, off, err := unpackTxt(msg, off) 397 if err != nil { 398 return nil, len(msg), err 399 } 400 return txt, off, nil 401 } 402 403 func packStringTxt(s []string, msg []byte, off int) (int, error) { 404 off, err := packTxt(s, msg, off) 405 if err != nil { 406 return len(msg), err 407 } 408 return off, nil 409 } 410 411 func unpackDataOpt(msg []byte, off int) ([]EDNS0, int, error) { 412 var edns []EDNS0 413 Option: 414 var code uint16 415 if off+4 > len(msg) { 416 return nil, len(msg), &Error{err: "overflow unpacking opt"} 417 } 418 code = binary.BigEndian.Uint16(msg[off:]) 419 off += 2 420 optlen := binary.BigEndian.Uint16(msg[off:]) 421 off += 2 422 if off+int(optlen) > len(msg) { 423 return nil, len(msg), &Error{err: "overflow unpacking opt"} 424 } 425 e := makeDataOpt(code) 426 if err := e.unpack(msg[off : off+int(optlen)]); err != nil { 427 return nil, len(msg), err 428 } 429 edns = append(edns, e) 430 off += int(optlen) 431 432 if off < len(msg) { 433 goto Option 434 } 435 436 return edns, off, nil 437 } 438 439 func packDataOpt(options []EDNS0, msg []byte, off int) (int, error) { 440 for _, el := range options { 441 b, err := el.pack() 442 if err != nil || off+4 > len(msg) { 443 return len(msg), &Error{err: "overflow packing opt"} 444 } 445 binary.BigEndian.PutUint16(msg[off:], el.Option()) // Option code 446 binary.BigEndian.PutUint16(msg[off+2:], uint16(len(b))) // Length 447 off += 4 448 if off+len(b) > len(msg) { 449 return len(msg), &Error{err: "overflow packing opt"} 450 } 451 // Actual data 452 copy(msg[off:off+len(b)], b) 453 off += len(b) 454 } 455 return off, nil 456 } 457 458 func unpackStringOctet(msg []byte, off int) (string, int, error) { 459 s := string(msg[off:]) 460 return s, len(msg), nil 461 } 462 463 func packStringOctet(s string, msg []byte, off int) (int, error) { 464 txtTmp := make([]byte, 256*4+1) 465 off, err := packOctetString(s, msg, off, txtTmp) 466 if err != nil { 467 return len(msg), err 468 } 469 return off, nil 470 } 471 472 func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) { 473 var nsec []uint16 474 length, window, lastwindow := 0, 0, -1 475 for off < len(msg) { 476 if off+2 > len(msg) { 477 return nsec, len(msg), &Error{err: "overflow unpacking NSEC(3)"} 478 } 479 window = int(msg[off]) 480 length = int(msg[off+1]) 481 off += 2 482 if window <= lastwindow { 483 // RFC 4034: Blocks are present in the NSEC RR RDATA in 484 // increasing numerical order. 485 return nsec, len(msg), &Error{err: "out of order NSEC(3) block in type bitmap"} 486 } 487 if length == 0 { 488 // RFC 4034: Blocks with no types present MUST NOT be included. 489 return nsec, len(msg), &Error{err: "empty NSEC(3) block in type bitmap"} 490 } 491 if length > 32 { 492 return nsec, len(msg), &Error{err: "NSEC(3) block too long in type bitmap"} 493 } 494 if off+length > len(msg) { 495 return nsec, len(msg), &Error{err: "overflowing NSEC(3) block in type bitmap"} 496 } 497 498 // Walk the bytes in the window and extract the type bits 499 for j, b := range msg[off : off+length] { 500 // Check the bits one by one, and set the type 501 if b&0x80 == 0x80 { 502 nsec = append(nsec, uint16(window*256+j*8+0)) 503 } 504 if b&0x40 == 0x40 { 505 nsec = append(nsec, uint16(window*256+j*8+1)) 506 } 507 if b&0x20 == 0x20 { 508 nsec = append(nsec, uint16(window*256+j*8+2)) 509 } 510 if b&0x10 == 0x10 { 511 nsec = append(nsec, uint16(window*256+j*8+3)) 512 } 513 if b&0x8 == 0x8 { 514 nsec = append(nsec, uint16(window*256+j*8+4)) 515 } 516 if b&0x4 == 0x4 { 517 nsec = append(nsec, uint16(window*256+j*8+5)) 518 } 519 if b&0x2 == 0x2 { 520 nsec = append(nsec, uint16(window*256+j*8+6)) 521 } 522 if b&0x1 == 0x1 { 523 nsec = append(nsec, uint16(window*256+j*8+7)) 524 } 525 } 526 off += length 527 lastwindow = window 528 } 529 return nsec, off, nil 530 } 531 532 // typeBitMapLen is a helper function which computes the "maximum" length of 533 // a the NSEC Type BitMap field. 534 func typeBitMapLen(bitmap []uint16) int { 535 var l int 536 var lastwindow, lastlength uint16 537 for _, t := range bitmap { 538 window := t / 256 539 length := (t-window*256)/8 + 1 540 if window > lastwindow && lastlength != 0 { // New window, jump to the new offset 541 l += int(lastlength) + 2 542 lastlength = 0 543 } 544 if window < lastwindow || length < lastlength { 545 // packDataNsec would return Error{err: "nsec bits out of order"} here, but 546 // when computing the length, we want do be liberal. 547 continue 548 } 549 lastwindow, lastlength = window, length 550 } 551 l += int(lastlength) + 2 552 return l 553 } 554 555 func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) { 556 if len(bitmap) == 0 { 557 return off, nil 558 } 559 if off > len(msg) { 560 return off, &Error{err: "overflow packing nsec"} 561 } 562 toZero := msg[off:] 563 if maxLen := typeBitMapLen(bitmap); maxLen < len(toZero) { 564 toZero = toZero[:maxLen] 565 } 566 for i := range toZero { 567 toZero[i] = 0 568 } 569 var lastwindow, lastlength uint16 570 for _, t := range bitmap { 571 window := t / 256 572 length := (t-window*256)/8 + 1 573 if window > lastwindow && lastlength != 0 { // New window, jump to the new offset 574 off += int(lastlength) + 2 575 lastlength = 0 576 } 577 if window < lastwindow || length < lastlength { 578 return len(msg), &Error{err: "nsec bits out of order"} 579 } 580 if off+2+int(length) > len(msg) { 581 return len(msg), &Error{err: "overflow packing nsec"} 582 } 583 // Setting the window # 584 msg[off] = byte(window) 585 // Setting the octets length 586 msg[off+1] = byte(length) 587 // Setting the bit value for the type in the right octet 588 msg[off+1+int(length)] |= byte(1 << (7 - t%8)) 589 lastwindow, lastlength = window, length 590 } 591 off += int(lastlength) + 2 592 return off, nil 593 } 594 595 func unpackDataSVCB(msg []byte, off int) ([]SVCBKeyValue, int, error) { 596 var xs []SVCBKeyValue 597 var code uint16 598 var length uint16 599 var err error 600 for off < len(msg) { 601 code, off, err = unpackUint16(msg, off) 602 if err != nil { 603 return nil, len(msg), &Error{err: "overflow unpacking SVCB"} 604 } 605 length, off, err = unpackUint16(msg, off) 606 if err != nil || off+int(length) > len(msg) { 607 return nil, len(msg), &Error{err: "overflow unpacking SVCB"} 608 } 609 e := makeSVCBKeyValue(SVCBKey(code)) 610 if e == nil { 611 return nil, len(msg), &Error{err: "bad SVCB key"} 612 } 613 if err := e.unpack(msg[off : off+int(length)]); err != nil { 614 return nil, len(msg), err 615 } 616 if len(xs) > 0 && e.Key() <= xs[len(xs)-1].Key() { 617 return nil, len(msg), &Error{err: "SVCB keys not in strictly increasing order"} 618 } 619 xs = append(xs, e) 620 off += int(length) 621 } 622 return xs, off, nil 623 } 624 625 func packDataSVCB(pairs []SVCBKeyValue, msg []byte, off int) (int, error) { 626 pairs = cloneSlice(pairs) 627 sort.Slice(pairs, func(i, j int) bool { 628 return pairs[i].Key() < pairs[j].Key() 629 }) 630 prev := svcb_RESERVED 631 for _, el := range pairs { 632 if el.Key() == prev { 633 return len(msg), &Error{err: "repeated SVCB keys are not allowed"} 634 } 635 prev = el.Key() 636 packed, err := el.pack() 637 if err != nil { 638 return len(msg), err 639 } 640 off, err = packUint16(uint16(el.Key()), msg, off) 641 if err != nil { 642 return len(msg), &Error{err: "overflow packing SVCB"} 643 } 644 off, err = packUint16(uint16(len(packed)), msg, off) 645 if err != nil || off+len(packed) > len(msg) { 646 return len(msg), &Error{err: "overflow packing SVCB"} 647 } 648 copy(msg[off:off+len(packed)], packed) 649 off += len(packed) 650 } 651 return off, nil 652 } 653 654 func unpackDataDomainNames(msg []byte, off, end int) ([]string, int, error) { 655 var ( 656 servers []string 657 s string 658 err error 659 ) 660 if end > len(msg) { 661 return nil, len(msg), &Error{err: "overflow unpacking domain names"} 662 } 663 for off < end { 664 s, off, err = UnpackDomainName(msg, off) 665 if err != nil { 666 return servers, len(msg), err 667 } 668 servers = append(servers, s) 669 } 670 return servers, off, nil 671 } 672 673 func packDataDomainNames(names []string, msg []byte, off int, compression compressionMap, compress bool) (int, error) { 674 var err error 675 for _, name := range names { 676 off, err = packDomainName(name, msg, off, compression, compress) 677 if err != nil { 678 return len(msg), err 679 } 680 } 681 return off, nil 682 } 683 684 func packDataApl(data []APLPrefix, msg []byte, off int) (int, error) { 685 var err error 686 for i := range data { 687 off, err = packDataAplPrefix(&data[i], msg, off) 688 if err != nil { 689 return len(msg), err 690 } 691 } 692 return off, nil 693 } 694 695 func packDataAplPrefix(p *APLPrefix, msg []byte, off int) (int, error) { 696 if len(p.Network.IP) != len(p.Network.Mask) { 697 return len(msg), &Error{err: "address and mask lengths don't match"} 698 } 699 700 var err error 701 prefix, _ := p.Network.Mask.Size() 702 addr := p.Network.IP.Mask(p.Network.Mask)[:(prefix+7)/8] 703 704 switch len(p.Network.IP) { 705 case net.IPv4len: 706 off, err = packUint16(1, msg, off) 707 case net.IPv6len: 708 off, err = packUint16(2, msg, off) 709 default: 710 err = &Error{err: "unrecognized address family"} 711 } 712 if err != nil { 713 return len(msg), err 714 } 715 716 off, err = packUint8(uint8(prefix), msg, off) 717 if err != nil { 718 return len(msg), err 719 } 720 721 var n uint8 722 if p.Negation { 723 n = 0x80 724 } 725 726 // trim trailing zero bytes as specified in RFC3123 Sections 4.1 and 4.2. 727 i := len(addr) - 1 728 for ; i >= 0 && addr[i] == 0; i-- { 729 } 730 addr = addr[:i+1] 731 732 adflen := uint8(len(addr)) & 0x7f 733 off, err = packUint8(n|adflen, msg, off) 734 if err != nil { 735 return len(msg), err 736 } 737 738 if off+len(addr) > len(msg) { 739 return len(msg), &Error{err: "overflow packing APL prefix"} 740 } 741 off += copy(msg[off:], addr) 742 743 return off, nil 744 } 745 746 func unpackDataApl(msg []byte, off int) ([]APLPrefix, int, error) { 747 var result []APLPrefix 748 for off < len(msg) { 749 prefix, end, err := unpackDataAplPrefix(msg, off) 750 if err != nil { 751 return nil, len(msg), err 752 } 753 off = end 754 result = append(result, prefix) 755 } 756 return result, off, nil 757 } 758 759 func unpackDataAplPrefix(msg []byte, off int) (APLPrefix, int, error) { 760 family, off, err := unpackUint16(msg, off) 761 if err != nil { 762 return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL prefix"} 763 } 764 prefix, off, err := unpackUint8(msg, off) 765 if err != nil { 766 return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL prefix"} 767 } 768 nlen, off, err := unpackUint8(msg, off) 769 if err != nil { 770 return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL prefix"} 771 } 772 773 var ip []byte 774 switch family { 775 case 1: 776 ip = make([]byte, net.IPv4len) 777 case 2: 778 ip = make([]byte, net.IPv6len) 779 default: 780 return APLPrefix{}, len(msg), &Error{err: "unrecognized APL address family"} 781 } 782 if int(prefix) > 8*len(ip) { 783 return APLPrefix{}, len(msg), &Error{err: "APL prefix too long"} 784 } 785 afdlen := int(nlen & 0x7f) 786 if afdlen > len(ip) { 787 return APLPrefix{}, len(msg), &Error{err: "APL length too long"} 788 } 789 if off+afdlen > len(msg) { 790 return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL address"} 791 } 792 793 // Address MUST NOT contain trailing zero bytes per RFC3123 Sections 4.1 and 4.2. 794 off += copy(ip, msg[off:off+afdlen]) 795 if afdlen > 0 { 796 last := ip[afdlen-1] 797 if last == 0 { 798 return APLPrefix{}, len(msg), &Error{err: "extra APL address bits"} 799 } 800 } 801 ipnet := net.IPNet{ 802 IP: ip, 803 Mask: net.CIDRMask(int(prefix), 8*len(ip)), 804 } 805 806 return APLPrefix{ 807 Negation: (nlen & 0x80) != 0, 808 Network: ipnet, 809 }, off, nil 810 } 811 812 func unpackIPSECGateway(msg []byte, off int, gatewayType uint8) (net.IP, string, int, error) { 813 var retAddr net.IP 814 var retString string 815 var err error 816 817 switch gatewayType { 818 case IPSECGatewayNone: // do nothing 819 case IPSECGatewayIPv4: 820 retAddr, off, err = unpackDataA(msg, off) 821 case IPSECGatewayIPv6: 822 retAddr, off, err = unpackDataAAAA(msg, off) 823 case IPSECGatewayHost: 824 retString, off, err = UnpackDomainName(msg, off) 825 } 826 827 return retAddr, retString, off, err 828 } 829 830 func packIPSECGateway(gatewayAddr net.IP, gatewayString string, msg []byte, off int, gatewayType uint8, compression compressionMap, compress bool) (int, error) { 831 var err error 832 833 switch gatewayType { 834 case IPSECGatewayNone: // do nothing 835 case IPSECGatewayIPv4: 836 off, err = packDataA(gatewayAddr, msg, off) 837 case IPSECGatewayIPv6: 838 off, err = packDataAAAA(gatewayAddr, msg, off) 839 case IPSECGatewayHost: 840 off, err = packDomainName(gatewayString, msg, off, compression, compress) 841 } 842 843 return off, err 844 }