Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,14 +474,14 @@ func IPv6Prefix(a Attribute) (*net.IPNet, error) {
ip := make(net.IP, net.IPv6len)
copy(ip, a[2:])

bit := uint(prefixLength % 8)
for octet := prefixLength / 8; octet < len(ip); octet++ {
for ; bit < 8; bit++ {
if ip[octet]&(1<<(7-bit)) != 0 {
return nil, errors.New("invalid prefix data")
}
}
bit = 0
// Clear any bits beyond the prefix length. RFC 3162 requires these bits to
// be zero, but some equipment leaves them set; tolerate that here instead
// of rejecting the attribute.
if bit := uint(prefixLength % 8); bit != 0 {
ip[prefixLength/8] &^= 0xff >> bit
}
for octet := (prefixLength + 7) / 8; octet < len(ip); octet++ {
ip[octet] = 0
}

return &net.IPNet{
Expand Down
33 changes: 33 additions & 0 deletions attribute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,39 @@ func TestIPv6Prefix_issue118(t *testing.T) {
}
}

func TestIPv6Prefix_issue119(t *testing.T) {
tests := []struct {
Name string
Attr []byte
Expected string
}{
{
// /64 prefix sent with the host bits (::1) still set.
Name: "host bits set",
Attr: []byte{0x00, 0x40, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
Expected: "2001:db8::/64",
},
{
// /47 prefix with a non-zero bit beyond the prefix length.
Name: "non-octet boundary with trailing bit",
Attr: []byte{0x00, 0x2f, 0x20, 0x01, 0x15, 0x30, 0x10, 0x0f},
Expected: "2001:1530:100e::/47",
},
}

for _, tt := range tests {
t.Run(tt.Name, func(t *testing.T) {
ipNet, err := IPv6Prefix(tt.Attr)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
if got := ipNet.String(); got != tt.Expected {
t.Fatalf("got %s, expected %s", got, tt.Expected)
}
})
}
}

func ipNetEquals(a, b *net.IPNet) bool {
if a == nil && b == nil {
return true
Expand Down