X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=libgo%2Fgo%2Fnet%2Finterface_linux.go;h=ce2e921e865f696837ed0468c06af3b25e1bbc6e;hp=3d2a0bb9f8a0a614142e871bd9cd653fb3fbd730;hb=a014f434de4832e6e680a58385acf5d9d03ba9fb;hpb=49b4e44b7d540fa846d353b10237848a67789cbf diff --git a/libgo/go/net/interface_linux.go b/libgo/go/net/interface_linux.go index 3d2a0bb9f8a..ce2e921e865 100644 --- a/libgo/go/net/interface_linux.go +++ b/libgo/go/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 { @@ -72,7 +64,7 @@ func newLink(attrs []syscall.NetlinkRouteAttr, ifim *syscall.IfInfomsg) Interfac case syscall.IFLA_IFNAME: ifi.Name = string(a.Value[:len(a.Value)-1]) case syscall.IFLA_MTU: - ifi.MTU = int(uint32(a.Value[3])<<24 | uint32(a.Value[2])<<16 | uint32(a.Value[1])<<8 | uint32(a.Value[0])) + ifi.MTU = int(*(*uint32)(unsafe.Pointer(&a.Value[:4][0]))) } } return ifi @@ -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,115 @@ 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) - ifma := IPAddr{IP: IPv4(b[3], b[2], b[1], b[0])} + // The Linux kernel puts the IP + // address in /proc/net/igmp in native + // endianness. + for i := 0; i+1 < len(f[0]); i += 2 { + b[i/2], _ = xtoi2(f[0][i:i+2], 0) + } + i := *(*uint32)(unsafe.Pointer(&b[:4][0])) + ifma := IPAddr{IP: IPv4(byte(i>>24), byte(i>>16), byte(i>>8), byte(i))} 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 }