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

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