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
+}