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

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

networkinfo fix wenn socket kaputt geht, erfolgreich verwendete bootstrap infos speichern und wenn overlay verbindungen alle weg sind diese infos ausprobieren

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_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
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_BLUETOOTH_BLUETOOTH_H
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.