diff options
author | Mikio Hara <mikioh.mikioh@gmail.com> | 2014-10-07 06:58:24 +0900 |
---|---|---|
committer | Mikio Hara <mikioh.mikioh@gmail.com> | 2014-10-07 06:58:24 +0900 |
commit | fb10a5fdb492051d7ae813d879f2c91c4b89d50f (patch) | |
tree | 1d82cd2fe4f528ab7ee2936ca372e29711a1432d /internal | |
parent | e5dac17b9bc9990733d38c2330f791d75659352b (diff) | |
download | net-fb10a5fdb492051d7ae813d879f2c91c4b89d50f.tar.gz |
go.net/internal/nettest: new package
This CL factors out testing utilities used by both ipv4 and ipv6 packages.
LGTM=iant
R=iant
CC=golang-codereviews
https://golang.org/cl/152070043
Diffstat (limited to 'internal')
-rw-r--r-- | internal/nettest/interface.go | 91 | ||||
-rw-r--r-- | internal/nettest/stack.go | 30 |
2 files changed, 121 insertions, 0 deletions
diff --git a/internal/nettest/interface.go b/internal/nettest/interface.go new file mode 100644 index 0000000..eeceb7e --- /dev/null +++ b/internal/nettest/interface.go @@ -0,0 +1,91 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package nettest + +import "net" + +// IsMulticastCapable reports whether ifi is an IP multicast-capable +// network interface. Network must be "ip", "ip4" or "ip6". +func IsMulticastCapable(network string, ifi *net.Interface) (net.IP, bool) { + switch network { + case "ip", "ip4", "ip6": + default: + return nil, false + } + if ifi == nil || ifi.Flags&net.FlagUp == 0 || ifi.Flags&net.FlagMulticast == 0 { + return nil, false + } + return hasRoutableIP(network, ifi) +} + +// RoutedInterface returns a network interface that can route IP +// traffic and satisfies flags. It returns nil when an appropriate +// network interface is not found. Network must be "ip", "ip4" or +// "ip6". +func RoutedInterface(network string, flags net.Flags) *net.Interface { + switch network { + case "ip", "ip4", "ip6": + default: + return nil + } + ift, err := net.Interfaces() + if err != nil { + return nil + } + for _, ifi := range ift { + if ifi.Flags&flags != flags { + continue + } + if _, ok := hasRoutableIP(network, &ifi); !ok { + continue + } + return &ifi + } + return nil +} + +func hasRoutableIP(network string, ifi *net.Interface) (net.IP, bool) { + ifat, err := ifi.Addrs() + if err != nil { + return nil, false + } + for _, ifa := range ifat { + switch ifa := ifa.(type) { + case *net.IPAddr: + if ip := routableIP(network, ifa.IP); ip != nil { + return ip, true + } + case *net.IPNet: + if ip := routableIP(network, ifa.IP); ip != nil { + return ip, true + } + } + } + return nil, false +} + +func routableIP(network string, ip net.IP) net.IP { + if !ip.IsLoopback() && !ip.IsLinkLocalUnicast() && !ip.IsGlobalUnicast() { + return nil + } + switch network { + case "ip4": + if ip := ip.To4(); ip != nil { + return ip + } + case "ip6": + if ip := ip.To16(); ip != nil && ip.To4() == nil { + return ip + } + default: + if ip := ip.To4(); ip != nil { + return ip + } + if ip := ip.To16(); ip != nil { + return ip + } + } + return nil +} diff --git a/internal/nettest/stack.go b/internal/nettest/stack.go new file mode 100644 index 0000000..a3b602e --- /dev/null +++ b/internal/nettest/stack.go @@ -0,0 +1,30 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package nettest provides utilities for IP testing. +package nettest + +import "net" + +// SupportsIPv4 reports whether the platform supports IPv4 networking +// functionality. +func SupportsIPv4() bool { + ln, err := net.Listen("tcp4", "127.0.0.1:0") + if err != nil { + return false + } + ln.Close() + return true +} + +// SupportsIPv6 reports whether the platform supports IPv6 networking +// functionality. +func SupportsIPv6() bool { + ln, err := net.Listen("tcp6", "[::1]:0") + if err != nil { + return false + } + ln.Close() + return true +} |