Commit 1bc24518 authored by Joel Sing's avatar Joel Sing Committed by Russ Cox

net, syscall: move multicast address handling

Multicast address handling is not consistent across all BSDs. Move
the multicast address handling code into OS dependent files. This
will be needed for OpenBSD support.

R=mikioh.mikioh, golang-dev
CC=golang-dev
https://golang.org/cl/4809074
parent c20ced95
...@@ -169,34 +169,3 @@ func newAddr(m *syscall.InterfaceAddrMessage) ([]Addr, os.Error) { ...@@ -169,34 +169,3 @@ func newAddr(m *syscall.InterfaceAddrMessage) ([]Addr, os.Error) {
return ifat, nil return ifat, nil
} }
func newMulticastAddr(m *syscall.InterfaceMulticastAddrMessage) ([]Addr, os.Error) {
var ifmat []Addr
sas, e := syscall.ParseRoutingSockaddr(m)
if e != 0 {
return nil, os.NewSyscallError("route sockaddr", e)
}
for _, s := range sas {
switch v := s.(type) {
case *syscall.SockaddrInet4:
ifma := &IPAddr{IP: IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])}
ifmat = append(ifmat, ifma.toAddr())
case *syscall.SockaddrInet6:
ifma := &IPAddr{IP: make(IP, IPv6len)}
copy(ifma.IP, v.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
ifma.IP[2], ifma.IP[3] = 0, 0
}
ifmat = append(ifmat, ifma.toAddr())
}
}
return ifmat, nil
}
...@@ -47,3 +47,34 @@ func interfaceMulticastAddrTable(ifindex int) ([]Addr, os.Error) { ...@@ -47,3 +47,34 @@ func interfaceMulticastAddrTable(ifindex int) ([]Addr, os.Error) {
return ifmat, nil return ifmat, nil
} }
func newMulticastAddr(m *syscall.InterfaceMulticastAddrMessage) ([]Addr, os.Error) {
var ifmat []Addr
sas, e := syscall.ParseRoutingSockaddr(m)
if e != 0 {
return nil, os.NewSyscallError("route sockaddr", e)
}
for _, s := range sas {
switch v := s.(type) {
case *syscall.SockaddrInet4:
ifma := &IPAddr{IP: IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])}
ifmat = append(ifmat, ifma.toAddr())
case *syscall.SockaddrInet6:
ifma := &IPAddr{IP: make(IP, IPv6len)}
copy(ifma.IP, v.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
ifma.IP[2], ifma.IP[3] = 0, 0
}
ifmat = append(ifmat, ifma.toAddr())
}
}
return ifmat, nil
}
...@@ -47,3 +47,34 @@ func interfaceMulticastAddrTable(ifindex int) ([]Addr, os.Error) { ...@@ -47,3 +47,34 @@ func interfaceMulticastAddrTable(ifindex int) ([]Addr, os.Error) {
return ifmat, nil return ifmat, nil
} }
func newMulticastAddr(m *syscall.InterfaceMulticastAddrMessage) ([]Addr, os.Error) {
var ifmat []Addr
sas, e := syscall.ParseRoutingSockaddr(m)
if e != 0 {
return nil, os.NewSyscallError("route sockaddr", e)
}
for _, s := range sas {
switch v := s.(type) {
case *syscall.SockaddrInet4:
ifma := &IPAddr{IP: IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])}
ifmat = append(ifmat, ifma.toAddr())
case *syscall.SockaddrInet6:
ifma := &IPAddr{IP: make(IP, IPv6len)}
copy(ifma.IP, v.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
ifma.IP[2], ifma.IP[3] = 0, 0
}
ifmat = append(ifmat, ifma.toAddr())
}
}
return ifmat, nil
}
...@@ -131,35 +131,6 @@ func (m *InterfaceAddrMessage) sockaddr() (sas []Sockaddr) { ...@@ -131,35 +131,6 @@ func (m *InterfaceAddrMessage) sockaddr() (sas []Sockaddr) {
return sas return sas
} }
const rtaIfmaMask = RTA_GATEWAY | RTA_IFP | RTA_IFA
func (m *InterfaceMulticastAddrMessage) sockaddr() (sas []Sockaddr) {
if m.Header.Addrs&rtaIfmaMask == 0 {
return nil
}
buf := m.Data[:]
for i := uint(0); i < RTAX_MAX; i++ {
if m.Header.Addrs&rtaIfmaMask&(1<<i) == 0 {
continue
}
rsa := (*RawSockaddr)(unsafe.Pointer(&buf[0]))
switch i {
case RTAX_IFA:
sa, e := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
if e != 0 {
return nil
}
sas = append(sas, sa)
case RTAX_GATEWAY, RTAX_IFP:
// nothing to do
}
buf = buf[rsaAlignOf(int(rsa.Len)):]
}
return sas
}
// ParseRoutingMessage parses buf as routing messages and returns // ParseRoutingMessage parses buf as routing messages and returns
// the slice containing the RoutingMessage interfaces. // the slice containing the RoutingMessage interfaces.
func ParseRoutingMessage(buf []byte) (msgs []RoutingMessage, errno int) { func ParseRoutingMessage(buf []byte) (msgs []RoutingMessage, errno int) {
......
...@@ -46,3 +46,32 @@ type InterfaceMulticastAddrMessage struct { ...@@ -46,3 +46,32 @@ type InterfaceMulticastAddrMessage struct {
Header IfmaMsghdr2 Header IfmaMsghdr2
Data []byte Data []byte
} }
const rtaIfmaMask = RTA_GATEWAY | RTA_IFP | RTA_IFA
func (m *InterfaceMulticastAddrMessage) sockaddr() (sas []Sockaddr) {
if m.Header.Addrs&rtaIfmaMask == 0 {
return nil
}
buf := m.Data[:]
for i := uint(0); i < RTAX_MAX; i++ {
if m.Header.Addrs&rtaIfmaMask&(1<<i) == 0 {
continue
}
rsa := (*RawSockaddr)(unsafe.Pointer(&buf[0]))
switch i {
case RTAX_IFA:
sa, e := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
if e != 0 {
return nil
}
sas = append(sas, sa)
case RTAX_GATEWAY, RTAX_IFP:
// nothing to do
}
buf = buf[rsaAlignOf(int(rsa.Len)):]
}
return sas
}
...@@ -46,3 +46,32 @@ type InterfaceMulticastAddrMessage struct { ...@@ -46,3 +46,32 @@ type InterfaceMulticastAddrMessage struct {
Header IfmaMsghdr Header IfmaMsghdr
Data []byte Data []byte
} }
const rtaIfmaMask = RTA_GATEWAY | RTA_IFP | RTA_IFA
func (m *InterfaceMulticastAddrMessage) sockaddr() (sas []Sockaddr) {
if m.Header.Addrs&rtaIfmaMask == 0 {
return nil
}
buf := m.Data[:]
for i := uint(0); i < RTAX_MAX; i++ {
if m.Header.Addrs&rtaIfmaMask&(1<<i) == 0 {
continue
}
rsa := (*RawSockaddr)(unsafe.Pointer(&buf[0]))
switch i {
case RTAX_IFA:
sa, e := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
if e != 0 {
return nil
}
sas = append(sas, sa)
case RTAX_GATEWAY, RTAX_IFP:
// nothing to do
}
buf = buf[rsaAlignOf(int(rsa.Len)):]
}
return sas
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment