blob: 327257a3f0c89f83312d66d04d86171aba7613eb [file] [log] [blame]
James Kuszmaul82f6c042021-01-17 11:30:16 -08001/**
2 * @file mcast.c UDP Multicast
3 *
4 * Copyright (C) 2010 Creytiv.com
5 */
6
7#define _BSD_SOURCE 1
8#define _DEFAULT_SOURCE 1
9#include <re_types.h>
10#include <re_fmt.h>
11#include <re_sa.h>
12#include <re_udp.h>
13
14
15static int multicast_update(struct udp_sock *us, const struct sa *group,
16 bool join)
17{
18 struct ip_mreq mreq;
19#ifdef HAVE_INET6
20 struct ipv6_mreq mreq6;
21#endif
22 int err;
23
24 if (!us || !group)
25 return EINVAL;
26
27 switch (sa_af(group)) {
28
29 case AF_INET:
30 mreq.imr_multiaddr = group->u.in.sin_addr;
31 mreq.imr_interface.s_addr = 0;
32
33 err = udp_setsockopt(us, IPPROTO_IP,
34 join
35 ? IP_ADD_MEMBERSHIP
36 : IP_DROP_MEMBERSHIP,
37 &mreq, sizeof(mreq));
38 break;
39
40#ifdef HAVE_INET6
41 case AF_INET6:
42 mreq6.ipv6mr_multiaddr = group->u.in6.sin6_addr;
43 mreq6.ipv6mr_interface = 0;
44
45 err = udp_setsockopt(us, IPPROTO_IPV6,
46 join
47 ? IPV6_JOIN_GROUP
48 : IPV6_LEAVE_GROUP,
49 &mreq6, sizeof(mreq6));
50 break;
51#endif
52
53 default:
54 return EAFNOSUPPORT;
55 }
56
57 return err;
58}
59
60
61int udp_multicast_join(struct udp_sock *us, const struct sa *group)
62{
63 return multicast_update(us, group, true);
64}
65
66
67int udp_multicast_leave(struct udp_sock *us, const struct sa *group)
68{
69 return multicast_update(us, group, false);
70}