]> Cypherpunks repositories - gostls13.git/commitdiff
net: implement network interface API for Solaris
authorMikio Hara <mikioh.mikioh@gmail.com>
Tue, 27 Sep 2016 10:54:05 +0000 (19:54 +0900)
committerMikio Hara <mikioh.mikioh@gmail.com>
Tue, 4 Oct 2016 03:04:50 +0000 (03:04 +0000)
Fixes #7177.

Change-Id: Iba6063905f4f9c6acef8aba76b55d996f186d835
Reviewed-on: https://go-review.googlesource.com/29892
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com>

src/go/build/deps_test.go
src/net/interface.go
src/net/interface_solaris.go [new file with mode: 0644]
src/net/interface_stub.go
src/net/interface_test.go

index bcd599af852e4da05e9a839a8c3bdb24a99bccc1..8b382ec39527588b12a99282942d7fd3a834335d 100644 (file)
@@ -298,7 +298,7 @@ var pkgDeps = map[string][]string{
                "context", "math/rand", "os", "sort", "syscall", "time",
                "internal/nettrace",
                "internal/syscall/windows", "internal/singleflight", "internal/race",
-               "golang_org/x/net/route",
+               "golang_org/x/net/lif", "golang_org/x/net/route",
        },
 
        // NET enables use of basic network-related packages.
index 295ab2dc9231556e543b5e936500632c9270cfeb..61ee0ce7c3a3aedd1f26b84a65c7ed6b826643e7 100644 (file)
@@ -10,10 +10,10 @@ import (
        "time"
 )
 
-// BUG(mikio): On NaCl, Plan9 and Solaris, methods and functions
-// related to Interface are not implemented.
+// BUG(mikio): On NaCl and Plan9, methods and functions related to
+// Interface are not implemented.
 
-// BUG(mikio): On DragonFly BSD, NetBSD and OpenBSD, the
+// BUG(mikio): On DragonFly BSD, NetBSD, OpenBSD and Solaris, the
 // MulticastAddrs method of Interface is not implemented.
 
 var (
@@ -117,6 +117,10 @@ func InterfaceAddrs() ([]Addr, error) {
 }
 
 // InterfaceByIndex returns the interface specified by index.
+//
+// On Solaris, it returns one of the logical network interfaces
+// sharing the logical data link; for more precision use
+// InterfaceByName.
 func InterfaceByIndex(index int) (*Interface, error) {
        if index <= 0 {
                return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterfaceIndex}
diff --git a/src/net/interface_solaris.go b/src/net/interface_solaris.go
new file mode 100644 (file)
index 0000000..dc8ffbf
--- /dev/null
@@ -0,0 +1,107 @@
+// Copyright 2016 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 net
+
+import (
+       "syscall"
+
+       "golang_org/x/net/lif"
+)
+
+// If the ifindex is zero, interfaceTable returns mappings of all
+// network interfaces. Otherwise it returns a mapping of a specific
+// interface.
+func interfaceTable(ifindex int) ([]Interface, error) {
+       lls, err := lif.Links(syscall.AF_UNSPEC, "")
+       if err != nil {
+               return nil, err
+       }
+       var ift []Interface
+       for _, ll := range lls {
+               if ifindex != 0 && ifindex != ll.Index {
+                       continue
+               }
+               ifi := Interface{Index: ll.Index, MTU: ll.MTU, Name: ll.Name, Flags: linkFlags(ll.Flags)}
+               if len(ll.Addr) > 0 {
+                       ifi.HardwareAddr = HardwareAddr(ll.Addr)
+               }
+               ift = append(ift, ifi)
+       }
+       return ift, nil
+}
+
+const (
+       sysIFF_UP          = 0x1
+       sysIFF_BROADCAST   = 0x2
+       sysIFF_DEBUG       = 0x4
+       sysIFF_LOOPBACK    = 0x8
+       sysIFF_POINTOPOINT = 0x10
+       sysIFF_NOTRAILERS  = 0x20
+       sysIFF_RUNNING     = 0x40
+       sysIFF_NOARP       = 0x80
+       sysIFF_PROMISC     = 0x100
+       sysIFF_ALLMULTI    = 0x200
+       sysIFF_INTELLIGENT = 0x400
+       sysIFF_MULTICAST   = 0x800
+       sysIFF_MULTI_BCAST = 0x1000
+       sysIFF_UNNUMBERED  = 0x2000
+       sysIFF_PRIVATE     = 0x8000
+)
+
+func linkFlags(rawFlags int) Flags {
+       var f Flags
+       if rawFlags&sysIFF_UP != 0 {
+               f |= FlagUp
+       }
+       if rawFlags&sysIFF_BROADCAST != 0 {
+               f |= FlagBroadcast
+       }
+       if rawFlags&sysIFF_LOOPBACK != 0 {
+               f |= FlagLoopback
+       }
+       if rawFlags&sysIFF_POINTOPOINT != 0 {
+               f |= FlagPointToPoint
+       }
+       if rawFlags&sysIFF_MULTICAST != 0 {
+               f |= FlagMulticast
+       }
+       return f
+}
+
+// If the ifi is nil, interfaceAddrTable returns addresses for all
+// network interfaces. Otherwise it returns addresses for a specific
+// interface.
+func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
+       var name string
+       if ifi != nil {
+               name = ifi.Name
+       }
+       as, err := lif.Addrs(syscall.AF_UNSPEC, name)
+       if err != nil {
+               return nil, err
+       }
+       var ifat []Addr
+       for _, a := range as {
+               var ip IP
+               var mask IPMask
+               switch a := a.(type) {
+               case *lif.Inet4Addr:
+                       ip = IPv4(a.IP[0], a.IP[1], a.IP[2], a.IP[3])
+                       mask = CIDRMask(a.PrefixLen, 8*IPv4len)
+               case *lif.Inet6Addr:
+                       ip = make(IP, IPv6len)
+                       copy(ip, a.IP[:])
+                       mask = CIDRMask(a.PrefixLen, 8*IPv6len)
+               }
+               ifat = append(ifat, &IPNet{IP: ip, Mask: mask})
+       }
+       return ifat, nil
+}
+
+// interfaceMulticastAddrTable returns addresses for a specific
+// interface.
+func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
+       return nil, nil
+}
index f64174c62eef3c4697b24fa90ccfa541523014c5..a4eff5329838935848bd8c914b3a8ad3b439d95b 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build nacl plan9 solaris
+// +build nacl plan9
 
 package net
 
index 4c695b902a226cea819f8c4687829bf93a471075..38a2ca46565d61cd9edf7eda3ebdeaa92b200a40 100644 (file)
@@ -58,8 +58,15 @@ func TestInterfaces(t *testing.T) {
                if err != nil {
                        t.Fatal(err)
                }
-               if !reflect.DeepEqual(ifxi, &ifi) {
-                       t.Errorf("got %v; want %v", ifxi, ifi)
+               switch runtime.GOOS {
+               case "solaris":
+                       if ifxi.Index != ifi.Index {
+                               t.Errorf("got %v; want %v", ifxi, ifi)
+                       }
+               default:
+                       if !reflect.DeepEqual(ifxi, &ifi) {
+                               t.Errorf("got %v; want %v", ifxi, ifi)
+                       }
                }
                ifxn, err := InterfaceByName(ifi.Name)
                if err != nil {