4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief MulticastSocketProtocol non-inline non-template implementation */
26 #include "MulticastSocketProtocol.hh"
27 //#include "MulticastSocketProtocol.ih"
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <net/if.h> // for if_nametoindex
33 #include "../../../Utils/Exception.hh"
35 //#include "MulticastSocketProtocol.mpp"
37 ///////////////////////////////cc.p////////////////////////////////////////
39 ///////////////////////////////////////////////////////////////////////////
40 // senf::MulticastSocketProtocol
42 prefix_ void senf::MulticastSocketProtocol::broadcastEnabled(bool v)
46 if (::setsockopt(fd(), SOL_SOCKET, SO_BROADCAST, &ivalue, sizeof(ivalue)) < 0)
47 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(SO_BROADCAST)");
50 prefix_ bool senf::MulticastSocketProtocol::broadcastEnabled()
54 ::socklen_t len (sizeof(value));
55 if (::getsockopt(fd(), SOL_SOCKET, SO_BROADCAST, &value, &len) < 0)
56 SENF_THROW_SYSTEM_EXCEPTION("::getsockopt(SO_BROADCAST)");
60 prefix_ bool senf::MulticastSocketProtocol::mcLoop()
64 socklen_t len (sizeof(value));
65 if (::getsockopt(fd(),SOL_IP,IP_MULTICAST_LOOP,&value,&len) < 0)
66 SENF_THROW_SYSTEM_EXCEPTION("");
70 prefix_ void senf::MulticastSocketProtocol::mcLoop(bool value)
74 if (::setsockopt(fd(),SOL_IP,IP_MULTICAST_LOOP,&ivalue,sizeof(ivalue)) < 0)
75 SENF_THROW_SYSTEM_EXCEPTION("");
78 prefix_ void senf::MulticastSocketProtocol::mcIface(std::string const & iface)
81 struct ip_mreqn mreqn;
82 ::memset(&mreqn,sizeof(mreqn),0);
84 mreqn.imr_ifindex = if_nametoindex(iface.c_str());
85 if (mreqn.imr_ifindex == 0)
86 throw SystemException(EINVAL SENF_EXC_DEBUGINFO);
88 if (::setsockopt(fd(),SOL_IP,IP_MULTICAST_IF,&mreqn,sizeof(mreqn)) < 0)
89 SENF_THROW_SYSTEM_EXCEPTION("");
92 prefix_ unsigned senf::MulticastSocketProtocol::mcTTL()
96 socklen_t len (sizeof(value));
97 if (::getsockopt(fd(),SOL_IP,IP_MULTICAST_TTL,&value,&len) < 0)
98 SENF_THROW_SYSTEM_EXCEPTION("");
102 prefix_ void senf::MulticastSocketProtocol::mcTTL(unsigned value)
105 if (::setsockopt(fd(),SOL_IP,IP_MULTICAST_TTL,&value,sizeof(value)) < 0)
106 SENF_THROW_SYSTEM_EXCEPTION("");
109 ///////////////////////////////////////////////////////////////////////////
110 // senf::INet4MulticastSocketProtocol
112 prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr)
115 struct ip_mreqn mreqn;
116 mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
117 mreqn.imr_address.s_addr = htons(INADDR_ANY);
118 mreqn.imr_ifindex = 0;
119 if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
120 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP)");
123 prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr,
124 INet4Address const & localAddr)
127 struct ip_mreqn mreqn;
128 mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
129 mreqn.imr_address.s_addr = localAddr.inaddr();
130 mreqn.imr_ifindex = 0;
131 if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
132 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP");
135 prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr,
136 std::string const & iface)
139 struct ip_mreqn mreqn;
140 mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
141 mreqn.imr_address.s_addr = htons(INADDR_ANY);
142 mreqn.imr_ifindex = if_nametoindex(iface.c_str());
143 if (mreqn.imr_ifindex == 0)
144 throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
145 if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
146 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP");
149 prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr)
152 struct ip_mreqn mreqn;
153 mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
154 mreqn.imr_address.s_addr = htons(INADDR_ANY);
155 mreqn.imr_ifindex = 0;
156 if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
157 SENF_THROW_SYSTEM_EXCEPTION("");
160 prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr,
161 INet4Address const & localAddr)
164 struct ip_mreqn mreqn;
165 mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
166 mreqn.imr_address.s_addr = localAddr.inaddr();
167 mreqn.imr_ifindex = 0;
168 if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
169 SENF_THROW_SYSTEM_EXCEPTION("");
172 prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr,
173 std::string const & iface)
176 struct ip_mreqn mreqn;
177 mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
178 mreqn.imr_address.s_addr = htons(INADDR_ANY);
179 mreqn.imr_ifindex = if_nametoindex(iface.c_str());
180 if (mreqn.imr_ifindex == 0)
181 throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
182 if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
183 SENF_THROW_SYSTEM_EXCEPTION("");
186 ///////////////////////////////////////////////////////////////////////////
187 // senf::INet6MulticastSocketProtocol
189 prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr)
192 if (mcAddr.inet4Mapped()) {
193 struct ip_mreqn mreqn;
194 mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
195 mreqn.imr_address.s_addr = htons(INADDR_ANY);
196 mreqn.imr_ifindex = 0;
197 if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
198 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP)");
201 struct ipv6_mreq mreqn;
202 std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
203 mreqn.ipv6mr_interface = 0;
204 if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
205 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP");
209 prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr,
210 std::string const & iface)
212 if (mcAddr.inet4Mapped()) {
213 struct ip_mreqn mreqn;
214 mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
215 mreqn.imr_address.s_addr = htons(INADDR_ANY);
216 mreqn.imr_ifindex = if_nametoindex(iface.c_str());
217 if (mreqn.imr_ifindex == 0)
218 throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
219 if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
220 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP");
223 struct ipv6_mreq mreqn;
224 std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
225 mreqn.ipv6mr_interface = if_nametoindex(iface.c_str());
226 if (mreqn.ipv6mr_interface == 0)
227 throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
228 if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
229 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP");
233 prefix_ void senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr)
236 if (mcAddr.inet4Mapped()) {
237 struct ip_mreqn mreqn;
238 mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
239 mreqn.imr_address.s_addr = htons(INADDR_ANY);
240 mreqn.imr_ifindex = 0;
241 if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
242 SENF_THROW_SYSTEM_EXCEPTION("");
245 struct ipv6_mreq mreqn;
246 std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
247 mreqn.ipv6mr_interface = 0;
248 if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
249 SENF_THROW_SYSTEM_EXCEPTION("");
254 senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr,
255 std::string const & iface)
258 if (mcAddr.inet4Mapped()) {
259 struct ip_mreqn mreqn;
260 mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
261 mreqn.imr_address.s_addr = htons(INADDR_ANY);
262 mreqn.imr_ifindex = if_nametoindex(iface.c_str());
263 if (mreqn.imr_ifindex == 0)
264 throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
265 if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
266 SENF_THROW_SYSTEM_EXCEPTION("");
269 struct ipv6_mreq mreqn;
270 std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
271 mreqn.ipv6mr_interface = if_nametoindex(iface.c_str());
272 if (mreqn.ipv6mr_interface == 0)
273 throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
274 if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
275 SENF_THROW_SYSTEM_EXCEPTION("");
279 ///////////////////////////////cc.e////////////////////////////////////////
281 //#include "MulticastSocketProtocol.mpp"
287 // comment-column: 40
288 // c-file-style: "senf"
289 // indent-tabs-mode: nil
290 // ispell-local-dictionary: "american"
291 // compile-command: "scons -u test"