aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorMikio Hara <mikioh.mikioh@gmail.com>2014-10-07 06:58:24 +0900
committerMikio Hara <mikioh.mikioh@gmail.com>2014-10-07 06:58:24 +0900
commitfb10a5fdb492051d7ae813d879f2c91c4b89d50f (patch)
tree1d82cd2fe4f528ab7ee2936ca372e29711a1432d /internal
parente5dac17b9bc9990733d38c2330f791d75659352b (diff)
downloadnet-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.go91
-rw-r--r--internal/nettest/stack.go30
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
+}