16
16
#include < unistd.h>
17
17
18
18
#include < arpa/inet.h>
19
- #include < linux/netlink.h>
20
- #include < linux/rtnetlink.h>
21
- #include < linux/ethtool.h>
22
- #include < linux/sockios.h>
23
19
#include < net/ethernet.h>
24
20
#include < net/if.h>
25
21
#include < netinet/in.h>
31
27
#include < sstream>
32
28
33
29
30
+
34
31
static std::string
35
32
SpeedToString (struct ethtool_cmd * edata)
36
33
{
@@ -109,20 +106,7 @@ NetworkInterface::Name() const
109
106
std::string
110
107
NetworkInterface::HardwareAddress () const
111
108
{
112
- struct ifreq ifr;
113
- if (_DoRequest (SIOCGIFHWADDR, ifr) != 0 )
114
- return " " ;
115
-
116
- struct sockaddr * addr = (struct sockaddr *)&ifr.ifr_hwaddr ;
117
- std::ostringstream stream;
118
- for (size_t i = 0 ; i < ETHER_ADDR_LEN; i++) {
119
- int byte = addr->sa_data [i] & 0xFF ;
120
- if (i != 0 )
121
- stream << " :" ;
122
- stream << std::hex << std::setw (2 ) << std::setfill (' 0' ) << byte;
123
- }
124
-
125
- return stream.str ();
109
+ return " " ;
126
110
}
127
111
128
112
@@ -151,46 +135,21 @@ NetworkInterface::IPAddress() const
151
135
std::string
152
136
NetworkInterface::NetMask () const
153
137
{
154
- struct ifreq ifr;
155
- if (_DoRequest (SIOCGIFNETMASK, ifr) != 0 )
156
- return " " ;
157
-
158
- struct sockaddr_in * ipaddr = (struct sockaddr_in *)&ifr.ifr_netmask ;
159
- return inet_ntoa (ipaddr->sin_addr );
138
+ return " " ;
160
139
}
161
140
162
141
163
142
std::string
164
143
NetworkInterface::Network () const
165
144
{
166
- struct ifreq ifrNetMask;
167
- if (_DoRequest (SIOCGIFNETMASK, ifrNetMask) != 0 )
168
- return " " ;
169
-
170
- struct ifreq ifrIpAddress;
171
- if (_DoRequest (SIOCGIFADDR, ifrIpAddress) != 0 )
172
- return " " ;
173
-
174
- struct sockaddr_in * ipAddr = (struct sockaddr_in *)&ifrIpAddress.ifr_addr ;
175
- struct sockaddr_in * netMask = (struct sockaddr_in *)&ifrNetMask.ifr_netmask ;
176
-
177
- struct in_addr networkAddress;
178
- ::memset (&networkAddress, 0 , sizeof (networkAddress));
179
- networkAddress.s_addr = ipAddr->sin_addr .s_addr & netMask->sin_addr .s_addr ;
180
-
181
- return inet_ntoa (networkAddress);
145
+ return " " ;
182
146
}
183
147
184
148
185
149
std::string
186
150
NetworkInterface::BroadcastAddress () const
187
151
{
188
- struct ifreq ifr;
189
- if (_DoRequest (SIOCGIFBRDADDR, ifr) != 0 )
190
- return " " ;
191
-
192
- struct sockaddr_in * ipaddr = (struct sockaddr_in *)&ifr.ifr_broadaddr ;
193
- return inet_ntoa (ipaddr->sin_addr );
152
+ return " " ;
194
153
}
195
154
196
155
@@ -207,16 +166,6 @@ NetworkInterface::HasDefaultGateway() const
207
166
std::string
208
167
NetworkInterface::DefaultGateway () const
209
168
{
210
- std::list<route_info> routeInfo;
211
- if (_GetRoutes (routeInfo) <= 0 )
212
- return " " ;
213
-
214
- std::list<route_info>::const_iterator i;
215
- for (i = routeInfo.begin (); i != routeInfo.end (); i++) {
216
- if (i->dstAddr .s_addr == 0 )
217
- return (char *)inet_ntoa (i->gateway );
218
- }
219
-
220
169
return " " ;
221
170
}
222
171
@@ -233,17 +182,7 @@ NetworkInterface::Type() const
233
182
std::string
234
183
NetworkInterface::Speed () const
235
184
{
236
- struct ifreq ifr;
237
- struct ethtool_cmd edata;
238
-
239
- ifr.ifr_data = (char *)&edata;
240
-
241
- edata.cmd = ETHTOOL_GSET;
242
-
243
- if (_DoRequest (SIOCETHTOOL, ifr) != 0 )
244
- return " 0" ;
245
-
246
- return SpeedToString (&edata);
185
+ return " " ;
247
186
}
248
187
249
188
@@ -267,163 +206,30 @@ NetworkInterface::SpeedWithUnit() const
267
206
std::string
268
207
NetworkInterface::Status () const
269
208
{
270
- struct ifreq ifr;
271
- if (_DoRequest (SIOCGIFFLAGS, ifr) != 0 )
272
- return " " ;
273
-
274
- return (ifr.ifr_flags & IFF_UP) ? " Up" : " Down" ;
209
+ return " " ;
275
210
}
276
211
277
212
278
213
bool
279
214
NetworkInterface::IsLoopback () const
280
215
{
281
- struct ifreq ifr;
282
- if (_DoRequest (SIOCGIFFLAGS, ifr) != 0 )
283
- return " " ;
284
-
285
- return ifr.ifr_flags & IFF_LOOPBACK;
216
+ return false ;
286
217
}
287
218
288
219
289
220
int
290
221
NetworkInterface::_DoRequest (int request, struct ifreq & ifr) const
291
222
{
292
- size_t ifNameLen = fName .size ();
293
- ::memcpy (ifr.ifr_name, fName .c_str(), ifNameLen);
294
- ifr.ifr_name [ifNameLen] = 0 ;
295
-
296
- int fd = ::socket (AF_INET, SOCK_DGRAM, 0 );
297
- if (fd == -1 )
298
- return errno;
299
-
300
223
int status = 0 ;
301
- if (::ioctl (fd, request, &ifr) < 0 )
302
- status = errno;
303
-
304
- ::close (fd);
305
224
306
225
return status;
307
226
}
308
227
309
228
310
- const static int kBufSize = 8192 ;
311
-
312
- static bool
313
- ParseRoutes (struct nlmsghdr * nlHdr, route_info* rtInfo,
314
- const char * interfaceName)
315
- {
316
- rtmsg* rtMsg = (rtmsg*)NLMSG_DATA (nlHdr);
317
-
318
- // If the route is not for AF_INET or does not belong to main routing table then return.
319
- if ((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table != RT_TABLE_MAIN))
320
- return false ;
321
-
322
- int rtLen = RTM_PAYLOAD (nlHdr);
323
- for (rtattr* rtAttr = (rtattr*)RTM_RTA (rtMsg);
324
- RTA_OK (rtAttr, rtLen);
325
- rtAttr = RTA_NEXT (rtAttr, rtLen)) {
326
- switch (rtAttr->rta_type ) {
327
- case RTA_OIF:
328
- if_indextoname (*(int *)RTA_DATA (rtAttr), rtInfo->ifName );
329
- break ;
330
- case RTA_GATEWAY:
331
- rtInfo->gateway = *(in_addr*)RTA_DATA (rtAttr);
332
- break ;
333
- case RTA_PREFSRC:
334
- rtInfo->srcAddr = *(in_addr*)RTA_DATA (rtAttr);
335
- break ;
336
- case RTA_DST:
337
- rtInfo->dstAddr = *(in_addr*)RTA_DATA (rtAttr);
338
- break ;
339
- default :
340
- break ;
341
- }
342
- }
343
-
344
- // If the route is for a different interface, return false
345
- // TODO: Check if we can filter the list beforehand
346
- return ::strcmp (interfaceName, rtInfo->ifName ) == 0 ;
347
- }
348
-
349
-
350
- static int
351
- ReadRouteInfoFromSocket (int sockFd, char *bufPtr, int seqNum, int pId)
352
- {
353
- nlmsghdr* nlHdr = NULL ;
354
- int msgLen = 0 ;
355
- do {
356
- // Receive response from the kernel
357
- int readLen = 0 ;
358
- if ((readLen = ::recv (sockFd, bufPtr, kBufSize - msgLen, 0 )) < 0 )
359
- return -1 ;
360
-
361
- nlHdr = (nlmsghdr*)bufPtr;
362
-
363
- // Check if the header is valid
364
- if ((NLMSG_OK (nlHdr, readLen) == (int )0 ) ||
365
- (nlHdr->nlmsg_type == NLMSG_ERROR)) {
366
- return -1 ;
367
- }
368
-
369
- // Check if the its the last message
370
- if (nlHdr->nlmsg_type == NLMSG_DONE) {
371
- break ;
372
- } else {
373
- // Else move the pointer to buffer appropriately
374
- bufPtr += readLen;
375
- msgLen += readLen;
376
- }
377
-
378
- // Check if its a multi part message
379
- if ((nlHdr->nlmsg_flags & NLM_F_MULTI) == 0 )
380
- break ;
381
- } while (((int )nlHdr->nlmsg_seq != seqNum) || ((int )nlHdr->nlmsg_pid != pId));
382
-
383
- return msgLen;
384
- }
385
229
386
230
387
231
int
388
232
NetworkInterface::_GetRoutes (std::list<route_info>& routeList) const
389
233
{
390
- int sock = 0 ;
391
- if ((sock = ::socket (PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0 )
392
- return errno;
393
-
394
- char msgBuf[kBufSize ];
395
- ::memset (msgBuf, 0 , kBufSize );
396
- struct nlmsghdr * nlMsg = (struct nlmsghdr *)msgBuf;
397
-
398
- int msgSeq = 0 ;
399
- // Fill in the nlmsg header
400
- nlMsg->nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg ));
401
- nlMsg->nlmsg_type = RTM_GETROUTE;
402
- nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
403
- nlMsg->nlmsg_seq = msgSeq++;
404
- nlMsg->nlmsg_pid = getpid ();
405
-
406
- if (::send (sock, nlMsg, nlMsg->nlmsg_len , 0 ) < 0 ) {
407
- ::close (sock);
408
- return errno;
409
- }
410
-
411
- // Read the response
412
- int len = 0 ;
413
- if ((len = ReadRouteInfoFromSocket (sock, msgBuf, msgSeq, getpid ())) < 0 ) {
414
- ::close (sock);
415
- return len;
416
- }
417
-
418
- // Parse and add to list
419
- for (; NLMSG_OK (nlMsg, len) != (int )0 ; nlMsg = NLMSG_NEXT (nlMsg, len)) {
420
- route_info rtInfo;
421
- memset (&rtInfo, 0 , sizeof (rtInfo));
422
- if (ParseRoutes (nlMsg, &rtInfo, Name ().c_str ()))
423
- routeList.push_back (rtInfo);
424
- }
425
-
426
- ::close (sock);
427
-
428
- return routeList.size ();
234
+ return 0 ;
429
235
}
0 commit comments