switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Socket / NetdeviceController.cc
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Thorsten Horstmann <tho@berlios.de>
27
28 /** \file
29     \brief NetdeviceController non-inline non-template implementation
30  */
31
32 #include "NetdeviceController.hh"
33 //#include "NetdeviceController.ih"
34
35 // Custom includes
36 #include <sys/socket.h>
37 #include <sys/ioctl.h>
38 #include <net/if.h>
39 #include <boost/weak_ptr.hpp>
40 #include <senf/Utils/Exception.hh>
41 #include <senf/Socket/Protocols/Raw/MACAddress.hh>
42
43 #define prefix_
44 //-/////////////////////////////////////////////////////////////////////////////////////////////////
45
46 #define doIoctl(ifr, request, errorMsg)                                                         \
47     if ( ::ioctl( sockfd_->fd, request, &ifr ) < 0 )                                            \
48         SENF_THROW_SYSTEM_EXCEPTION("NetdeviceController: " errorMsg)
49
50
51 prefix_ senf::NetdeviceController::NetdeviceController(std::string const & interface_name)
52     : sockfd_ (sockfd())
53 {
54     struct ifreq ifr;
55     ::memset( &ifr, 0, sizeof(ifr));
56     interface_name.copy( ifr.ifr_name, IFNAMSIZ);
57     doIoctl(ifr, SIOCGIFINDEX, "Could not discover the index of interface \"" + interface_name + "\"");
58     ifindex_ = ifr.ifr_ifindex;
59 }
60
61 prefix_ senf::NetdeviceController::NetdeviceController(int interface_index)
62     : sockfd_ (sockfd())
63 {
64     ifindex_ = interface_index;
65 }
66
67 prefix_ std::string senf::NetdeviceController::interfaceName()
68     const
69 {
70     struct ifreq ifr;
71     ifrName( ifr);
72     return std::string( ifr.ifr_name);
73 }
74
75 prefix_ void senf::NetdeviceController::interfaceName(std::string const & newname)
76 {
77     if (sizeof(newname) <= IFNAMSIZ) {
78         struct ifreq ifr;
79         ifrName(ifr);
80         strncpy(ifr. ifr_newname, newname.c_str(), IFNAMSIZ);
81         doIoctl(ifr, SIOCSIFNAME, "Could not change the interface name. Is the interface really down?");
82     }
83     return;
84 }
85
86 prefix_ senf::MACAddress senf::NetdeviceController::hardwareAddress()
87     const
88 {
89     struct ifreq ifr;
90     ifrName( ifr);
91     doIoctl( ifr, SIOCGIFHWADDR, "Could not discover hardwareAddress");
92     return MACAddress::from_data( ifr.ifr_hwaddr.sa_data);
93 }
94
95 prefix_ void senf::NetdeviceController::hardwareAddress(MACAddress const & newAddress) {
96     struct ifreq ifr;
97     ifrName( ifr);
98     ifr.ifr_hwaddr.sa_family = 1; // TODO: lookup named constant; PF_LOCAL ???
99     std::copy(newAddress.begin(), newAddress.end(), ifr.ifr_hwaddr.sa_data);
100     doIoctl(ifr, SIOCSIFHWADDR, "Could not change the interface MAC address. Is the interface really down?");
101 }
102
103 prefix_ int senf::NetdeviceController::mtu()
104     const
105 {
106     struct ifreq ifr;
107     ifrName( ifr);
108     doIoctl( ifr, SIOCGIFMTU, "Could not discover mtu");
109     return ifr.ifr_mtu;
110 }
111
112 prefix_ void senf::NetdeviceController::mtu(int new_mtu)
113 {
114     struct ifreq ifr;
115     ifrName( ifr);
116     ifr.ifr_mtu = new_mtu;
117     doIoctl( ifr, SIOCSIFMTU, "Could not set mtu");
118 }
119
120 prefix_ int senf::NetdeviceController::txqueuelen()
121     const
122 {
123     struct ifreq ifr;
124     ifrName( ifr);
125     doIoctl( ifr, SIOCGIFTXQLEN, "Could not discover txqueuelen");
126     return ifr.ifr_qlen;
127 }
128
129 prefix_ void senf::NetdeviceController::txqueuelen(int new_txqueuelen)
130 {
131     struct ifreq ifr;
132     ifrName( ifr);
133     ifr.ifr_qlen = new_txqueuelen;
134     doIoctl( ifr, SIOCSIFTXQLEN, "Could not set txqueuelen");
135 }
136
137
138 prefix_ bool senf::NetdeviceController::promisc()
139     const
140 {
141     struct ifreq ifr;
142     ifrName( ifr);
143     doIoctl( ifr, SIOCGIFFLAGS, "Could not discover promisc mode");
144     return ifr.ifr_flags & IFF_PROMISC;
145 }
146
147 prefix_ void senf::NetdeviceController::promisc(bool mode)
148 {
149     struct ifreq ifr;
150     ifrName( ifr);
151     doIoctl( ifr, SIOCGIFFLAGS, "Could not set promisc mode");
152     if (mode)
153         ifr.ifr_flags |= IFF_PROMISC;
154     else
155         ifr.ifr_flags &= ~IFF_PROMISC;
156     doIoctl( ifr, SIOCSIFFLAGS, "Could not set promisc mode");
157 }
158
159 prefix_ bool senf::NetdeviceController::isUp()
160     const
161 {
162     struct ifreq ifr;
163     ifrName(ifr);
164     doIoctl(ifr, SIOCGIFFLAGS, "Could not discover interface status");
165     return ifr.ifr_flags & IFF_UP;
166 }
167
168 prefix_ void senf::NetdeviceController::up()
169 {
170     struct ifreq ifr;
171     ifrName(ifr);
172     doIoctl(ifr, SIOCGIFFLAGS, "Could not set interface status");
173     ifr.ifr_flags |= IFF_UP;
174     doIoctl(ifr, SIOCSIFFLAGS, "Could not set interface status");
175 }
176
177 prefix_ void senf::NetdeviceController::down()
178 {
179     struct ifreq ifr;
180     ifrName(ifr);
181     doIoctl(ifr, SIOCGIFFLAGS, "Could not set interface status");
182     ifr.ifr_flags &= ~IFF_UP;
183     doIoctl(ifr, SIOCSIFFLAGS, "Could not set interface status");
184 }
185
186 prefix_ int senf::NetdeviceController::interfaceIndex()
187     const
188 {
189     return ifindex_;
190 }
191
192 prefix_ void senf::NetdeviceController::ifrName(ifreq & ifr)
193     const
194 {
195     ::memset( &ifr, 0, sizeof(ifr));
196     ifr.ifr_ifindex = ifindex_;
197     if ( ::ioctl( sockfd_->fd, SIOCGIFNAME, &ifr ) < 0 )
198         SENF_THROW_SYSTEM_EXCEPTION("NetdeviceController")
199         << " could not discover the name of the interface with index " << ifindex_ << ".";
200 }
201
202 #undef doIoctl
203
204 //-/////////////////////////////////////////////////////////////////////////////////////////////////
205 // senf::NetdeviceController::SockFd
206
207 prefix_ senf::NetdeviceController::SockFd::SockFd()
208     : fd (::socket(PF_INET, SOCK_DGRAM, 0))
209 {
210     if ( fd < 0)
211         SENF_THROW_SYSTEM_EXCEPTION("Could not open socket for NetdeviceController.");
212 }
213
214 prefix_ senf::NetdeviceController::SockFd::~SockFd()
215 {
216     ::close(fd);
217 }
218
219 prefix_ senf::NetdeviceController::SockFd::ptr senf::NetdeviceController::sockfd()
220 {
221     static boost::weak_ptr<SockFd> sockfd;
222     SockFd::ptr p (sockfd.lock());
223     if (!p)
224          sockfd = p = SockFd::ptr(new SockFd());
225     return p;
226 }
227
228 //-/////////////////////////////////////////////////////////////////////////////////////////////////
229 #undef prefix_
230 //#include "NetdeviceController.mpp"
231
232 \f
233 // Local Variables:
234 // mode: c++
235 // fill-column: 100
236 // c-file-style: "senf"
237 // indent-tabs-mode: nil
238 // ispell-local-dictionary: "american"
239 // compile-command: "scons -u test"
240 // comment-column: 40
241 // End: