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