| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- package nicfinder
- import (
- "context"
- "net"
- "net/netip"
- "regexp"
- "testing"
- "github.com/slackhq/nebula/test"
- "github.com/stretchr/testify/assert"
- )
- type allowAll struct{}
- func (allowAll) Allow(netip.Addr) bool { return true }
- func (allowAll) AllowName(string) bool { return true }
- type testAllowList struct {
- bannedName *regexp.Regexp
- bannedAddr netip.Addr
- }
- func (l *testAllowList) Allow(addr netip.Addr) bool {
- return addr != l.bannedAddr
- }
- func (l *testAllowList) AllowName(n string) bool {
- return !l.bannedName.MatchString(n)
- }
- func newTestAllowList(bannedName string) *testAllowList {
- return &testAllowList{
- bannedName: regexp.MustCompile(bannedName),
- }
- }
- func TestAllowedAddr(t *testing.T) {
- ctx, l := context.Background(), test.NewLogger()
- allowed := func(filter Filter, addrs []net.Addr) []netip.Addr {
- var out []netip.Addr
- for _, rawAddr := range addrs {
- if addr, ok := allowedAddr(ctx, l, filter, rawAddr); ok {
- out = append(out, addr)
- }
- }
- return out
- }
- addrs := []net.Addr{
- &net.IPNet{IP: net.ParseIP("127.0.0.1"), Mask: net.CIDRMask(8, 32)},
- &net.IPNet{IP: net.ParseIP("::1"), Mask: net.CIDRMask(128, 128)},
- &net.IPNet{IP: net.ParseIP("10.0.0.5"), Mask: net.CIDRMask(24, 32)},
- &net.IPNet{IP: net.ParseIP("169.254.10.10"), Mask: net.CIDRMask(16, 32)},
- &net.IPNet{IP: net.ParseIP("fe80::1"), Mask: net.CIDRMask(64, 128)},
- &net.IPAddr{IP: net.ParseIP("fd00::5")},
- &net.IPNet{},
- otherAddr{},
- nil,
- }
- // Loopback, link local and anything without an IP are dropped, and IPv4 comes back unmapped
- // even though net.ParseIP hands over a 16 byte slice.
- assert.Equal(t, []netip.Addr{
- netip.MustParseAddr("10.0.0.5"),
- netip.MustParseAddr("fd00::5"),
- }, allowed(allowAll{}, addrs))
- // The filter sees the unmapped form and can drop a single address.
- al := newTestAllowList("none")
- al.bannedAddr = netip.MustParseAddr("10.0.0.5")
- assert.Equal(t, []netip.Addr{netip.MustParseAddr("fd00::5")}, allowed(al, addrs))
- }
- // otherAddr is a net.Addr that is neither *net.IPNet nor *net.IPAddr. netlink.Addr is one such
- // type: it satisfies net.Addr through an embedded *net.IPNet, and passing it directly once
- // silently produced no addresses.
- type otherAddr struct{}
- func (otherAddr) Network() string { return "other" }
- func (otherAddr) String() string { return "other" }
- // hostFilter counts AllowName calls and can reject every name or every address.
- type hostFilter struct {
- rejectNames bool
- rejectAddrs bool
- asked map[string]int
- }
- func (f *hostFilter) Allow(netip.Addr) bool { return !f.rejectAddrs }
- func (f *hostFilter) AllowName(name string) bool {
- f.asked[name]++
- return !f.rejectNames
- }
- // Runs this platform's localAddrs against the host and checks it honors the whole filter.
- func TestLocalAddrsAppliesFilter(t *testing.T) {
- ctx, l := context.Background(), test.NewLogger()
- f := &hostFilter{asked: map[string]int{}}
- all, err := localAddrs(ctx, l, f)
- if len(f.asked) == 0 {
- t.Skipf("no interfaces to enumerate here: %v", err)
- }
- for name, n := range f.asked {
- assert.Equal(t, 1, n, "AllowName asked %d times for %s", n, name)
- }
- // Loopback and link-local never come back, whatever the filter says.
- for _, addr := range all {
- assert.False(t, addr.IsLoopback() || addr.IsLinkLocalUnicast(), "%s", addr)
- }
- none, _ := localAddrs(ctx, l, &hostFilter{rejectNames: true, asked: map[string]int{}})
- assert.Empty(t, none, "addresses got past a filter that rejects every interface name")
- none, _ = localAddrs(ctx, l, &hostFilter{rejectAddrs: true, asked: map[string]int{}})
- assert.Empty(t, none, "addresses got past a filter that rejects every address")
- }
|