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
diff --git a/src/pkg/net/interface_bsd.go b/src/pkg/net/interface_bsd.go
index 130820d..2675f94 100644
--- a/src/pkg/net/interface_bsd.go
+++ b/src/pkg/net/interface_bsd.go
@@ -169,34 +169,3 @@
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
-}
diff --git a/src/pkg/net/interface_darwin.go b/src/pkg/net/interface_darwin.go
index 6fbcd37..a7b68ad 100644
--- a/src/pkg/net/interface_darwin.go
+++ b/src/pkg/net/interface_darwin.go
@@ -47,3 +47,34 @@
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
+}
diff --git a/src/pkg/net/interface_freebsd.go b/src/pkg/net/interface_freebsd.go
index e0ff6ca..20f506b 100644
--- a/src/pkg/net/interface_freebsd.go
+++ b/src/pkg/net/interface_freebsd.go
@@ -47,3 +47,34 @@
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
+}
diff --git a/src/pkg/syscall/route_bsd.go b/src/pkg/syscall/route_bsd.go
index e41667c..93e345d 100644
--- a/src/pkg/syscall/route_bsd.go
+++ b/src/pkg/syscall/route_bsd.go
@@ -131,35 +131,6 @@
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
// the slice containing the RoutingMessage interfaces.
func ParseRoutingMessage(buf []byte) (msgs []RoutingMessage, errno int) {
diff --git a/src/pkg/syscall/route_darwin.go b/src/pkg/syscall/route_darwin.go
index 8f79b70..9d3a701 100644
--- a/src/pkg/syscall/route_darwin.go
+++ b/src/pkg/syscall/route_darwin.go
@@ -46,3 +46,32 @@
Header IfmaMsghdr2
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
+}
diff --git a/src/pkg/syscall/route_freebsd.go b/src/pkg/syscall/route_freebsd.go
index 128e93c..0d61d08 100644
--- a/src/pkg/syscall/route_freebsd.go
+++ b/src/pkg/syscall/route_freebsd.go
@@ -46,3 +46,32 @@
Header IfmaMsghdr
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
+}