xref: /haiku/src/add-ons/kernel/network/protocols/ipv6/multicast.cpp (revision 25a7b01d15612846f332751841da3579db313082)
18d1485faSAxel Dörfler /*
28d1485faSAxel Dörfler  * Copyright 2010, Haiku, Inc. All Rights Reserved.
38d1485faSAxel Dörfler  * Distributed under the terms of the MIT License.
48d1485faSAxel Dörfler  *
58d1485faSAxel Dörfler  * Authors:
68d1485faSAxel Dörfler  *		Atis Elsts, the.kfx@gmail.com
78d1485faSAxel Dörfler  */
88d1485faSAxel Dörfler 
98d1485faSAxel Dörfler 
108d1485faSAxel Dörfler #include "ipv6_address.h"
118d1485faSAxel Dörfler #include "multicast.h"
128d1485faSAxel Dörfler 
138d1485faSAxel Dörfler #include <net_buffer.h>
148d1485faSAxel Dörfler 
158d1485faSAxel Dörfler #include <netinet6/in6.h>
168d1485faSAxel Dörfler 
178d1485faSAxel Dörfler #include <new>
188d1485faSAxel Dörfler 
198d1485faSAxel Dörfler 
208d1485faSAxel Dörfler using std::nothrow;
218d1485faSAxel Dörfler 
228d1485faSAxel Dörfler 
238d1485faSAxel Dörfler template<typename Addressing>
MulticastGroupInterface(Filter * parent,const AddressType & address,net_interface * interface)248d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::MulticastGroupInterface(Filter *parent,
258d1485faSAxel Dörfler 	const AddressType &address, net_interface *interface)
268d1485faSAxel Dörfler 	: fParent(parent), fMulticastAddress(address), fInterface(interface)
278d1485faSAxel Dörfler {
288d1485faSAxel Dörfler }
298d1485faSAxel Dörfler 
308d1485faSAxel Dörfler 
318d1485faSAxel Dörfler template<typename Addressing>
~MulticastGroupInterface()328d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::~MulticastGroupInterface()
338d1485faSAxel Dörfler {
348d1485faSAxel Dörfler 	Clear();
358d1485faSAxel Dörfler }
368d1485faSAxel Dörfler 
378d1485faSAxel Dörfler 
388d1485faSAxel Dörfler template<typename Addressing> status_t
Add()398d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::Add()
408d1485faSAxel Dörfler {
418d1485faSAxel Dörfler 	if (fFilterMode == kInclude && !fAddresses.IsEmpty())
428d1485faSAxel Dörfler 		return EINVAL;
438d1485faSAxel Dörfler 
448d1485faSAxel Dörfler 	fFilterMode = kExclude;
458d1485faSAxel Dörfler 	return B_OK;
468d1485faSAxel Dörfler }
478d1485faSAxel Dörfler 
488d1485faSAxel Dörfler 
498d1485faSAxel Dörfler template<typename Addressing> status_t
Drop()508d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::Drop()
518d1485faSAxel Dörfler {
528d1485faSAxel Dörfler 	fAddresses.Clear();
53*fa2fa026SSiarzhuk Zharski 	Addressing::LeaveGroup(this);
548d1485faSAxel Dörfler 	fFilterMode = kInclude;
558d1485faSAxel Dörfler 	return B_OK;
568d1485faSAxel Dörfler }
578d1485faSAxel Dörfler 
588d1485faSAxel Dörfler 
598d1485faSAxel Dörfler template<typename Addressing> status_t
BlockSource(const AddressType & sourceAddress)608d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::BlockSource(
618d1485faSAxel Dörfler 	const AddressType &sourceAddress)
628d1485faSAxel Dörfler {
638d1485faSAxel Dörfler 	if (fFilterMode != kExclude)
648d1485faSAxel Dörfler 		return EINVAL;
658d1485faSAxel Dörfler 
668d1485faSAxel Dörfler 	fAddresses.Add(sourceAddress);
678d1485faSAxel Dörfler 	return B_OK;
688d1485faSAxel Dörfler }
698d1485faSAxel Dörfler 
708d1485faSAxel Dörfler 
718d1485faSAxel Dörfler template<typename Addressing> status_t
UnblockSource(const AddressType & sourceAddress)728d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::UnblockSource(
738d1485faSAxel Dörfler 	const AddressType &sourceAddress)
748d1485faSAxel Dörfler {
758d1485faSAxel Dörfler 	if (fFilterMode != kExclude)
768d1485faSAxel Dörfler 		return EINVAL;
778d1485faSAxel Dörfler 
788d1485faSAxel Dörfler 	if (!fAddresses.Has(sourceAddress))
798d1485faSAxel Dörfler 		return EADDRNOTAVAIL;
808d1485faSAxel Dörfler 
818d1485faSAxel Dörfler 	fAddresses.Add(sourceAddress);
828d1485faSAxel Dörfler 	return B_OK;
838d1485faSAxel Dörfler }
848d1485faSAxel Dörfler 
858d1485faSAxel Dörfler 
868d1485faSAxel Dörfler template<typename Addressing> status_t
AddSSM(const AddressType & sourceAddress)878d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::AddSSM(const AddressType &sourceAddress)
888d1485faSAxel Dörfler {
898d1485faSAxel Dörfler 	if (fFilterMode == kExclude)
908d1485faSAxel Dörfler 		return EINVAL;
918d1485faSAxel Dörfler 
928d1485faSAxel Dörfler 	fAddresses.Add(sourceAddress);
938d1485faSAxel Dörfler 	return B_OK;
948d1485faSAxel Dörfler }
958d1485faSAxel Dörfler 
968d1485faSAxel Dörfler 
978d1485faSAxel Dörfler template<typename Addressing> status_t
DropSSM(const AddressType & sourceAddress)988d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::DropSSM(const AddressType &sourceAddress)
998d1485faSAxel Dörfler {
1008d1485faSAxel Dörfler 	if (fFilterMode == kExclude)
1018d1485faSAxel Dörfler 		return EINVAL;
1028d1485faSAxel Dörfler 
1038d1485faSAxel Dörfler 	if (!fAddresses.Has(sourceAddress))
1048d1485faSAxel Dörfler 		return EADDRNOTAVAIL;
1058d1485faSAxel Dörfler 
1068d1485faSAxel Dörfler 	fAddresses.Add(sourceAddress);
1078d1485faSAxel Dörfler 	return B_OK;
1088d1485faSAxel Dörfler }
1098d1485faSAxel Dörfler 
1108d1485faSAxel Dörfler 
1118d1485faSAxel Dörfler template<typename Addressing> bool
IsEmpty() const1128d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::IsEmpty() const
1138d1485faSAxel Dörfler {
1148d1485faSAxel Dörfler 	return fFilterMode == kInclude && fAddresses.IsEmpty();
1158d1485faSAxel Dörfler }
1168d1485faSAxel Dörfler 
1178d1485faSAxel Dörfler 
1188d1485faSAxel Dörfler template<typename Addressing> void
Clear()1198d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::Clear()
1208d1485faSAxel Dörfler {
1218d1485faSAxel Dörfler 	if (IsEmpty())
1228d1485faSAxel Dörfler 		return;
1238d1485faSAxel Dörfler 
1248d1485faSAxel Dörfler 	fFilterMode = kInclude;
1258d1485faSAxel Dörfler 	fAddresses.Clear();
1268d1485faSAxel Dörfler 	Addressing::LeaveGroup(this);
1278d1485faSAxel Dörfler }
1288d1485faSAxel Dörfler 
1298d1485faSAxel Dörfler 
1308d1485faSAxel Dörfler template<typename Addressing> bool
FilterAccepts(net_buffer * buffer) const1318d1485faSAxel Dörfler MulticastGroupInterface<Addressing>::FilterAccepts(net_buffer *buffer) const
1328d1485faSAxel Dörfler {
1338d1485faSAxel Dörfler 	bool has = fAddresses.Has(Addressing::AddressFromSockAddr(
1348d1485faSAxel Dörfler 		buffer->source));
1358d1485faSAxel Dörfler 
1368d1485faSAxel Dörfler 	return (has && fFilterMode == kInclude)
1378d1485faSAxel Dörfler 		|| (!has && fFilterMode == kExclude);
1388d1485faSAxel Dörfler }
1398d1485faSAxel Dörfler 
1408d1485faSAxel Dörfler 
1418d1485faSAxel Dörfler template<typename Addressing>
MulticastFilter(ProtocolType * socket)1428d1485faSAxel Dörfler MulticastFilter<Addressing>::MulticastFilter(ProtocolType *socket)
1438d1485faSAxel Dörfler 	: fParent(socket), fStates()
1448d1485faSAxel Dörfler {
1458d1485faSAxel Dörfler }
1468d1485faSAxel Dörfler 
1478d1485faSAxel Dörfler 
1488d1485faSAxel Dörfler template<typename Addressing>
~MulticastFilter()1498d1485faSAxel Dörfler MulticastFilter<Addressing>::~MulticastFilter()
1508d1485faSAxel Dörfler {
1518d1485faSAxel Dörfler 	while (true) {
1528d1485faSAxel Dörfler 		typename States::Iterator iterator = fStates.GetIterator();
1538d1485faSAxel Dörfler 		if (!iterator.HasNext())
1548d1485faSAxel Dörfler 			return;
1558d1485faSAxel Dörfler 
1568d1485faSAxel Dörfler 		GroupInterface *state = iterator.Next();
1578d1485faSAxel Dörfler 		state->Clear();
1588d1485faSAxel Dörfler 		_ReturnState(state);
1598d1485faSAxel Dörfler 	}
1608d1485faSAxel Dörfler }
1618d1485faSAxel Dörfler 
1628d1485faSAxel Dörfler 
1638d1485faSAxel Dörfler template<typename Addressing> status_t
GetState(const AddressType & groupAddress,net_interface * interface,GroupInterface * & state,bool create)1648d1485faSAxel Dörfler MulticastFilter<Addressing>::GetState(const AddressType &groupAddress,
1658d1485faSAxel Dörfler 	net_interface *interface, GroupInterface* &state, bool create)
1668d1485faSAxel Dörfler {
1678d1485faSAxel Dörfler 	state = fStates.Lookup(std::make_pair(&groupAddress, interface->index));
1688d1485faSAxel Dörfler 
1698d1485faSAxel Dörfler 	if (state == NULL && create) {
1708d1485faSAxel Dörfler 		state = new (nothrow) GroupInterface(this, groupAddress, interface);
1718d1485faSAxel Dörfler 		if (state == NULL)
1728d1485faSAxel Dörfler 			return B_NO_MEMORY;
1738d1485faSAxel Dörfler 
1748d1485faSAxel Dörfler 		status_t status = fStates.Insert(state);
1758d1485faSAxel Dörfler 		if (status < B_OK) {
1768d1485faSAxel Dörfler 			delete state;
1778d1485faSAxel Dörfler 			return status;
1788d1485faSAxel Dörfler 		}
1798d1485faSAxel Dörfler 
1808d1485faSAxel Dörfler 		status = Addressing::JoinGroup(state);
1818d1485faSAxel Dörfler 		if (status < B_OK) {
1828d1485faSAxel Dörfler 			fStates.Remove(state);
1838d1485faSAxel Dörfler 			delete state;
1848d1485faSAxel Dörfler 			return status;
1858d1485faSAxel Dörfler 		}
1868d1485faSAxel Dörfler 
1878d1485faSAxel Dörfler 	}
1888d1485faSAxel Dörfler 
1898d1485faSAxel Dörfler 	return B_OK;
1908d1485faSAxel Dörfler }
1918d1485faSAxel Dörfler 
1928d1485faSAxel Dörfler 
1938d1485faSAxel Dörfler template<typename Addressing> void
ReturnState(GroupInterface * state)1948d1485faSAxel Dörfler MulticastFilter<Addressing>::ReturnState(GroupInterface *state)
1958d1485faSAxel Dörfler {
1968d1485faSAxel Dörfler 	if (state->IsEmpty())
1978d1485faSAxel Dörfler 		_ReturnState(state);
1988d1485faSAxel Dörfler }
1998d1485faSAxel Dörfler 
2008d1485faSAxel Dörfler 
2018d1485faSAxel Dörfler template<typename Addressing> void
_ReturnState(GroupInterface * state)2028d1485faSAxel Dörfler MulticastFilter<Addressing>::_ReturnState(GroupInterface *state)
2038d1485faSAxel Dörfler {
2048d1485faSAxel Dörfler 	fStates.Remove(state);
2058d1485faSAxel Dörfler 	delete state;
2068d1485faSAxel Dörfler }
2078d1485faSAxel Dörfler 
2088d1485faSAxel Dörfler // IPv6 explicit template instantiation
2098d1485faSAxel Dörfler template class MulticastFilter<IPv6Multicast>;
2108d1485faSAxel Dörfler template class MulticastGroupInterface<IPv6Multicast>;
211