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

Last change on this file since 5638 was 5638, checked in by Christoph Mayer, 15 years ago

adress detection aufgeräumt, network info für bleutooth, data stream (hopeful crash fix), logging auf maemo nur warn, ...

File size: 7.7 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_BLUETOOTH_BLUETOOTH_H
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 return retlist;
94 }
95
96 if( ifconf.ifc_len > lastlen ){
97 lastlen = ifconf.ifc_len;
98 ifnum += 10;
99 continue;
100 }
101
102 break; // length did not change any more, success
103 }
104
105 struct ifreq* ifr = ifconf.ifc_req;
106
107 for (int i = 0; i<ifconf.ifc_len; i+=sizeof(struct ifreq), ifr++){
108 NetworkInterface interface;
109 interface.name = string( ifr->ifr_name );
110 retlist.push_back( interface );
111 }
112
113 free( ifconf.ifc_buf );
114
115 //
116 // SIOCGIFCONF does not return interfaces that are currently
117 // not running. therefore we try to complete the list of interfaces now
118 // using getifaddrs. but we can't use _only_ getifaddrs, because
119 // it only contains an interface it it has an address configured
120 //
121
122 struct ifaddrs* ifap;
123 getifaddrs( &ifap );
124
125 for( struct ifaddrs* p = ifap; p != NULL; p=p->ifa_next ){
126 NetworkInterface interface;
127 interface.name = string( p->ifa_name );
128
129 if( find(retlist.begin(), retlist.end(), interface) == retlist.end() )
130 retlist.push_back( interface );
131 }
132
133 freeifaddrs( ifap );
134
135 //
136 // now we start to complete the interface information.
137 // we can't just call al IO ctrls and then get the
138 // information, as some vars of the ifreq structure
139 // hold several values, depending on the request
140 // see /usr/include/net/if.h
141 //
142
143 NetworkInterfaceList::iterator i = retlist.begin();
144 NetworkInterfaceList::iterator iend = retlist.end();
145
146 for( ; i != iend; i++ ){
147
148 NetworkInterface* interface = &(*i);
149 struct ifreq ifr;
150
151 memset( &ifr, 0, sizeof(struct ifreq) );
152 strcpy( ifr.ifr_name, i->name.c_str() );
153
154
155 { // get interface index
156 if( ioctl(infoSocket, SIOCGIFINDEX, &ifr) ){
157 logging_error( "could not get interface index for " <<
158 i->name << ": " << strerror(errno) );
159 return retlist;
160 }
161
162 interface->index = ifr.ifr_ifindex;
163 }
164
165 { // get interface flags
166 if( ioctl(infoSocket, SIOCGIFFLAGS, &ifr) ){
167 logging_error( "could not get interface flags for " <<
168 i->name << ": " << strerror(errno) );
169 return retlist;
170 }
171
172 interface->isRunning = (ifr.ifr_flags & IFF_RUNNING) != 0 ? true : false;
173 interface->isUp = (ifr.ifr_flags & IFF_UP) != 0 ? true : false;
174 interface->isLoopback = (ifr.ifr_flags & IFF_LOOPBACK) != 0 ? true : false;
175 interface->isBroadcast = (ifr.ifr_flags & IFF_BROADCAST) != 0 ? true : false;
176 interface->isMulticast = (ifr.ifr_flags & IFF_MULTICAST) != 0 ? true : false;
177 }
178
179 { // get mtu
180 if( ioctl(infoSocket, SIOCGIFMTU, &ifr) ){
181 logging_error( "could not get mtu for " <<
182 i->name << ": " << strerror(errno) );
183 return retlist;
184 }
185
186 interface->mtu = ifr.ifr_mtu;
187 }
188
189 { // get tx queue length
190 if( ioctl(infoSocket, SIOCGIFTXQLEN, &ifr) ){
191 logging_error( "could not get tx queue length for " <<
192 i->name << ": " << strerror(errno) );
193 return retlist;
194 }
195
196 interface->txQueueLen = ifr.ifr_qlen;
197 }
198
199 } // for( ; i != iend; i++ )*/
200
201 //
202 // not we try to get bluetooth interfaces
203 //
204
205#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
206
207 int btsock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
208 if(btsock < 0){
209 logging_error("failed getting bluetooth raw socket");
210 return retlist;
211 }
212
213 struct hci_dev_list_req* btlist = NULL;
214 struct hci_dev_req* btdev = NULL;
215
216 btlist = (hci_dev_list_req*)malloc(HCI_MAX_DEV *
217 sizeof(struct hci_dev_list_req) + sizeof(struct hci_dev_req));
218
219 btlist->dev_num = HCI_MAX_DEV;
220 btdev = btlist->dev_req;
221
222 if(ioctl(btsock, HCIGETDEVLIST, btlist) < 0){
223 logging_error("failed getting requesting bluetooth devices");
224 free(btlist);
225 close(btsock);
226 return retlist;
227 }
228
229 btdev = btlist->dev_req;
230
231 for(int i=0; i<btlist->dev_num; i++, btdev++){
232 struct hci_dev_info di;
233 NetworkInterface interface;
234
235 if(hci_devinfo(btdev->dev_id, &di) < 0) continue;
236 if(hci_test_bit(HCI_RAW, &di.flags)) continue;
237
238 interface.name = string(di.name);
239 interface.index = di.dev_id;
240 interface.mtu = di.sco_mtu;
241 interface.isBroadcast = false;
242 interface.isLoopback = false;
243 interface.isMulticast = false;
244 interface.isUp = hci_test_bit(HCI_UP, &di.flags);
245 interface.isRunning = hci_test_bit(HCI_RUNNING, &di.flags);
246
247 retlist.push_back( interface );
248 }
249
250 free(btlist);
251 close(btsock);
252#endif
253
254 return retlist;
255}
256
257NetworkInterface NetworkInformation::getInterface(int index){
258
259 NetworkInterfaceList ifaces = getInterfaces();
260 NetworkInterfaceList::iterator i = ifaces.begin();
261 NetworkInterfaceList::iterator iend = ifaces.end();
262
263 for( ; i != iend; i++ ){
264 if( i->index == index ) return *i;
265 }
266
267 return NetworkInterface::UNDEFINED;
268}
269
270NetworkInterface NetworkInformation::getInterface(string name){
271
272 NetworkInterfaceList ifaces = getInterfaces();
273 NetworkInterfaceList::iterator i = ifaces.begin();
274 NetworkInterfaceList::iterator iend = ifaces.end();
275
276 for( ; i != iend; i++ ){
277 if( i->name.compare(name) == 0 ) return *i;
278 }
279
280 return NetworkInterface::UNDEFINED;
281}
282
283}} // namespace ariba, communication
Note: See TracBrowser for help on using the repository browser.