summaryrefslogtreecommitdiff
path: root/libgo/go/net/interface_linux.go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2013-07-16 06:54:42 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2013-07-16 06:54:42 +0000
commitbe47d6eceffd2c5dbbc1566d5eea490527fb2bd4 (patch)
tree0e8fda573576bb4181dba29d0e88380a8c38fafd /libgo/go/net/interface_linux.go
parentefb30cdeb003fd7c585ee0d7657340086abcbd9e (diff)
libgo: Update to Go 1.1.1.
From-SVN: r200974
Diffstat (limited to 'libgo/go/net/interface_linux.go')
-rw-r--r--libgo/go/net/interface_linux.go95
1 files changed, 47 insertions, 48 deletions
diff --git a/libgo/go/net/interface_linux.go b/libgo/go/net/interface_linux.go
index ce2e921e865..1207c0f269d 100644
--- a/libgo/go/net/interface_linux.go
+++ b/libgo/go/net/interface_linux.go
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Network interface identification for Linux
-
package net
import (
@@ -20,17 +18,16 @@ func interfaceTable(ifindex int) ([]Interface, error) {
if err != nil {
return nil, os.NewSyscallError("netlink rib", err)
}
-
msgs, err := syscall.ParseNetlinkMessage(tab)
if err != nil {
return nil, os.NewSyscallError("netlink message", err)
}
-
var ift []Interface
+loop:
for _, m := range msgs {
switch m.Header.Type {
case syscall.NLMSG_DONE:
- goto done
+ break loop
case syscall.RTM_NEWLINK:
ifim := (*syscall.IfInfomsg)(unsafe.Pointer(&m.Data[0]))
if ifindex == 0 || ifindex == int(ifim.Index) {
@@ -38,17 +35,18 @@ func interfaceTable(ifindex int) ([]Interface, error) {
if err != nil {
return nil, os.NewSyscallError("netlink routeattr", err)
}
- ifi := newLink(ifim, attrs)
- ift = append(ift, ifi)
+ ift = append(ift, *newLink(ifim, attrs))
+ if ifindex == int(ifim.Index) {
+ break loop
+ }
}
}
}
-done:
return ift, nil
}
-func newLink(ifim *syscall.IfInfomsg, attrs []syscall.NetlinkRouteAttr) Interface {
- ifi := Interface{Index: int(ifim.Index), Flags: linkFlags(ifim.Flags)}
+func newLink(ifim *syscall.IfInfomsg, attrs []syscall.NetlinkRouteAttr) *Interface {
+ ifi := &Interface{Index: int(ifim.Index), Flags: linkFlags(ifim.Flags)}
for _, a := range attrs {
switch a.Attr.Type {
case syscall.IFLA_ADDRESS:
@@ -90,81 +88,84 @@ func linkFlags(rawFlags uint32) Flags {
return f
}
-// If the ifindex is zero, interfaceAddrTable returns addresses
-// for all network interfaces. Otherwise it returns addresses
-// for a specific interface.
-func interfaceAddrTable(ifindex int) ([]Addr, error) {
+// 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) {
tab, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC)
if err != nil {
return nil, os.NewSyscallError("netlink rib", err)
}
-
msgs, err := syscall.ParseNetlinkMessage(tab)
if err != nil {
return nil, os.NewSyscallError("netlink message", err)
}
-
- ifat, err := addrTable(msgs, ifindex)
+ var ift []Interface
+ if ifi == nil {
+ var err error
+ ift, err = interfaceTable(0)
+ if err != nil {
+ return nil, err
+ }
+ }
+ ifat, err := addrTable(ift, ifi, msgs)
if err != nil {
return nil, err
}
return ifat, nil
}
-func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]Addr, error) {
+func addrTable(ift []Interface, ifi *Interface, msgs []syscall.NetlinkMessage) ([]Addr, error) {
var ifat []Addr
+loop:
for _, m := range msgs {
switch m.Header.Type {
case syscall.NLMSG_DONE:
- goto done
+ break loop
case syscall.RTM_NEWADDR:
ifam := (*syscall.IfAddrmsg)(unsafe.Pointer(&m.Data[0]))
- if ifindex == 0 || ifindex == int(ifam.Index) {
+ if len(ift) != 0 || ifi.Index == int(ifam.Index) {
+ if len(ift) != 0 {
+ var err error
+ ifi, err = interfaceByIndex(ift, int(ifam.Index))
+ if err != nil {
+ return nil, err
+ }
+ }
attrs, err := syscall.ParseNetlinkRouteAttr(&m)
if err != nil {
return nil, os.NewSyscallError("netlink routeattr", err)
}
- ifat = append(ifat, newAddr(attrs, int(ifam.Family), int(ifam.Prefixlen)))
+ ifa := newAddr(ifi, ifam, attrs)
+ if ifa != nil {
+ ifat = append(ifat, ifa)
+ }
}
}
}
-done:
return ifat, nil
}
-func newAddr(attrs []syscall.NetlinkRouteAttr, family, pfxlen int) Addr {
- ifa := &IPNet{}
+func newAddr(ifi *Interface, ifam *syscall.IfAddrmsg, attrs []syscall.NetlinkRouteAttr) Addr {
for _, a := range attrs {
- switch a.Attr.Type {
- case syscall.IFA_ADDRESS:
- switch family {
+ if ifi.Flags&FlagPointToPoint != 0 && a.Attr.Type == syscall.IFA_LOCAL ||
+ ifi.Flags&FlagPointToPoint == 0 && a.Attr.Type == syscall.IFA_ADDRESS {
+ switch ifam.Family {
case syscall.AF_INET:
- ifa.IP = IPv4(a.Value[0], a.Value[1], a.Value[2], a.Value[3])
- ifa.Mask = CIDRMask(pfxlen, 8*IPv4len)
+ return &IPNet{IP: IPv4(a.Value[0], a.Value[1], a.Value[2], a.Value[3]), Mask: CIDRMask(int(ifam.Prefixlen), 8*IPv4len)}
case syscall.AF_INET6:
- ifa.IP = make(IP, IPv6len)
+ ifa := &IPNet{IP: make(IP, IPv6len), Mask: CIDRMask(int(ifam.Prefixlen), 8*IPv6len)}
copy(ifa.IP, a.Value[:])
- ifa.Mask = CIDRMask(pfxlen, 8*IPv6len)
+ return ifa
}
}
}
- return ifa
+ return nil
}
-// If the ifindex is zero, interfaceMulticastAddrTable returns
-// addresses for all network interfaces. Otherwise it returns
-// addresses for a specific interface.
-func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
- var (
- err error
- ifi *Interface
- )
- if ifindex > 0 {
- ifi, err = InterfaceByIndex(ifindex)
- if err != nil {
- return nil, err
- }
- }
+// interfaceMulticastAddrTable returns addresses for a specific
+// interface.
+func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
ifmat4 := parseProcNetIGMP("/proc/net/igmp", ifi)
ifmat6 := parseProcNetIGMP6("/proc/net/igmp6", ifi)
return append(ifmat4, ifmat6...), nil
@@ -176,7 +177,6 @@ func parseProcNetIGMP(path string, ifi *Interface) []Addr {
return nil
}
defer fd.close()
-
var (
ifmat []Addr
name string
@@ -214,7 +214,6 @@ func parseProcNetIGMP6(path string, ifi *Interface) []Addr {
return nil
}
defer fd.close()
-
var ifmat []Addr
b := make([]byte, IPv6len)
for l, ok := fd.readLine(); ok; l, ok = fd.readLine() {