ba30fcee99806861e57db68d8efe4a44e7f66c04
[senf.git] / Socket / Protocols / INet / MulticastSocketProtocol.cc
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \file
24     \brief MulticastSocketProtocol non-inline non-template implementation */
25
26 #include "MulticastSocketProtocol.hh"
27 //#include "MulticastSocketProtocol.ih"
28
29 // Custom includes
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <net/if.h> // for if_nametoindex
33
34 //#include "MulticastSocketProtocol.mpp"
35 #define prefix_
36 ///////////////////////////////cc.p////////////////////////////////////////
37
38 ///////////////////////////////////////////////////////////////////////////
39 // senf::MulticastSocketProtocol
40
41 prefix_ void senf::MulticastSocketProtocol::broadcastEnabled(bool v)
42     const
43 {
44     int ivalue (v);
45     if (::setsockopt(fd(), SOL_SOCKET, SO_BROADCAST, &ivalue, sizeof(ivalue)) < 0)
46         throw SystemException("::setsockopt(SO_BROADCAST)");
47 }
48
49 prefix_ bool senf::MulticastSocketProtocol::broadcastEnabled()
50     const
51 {
52     int value (0);
53     ::socklen_t len (sizeof(value));
54     if (::getsockopt(fd(), SOL_SOCKET, SO_BROADCAST, &value, &len) < 0)
55         throw SystemException("::getsockopt(SO_BROADCAST)");
56     return value;
57 }
58
59 prefix_ bool senf::MulticastSocketProtocol::mcLoop()
60     const
61 {
62     int value (0);
63     socklen_t len (sizeof(value));
64     if (::getsockopt(fd(),SOL_IP,IP_MULTICAST_LOOP,&value,&len) < 0)
65         throw SystemException();
66     return value;
67 }
68
69 prefix_ void senf::MulticastSocketProtocol::mcLoop(bool value)
70     const
71 {
72     int ivalue (value);
73     if (::setsockopt(fd(),SOL_IP,IP_MULTICAST_LOOP,&ivalue,sizeof(ivalue)) < 0)
74         throw SystemException();
75 }
76
77 prefix_ void senf::MulticastSocketProtocol::mcIface(std::string const & iface)
78     const
79 {
80     struct ip_mreqn mreqn;
81     ::memset(&mreqn,sizeof(mreqn),0);
82     if (!iface.empty()) {
83         mreqn.imr_ifindex = if_nametoindex(iface.c_str());
84         if (mreqn.imr_ifindex == 0)
85             throw SystemException(EINVAL);
86     }
87     if (::setsockopt(fd(),SOL_IP,IP_MULTICAST_IF,&mreqn,sizeof(mreqn)) < 0)
88         throw SystemException();
89 }
90
91 prefix_ unsigned senf::MulticastSocketProtocol::mcTTL()
92     const
93 {
94     int value (0);
95     socklen_t len (sizeof(value));
96     if (::getsockopt(fd(),SOL_IP,IP_MULTICAST_TTL,&value,&len) < 0)
97         throw SystemException();
98     return value;
99 }
100
101 prefix_ void senf::MulticastSocketProtocol::mcTTL(unsigned value)
102     const
103 {
104     if (::setsockopt(fd(),SOL_IP,IP_MULTICAST_TTL,&value,sizeof(value)) < 0)
105         throw SystemException();
106 }
107
108 ///////////////////////////////////////////////////////////////////////////
109 // senf::INet4MulticastSocketProtocol
110
111 prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr)
112     const
113 {
114     struct ip_mreqn mreqn;
115     mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
116     mreqn.imr_address.s_addr = htons(INADDR_ANY);
117     mreqn.imr_ifindex = 0;
118     if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
119         throw SystemException("::setsockopt(IP_ADD_MEMBERSHIP");
120 }
121
122 prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr,
123                                                            INet4Address const & localAddr)
124     const
125 {
126     struct ip_mreqn mreqn;
127     mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
128     mreqn.imr_address.s_addr = localAddr.inaddr();
129     mreqn.imr_ifindex = 0;
130     if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
131         throw SystemException("::setsockopt(IP_ADD_MEMBERSHIP");
132 }
133
134 prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr,
135                                                            std::string const & iface)
136     const
137 {
138     struct ip_mreqn mreqn;
139     mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
140     mreqn.imr_address.s_addr = htons(INADDR_ANY);
141     mreqn.imr_ifindex = if_nametoindex(iface.c_str());
142     if (mreqn.imr_ifindex == 0)
143         throw SystemException("::if_nametoindex()",ENOENT);
144     if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
145         throw SystemException("::setsockopt(IP_ADD_MEMBERSHIP");
146 }
147
148 prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr)
149     const
150 {
151     struct ip_mreqn mreqn;
152     mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
153     mreqn.imr_address.s_addr = htons(INADDR_ANY);
154     mreqn.imr_ifindex = 0;
155     if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
156         throw SystemException();
157 }
158
159 prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr,
160                                                             INet4Address const & localAddr)
161     const
162 {
163     struct ip_mreqn mreqn;
164     mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
165     mreqn.imr_address.s_addr = localAddr.inaddr();
166     mreqn.imr_ifindex = 0;
167     if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
168         throw SystemException();
169 }
170
171 prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr,
172                                                             std::string const & iface)
173     const
174 {
175     struct ip_mreqn mreqn;
176     mreqn.imr_multiaddr.s_addr = mcAddr.inaddr();
177     mreqn.imr_address.s_addr = htons(INADDR_ANY);
178     mreqn.imr_ifindex = if_nametoindex(iface.c_str());
179     if (mreqn.imr_ifindex == 0)
180         throw SystemException("::if_nametoindex()",ENOENT);
181     if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
182         throw SystemException();
183 }
184
185 ///////////////////////////////////////////////////////////////////////////
186 // senf::INet6MulticastSocketProtocol
187
188 prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr)
189     const
190 {
191     struct ipv6_mreq mreqn;
192     std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
193     mreqn.ipv6mr_interface = 0;
194     if (::setsockopt(fd(),SOL_IP,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
195         throw SystemException("::setsockopt(IPV6_ADD_MEMBERSHIP");
196 }
197
198 prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr,
199                                                            std::string const & iface)
200 {
201     struct ipv6_mreq mreqn;
202     std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
203     mreqn.ipv6mr_interface = if_nametoindex(iface.c_str());
204     if (mreqn.ipv6mr_interface == 0)
205         throw SystemException("::if_nametoindex()",ENOENT);
206     if (::setsockopt(fd(),SOL_IP,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
207         throw SystemException("::setsockopt(IPV6_ADD_MEMBERSHIP");
208 }
209
210 prefix_ void senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr)
211     const
212 {
213     struct ipv6_mreq mreqn;
214     std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
215     mreqn.ipv6mr_interface = 0;
216     if (::setsockopt(fd(),SOL_IP,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
217         throw SystemException();
218 }
219
220 prefix_ void
221 senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr,
222                                                std::string const & iface)
223     const
224 {
225     struct ipv6_mreq mreqn;
226     std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
227     mreqn.ipv6mr_interface = if_nametoindex(iface.c_str());
228     if (mreqn.ipv6mr_interface == 0)
229         throw SystemException("::if_nametoindex()",ENOENT);
230     if (::setsockopt(fd(),SOL_IP,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
231         throw SystemException();
232 }
233
234 ///////////////////////////////cc.e////////////////////////////////////////
235 #undef prefix_
236 //#include "MulticastSocketProtocol.mpp"
237
238 \f
239 // Local Variables:
240 // mode: c++
241 // fill-column: 100
242 // comment-column: 40
243 // c-file-style: "senf"
244 // indent-tabs-mode: nil
245 // ispell-local-dictionary: "american"
246 // compile-command: "scons -u test"
247 // End: