1 #include	"unp.h"
2 
3 int
mcast_leave(int sockfd,const SA * sa,socklen_t salen)4 mcast_leave(int sockfd, const SA *sa, socklen_t salen)
5 {
6 	switch (sa->sa_family) {
7 	case AF_INET: {
8 		struct ip_mreq		mreq;
9 
10 		memcpy(&mreq.imr_multiaddr,
11 			   &((struct sockaddr_in *) sa)->sin_addr,
12 			   sizeof(struct in_addr));
13 		mreq.imr_interface.s_addr = htonl(INADDR_ANY);
14 		return(setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
15 						  &mreq, sizeof(mreq)));
16 	}
17 
18 #ifdef	IPV6
19 	case AF_INET6: {
20 		struct ipv6_mreq	mreq6;
21 
22 		memcpy(&mreq6.ipv6mr_multiaddr,
23 			   &((struct sockaddr_in6 *) sa)->sin6_addr,
24 			   sizeof(struct in6_addr));
25 		mreq6.ipv6mr_interface = 0;
26 		return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
27 						  &mreq6, sizeof(mreq6)));
28 	}
29 #endif
30 
31 	default:
32 		errno = EPROTONOSUPPORT;
33 		return(-1);
34 	}
35 }
36 
37 void
Mcast_leave(int sockfd,const SA * sa,socklen_t salen)38 Mcast_leave(int sockfd, const SA *sa, socklen_t salen)
39 {
40 	if (mcast_leave(sockfd, sa, salen) < 0)
41 		err_sys("mcast_leave error");
42 }
43