net: add IPv4 multicast to UDPConn

notes:
Darwin is very particular about joining a multicast group if the
listneing socket is not created in "udp4" mode, the other supported
OS's are more flexible.

A simple example sets up a socket to listen on the mdns/bonjour
group 224.0.0.251:5353

// ensure the sock is udp4, and the IP is a 4 byte IPv4
socket, err := net.ListenUDP("udp4", &net.UDPAddr {
        IP: net.IPv4zero,
        // currently darwin will not allow you to bind to
        // a port if it is already bound to another process
        Port: 5353,
})
if err != nil {
        log.Exitf("listen %s", err)
}
defer socket.Close()
err = socket.JoinGroup(net.IPv4(224, 0, 0, 251))
if err != nil {
        log.Exitf("join group %s", err)
}

R=adg, rsc
CC=golang-dev
https://golang.org/cl/4066044
diff --git a/src/pkg/net/multicast_test.go b/src/pkg/net/multicast_test.go
new file mode 100644
index 0000000..0c9a035
--- /dev/null
+++ b/src/pkg/net/multicast_test.go
@@ -0,0 +1,56 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"testing"
+)
+
+func TestMulticastJoinAndLeave(t *testing.T) {
+	addr := &UDPAddr{
+		IP:   IPv4zero,
+		Port: 0,
+	}
+	// open a UDPConn
+	conn, err := ListenUDP("udp4", addr)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer conn.Close()
+
+	// try to join group
+	mcast := IPv4(224, 0, 0, 251)
+	err = conn.JoinGroup(mcast)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// try to leave group
+	err = conn.LeaveGroup(mcast)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestJoinFailureWithIPv6Address(t *testing.T) {
+	addr := &UDPAddr{
+		IP:   IPv4zero,
+		Port: 0,
+	}
+
+	// open a UDPConn
+	conn, err := ListenUDP("udp4", addr)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer conn.Close()
+	// try to join group
+	mcast := ParseIP("ff02::1")
+	err = conn.JoinGroup(mcast)
+	if err == nil {
+		t.Fatal("JoinGroup succeeded, should fail")
+	}
+	t.Logf("%s", err)
+}