00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #include "MulticastSocketProtocol.hh"
00027
00028
00029
00030 #include <sys/socket.h>
00031 #include <netinet/in.h>
00032 #include <net/if.h>
00033 #include <senf/Utils/Exception.hh>
00034
00035
00036 #define prefix_
00037
00038
00039
00040
00041
00042 prefix_ void senf::MulticastSocketProtocol::broadcastEnabled(bool v)
00043 const
00044 {
00045 int ivalue (v);
00046 if (::setsockopt(fd(), SOL_SOCKET, SO_BROADCAST, &ivalue, sizeof(ivalue)) < 0)
00047 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(SO_BROADCAST)");
00048 }
00049
00050 prefix_ bool senf::MulticastSocketProtocol::broadcastEnabled()
00051 const
00052 {
00053 int value (0);
00054 ::socklen_t len (sizeof(value));
00055 if (::getsockopt(fd(), SOL_SOCKET, SO_BROADCAST, &value, &len) < 0)
00056 SENF_THROW_SYSTEM_EXCEPTION("::getsockopt(SO_BROADCAST)");
00057 return value;
00058 }
00059
00060 prefix_ bool senf::MulticastSocketProtocol::mcLoop()
00061 const
00062 {
00063 int value (0);
00064 socklen_t len (sizeof(value));
00065 if (::getsockopt(fd(),SOL_IP,IP_MULTICAST_LOOP,&value,&len) < 0)
00066 SENF_THROW_SYSTEM_EXCEPTION("");
00067 return value;
00068 }
00069
00070 prefix_ void senf::MulticastSocketProtocol::mcLoop(bool value)
00071 const
00072 {
00073 int ivalue (value);
00074 if (::setsockopt(fd(),SOL_IP,IP_MULTICAST_LOOP,&ivalue,sizeof(ivalue)) < 0)
00075 SENF_THROW_SYSTEM_EXCEPTION("");
00076 }
00077
00078 prefix_ void senf::MulticastSocketProtocol::mcIface(std::string const & iface)
00079 const
00080 {
00081 struct ip_mreqn mreqn;
00082 ::memset(&mreqn, 0, sizeof(mreqn));
00083 if (!iface.empty()) {
00084 mreqn.imr_ifindex = if_nametoindex(iface.c_str());
00085 if (mreqn.imr_ifindex == 0)
00086 throw SystemException(EINVAL SENF_EXC_DEBUGINFO);
00087 }
00088 if (::setsockopt(fd(),SOL_IP,IP_MULTICAST_IF,&mreqn,sizeof(mreqn)) < 0)
00089 SENF_THROW_SYSTEM_EXCEPTION("");
00090 }
00091
00092 prefix_ unsigned senf::MulticastSocketProtocol::mcTTL()
00093 const
00094 {
00095 int value (0);
00096 socklen_t len (sizeof(value));
00097 if (::getsockopt(fd(),SOL_IP,IP_MULTICAST_TTL,&value,&len) < 0)
00098 SENF_THROW_SYSTEM_EXCEPTION("");
00099 return value;
00100 }
00101
00102 prefix_ void senf::MulticastSocketProtocol::mcTTL(unsigned value)
00103 const
00104 {
00105 if (::setsockopt(fd(),SOL_IP,IP_MULTICAST_TTL,&value,sizeof(value)) < 0)
00106 SENF_THROW_SYSTEM_EXCEPTION("");
00107 }
00108
00109
00110
00111
00112 prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr)
00113 const
00114 {
00115 struct ip_mreqn mreqn;
00116 mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
00117 mreqn.imr_address.s_addr = htons(INADDR_ANY);
00118 mreqn.imr_ifindex = 0;
00119 if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
00120 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP)");
00121 }
00122
00123 prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr,
00124 INet4Address const & localAddr)
00125 const
00126 {
00127 struct ip_mreqn mreqn;
00128 mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
00129 mreqn.imr_address.s_addr = localAddr.inaddr();
00130 mreqn.imr_ifindex = 0;
00131 if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
00132 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP");
00133 }
00134
00135 prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr,
00136 std::string const & iface)
00137 const
00138 {
00139 struct ip_mreqn mreqn;
00140 mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
00141 mreqn.imr_address.s_addr = htons(INADDR_ANY);
00142 mreqn.imr_ifindex = if_nametoindex(iface.c_str());
00143 if (mreqn.imr_ifindex == 0)
00144 throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
00145 if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
00146 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP");
00147 }
00148
00149 prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr)
00150 const
00151 {
00152 struct ip_mreqn mreqn;
00153 mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
00154 mreqn.imr_address.s_addr = htons(INADDR_ANY);
00155 mreqn.imr_ifindex = 0;
00156 if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
00157 SENF_THROW_SYSTEM_EXCEPTION("");
00158 }
00159
00160 prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr,
00161 INet4Address const & localAddr)
00162 const
00163 {
00164 struct ip_mreqn mreqn;
00165 mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
00166 mreqn.imr_address.s_addr = localAddr.inaddr();
00167 mreqn.imr_ifindex = 0;
00168 if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
00169 SENF_THROW_SYSTEM_EXCEPTION("");
00170 }
00171
00172 prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr,
00173 std::string const & iface)
00174 const
00175 {
00176 struct ip_mreqn mreqn;
00177 mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
00178 mreqn.imr_address.s_addr = htons(INADDR_ANY);
00179 mreqn.imr_ifindex = if_nametoindex(iface.c_str());
00180 if (mreqn.imr_ifindex == 0)
00181 throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
00182 if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
00183 SENF_THROW_SYSTEM_EXCEPTION("");
00184 }
00185
00186 namespace {
00187 void mc4SSMSourceRequest(int operation, int fd, senf::INet4Address const & group,
00188 senf::INet4Address const & source, std::string const & iface)
00189 {
00190 struct group_source_req req;
00191 ::memset(&req, 0, sizeof(req));
00192 req.gsr_interface = if_nametoindex(iface.c_str());
00193 if (req.gsr_interface == 0)
00194 throw senf::SystemException("::if_nametoindex()", ENOENT SENF_EXC_DEBUGINFO);
00195 req.gsr_group.ss_family = AF_INET;
00196 reinterpret_cast<struct sockaddr_in&>(req.gsr_group).sin_addr.s_addr = group.inaddr();
00197 req.gsr_source.ss_family = AF_INET;
00198 reinterpret_cast<struct sockaddr_in&>(req.gsr_source).sin_addr.s_addr = source.inaddr();
00199 if (::setsockopt(fd, SOL_IP, MCAST_JOIN_SOURCE_GROUP, &req, sizeof(req)) < 0)
00200 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt()");
00201 }
00202 }
00203
00204 prefix_ void senf::INet4MulticastSocketProtocol::mcJoinSSMSource(INet4Address const & group,
00205 INet4Address const & source,
00206 std::string const & iface)
00207 const
00208 {
00209 mc4SSMSourceRequest(MCAST_JOIN_SOURCE_GROUP, fd(), group, source, iface);
00210 }
00211
00212 prefix_ void senf::INet4MulticastSocketProtocol::mcLeaveSSMSource(INet4Address const & group,
00213 INet4Address const & source,
00214 std::string const & iface)
00215 const
00216 {
00217 mc4SSMSourceRequest(MCAST_LEAVE_SOURCE_GROUP, fd(), group, source, iface);
00218 }
00219
00220
00221
00222
00223 prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr)
00224 const
00225 {
00226 if (mcAddr.inet4Mapped()) {
00227 struct ip_mreqn mreqn;
00228 mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
00229 mreqn.imr_address.s_addr = htons(INADDR_ANY);
00230 mreqn.imr_ifindex = 0;
00231 if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
00232 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP)");
00233 }
00234 else {
00235 struct ipv6_mreq mreqn;
00236 std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
00237 mreqn.ipv6mr_interface = 0;
00238 if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
00239 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP");
00240 }
00241 }
00242
00243 prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr,
00244 std::string const & iface)
00245 const
00246 {
00247 if (mcAddr.inet4Mapped()) {
00248 struct ip_mreqn mreqn;
00249 mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
00250 mreqn.imr_address.s_addr = htons(INADDR_ANY);
00251 mreqn.imr_ifindex = if_nametoindex(iface.c_str());
00252 if (mreqn.imr_ifindex == 0)
00253 throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
00254 if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
00255 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP");
00256 }
00257 else {
00258 struct ipv6_mreq mreqn;
00259 std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
00260 mreqn.ipv6mr_interface = if_nametoindex(iface.c_str());
00261 if (mreqn.ipv6mr_interface == 0)
00262 throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
00263 if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
00264 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP");
00265 }
00266 }
00267
00268 prefix_ void senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr)
00269 const
00270 {
00271 if (mcAddr.inet4Mapped()) {
00272 struct ip_mreqn mreqn;
00273 mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
00274 mreqn.imr_address.s_addr = htons(INADDR_ANY);
00275 mreqn.imr_ifindex = 0;
00276 if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
00277 SENF_THROW_SYSTEM_EXCEPTION("");
00278 }
00279 else {
00280 struct ipv6_mreq mreqn;
00281 std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
00282 mreqn.ipv6mr_interface = 0;
00283 if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
00284 SENF_THROW_SYSTEM_EXCEPTION("");
00285 }
00286 }
00287
00288 prefix_ void
00289 senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr,
00290 std::string const & iface)
00291 const
00292 {
00293 if (mcAddr.inet4Mapped()) {
00294 struct ip_mreqn mreqn;
00295 mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
00296 mreqn.imr_address.s_addr = htons(INADDR_ANY);
00297 mreqn.imr_ifindex = if_nametoindex(iface.c_str());
00298 if (mreqn.imr_ifindex == 0)
00299 throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
00300 if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
00301 SENF_THROW_SYSTEM_EXCEPTION("");
00302 }
00303 else {
00304 struct ipv6_mreq mreqn;
00305 std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
00306 mreqn.ipv6mr_interface = if_nametoindex(iface.c_str());
00307 if (mreqn.ipv6mr_interface == 0)
00308 throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
00309 if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
00310 SENF_THROW_SYSTEM_EXCEPTION("");
00311 }
00312 }
00313
00314 namespace {
00315
00316 void mc6SSMSourceRequest(int operation, int fd, senf::INet6Address const & group,
00317 senf::INet6Address const & source, int ifacei)
00318 {
00319 struct group_source_req req;
00320 ::memset(&req, 0, sizeof(req));
00321 req.gsr_interface = ifacei;
00322 req.gsr_group.ss_family = AF_INET6;
00323 std::copy(group.begin(), group.end(),
00324 reinterpret_cast<struct sockaddr_in6&>(req.gsr_group).sin6_addr.s6_addr);
00325 req.gsr_source.ss_family = AF_INET6;
00326 std::copy(source.begin(), source.end(),
00327 reinterpret_cast<struct sockaddr_in6&>(req.gsr_source).sin6_addr.s6_addr);
00328 if (::setsockopt(fd, SOL_IPV6, MCAST_JOIN_SOURCE_GROUP, &req, sizeof(req)) < 0)
00329 SENF_THROW_SYSTEM_EXCEPTION("::setsockopt()");
00330 }
00331
00332 void mc6SSMSourceRequest(int operation, int fd, senf::INet6Address const & group,
00333 senf::INet6Address const & source, std::string const & iface)
00334 {
00335 int ifacei (0);
00336 if (! iface.empty()) {
00337 ifacei = if_nametoindex(iface.c_str());
00338 if (ifacei == 0)
00339 throw senf::SystemException("::if_nametoindex()", ENOENT SENF_EXC_DEBUGINFO);
00340 }
00341 mc6SSMSourceRequest(operation, fd, group, source, ifacei);
00342 }
00343
00344 }
00345
00346 prefix_ void senf::INet6MulticastSocketProtocol::mcJoinSSMSource(INet6Address const & group,
00347 INet6Address const & source,
00348 std::string const & iface)
00349 const
00350 {
00351 mc6SSMSourceRequest(MCAST_JOIN_SOURCE_GROUP, fd(), group, source, iface);
00352 }
00353
00354 prefix_ void senf::INet6MulticastSocketProtocol::mcJoinSSMSource(INet6Address const & group,
00355 INet6Address const & source,
00356 int ifacei)
00357 const
00358 {
00359 mc6SSMSourceRequest(MCAST_JOIN_SOURCE_GROUP, fd(), group, source, ifacei);
00360 }
00361
00362 prefix_ void senf::INet6MulticastSocketProtocol::mcLeaveSSMSource(INet6Address const & group,
00363 INet6Address const & source,
00364 std::string const & iface)
00365 const
00366 {
00367 mc6SSMSourceRequest(MCAST_LEAVE_SOURCE_GROUP, fd(), group, source, iface);
00368 }
00369
00370
00371
00372 #undef prefix_
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384