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 mayer, 9 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.