An Overlay-based
Virtual Network Substrate
SpoVNet

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

Last change on this file since 5860 was 5860, checked in by Christoph Mayer, 10 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.