Commit 456cf0f2 authored by Mikio Hara's avatar Mikio Hara

net: fix inconsistent error values on Interface

This change fixes inconsistent error values on Interfaces,
InterfaceAddrs, InterfaceBy{Index,Name}, and Addrs and MulticastAddrs
methods of Interface.

Updates #4856.

Change-Id: I09e65522a22f45c641792d774ebf7a0081b874ad
Reviewed-on: https://go-review.googlesource.com/9140Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent 2173a279
...@@ -62,41 +62,61 @@ func (f Flags) String() string { ...@@ -62,41 +62,61 @@ func (f Flags) String() string {
// Addrs returns interface addresses for a specific interface. // Addrs returns interface addresses for a specific interface.
func (ifi *Interface) Addrs() ([]Addr, error) { func (ifi *Interface) Addrs() ([]Addr, error) {
if ifi == nil { if ifi == nil {
return nil, errInvalidInterface return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: errInvalidInterface}
} }
return interfaceAddrTable(ifi) ifat, err := interfaceAddrTable(ifi)
if err != nil {
err = &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err}
}
return ifat, err
} }
// MulticastAddrs returns multicast, joined group addresses for // MulticastAddrs returns multicast, joined group addresses for
// a specific interface. // a specific interface.
func (ifi *Interface) MulticastAddrs() ([]Addr, error) { func (ifi *Interface) MulticastAddrs() ([]Addr, error) {
if ifi == nil { if ifi == nil {
return nil, errInvalidInterface return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: errInvalidInterface}
}
ifat, err := interfaceMulticastAddrTable(ifi)
if err != nil {
err = &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err}
} }
return interfaceMulticastAddrTable(ifi) return ifat, err
} }
// Interfaces returns a list of the system's network interfaces. // Interfaces returns a list of the system's network interfaces.
func Interfaces() ([]Interface, error) { func Interfaces() ([]Interface, error) {
return interfaceTable(0) ift, err := interfaceTable(0)
if err != nil {
err = &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err}
}
return ift, err
} }
// InterfaceAddrs returns a list of the system's network interface // InterfaceAddrs returns a list of the system's network interface
// addresses. // addresses.
func InterfaceAddrs() ([]Addr, error) { func InterfaceAddrs() ([]Addr, error) {
return interfaceAddrTable(nil) ifat, err := interfaceAddrTable(nil)
if err != nil {
err = &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err}
}
return ifat, err
} }
// InterfaceByIndex returns the interface specified by index. // InterfaceByIndex returns the interface specified by index.
func InterfaceByIndex(index int) (*Interface, error) { func InterfaceByIndex(index int) (*Interface, error) {
if index <= 0 { if index <= 0 {
return nil, errInvalidInterfaceIndex return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: errInvalidInterfaceIndex}
} }
ift, err := interfaceTable(index) ift, err := interfaceTable(index)
if err != nil { if err != nil {
return nil, err return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err}
} }
return interfaceByIndex(ift, index) ifi, err := interfaceByIndex(ift, index)
if err != nil {
err = &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err}
}
return ifi, err
} }
func interfaceByIndex(ift []Interface, index int) (*Interface, error) { func interfaceByIndex(ift []Interface, index int) (*Interface, error) {
...@@ -111,16 +131,16 @@ func interfaceByIndex(ift []Interface, index int) (*Interface, error) { ...@@ -111,16 +131,16 @@ func interfaceByIndex(ift []Interface, index int) (*Interface, error) {
// InterfaceByName returns the interface specified by name. // InterfaceByName returns the interface specified by name.
func InterfaceByName(name string) (*Interface, error) { func InterfaceByName(name string) (*Interface, error) {
if name == "" { if name == "" {
return nil, errInvalidInterfaceName return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: errInvalidInterfaceName}
} }
ift, err := interfaceTable(0) ift, err := interfaceTable(0)
if err != nil { if err != nil {
return nil, err return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err}
} }
for _, ifi := range ift { for _, ifi := range ift {
if name == ifi.Name { if name == ifi.Name {
return &ifi, nil return &ifi, nil
} }
} }
return nil, errNoSuchInterface return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: errNoSuchInterface}
} }
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
package net package net
import ( import (
"os"
"syscall" "syscall"
"unsafe" "unsafe"
) )
...@@ -18,11 +17,11 @@ import ( ...@@ -18,11 +17,11 @@ import (
func interfaceTable(ifindex int) ([]Interface, error) { func interfaceTable(ifindex int) ([]Interface, error) {
tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex) tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex)
if err != nil { if err != nil {
return nil, os.NewSyscallError("route rib", err) return nil, err
} }
msgs, err := syscall.ParseRoutingMessage(tab) msgs, err := syscall.ParseRoutingMessage(tab)
if err != nil { if err != nil {
return nil, os.NewSyscallError("route message", err) return nil, err
} }
return parseInterfaceTable(ifindex, msgs) return parseInterfaceTable(ifindex, msgs)
} }
...@@ -51,7 +50,7 @@ loop: ...@@ -51,7 +50,7 @@ loop:
func newLink(m *syscall.InterfaceMessage) (*Interface, error) { func newLink(m *syscall.InterfaceMessage) (*Interface, error) {
sas, err := syscall.ParseRoutingSockaddr(m) sas, err := syscall.ParseRoutingSockaddr(m)
if err != nil { if err != nil {
return nil, os.NewSyscallError("route sockaddr", err) return nil, err
} }
ifi := &Interface{Index: int(m.Header.Index), Flags: linkFlags(m.Header.Flags)} ifi := &Interface{Index: int(m.Header.Index), Flags: linkFlags(m.Header.Flags)}
sa, _ := sas[syscall.RTAX_IFP].(*syscall.SockaddrDatalink) sa, _ := sas[syscall.RTAX_IFP].(*syscall.SockaddrDatalink)
...@@ -104,11 +103,11 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) { ...@@ -104,11 +103,11 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
} }
tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, index) tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, index)
if err != nil { if err != nil {
return nil, os.NewSyscallError("route rib", err) return nil, err
} }
msgs, err := syscall.ParseRoutingMessage(tab) msgs, err := syscall.ParseRoutingMessage(tab)
if err != nil { if err != nil {
return nil, os.NewSyscallError("route message", err) return nil, err
} }
var ift []Interface var ift []Interface
if index == 0 { if index == 0 {
...@@ -145,7 +144,7 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) { ...@@ -145,7 +144,7 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
func newAddr(ifi *Interface, m *syscall.InterfaceAddrMessage) (*IPNet, error) { func newAddr(ifi *Interface, m *syscall.InterfaceAddrMessage) (*IPNet, error) {
sas, err := syscall.ParseRoutingSockaddr(m) sas, err := syscall.ParseRoutingSockaddr(m)
if err != nil { if err != nil {
return nil, os.NewSyscallError("route sockaddr", err) return nil, err
} }
ifa := &IPNet{} ifa := &IPNet{}
switch sa := sas[syscall.RTAX_NETMASK].(type) { switch sa := sas[syscall.RTAX_NETMASK].(type) {
......
...@@ -4,21 +4,18 @@ ...@@ -4,21 +4,18 @@
package net package net
import ( import "syscall"
"os"
"syscall"
)
// interfaceMulticastAddrTable returns addresses for a specific // interfaceMulticastAddrTable returns addresses for a specific
// interface. // interface.
func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) { func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST2, ifi.Index) tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST2, ifi.Index)
if err != nil { if err != nil {
return nil, os.NewSyscallError("route rib", err) return nil, err
} }
msgs, err := syscall.ParseRoutingMessage(tab) msgs, err := syscall.ParseRoutingMessage(tab)
if err != nil { if err != nil {
return nil, os.NewSyscallError("route message", err) return nil, err
} }
var ifmat []Addr var ifmat []Addr
for _, m := range msgs { for _, m := range msgs {
...@@ -41,7 +38,7 @@ func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) { ...@@ -41,7 +38,7 @@ func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) (*IPAddr, error) { func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) (*IPAddr, error) {
sas, err := syscall.ParseRoutingSockaddr(m) sas, err := syscall.ParseRoutingSockaddr(m)
if err != nil { if err != nil {
return nil, os.NewSyscallError("route sockaddr", err) return nil, err
} }
switch sa := sas[syscall.RTAX_IFA].(type) { switch sa := sas[syscall.RTAX_IFA].(type) {
case *syscall.SockaddrInet4: case *syscall.SockaddrInet4:
......
...@@ -4,21 +4,18 @@ ...@@ -4,21 +4,18 @@
package net package net
import ( import "syscall"
"os"
"syscall"
)
// interfaceMulticastAddrTable returns addresses for a specific // interfaceMulticastAddrTable returns addresses for a specific
// interface. // interface.
func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) { func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
tab, err := syscall.RouteRIB(syscall.NET_RT_IFMALIST, ifi.Index) tab, err := syscall.RouteRIB(syscall.NET_RT_IFMALIST, ifi.Index)
if err != nil { if err != nil {
return nil, os.NewSyscallError("route rib", err) return nil, err
} }
msgs, err := syscall.ParseRoutingMessage(tab) msgs, err := syscall.ParseRoutingMessage(tab)
if err != nil { if err != nil {
return nil, os.NewSyscallError("route message", err) return nil, err
} }
var ifmat []Addr var ifmat []Addr
for _, m := range msgs { for _, m := range msgs {
...@@ -41,7 +38,7 @@ func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) { ...@@ -41,7 +38,7 @@ func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) (*IPAddr, error) { func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) (*IPAddr, error) {
sas, err := syscall.ParseRoutingSockaddr(m) sas, err := syscall.ParseRoutingSockaddr(m)
if err != nil { if err != nil {
return nil, os.NewSyscallError("route sockaddr", err) return nil, err
} }
switch sa := sas[syscall.RTAX_IFA].(type) { switch sa := sas[syscall.RTAX_IFA].(type) {
case *syscall.SockaddrInet4: case *syscall.SockaddrInet4:
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
package net package net
import ( import (
"os"
"syscall" "syscall"
"unsafe" "unsafe"
) )
...@@ -16,11 +15,11 @@ import ( ...@@ -16,11 +15,11 @@ import (
func interfaceTable(ifindex int) ([]Interface, error) { func interfaceTable(ifindex int) ([]Interface, error) {
tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC) tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
if err != nil { if err != nil {
return nil, os.NewSyscallError("netlink rib", err) return nil, err
} }
msgs, err := syscall.ParseNetlinkMessage(tab) msgs, err := syscall.ParseNetlinkMessage(tab)
if err != nil { if err != nil {
return nil, os.NewSyscallError("netlink message", err) return nil, err
} }
var ift []Interface var ift []Interface
loop: loop:
...@@ -33,7 +32,7 @@ loop: ...@@ -33,7 +32,7 @@ loop:
if ifindex == 0 || ifindex == int(ifim.Index) { if ifindex == 0 || ifindex == int(ifim.Index) {
attrs, err := syscall.ParseNetlinkRouteAttr(&m) attrs, err := syscall.ParseNetlinkRouteAttr(&m)
if err != nil { if err != nil {
return nil, os.NewSyscallError("netlink routeattr", err) return nil, err
} }
ift = append(ift, *newLink(ifim, attrs)) ift = append(ift, *newLink(ifim, attrs))
if ifindex == int(ifim.Index) { if ifindex == int(ifim.Index) {
...@@ -120,11 +119,11 @@ func linkFlags(rawFlags uint32) Flags { ...@@ -120,11 +119,11 @@ func linkFlags(rawFlags uint32) Flags {
func interfaceAddrTable(ifi *Interface) ([]Addr, error) { func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
tab, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC) tab, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC)
if err != nil { if err != nil {
return nil, os.NewSyscallError("netlink rib", err) return nil, err
} }
msgs, err := syscall.ParseNetlinkMessage(tab) msgs, err := syscall.ParseNetlinkMessage(tab)
if err != nil { if err != nil {
return nil, os.NewSyscallError("netlink message", err) return nil, err
} }
var ift []Interface var ift []Interface
if ifi == nil { if ifi == nil {
...@@ -160,7 +159,7 @@ loop: ...@@ -160,7 +159,7 @@ loop:
} }
attrs, err := syscall.ParseNetlinkRouteAttr(&m) attrs, err := syscall.ParseNetlinkRouteAttr(&m)
if err != nil { if err != nil {
return nil, os.NewSyscallError("netlink routeattr", err) return nil, err
} }
ifa := newAddr(ifi, ifam, attrs) ifa := newAddr(ifi, ifam, attrs)
if ifa != nil { if ifa != nil {
......
...@@ -6,7 +6,6 @@ package net ...@@ -6,7 +6,6 @@ package net
import ( import (
"internal/syscall/windows" "internal/syscall/windows"
"os"
"syscall" "syscall"
"unsafe" "unsafe"
) )
...@@ -27,7 +26,7 @@ func getAdapters() (*windows.IpAdapterAddresses, error) { ...@@ -27,7 +26,7 @@ func getAdapters() (*windows.IpAdapterAddresses, error) {
break break
} }
if err.(syscall.Errno) != syscall.ERROR_BUFFER_OVERFLOW { if err.(syscall.Errno) != syscall.ERROR_BUFFER_OVERFLOW {
return nil, os.NewSyscallError("GetAdaptersAddresses", err) return nil, err
} }
} }
return &addrs[0], nil return &addrs[0], nil
...@@ -36,16 +35,16 @@ func getAdapters() (*windows.IpAdapterAddresses, error) { ...@@ -36,16 +35,16 @@ func getAdapters() (*windows.IpAdapterAddresses, error) {
func getInterfaceInfos() ([]syscall.InterfaceInfo, error) { func getInterfaceInfos() ([]syscall.InterfaceInfo, error) {
s, err := sysSocket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP) s, err := sysSocket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
if err != nil { if err != nil {
return nil, os.NewSyscallError("Socket", err) return nil, err
} }
defer syscall.Closesocket(s) defer closeFunc(s)
iia := [20]syscall.InterfaceInfo{} iia := [20]syscall.InterfaceInfo{}
ret := uint32(0) ret := uint32(0)
size := uint32(unsafe.Sizeof(iia)) size := uint32(unsafe.Sizeof(iia))
err = syscall.WSAIoctl(s, syscall.SIO_GET_INTERFACE_LIST, nil, 0, (*byte)(unsafe.Pointer(&iia[0])), size, &ret, nil, 0) err = syscall.WSAIoctl(s, syscall.SIO_GET_INTERFACE_LIST, nil, 0, (*byte)(unsafe.Pointer(&iia[0])), size, &ret, nil, 0)
if err != nil { if err != nil {
return nil, os.NewSyscallError("WSAIoctl", err) return nil, err
} }
iilen := ret / uint32(unsafe.Sizeof(iia[0])) iilen := ret / uint32(unsafe.Sizeof(iia[0]))
return iia[:iilen-1], nil return iia[:iilen-1], nil
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment