An Overlay-based
Virtual Network Substrate
SpoVNet

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

Last change on this file since 4843 was 4843, checked in by Christoph Mayer, 14 years ago

textual

File size: 6.3 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
41namespace ariba {
42namespace communication {
43
44use_logging_cpp(NetworkInformation);
45
46NetworkInformation::NetworkInformation() : infoSocket( -1 ){
47
48        infoSocket = socket( AF_INET, SOCK_DGRAM, 0 );
49}
50
51NetworkInformation::~NetworkInformation(){
52
53        close( infoSocket );
54}
55
56NetworkInterfaceList NetworkInformation::getInterfaces(){
57
58        NetworkInterfaceList retlist;
59
60        //
61        // get all network interfaces with basic information
62        // and all addresses configured on the interface
63        //
64
65        // TODO: can be optimized using SIOCGIFCOUNT
66        // but maybe this way its more robust?
67        // TODO: or using if_nameindex() problem is here,
68        // that i don't know the number of ifaces returned ...
69
70        struct ifconf ifconf;
71        int ifnum = 5;
72        int lastlen = 0;
73
74        ifconf.ifc_buf = NULL;
75        ifconf.ifc_len = 0;
76
77        while( true ){
78
79                ifconf.ifc_len = sizeof(struct ifreq) * ifnum;
80                ifconf.ifc_buf = (char*)realloc( ifconf.ifc_buf, ifconf.ifc_len );
81
82                int ret = ioctl( infoSocket, SIOCGIFCONF, &ifconf );
83                if (ret < 0){
84                        logging_error( "getting interface list failed with: " <<
85                                                strerror(errno));
86                        return retlist;
87                }
88
89                if( ifconf.ifc_len > lastlen ){
90                        lastlen = ifconf.ifc_len;
91                        ifnum += 10;
92                        continue;
93                }
94
95                break; // length did not change any more, success
96        }
97
98        struct ifreq* ifr = ifconf.ifc_req;
99
100        for (int i = 0; i<ifconf.ifc_len; i+=sizeof(struct ifreq), ifr++){
101                NetworkInterface interface;
102                interface.name = string( ifr->ifr_name );
103                retlist.push_back( interface );
104        }
105
106        free( ifconf.ifc_buf );
107
108        //
109        // SIOCGIFCONF does not return interfaces that are currently
110        // not running. therefore we try to complete the list of interfaces now
111        // using getifaddrs. but we can't use _only_ getifaddrs, because
112        // it only contains an interface it it has an address configured
113        //
114
115        struct ifaddrs* ifap;
116        getifaddrs( &ifap );
117
118        for( struct ifaddrs* p = ifap; p != NULL; p=p->ifa_next ){
119                NetworkInterface interface;
120                interface.name = string( p->ifa_name );
121
122                if( find(retlist.begin(), retlist.end(), interface) == retlist.end() )
123                        retlist.push_back( interface );
124        }
125
126        freeifaddrs( ifap );
127
128        //
129        // now we start to complete the interface information.
130        // we can't just call al IO ctrls and then get the
131        // information, as some vars of the ifreq structure
132        // hold several values, depending on the request
133        // see /usr/include/net/if.h
134        //
135
136        NetworkInterfaceList::iterator i = retlist.begin();
137        NetworkInterfaceList::iterator iend = retlist.end();
138
139        for( ; i != iend; i++ ){
140
141                NetworkInterface* interface = &(*i);
142                struct ifreq ifr;
143
144                memset( &ifr, 0, sizeof(struct ifreq) );
145                strcpy( ifr.ifr_name, i->name.c_str() );
146
147
148                { // get interface index
149                        if( ioctl(infoSocket, SIOCGIFINDEX, &ifr) ){
150                                logging_error( "could not get interface index for " <<
151                                                i->name << ": " << strerror(errno) );
152                                return retlist;
153                        }
154
155                        interface->index = ifr.ifr_ifindex;
156                }
157
158                { // get interface flags
159                        if( ioctl(infoSocket, SIOCGIFFLAGS, &ifr) ){
160                                logging_error( "could not get interface flags for " <<
161                                                i->name << ": " << strerror(errno) );
162                                return retlist;
163                        }
164
165                        interface->isRunning   = (ifr.ifr_flags & IFF_RUNNING)   != 0 ? true : false;
166                        interface->isUp        = (ifr.ifr_flags & IFF_UP)        != 0 ? true : false;
167                        interface->isLoopback  = (ifr.ifr_flags & IFF_LOOPBACK)  != 0 ? true : false;
168                        interface->isBroadcast = (ifr.ifr_flags & IFF_BROADCAST) != 0 ? true : false;
169                        interface->isMulticast = (ifr.ifr_flags & IFF_MULTICAST) != 0 ? true : false;
170                }
171
172                { // get mtu
173                        if( ioctl(infoSocket, SIOCGIFMTU, &ifr) ){
174                                logging_error( "could not get mtu for " <<
175                                                i->name << ": " << strerror(errno) );
176                                return retlist;
177                        }
178
179                        interface->mtu = ifr.ifr_mtu;
180                }
181
182                { // get tx queue length
183                        if( ioctl(infoSocket, SIOCGIFTXQLEN, &ifr) ){
184                                logging_error( "could not get tx queue length for " <<
185                                                i->name << ": " << strerror(errno) );
186                                return retlist;
187                        }
188
189                        interface->txQueueLen = ifr.ifr_qlen;
190                }
191
192        } // for( ; i != iend; i++ )*/
193
194        return retlist;
195}
196
197NetworkInterface NetworkInformation::getInterface(int index){
198
199        NetworkInterfaceList ifaces = getInterfaces();
200        NetworkInterfaceList::iterator i = ifaces.begin();
201        NetworkInterfaceList::iterator iend = ifaces.end();
202
203        for( ; i != iend; i++ ){
204                if( i->index == index ) return *i;
205        }
206
207        return NetworkInterface::UNDEFINED;
208}
209
210NetworkInterface NetworkInformation::getInterface(string name){
211
212        NetworkInterfaceList ifaces = getInterfaces();
213        NetworkInterfaceList::iterator i = ifaces.begin();
214        NetworkInterfaceList::iterator iend = ifaces.end();
215
216        for( ; i != iend; i++ ){
217                if( i->name.compare(name) == 0 ) return *i;
218        }
219
220        return NetworkInterface::UNDEFINED;
221}
222
223}} // namespace ariba, communication
Note: See TracBrowser for help on using the repository browser.