An Overlay-based
Virtual Network Substrate
SpoVNet

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

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