Index: include/apr_network_io.h
===================================================================
RCS file: /home/cvspublic/apr/include/apr_network_io.h,v
retrieving revision 1.140
diff -u -d -b -w -r1.140 apr_network_io.h
--- include/apr_network_io.h	5 Mar 2003 21:22:26 -0000	1.140
+++ include/apr_network_io.h	6 Apr 2003 07:36:57 -0000
@@ -840,6 +840,25 @@
                                                   int *protocol);
 
 /**
+ * Join a multicast group.
+ * @param sock The socket that will join the group.
+ * @param group The address of the multicast group being joined.
+ * @param iface The address of the local interface this multicast group will 
+ *              use.
+ */
+APR_DECLARE(apr_status_t) apr_socket_multicast_join(apr_socket_t *sock,
+                                                    apr_sockaddr_t *group,
+                                                    apr_sockaddr_t *iface);
+
+/**
+ * Leave a multicast group.
+ * @param sock The socket that will leave the group.
+ * @param group The address of the group you wish to leave.
+ */
+APR_DECLARE(apr_status_t) apr_socket_multicast_leave(apr_socket_t *sock,
+                                                     apr_sockaddr_t *group);
+
+/**
  * Set a socket to be inherited by child processes.
  */
 APR_DECLARE_INHERIT_SET(socket);
Index: network_io/unix/sockets.c
===================================================================
RCS file: /home/cvspublic/apr/network_io/unix/sockets.c,v
retrieving revision 1.108
diff -u -d -b -w -r1.108 sockets.c
--- network_io/unix/sockets.c	19 Mar 2003 05:03:24 -0000	1.108
+++ network_io/unix/sockets.c	6 Apr 2003 07:36:57 -0000
@@ -396,6 +396,84 @@
 
 APR_IMPLEMENT_INHERIT_UNSET(socket, inherit, cntxt, socket_cleanup)
 
+apr_status_t apr_socket_multicast_join(apr_socket_t *sock,
+                                       apr_sockaddr_t *group,
+                                       apr_sockaddr_t *iface)
+{
+    switch (sock->local_addr->family) {
+    case APR_INET:
+        {
+            struct ip_mreq mreq;
+
+            memcpy(&mreq.imr_multiaddr, &group->sa.sin.sin_addr,
+                   sizeof(struct in_addr));
+
+            memcpy(&mreq.imr_interface, &iface->sa.sin.sin_addr,
+                   sizeof(struct in_addr));
+
+            return setsockopt(sock->socketdes, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+                              &mreq, sizeof(mreq));
+        }
+#if APR_HAVE_INET6
+    case APR_INET6:
+        {
+            struct ipv6_mreq mreq6;
+
+            memcpy(&mreq6.ipv6mr_multiaddr, &group->sa.sin6.sin6_addr,
+                   sizeof(struct in6_addr));
+
+            memcpy(&mreq6.ipv6mr_interface, &iface->sa.sin6.sin6_addr,
+                   sizeof(struct in6_addr));
+
+            return setsockopt(sock->socketdes, IPPROTO_IPV6, 
+                              IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+        }
+#endif
+    default:
+        /* XXX this seems wrong...  in unpv1e2 they returns EPROTONOTSUPPORT, 
+         * but that doesn't appear to exist on this os.  any thoughts? */
+        return APR_ENOTIMPL;
+    }
+}
+
+apr_status_t apr_socket_multicast_leave(apr_socket_t *sock,
+                                        apr_sockaddr_t *group)
+{
+    switch (sock->local_addr->family) {
+    case APR_INET:
+        {
+            struct ip_mreq mreq;
+
+            memcpy(&mreq.imr_multiaddr, &group->sa.sin.sin_addr,
+                   sizeof(struct in_addr));
+
+            mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+
+            return setsockopt(sock->socketdes, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+                              &mreq, sizeof(mreq));
+        }
+#if APR_HAVE_INET6
+    case APR_INET6:
+        {
+            struct ipv6_mreq mreq6;
+
+            memcpy(&mreq6.ipv6mr_multiaddr,
+                   &group->sa.sin6_addr,
+                   sizeof(struct in6_addr));
+
+            mreq6.ipv6mr_interface = 0;
+
+            return setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP,
+                              &mreq6, sizeof(mreq6));
+        }
+#endif
+    default:
+        /* XXX this seems wrong...  in unpv1e2 they returns EPROTONOTSUPPORT, 
+         * but that doesn't appear to exist on this os.  any thoughts? */
+        return APR_ENOTIMPL;
+    }
+}
+
 /* deprecated */
 apr_status_t apr_shutdown(apr_socket_t *thesocket, apr_shutdown_how_e how)
 {
