source: source/ariba/communication/networkinfo/NetworkInformation.cpp@ 10700

Last change on this file since 10700 was 10700, checked in by Michael Tänzer, 12 years ago

Merge CMake branch into trunk

File size: 7.9 KB
Line 
1// [License]
2// The Ariba-Underlay Copyright
3//
4// Copyright (c) 2008-2009, Institute of Telematics, UniversitÀt Karlsruhe (TH)
5//
6// Institute of Telematics
7// UniversitÀt Karlsruhe (TH)
8// Zirkel 2, 76128 Karlsruhe
9// Germany
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND
22// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ARIBA PROJECT OR
25// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//
33// The views and conclusions contained in the software and documentation
34// are those of the authors and should not be interpreted as representing
35// official policies, either expressed or implied, of the Institute of
36// Telematics.
37// [License]
38
39#include "NetworkInformation.h"
40#include "ariba/config.h"
41
42#ifdef HAVE_LIBBLUETOOTH
43 #include <bluetooth/bluetooth.h>
44 #include <bluetooth/hci.h>
45 #include <bluetooth/hci_lib.h>
46#endif
47
48namespace ariba {
49namespace communication {
50
51use_logging_cpp(NetworkInformation);
52
53NetworkInformation::NetworkInformation() : infoSocket( -1 ){
54
55 infoSocket = socket( AF_INET, SOCK_DGRAM, 0 );
56}
57
58NetworkInformation::~NetworkInformation(){
59
60 close( infoSocket );
61}
62
63NetworkInterfaceList NetworkInformation::getInterfaces(){
64
65 NetworkInterfaceList retlist;
66
67 //
68 // get all network interfaces with basic information
69 // and all addresses configured on the interface
70 //
71
72 // TODO: can be optimized using SIOCGIFCOUNT
73 // but maybe this way its more robust?
74 // TODO: or using if_nameindex() problem is here,
75 // that i don't know the number of ifaces returned ...
76
77 struct ifconf ifconf;
78 int ifnum = 5;
79 int lastlen = 0;
80
81 ifconf.ifc_buf = NULL;
82 ifconf.ifc_len = 0;
83
84 while( true ){
85
86 ifconf.ifc_len = sizeof(struct ifreq) * ifnum;
87 ifconf.ifc_buf = (char*)realloc( ifconf.ifc_buf, ifconf.ifc_len );
88
89 int ret = ioctl( infoSocket, SIOCGIFCONF, &ifconf );
90 if (ret < 0){
91 logging_error( "getting interface list failed with: " <<
92 strerror(errno));
93
94 // if the socket is bogus, try to get
95 // a new one for the next call
96 if(errno == EBADF){
97 close( infoSocket );
98 infoSocket = socket( AF_INET, SOCK_DGRAM, 0 );
99 }
100
101 return retlist;
102 }
103
104 if( ifconf.ifc_len > lastlen ){
105 lastlen = ifconf.ifc_len;
106 ifnum += 10;
107 continue;
108 }
109
110 break; // length did not change any more, success
111 }
112
113 struct ifreq* ifr = ifconf.ifc_req;
114
115 for (int i = 0; i<ifconf.ifc_len; i+=sizeof(struct ifreq), ifr++){
116 NetworkInterface interface;
117 interface.name = string( ifr->ifr_name );
118 retlist.push_back( interface );
119 }
120
121 free( ifconf.ifc_buf );
122
123 //
124 // SIOCGIFCONF does not return interfaces that are currently
125 // not running. therefore we try to complete the list of interfaces now
126 // using getifaddrs. but we can't use _only_ getifaddrs, because
127 // it only contains an interface it it has an address configured
128 //
129
130 struct ifaddrs* ifap;
131 getifaddrs( &ifap );
132
133 for( struct ifaddrs* p = ifap; p != NULL; p=p->ifa_next ){
134 NetworkInterface interface;
135 interface.name = string( p->ifa_name );
136
137 if( find(retlist.begin(), retlist.end(), interface) == retlist.end() )
138 retlist.push_back( interface );
139 }
140
141 freeifaddrs( ifap );
142
143 //
144 // now we start to complete the interface information.
145 // we can't just call al IO ctrls and then get the
146 // information, as some vars of the ifreq structure
147 // hold several values, depending on the request
148 // see /usr/include/net/if.h
149 //
150
151 NetworkInterfaceList::iterator i = retlist.begin();
152 NetworkInterfaceList::iterator iend = retlist.end();
153
154 for( ; i != iend; i++ ){
155
156 NetworkInterface* interface = &(*i);
157 struct ifreq ifr;
158
159 memset( &ifr, 0, sizeof(struct ifreq) );
160 strcpy( ifr.ifr_name, i->name.c_str() );
161
162
163 { // get interface index
164 if( ioctl(infoSocket, SIOCGIFINDEX, &ifr) ){
165 logging_error( "could not get interface index for " <<
166 i->name << ": " << strerror(errno) );
167 return retlist;
168 }
169
170 interface->index = ifr.ifr_ifindex;
171 }
172
173 { // get interface flags
174 if( ioctl(infoSocket, SIOCGIFFLAGS, &ifr) ){
175 logging_error( "could not get interface flags for " <<
176 i->name << ": " << strerror(errno) );
177 return retlist;
178 }
179
180 interface->isRunning = (ifr.ifr_flags & IFF_RUNNING) != 0 ? true : false;
181 interface->isUp = (ifr.ifr_flags & IFF_UP) != 0 ? true : false;
182 interface->isLoopback = (ifr.ifr_flags & IFF_LOOPBACK) != 0 ? true : false;
183 interface->isBroadcast = (ifr.ifr_flags & IFF_BROADCAST) != 0 ? true : false;
184 interface->isMulticast = (ifr.ifr_flags & IFF_MULTICAST) != 0 ? true : false;
185 }
186
187 { // get mtu
188 if( ioctl(infoSocket, SIOCGIFMTU, &ifr) ){
189 logging_error( "could not get mtu for " <<
190 i->name << ": " << strerror(errno) );
191 return retlist;
192 }
193
194 interface->mtu = ifr.ifr_mtu;
195 }
196
197 { // get tx queue length
198 if( ioctl(infoSocket, SIOCGIFTXQLEN, &ifr) ){
199 logging_error( "could not get tx queue length for " <<
200 i->name << ": " << strerror(errno) );
201 return retlist;
202 }
203
204 interface->txQueueLen = ifr.ifr_qlen;
205 }
206
207 } // for( ; i != iend; i++ )*/
208
209 //
210 // not we try to get bluetooth interfaces
211 //
212
213#ifdef HAVE_LIBBLUETOOTH
214
215 int btsock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
216 if(btsock < 0){
217 logging_error("failed getting bluetooth raw socket");
218 return retlist;
219 }
220
221 struct hci_dev_list_req* btlist = NULL;
222 struct hci_dev_req* btdev = NULL;
223
224 btlist = (hci_dev_list_req*)malloc(HCI_MAX_DEV *
225 sizeof(struct hci_dev_list_req) + sizeof(struct hci_dev_req));
226
227 btlist->dev_num = HCI_MAX_DEV;
228 btdev = btlist->dev_req;
229
230 if(ioctl(btsock, HCIGETDEVLIST, btlist) < 0){
231 logging_error("failed getting requesting bluetooth devices");
232 free(btlist);
233 close(btsock);
234 return retlist;
235 }
236
237 btdev = btlist->dev_req;
238
239 for(int i=0; i<btlist->dev_num; i++, btdev++){
240 struct hci_dev_info di;
241 NetworkInterface interface;
242
243 if(hci_devinfo(btdev->dev_id, &di) < 0) continue;
244 if(hci_test_bit(HCI_RAW, &di.flags)) continue;
245
246 interface.name = string(di.name);
247 interface.index = di.dev_id;
248 interface.mtu = di.sco_mtu;
249 interface.isBroadcast = false;
250 interface.isLoopback = false;
251 interface.isMulticast = false;
252 interface.isUp = hci_test_bit(HCI_UP, &di.flags);
253 interface.isRunning = hci_test_bit(HCI_RUNNING, &di.flags);
254
255 retlist.push_back( interface );
256 }
257
258 free(btlist);
259 close(btsock);
260#endif
261
262 return retlist;
263}
264
265NetworkInterface NetworkInformation::getInterface(int index){
266
267 NetworkInterfaceList ifaces = getInterfaces();
268 NetworkInterfaceList::iterator i = ifaces.begin();
269 NetworkInterfaceList::iterator iend = ifaces.end();
270
271 for( ; i != iend; i++ ){
272 if( i->index == index ) return *i;
273 }
274
275 return NetworkInterface::UNDEFINED;
276}
277
278NetworkInterface NetworkInformation::getInterface(string name){
279
280 NetworkInterfaceList ifaces = getInterfaces();
281 NetworkInterfaceList::iterator i = ifaces.begin();
282 NetworkInterfaceList::iterator iend = ifaces.end();
283
284 for( ; i != iend; i++ ){
285 if( i->name.compare(name) == 0 ) return *i;
286 }
287
288 return NetworkInterface::UNDEFINED;
289}
290
291}} // namespace ariba, communication
Note: See TracBrowser for help on using the repository browser.