close Warning: Can't use blame annotator:
No changeset 2259 in the repository

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

Last change on this file since 3057 was 3057, checked in by Christoph Mayer, 16 years ago

-fixes #4 (merge tidy interface with current implementation)

File size: 6.3 KB
RevLine 
1// [Licence]
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// [Licence]
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 NetworkInterfaceList::iterator i = retlist.begin();
136 NetworkInterfaceList::iterator iend = retlist.end();
137
138 for( ; i != iend; i++ ){
139
140 NetworkInterface* interface = &(*i);
141 struct ifreq ifr;
142
143 memset( &ifr, 0, sizeof(struct ifreq) );
144 strcpy( ifr.ifr_name, i->name.c_str() );
145
146
147 { // get interface index
148 if( ioctl(infoSocket, SIOCGIFINDEX, &ifr) ){
149 logging_error( "could not get interface index for " <<
150 i->name << ": " << strerror(errno) );
151 return retlist;
152 }
153
154 interface->index = ifr.ifr_ifindex;
155 }
156
157 { // get interface flags
158 if( ioctl(infoSocket, SIOCGIFFLAGS, &ifr) ){
159 logging_error( "could not get interface flags for " <<
160 i->name << ": " << strerror(errno) );
161 return retlist;
162 }
163
164 interface->isRunning = (ifr.ifr_flags & IFF_RUNNING) != 0 ? true : false;
165 interface->isUp = (ifr.ifr_flags & IFF_UP) != 0 ? true : false;
166 interface->isLoopback = (ifr.ifr_flags & IFF_LOOPBACK) != 0 ? true : false;
167 interface->isBroadcast = (ifr.ifr_flags & IFF_BROADCAST) != 0 ? true : false;
168 interface->isMulticast = (ifr.ifr_flags & IFF_MULTICAST) != 0 ? true : false;
169 }
170
171 { // get mtu
172 if( ioctl(infoSocket, SIOCGIFMTU, &ifr) ){
173 logging_error( "could not get mtu for " <<
174 i->name << ": " << strerror(errno) );
175 return retlist;
176 }
177
178 interface->mtu = ifr.ifr_mtu;
179 }
180
181 { // get tx queue length
182 if( ioctl(infoSocket, SIOCGIFTXQLEN, &ifr) ){
183 logging_error( "could not get tx queue length for " <<
184 i->name << ": " << strerror(errno) );
185 return retlist;
186 }
187
188 interface->txQueueLen = ifr.ifr_qlen;
189 }
190
191 } // for( ; i != iend; i++ )*/
192
193 return retlist;
194}
195
196NetworkInterface NetworkInformation::getInterface(int index){
197
198 NetworkInterfaceList ifaces = getInterfaces();
199 NetworkInterfaceList::iterator i = ifaces.begin();
200 NetworkInterfaceList::iterator iend = ifaces.end();
201
202 for( ; i != iend; i++ ){
203 if( i->index == index ) return *i;
204 }
205
206 return NetworkInterface::UNDEFINED;
207}
208
209NetworkInterface NetworkInformation::getInterface(string name){
210
211 NetworkInterfaceList ifaces = getInterfaces();
212 NetworkInterfaceList::iterator i = ifaces.begin();
213 NetworkInterfaceList::iterator iend = ifaces.end();
214
215 for( ; i != iend; i++ ){
216 if( i->name.compare(name) == 0 ) return *i;
217 }
218
219 return NetworkInterface::UNDEFINED;
220}
221
222}} // namespace ariba, communication
Note: See TracBrowser for help on using the repository browser.