summaryrefslogtreecommitdiff
path: root/src/pkg/net/interface_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/net/interface_linux.go')
-rw-r--r--src/pkg/net/interface_linux.go164
1 files changed, 66 insertions, 98 deletions
diff --git a/src/pkg/net/interface_linux.go b/src/pkg/net/interface_linux.go
index 3d2a0bb9f..825b20227 100644
--- a/src/pkg/net/interface_linux.go
+++ b/src/pkg/net/interface_linux.go
@@ -7,33 +7,26 @@
package net
import (
- "fmt"
"os"
"syscall"
"unsafe"
)
// If the ifindex is zero, interfaceTable returns mappings of all
-// network interfaces. Otheriwse it returns a mapping of a specific
+// network interfaces. Otherwise it returns a mapping of a specific
// interface.
-func interfaceTable(ifindex int) ([]Interface, os.Error) {
- var (
- ift []Interface
- tab []byte
- msgs []syscall.NetlinkMessage
- e int
- )
-
- tab, e = syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
- if e != 0 {
- return nil, os.NewSyscallError("netlink rib", e)
+func interfaceTable(ifindex int) ([]Interface, error) {
+ tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
+ if err != nil {
+ return nil, os.NewSyscallError("netlink rib", err)
}
- msgs, e = syscall.ParseNetlinkMessage(tab)
- if e != 0 {
- return nil, os.NewSyscallError("netlink message", e)
+ msgs, err := syscall.ParseNetlinkMessage(tab)
+ if err != nil {
+ return nil, os.NewSyscallError("netlink message", err)
}
+ var ift []Interface
for _, m := range msgs {
switch m.Header.Type {
case syscall.NLMSG_DONE:
@@ -41,21 +34,20 @@ func interfaceTable(ifindex int) ([]Interface, os.Error) {
case syscall.RTM_NEWLINK:
ifim := (*syscall.IfInfomsg)(unsafe.Pointer(&m.Data[0]))
if ifindex == 0 || ifindex == int(ifim.Index) {
- attrs, e := syscall.ParseNetlinkRouteAttr(&m)
- if e != 0 {
- return nil, os.NewSyscallError("netlink routeattr", e)
+ attrs, err := syscall.ParseNetlinkRouteAttr(&m)
+ if err != nil {
+ return nil, os.NewSyscallError("netlink routeattr", err)
}
- ifi := newLink(attrs, ifim)
+ ifi := newLink(ifim, attrs)
ift = append(ift, ifi)
}
}
}
-
done:
return ift, nil
}
-func newLink(attrs []syscall.NetlinkRouteAttr, ifim *syscall.IfInfomsg) Interface {
+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 {
@@ -101,49 +93,26 @@ func linkFlags(rawFlags uint32) Flags {
// 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, os.Error) {
- var (
- tab []byte
- e int
- err os.Error
- ifat4 []Addr
- ifat6 []Addr
- msgs4 []syscall.NetlinkMessage
- msgs6 []syscall.NetlinkMessage
- )
-
- tab, e = syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_INET)
- if e != 0 {
- return nil, os.NewSyscallError("netlink rib", e)
- }
- msgs4, e = syscall.ParseNetlinkMessage(tab)
- if e != 0 {
- return nil, os.NewSyscallError("netlink message", e)
- }
- ifat4, err = addrTable(msgs4, ifindex)
+func interfaceAddrTable(ifindex int) ([]Addr, error) {
+ tab, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC)
if err != nil {
- return nil, err
+ return nil, os.NewSyscallError("netlink rib", err)
}
- tab, e = syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_INET6)
- if e != 0 {
- return nil, os.NewSyscallError("netlink rib", e)
- }
- msgs6, e = syscall.ParseNetlinkMessage(tab)
- if e != 0 {
- return nil, os.NewSyscallError("netlink message", e)
+ msgs, err := syscall.ParseNetlinkMessage(tab)
+ if err != nil {
+ return nil, os.NewSyscallError("netlink message", err)
}
- ifat6, err = addrTable(msgs6, ifindex)
+
+ ifat, err := addrTable(msgs, ifindex)
if err != nil {
return nil, err
}
-
- return append(ifat4, ifat6...), nil
+ return ifat, nil
}
-func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]Addr, os.Error) {
+func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]Addr, error) {
var ifat []Addr
-
for _, m := range msgs {
switch m.Header.Type {
case syscall.NLMSG_DONE:
@@ -151,112 +120,111 @@ func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]Addr, os.Error) {
case syscall.RTM_NEWADDR:
ifam := (*syscall.IfAddrmsg)(unsafe.Pointer(&m.Data[0]))
if ifindex == 0 || ifindex == int(ifam.Index) {
- attrs, e := syscall.ParseNetlinkRouteAttr(&m)
- if e != 0 {
- return nil, os.NewSyscallError("netlink routeattr", e)
+ attrs, err := syscall.ParseNetlinkRouteAttr(&m)
+ if err != nil {
+ return nil, os.NewSyscallError("netlink routeattr", err)
}
- ifat = append(ifat, newAddr(attrs, int(ifam.Family))...)
+ ifat = append(ifat, newAddr(attrs, int(ifam.Family), int(ifam.Prefixlen)))
}
}
}
-
done:
return ifat, nil
}
-func newAddr(attrs []syscall.NetlinkRouteAttr, family int) []Addr {
- var ifat []Addr
-
+func newAddr(attrs []syscall.NetlinkRouteAttr, family, pfxlen int) Addr {
+ ifa := &IPNet{}
for _, a := range attrs {
switch a.Attr.Type {
case syscall.IFA_ADDRESS:
switch family {
case syscall.AF_INET:
- ifa := &IPAddr{IP: IPv4(a.Value[0], a.Value[1], a.Value[2], a.Value[3])}
- ifat = append(ifat, ifa.toAddr())
+ ifa.IP = IPv4(a.Value[0], a.Value[1], a.Value[2], a.Value[3])
+ ifa.Mask = CIDRMask(pfxlen, 8*IPv4len)
case syscall.AF_INET6:
- ifa := &IPAddr{IP: make(IP, IPv6len)}
+ ifa.IP = make(IP, IPv6len)
copy(ifa.IP, a.Value[:])
- ifat = append(ifat, ifa.toAddr())
+ ifa.Mask = CIDRMask(pfxlen, 8*IPv6len)
}
}
}
-
- return ifat
+ return ifa
}
// 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, os.Error) {
+func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
var (
+ err error
ifi *Interface
- err os.Error
)
-
if ifindex > 0 {
ifi, err = InterfaceByIndex(ifindex)
if err != nil {
return nil, err
}
}
-
- ifmat4 := parseProcNetIGMP(ifi)
- ifmat6 := parseProcNetIGMP6(ifi)
-
+ ifmat4 := parseProcNetIGMP("/proc/net/igmp", ifi)
+ ifmat6 := parseProcNetIGMP6("/proc/net/igmp6", ifi)
return append(ifmat4, ifmat6...), nil
}
-func parseProcNetIGMP(ifi *Interface) []Addr {
- var (
- ifmat []Addr
- name string
- )
-
- fd, err := open("/proc/net/igmp")
+func parseProcNetIGMP(path string, ifi *Interface) []Addr {
+ fd, err := open(path)
if err != nil {
return nil
}
defer fd.close()
+ var (
+ ifmat []Addr
+ name string
+ )
fd.readLine() // skip first line
b := make([]byte, IPv4len)
for l, ok := fd.readLine(); ok; l, ok = fd.readLine() {
- f := getFields(l)
- switch len(f) {
- case 4:
+ f := splitAtBytes(l, " :\r\t\n")
+ if len(f) < 4 {
+ continue
+ }
+ switch {
+ case l[0] != ' ' && l[0] != '\t': // new interface line
+ name = f[1]
+ case len(f[0]) == 8:
if ifi == nil || name == ifi.Name {
- fmt.Sscanf(f[0], "%08x", &b)
+ for i := 0; i+1 < len(f[0]); i += 2 {
+ b[i/2], _ = xtoi2(f[0][i:i+2], 0)
+ }
ifma := IPAddr{IP: IPv4(b[3], b[2], b[1], b[0])}
ifmat = append(ifmat, ifma.toAddr())
}
- case 5:
- name = f[1]
}
}
-
return ifmat
}
-func parseProcNetIGMP6(ifi *Interface) []Addr {
- var ifmat []Addr
-
- fd, err := open("/proc/net/igmp6")
+func parseProcNetIGMP6(path string, ifi *Interface) []Addr {
+ fd, err := open(path)
if err != nil {
return nil
}
defer fd.close()
+ var ifmat []Addr
b := make([]byte, IPv6len)
for l, ok := fd.readLine(); ok; l, ok = fd.readLine() {
- f := getFields(l)
+ f := splitAtBytes(l, " \r\t\n")
+ if len(f) < 6 {
+ continue
+ }
if ifi == nil || f[1] == ifi.Name {
- fmt.Sscanf(f[2], "%32x", &b)
+ for i := 0; i+1 < len(f[2]); i += 2 {
+ b[i/2], _ = xtoi2(f[2][i:i+2], 0)
+ }
ifma := IPAddr{IP: IP{b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]}}
ifmat = append(ifmat, ifma.toAddr())
-
}
}
-
return ifmat
}