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