diff --git a/msg_helpers.go b/msg_helpers.go index cbcab57b..6fb64475 100644 --- a/msg_helpers.go +++ b/msg_helpers.go @@ -683,6 +683,13 @@ func packDataAplPrefix(p *APLPrefix, msg []byte, off int) (int, error) { if p.Negation { n = 0x80 } + + // trim trailing zero bytes as specified in RFC3123 Sections 4.1 and 4.2. + i := len(addr) - 1 + for ; i >= 0 && addr[i] == 0; i-- { + } + addr = addr[:i+1] + adflen := uint8(len(addr)) & 0x7f off, err = packUint8(n|adflen, msg, off) if err != nil { diff --git a/msg_helpers_test.go b/msg_helpers_test.go index 70e3b238..c1fa195a 100644 --- a/msg_helpers_test.go +++ b/msg_helpers_test.go @@ -180,6 +180,20 @@ func TestPackDataAplPrefix(t *testing.T) { net.CIDRMask(48, 128), []byte{0x00, 0x02, 0x30, 0x06, 0x20, 0x01, 0x0d, 0xb8, 0xca, 0xfe}, }, + { + "with trailing zero bytes 2:2001:db8:cafe::0/64", + false, + net.ParseIP("2001:db8:cafe::"), + net.CIDRMask(64, 128), + []byte{0x00, 0x02, 0x40, 0x06, 0x20, 0x01, 0x0d, 0xb8, 0xca, 0xfe}, + }, + { + "no non-zero bytes 2::/16", + false, + net.ParseIP("::"), + net.CIDRMask(16, 128), + []byte{0x00, 0x02, 0x10, 0x00}, + }, { "!2:2001:db8::/32", true, @@ -209,6 +223,11 @@ func TestPackDataAplPrefix(t *testing.T) { if !bytes.Equal(tt.expect, out[:off]) { t.Fatalf("expected output %02x, got %02x", tt.expect, out[:off]) } + // Make sure the packed bytes would be accepted by its own unpack + _, _, err = unpackDataAplPrefix(out, 0) + if err != nil { + t.Fatalf("expected no error, got %q", err) + } }) } }