xref: /haiku/src/add-ons/kernel/network/protocols/ipv6/multicast.cpp (revision 8d1485fa06b26cb13b0417e3cdafd5b45520a567)
1*8d1485faSAxel Dörfler /*
2*8d1485faSAxel Dörfler  * Copyright 2010, Haiku, Inc. All Rights Reserved.
3*8d1485faSAxel Dörfler  * Distributed under the terms of the MIT License.
4*8d1485faSAxel Dörfler  *
5*8d1485faSAxel Dörfler  * Authors:
6*8d1485faSAxel Dörfler  *		Atis Elsts, the.kfx@gmail.com
7*8d1485faSAxel Dörfler  */
8*8d1485faSAxel Dörfler 
9*8d1485faSAxel Dörfler 
10*8d1485faSAxel Dörfler #include "ipv6_address.h"
11*8d1485faSAxel Dörfler #include "multicast.h"
12*8d1485faSAxel Dörfler 
13*8d1485faSAxel Dörfler #include <net_buffer.h>
14*8d1485faSAxel Dörfler 
15*8d1485faSAxel Dörfler #include <netinet6/in6.h>
16*8d1485faSAxel Dörfler 
17*8d1485faSAxel Dörfler #include <new>
18*8d1485faSAxel Dörfler 
19*8d1485faSAxel Dörfler 
20*8d1485faSAxel Dörfler using std::nothrow;
21*8d1485faSAxel Dörfler 
22*8d1485faSAxel Dörfler 
23*8d1485faSAxel Dörfler template<typename Addressing>
24*8d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::MulticastGroupInterface(Filter *parent,
25*8d1485faSAxel Dörfler 	const AddressType &address, net_interface *interface)
26*8d1485faSAxel Dörfler 	: fParent(parent), fMulticastAddress(address), fInterface(interface)
27*8d1485faSAxel Dörfler {
28*8d1485faSAxel Dörfler }
29*8d1485faSAxel Dörfler 
30*8d1485faSAxel Dörfler 
31*8d1485faSAxel Dörfler template<typename Addressing>
32*8d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::~MulticastGroupInterface()
33*8d1485faSAxel Dörfler {
34*8d1485faSAxel Dörfler 	Clear();
35*8d1485faSAxel Dörfler }
36*8d1485faSAxel Dörfler 
37*8d1485faSAxel Dörfler 
38*8d1485faSAxel Dörfler template<typename Addressing> status_t
39*8d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::Add()
40*8d1485faSAxel Dörfler {
41*8d1485faSAxel Dörfler 	if (fFilterMode == kInclude && !fAddresses.IsEmpty())
42*8d1485faSAxel Dörfler 		return EINVAL;
43*8d1485faSAxel Dörfler 
44*8d1485faSAxel Dörfler 	fFilterMode = kExclude;
45*8d1485faSAxel Dörfler 	return B_OK;
46*8d1485faSAxel Dörfler }
47*8d1485faSAxel Dörfler 
48*8d1485faSAxel Dörfler 
49*8d1485faSAxel Dörfler template<typename Addressing> status_t
50*8d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::Drop()
51*8d1485faSAxel Dörfler {
52*8d1485faSAxel Dörfler 	fAddresses.Clear();
53*8d1485faSAxel Dörfler 	fFilterMode = kInclude;
54*8d1485faSAxel Dörfler 	return B_OK;
55*8d1485faSAxel Dörfler }
56*8d1485faSAxel Dörfler 
57*8d1485faSAxel Dörfler 
58*8d1485faSAxel Dörfler template<typename Addressing> status_t
59*8d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::BlockSource(
60*8d1485faSAxel Dörfler 	const AddressType &sourceAddress)
61*8d1485faSAxel Dörfler {
62*8d1485faSAxel Dörfler 	if (fFilterMode != kExclude)
63*8d1485faSAxel Dörfler 		return EINVAL;
64*8d1485faSAxel Dörfler 
65*8d1485faSAxel Dörfler 	fAddresses.Add(sourceAddress);
66*8d1485faSAxel Dörfler 	return B_OK;
67*8d1485faSAxel Dörfler }
68*8d1485faSAxel Dörfler 
69*8d1485faSAxel Dörfler 
70*8d1485faSAxel Dörfler template<typename Addressing> status_t
71*8d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::UnblockSource(
72*8d1485faSAxel Dörfler 	const AddressType &sourceAddress)
73*8d1485faSAxel Dörfler {
74*8d1485faSAxel Dörfler 	if (fFilterMode != kExclude)
75*8d1485faSAxel Dörfler 		return EINVAL;
76*8d1485faSAxel Dörfler 
77*8d1485faSAxel Dörfler 	if (!fAddresses.Has(sourceAddress))
78*8d1485faSAxel Dörfler 		return EADDRNOTAVAIL;
79*8d1485faSAxel Dörfler 
80*8d1485faSAxel Dörfler 	fAddresses.Add(sourceAddress);
81*8d1485faSAxel Dörfler 	return B_OK;
82*8d1485faSAxel Dörfler }
83*8d1485faSAxel Dörfler 
84*8d1485faSAxel Dörfler 
85*8d1485faSAxel Dörfler template<typename Addressing> status_t
86*8d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::AddSSM(const AddressType &sourceAddress)
87*8d1485faSAxel Dörfler {
88*8d1485faSAxel Dörfler 	if (fFilterMode == kExclude)
89*8d1485faSAxel Dörfler 		return EINVAL;
90*8d1485faSAxel Dörfler 
91*8d1485faSAxel Dörfler 	fAddresses.Add(sourceAddress);
92*8d1485faSAxel Dörfler 	return B_OK;
93*8d1485faSAxel Dörfler }
94*8d1485faSAxel Dörfler 
95*8d1485faSAxel Dörfler 
96*8d1485faSAxel Dörfler template<typename Addressing> status_t
97*8d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::DropSSM(const AddressType &sourceAddress)
98*8d1485faSAxel Dörfler {
99*8d1485faSAxel Dörfler 	if (fFilterMode == kExclude)
100*8d1485faSAxel Dörfler 		return EINVAL;
101*8d1485faSAxel Dörfler 
102*8d1485faSAxel Dörfler 	if (!fAddresses.Has(sourceAddress))
103*8d1485faSAxel Dörfler 		return EADDRNOTAVAIL;
104*8d1485faSAxel Dörfler 
105*8d1485faSAxel Dörfler 	fAddresses.Add(sourceAddress);
106*8d1485faSAxel Dörfler 	return B_OK;
107*8d1485faSAxel Dörfler }
108*8d1485faSAxel Dörfler 
109*8d1485faSAxel Dörfler 
110*8d1485faSAxel Dörfler template<typename Addressing> bool
111*8d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::IsEmpty() const
112*8d1485faSAxel Dörfler {
113*8d1485faSAxel Dörfler 	return fFilterMode == kInclude && fAddresses.IsEmpty();
114*8d1485faSAxel Dörfler }
115*8d1485faSAxel Dörfler 
116*8d1485faSAxel Dörfler 
117*8d1485faSAxel Dörfler template<typename Addressing> void
118*8d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::Clear()
119*8d1485faSAxel Dörfler {
120*8d1485faSAxel Dörfler 	if (IsEmpty())
121*8d1485faSAxel Dörfler 		return;
122*8d1485faSAxel Dörfler 
123*8d1485faSAxel Dörfler 	fFilterMode = kInclude;
124*8d1485faSAxel Dörfler 	fAddresses.Clear();
125*8d1485faSAxel Dörfler 	Addressing::LeaveGroup(this);
126*8d1485faSAxel Dörfler }
127*8d1485faSAxel Dörfler 
128*8d1485faSAxel Dörfler 
129*8d1485faSAxel Dörfler template<typename Addressing> bool
130*8d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::FilterAccepts(net_buffer *buffer) const
131*8d1485faSAxel Dörfler {
132*8d1485faSAxel Dörfler 	bool has = fAddresses.Has(Addressing::AddressFromSockAddr(
133*8d1485faSAxel Dörfler 		buffer->source));
134*8d1485faSAxel Dörfler 
135*8d1485faSAxel Dörfler 	return (has && fFilterMode == kInclude)
136*8d1485faSAxel Dörfler 		|| (!has && fFilterMode == kExclude);
137*8d1485faSAxel Dörfler }
138*8d1485faSAxel Dörfler 
139*8d1485faSAxel Dörfler 
140*8d1485faSAxel Dörfler template<typename Addressing>
141*8d1485faSAxel Dörfler MulticastFilter<Addressing>::MulticastFilter(ProtocolType *socket)
142*8d1485faSAxel Dörfler 	: fParent(socket), fStates()
143*8d1485faSAxel Dörfler {
144*8d1485faSAxel Dörfler }
145*8d1485faSAxel Dörfler 
146*8d1485faSAxel Dörfler 
147*8d1485faSAxel Dörfler template<typename Addressing>
148*8d1485faSAxel Dörfler MulticastFilter<Addressing>::~MulticastFilter()
149*8d1485faSAxel Dörfler {
150*8d1485faSAxel Dörfler 	while (true) {
151*8d1485faSAxel Dörfler 		typename States::Iterator iterator = fStates.GetIterator();
152*8d1485faSAxel Dörfler 		if (!iterator.HasNext())
153*8d1485faSAxel Dörfler 			return;
154*8d1485faSAxel Dörfler 
155*8d1485faSAxel Dörfler 		GroupInterface *state = iterator.Next();
156*8d1485faSAxel Dörfler 		state->Clear();
157*8d1485faSAxel Dörfler 		_ReturnState(state);
158*8d1485faSAxel Dörfler 	}
159*8d1485faSAxel Dörfler }
160*8d1485faSAxel Dörfler 
161*8d1485faSAxel Dörfler 
162*8d1485faSAxel Dörfler template<typename Addressing> status_t
163*8d1485faSAxel Dörfler MulticastFilter<Addressing>::GetState(const AddressType &groupAddress,
164*8d1485faSAxel Dörfler 	net_interface *interface, GroupInterface* &state, bool create)
165*8d1485faSAxel Dörfler {
166*8d1485faSAxel Dörfler 	state = fStates.Lookup(std::make_pair(&groupAddress, interface->index));
167*8d1485faSAxel Dörfler 
168*8d1485faSAxel Dörfler 	if (state == NULL && create) {
169*8d1485faSAxel Dörfler 		state = new (nothrow) GroupInterface(this, groupAddress, interface);
170*8d1485faSAxel Dörfler 		if (state == NULL)
171*8d1485faSAxel Dörfler 			return B_NO_MEMORY;
172*8d1485faSAxel Dörfler 
173*8d1485faSAxel Dörfler 		status_t status = fStates.Insert(state);
174*8d1485faSAxel Dörfler 		if (status < B_OK) {
175*8d1485faSAxel Dörfler 			delete state;
176*8d1485faSAxel Dörfler 			return status;
177*8d1485faSAxel Dörfler 		}
178*8d1485faSAxel Dörfler 
179*8d1485faSAxel Dörfler 		status = Addressing::JoinGroup(state);
180*8d1485faSAxel Dörfler 		if (status < B_OK) {
181*8d1485faSAxel Dörfler 			fStates.Remove(state);
182*8d1485faSAxel Dörfler 			delete state;
183*8d1485faSAxel Dörfler 			return status;
184*8d1485faSAxel Dörfler 		}
185*8d1485faSAxel Dörfler 
186*8d1485faSAxel Dörfler 	}
187*8d1485faSAxel Dörfler 
188*8d1485faSAxel Dörfler 	return B_OK;
189*8d1485faSAxel Dörfler }
190*8d1485faSAxel Dörfler 
191*8d1485faSAxel Dörfler 
192*8d1485faSAxel Dörfler template<typename Addressing> void
193*8d1485faSAxel Dörfler MulticastFilter<Addressing>::ReturnState(GroupInterface *state)
194*8d1485faSAxel Dörfler {
195*8d1485faSAxel Dörfler 	if (state->IsEmpty())
196*8d1485faSAxel Dörfler 		_ReturnState(state);
197*8d1485faSAxel Dörfler }
198*8d1485faSAxel Dörfler 
199*8d1485faSAxel Dörfler 
200*8d1485faSAxel Dörfler template<typename Addressing> void
201*8d1485faSAxel Dörfler MulticastFilter<Addressing>::_ReturnState(GroupInterface *state)
202*8d1485faSAxel Dörfler {
203*8d1485faSAxel Dörfler 	fStates.Remove(state);
204*8d1485faSAxel Dörfler 	delete state;
205*8d1485faSAxel Dörfler }
206*8d1485faSAxel Dörfler 
207*8d1485faSAxel Dörfler // IPv6 explicit template instantiation
208*8d1485faSAxel Dörfler template class MulticastFilter<IPv6Multicast>;
209*8d1485faSAxel Dörfler template class MulticastGroupInterface<IPv6Multicast>;
210