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