1
0
mirror of https://github.com/golang/go synced 2024-11-12 10:00:25 -07:00

net: return correct point-to-point interface address on linux

On Linux point-to-point interface an IFA_ADDRESS attribute
represents a peer address. For a correct interface address
we should take an IFA_LOCAL attribute instead.

Fixes #4839.

R=golang-dev, dave, rsc
CC=golang-dev
https://golang.org/cl/7352045
This commit is contained in:
Mikio Hara 2013-02-20 07:31:44 +09:00
parent a17c46169f
commit e4890e57e1

View File

@ -119,12 +119,16 @@ func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]Addr, error) {
goto done
case syscall.RTM_NEWADDR:
ifam := (*syscall.IfAddrmsg)(unsafe.Pointer(&m.Data[0]))
ifi, err := InterfaceByIndex(int(ifam.Index))
if err != nil {
return nil, err
}
if ifindex == 0 || ifindex == int(ifam.Index) {
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)))
ifat = append(ifat, newAddr(attrs, ifi, ifam))
}
}
}
@ -132,19 +136,19 @@ done:
return ifat, nil
}
func newAddr(attrs []syscall.NetlinkRouteAttr, family, pfxlen int) Addr {
func newAddr(attrs []syscall.NetlinkRouteAttr, ifi *Interface, ifam *syscall.IfAddrmsg) Addr {
ifa := &IPNet{}
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)
ifa.Mask = CIDRMask(int(ifam.Prefixlen), 8*IPv4len)
case syscall.AF_INET6:
ifa.IP = make(IP, IPv6len)
copy(ifa.IP, a.Value[:])
ifa.Mask = CIDRMask(pfxlen, 8*IPv6len)
ifa.Mask = CIDRMask(int(ifam.Prefixlen), 8*IPv6len)
}
}
}