mirror of https://github.com/golang/go.git
net: set up IPv6 scoped addressing zone for network facilities
This CL changes nothing to existing API behavior, just sets up Zone in IPNet and IPAddr structures if possible. Also does small simplification. Update #4234. R=rsc, dave CC=golang-dev https://golang.org/cl/7300081
This commit is contained in:
parent
e4890e57e1
commit
40c2fbf4f2
|
|
@ -22,18 +22,16 @@ func interfaceTable(ifindex int) ([]Interface, error) {
|
|||
if err != nil {
|
||||
return nil, os.NewSyscallError("route rib", err)
|
||||
}
|
||||
|
||||
msgs, err := syscall.ParseRoutingMessage(tab)
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("route message", err)
|
||||
}
|
||||
|
||||
var ift []Interface
|
||||
for _, m := range msgs {
|
||||
switch v := m.(type) {
|
||||
switch m := m.(type) {
|
||||
case *syscall.InterfaceMessage:
|
||||
if ifindex == 0 || ifindex == int(v.Header.Index) {
|
||||
ifi, err := newLink(v)
|
||||
if ifindex == 0 || ifindex == int(m.Header.Index) {
|
||||
ifi, err := newLink(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -49,26 +47,25 @@ func newLink(m *syscall.InterfaceMessage) ([]Interface, error) {
|
|||
if err != nil {
|
||||
return nil, os.NewSyscallError("route sockaddr", err)
|
||||
}
|
||||
|
||||
var ift []Interface
|
||||
for _, s := range sas {
|
||||
switch v := s.(type) {
|
||||
for _, sa := range sas {
|
||||
switch sa := sa.(type) {
|
||||
case *syscall.SockaddrDatalink:
|
||||
// NOTE: SockaddrDatalink.Data is minimum work area,
|
||||
// can be larger.
|
||||
m.Data = m.Data[unsafe.Offsetof(v.Data):]
|
||||
m.Data = m.Data[unsafe.Offsetof(sa.Data):]
|
||||
ifi := Interface{Index: int(m.Header.Index), Flags: linkFlags(m.Header.Flags)}
|
||||
var name [syscall.IFNAMSIZ]byte
|
||||
for i := 0; i < int(v.Nlen); i++ {
|
||||
for i := 0; i < int(sa.Nlen); i++ {
|
||||
name[i] = byte(m.Data[i])
|
||||
}
|
||||
ifi.Name = string(name[:v.Nlen])
|
||||
ifi.Name = string(name[:sa.Nlen])
|
||||
ifi.MTU = int(m.Header.Data.Mtu)
|
||||
addr := make([]byte, v.Alen)
|
||||
for i := 0; i < int(v.Alen); i++ {
|
||||
addr[i] = byte(m.Data[int(v.Nlen)+i])
|
||||
addr := make([]byte, sa.Alen)
|
||||
for i := 0; i < int(sa.Alen); i++ {
|
||||
addr[i] = byte(m.Data[int(sa.Nlen)+i])
|
||||
}
|
||||
ifi.HardwareAddr = addr[:v.Alen]
|
||||
ifi.HardwareAddr = addr[:sa.Alen]
|
||||
ift = append(ift, ifi)
|
||||
}
|
||||
}
|
||||
|
|
@ -103,18 +100,16 @@ func interfaceAddrTable(ifindex int) ([]Addr, error) {
|
|||
if err != nil {
|
||||
return nil, os.NewSyscallError("route rib", err)
|
||||
}
|
||||
|
||||
msgs, err := syscall.ParseRoutingMessage(tab)
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("route message", err)
|
||||
}
|
||||
|
||||
var ifat []Addr
|
||||
for _, m := range msgs {
|
||||
switch v := m.(type) {
|
||||
switch m := m.(type) {
|
||||
case *syscall.InterfaceAddrMessage:
|
||||
if ifindex == 0 || ifindex == int(v.Header.Index) {
|
||||
ifa, err := newAddr(v)
|
||||
if ifindex == 0 || ifindex == int(m.Header.Index) {
|
||||
ifa, err := newAddr(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -132,30 +127,29 @@ func newAddr(m *syscall.InterfaceAddrMessage) (Addr, error) {
|
|||
if err != nil {
|
||||
return nil, os.NewSyscallError("route sockaddr", err)
|
||||
}
|
||||
|
||||
ifa := &IPNet{}
|
||||
for i, s := range sas {
|
||||
switch v := s.(type) {
|
||||
for i, sa := range sas {
|
||||
switch sa := sa.(type) {
|
||||
case *syscall.SockaddrInet4:
|
||||
switch i {
|
||||
case 0:
|
||||
ifa.Mask = IPv4Mask(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])
|
||||
ifa.Mask = IPv4Mask(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
|
||||
case 1:
|
||||
ifa.IP = IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])
|
||||
ifa.IP = IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
|
||||
}
|
||||
case *syscall.SockaddrInet6:
|
||||
switch i {
|
||||
case 0:
|
||||
ifa.Mask = make(IPMask, IPv6len)
|
||||
copy(ifa.Mask, v.Addr[:])
|
||||
copy(ifa.Mask, sa.Addr[:])
|
||||
case 1:
|
||||
ifa.IP = make(IP, IPv6len)
|
||||
copy(ifa.IP, v.Addr[:])
|
||||
copy(ifa.IP, sa.Addr[:])
|
||||
// NOTE: KAME based IPv6 protcol stack usually embeds
|
||||
// the interface index in the interface-local or link-
|
||||
// local address as the kernel-internal form.
|
||||
if ifa.IP.IsLinkLocalUnicast() {
|
||||
// remove embedded scope zone ID
|
||||
ifa.Zone = zoneToString(int(ifa.IP[2]<<8 | ifa.IP[3]))
|
||||
ifa.IP[2], ifa.IP[3] = 0, 0
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,18 +19,16 @@ func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
|
|||
if err != nil {
|
||||
return nil, os.NewSyscallError("route rib", err)
|
||||
}
|
||||
|
||||
msgs, err := syscall.ParseRoutingMessage(tab)
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("route message", err)
|
||||
}
|
||||
|
||||
var ifmat []Addr
|
||||
for _, m := range msgs {
|
||||
switch v := m.(type) {
|
||||
switch m := m.(type) {
|
||||
case *syscall.InterfaceMulticastAddrMessage:
|
||||
if ifindex == 0 || ifindex == int(v.Header.Index) {
|
||||
ifma, err := newMulticastAddr(v)
|
||||
if ifindex == 0 || ifindex == int(m.Header.Index) {
|
||||
ifma, err := newMulticastAddr(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -46,22 +44,20 @@ func newMulticastAddr(m *syscall.InterfaceMulticastAddrMessage) ([]Addr, error)
|
|||
if err != nil {
|
||||
return nil, os.NewSyscallError("route sockaddr", err)
|
||||
}
|
||||
|
||||
var ifmat []Addr
|
||||
for _, s := range sas {
|
||||
switch v := s.(type) {
|
||||
for _, sa := range sas {
|
||||
switch sa := sa.(type) {
|
||||
case *syscall.SockaddrInet4:
|
||||
ifma := &IPAddr{IP: IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])}
|
||||
ifma := &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}
|
||||
ifmat = append(ifmat, ifma.toAddr())
|
||||
case *syscall.SockaddrInet6:
|
||||
ifma := &IPAddr{IP: make(IP, IPv6len)}
|
||||
copy(ifma.IP, v.Addr[:])
|
||||
copy(ifma.IP, sa.Addr[:])
|
||||
// NOTE: KAME based IPv6 protcol stack usually embeds
|
||||
// the interface index in the interface-local or link-
|
||||
// local address as the kernel-internal form.
|
||||
if ifma.IP.IsInterfaceLocalMulticast() ||
|
||||
ifma.IP.IsLinkLocalMulticast() {
|
||||
// remove embedded scope zone ID
|
||||
if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
|
||||
ifma.Zone = zoneToString(int(ifma.IP[2]<<8 | ifma.IP[3]))
|
||||
ifma.IP[2], ifma.IP[3] = 0, 0
|
||||
}
|
||||
ifmat = append(ifmat, ifma.toAddr())
|
||||
|
|
|
|||
|
|
@ -19,18 +19,16 @@ func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
|
|||
if err != nil {
|
||||
return nil, os.NewSyscallError("route rib", err)
|
||||
}
|
||||
|
||||
msgs, err := syscall.ParseRoutingMessage(tab)
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("route message", err)
|
||||
}
|
||||
|
||||
var ifmat []Addr
|
||||
for _, m := range msgs {
|
||||
switch v := m.(type) {
|
||||
switch m := m.(type) {
|
||||
case *syscall.InterfaceMulticastAddrMessage:
|
||||
if ifindex == 0 || ifindex == int(v.Header.Index) {
|
||||
ifma, err := newMulticastAddr(v)
|
||||
if ifindex == 0 || ifindex == int(m.Header.Index) {
|
||||
ifma, err := newMulticastAddr(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -46,22 +44,20 @@ func newMulticastAddr(m *syscall.InterfaceMulticastAddrMessage) ([]Addr, error)
|
|||
if err != nil {
|
||||
return nil, os.NewSyscallError("route sockaddr", err)
|
||||
}
|
||||
|
||||
var ifmat []Addr
|
||||
for _, s := range sas {
|
||||
switch v := s.(type) {
|
||||
for _, sa := range sas {
|
||||
switch sa := sa.(type) {
|
||||
case *syscall.SockaddrInet4:
|
||||
ifma := &IPAddr{IP: IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])}
|
||||
ifma := &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}
|
||||
ifmat = append(ifmat, ifma.toAddr())
|
||||
case *syscall.SockaddrInet6:
|
||||
ifma := &IPAddr{IP: make(IP, IPv6len)}
|
||||
copy(ifma.IP, v.Addr[:])
|
||||
copy(ifma.IP, sa.Addr[:])
|
||||
// NOTE: KAME based IPv6 protcol stack usually embeds
|
||||
// the interface index in the interface-local or link-
|
||||
// local address as the kernel-internal form.
|
||||
if ifma.IP.IsInterfaceLocalMulticast() ||
|
||||
ifma.IP.IsLinkLocalMulticast() {
|
||||
// remove embedded scope zone ID
|
||||
if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
|
||||
ifma.Zone = zoneToString(int(ifma.IP[2]<<8 | ifma.IP[3]))
|
||||
ifma.IP[2], ifma.IP[3] = 0, 0
|
||||
}
|
||||
ifmat = append(ifmat, ifma.toAddr())
|
||||
|
|
|
|||
|
|
@ -20,17 +20,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) {
|
||||
|
|
@ -43,7 +42,6 @@ func interfaceTable(ifindex int) ([]Interface, error) {
|
|||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
return ift, nil
|
||||
}
|
||||
|
||||
|
|
@ -98,12 +96,10 @@ func interfaceAddrTable(ifindex int) ([]Addr, 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)
|
||||
}
|
||||
|
||||
ifat, err := addrTable(msgs, ifindex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -113,10 +109,11 @@ func interfaceAddrTable(ifindex int) ([]Addr, error) {
|
|||
|
||||
func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]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]))
|
||||
ifi, err := InterfaceByIndex(int(ifam.Index))
|
||||
|
|
@ -132,7 +129,6 @@ func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]Addr, error) {
|
|||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
return ifat, nil
|
||||
}
|
||||
|
||||
|
|
@ -149,6 +145,9 @@ func newAddr(attrs []syscall.NetlinkRouteAttr, ifi *Interface, ifam *syscall.IfA
|
|||
ifa.IP = make(IP, IPv6len)
|
||||
copy(ifa.IP, a.Value[:])
|
||||
ifa.Mask = CIDRMask(int(ifam.Prefixlen), 8*IPv6len)
|
||||
if ifam.Scope == syscall.RT_SCOPE_HOST || ifam.Scope == syscall.RT_SCOPE_LINK {
|
||||
ifa.Zone = zoneToString(int(ifam.Index))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -180,7 +179,6 @@ func parseProcNetIGMP(path string, ifi *Interface) []Addr {
|
|||
return nil
|
||||
}
|
||||
defer fd.close()
|
||||
|
||||
var (
|
||||
ifmat []Addr
|
||||
name string
|
||||
|
|
@ -218,7 +216,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() {
|
||||
|
|
@ -231,6 +228,9 @@ func parseProcNetIGMP6(path string, ifi *Interface) []Addr {
|
|||
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]}}
|
||||
if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
|
||||
ifma.Zone = ifi.Name
|
||||
}
|
||||
ifmat = append(ifmat, ifma.toAddr())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,5 +10,6 @@ package net
|
|||
// addresses for all network interfaces. Otherwise it returns
|
||||
// addresses for a specific interface.
|
||||
func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
|
||||
// TODO(mikio): Implement this like other platforms.
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,5 +10,6 @@ package net
|
|||
// addresses for all network interfaces. Otherwise it returns
|
||||
// addresses for a specific interface.
|
||||
func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
|
||||
// TODO(mikio): Implement this like other platforms.
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@ func getAdapterList() (*syscall.IpAdapterInfo, error) {
|
|||
b := make([]byte, 1000)
|
||||
l := uint32(len(b))
|
||||
a := (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
|
||||
// TODO(mikio): GetAdaptersInfo returns IP_ADAPTER_INFO that
|
||||
// contains IPv4 address list only. We should use another API
|
||||
// for fetching IPv6 stuff from the kernel.
|
||||
err := syscall.GetAdaptersInfo(a, &l)
|
||||
if err == syscall.ERROR_BUFFER_OVERFLOW {
|
||||
b = make([]byte, l)
|
||||
|
|
@ -154,5 +157,6 @@ func interfaceAddrTable(ifindex int) ([]Addr, error) {
|
|||
// addresses for all network interfaces. Otherwise it returns
|
||||
// addresses for a specific interface.
|
||||
func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
|
||||
// TODO(mikio): Implement this like other platforms.
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue