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