I’m using the getifaddrs
Linux function to get information about network interfaces on a Linux machine running Debian Jessie kernel 3.16.0.
Among the info I want to know is network statistics (packets dropped, sent, etc.) which, as the manpage for getifaddrs states, is contained in a rtnl_link_stats
structure pointed to by ifaddrs::ifa_addr::ifa_data
when ifaddrs::if_addr::sa_family
is set to AF_PACKET
.
This works well for ethernet interfaces, but does not work for CAN interfaces on the machine, because ifaddrs::ifa_addr
is NULL and thus AF_PACKET
is never returned for any CAN interface.
The following C++ code…
#include <ifaddrs.h>
#include <linux/if_link.h>
#include <net/if.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <cstdio>
#include <cstdlib>
int main() {
ifaddrs *addrs;
if (getifaddrs(&addrs) == -1) {
perror("getifaddrs");
return EXIT_FAILURE;
}
printf("AF_PACKET: %dnn", (int)AF_PACKET);
for (auto addr = addrs; addr != NULL; addr = addr->ifa_next) {
if (addr->ifa_addr != nullptr) {
printf("%s: family: %dn", addr->ifa_name, (int)addr->ifa_addr->sa_family);
} else {
printf("%s: family: nonen", addr->ifa_name);
}
}
freeifaddrs(addrs);
return EXIT_SUCCESS;
}
…prints out
AF_PACKET: 17
lo: family: 17
eth0: family: 17
eth1: family: 17
can0: family: none
can1: family: none
lo: family: 2
eth1: family: 2
lo: family: 10
eth1: family: 10
which means that neither of the CAN interfaces have any family set.
The ifconfig
command has no problem showing the information, though:
can0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
UP RUNNING NOARP MTU:16 Metric:1
RX packets:28481588 errors:0 dropped:8729866 overruns:0 frame:0
TX packets:8168599 errors:2292404 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:10
RX bytes:211108099 (201.3 MiB) TX bytes:64828340 (61.8 MiB)
Interrupt:17
can1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
UP RUNNING NOARP MTU:16 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:10
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Interrupt:17
(note I included only the output for CAN interfaces, not the rest)
What am I doing wrong? What is the correct way to retrieve packet stats for CAN interfaces?
3
Answers
Use the "address_family" option in the "ifconfig" command; check your "man ifconfig" page, here is the relevant text from mine (no CAN intfs on my system):
Given net-tools source code it reads file
/proc/net/dev
in the proc filesystem for this information.See the following functions in lib/interface.c:
if_readlist()
if_readlist_proc()
Good luck with your project!
EDIT> With a CAN adapter connected
File
/proc/net/dev
:Output of
ifconfig
:I had a similar problem in my C project nagios-plugins-linux and had to switch from the very easy interface
getifaddrs
tolinux rtnetlink
, which is a lot more complex to manage but also more powerfull (getifaddrs
provides the network statistics for theAF_PACKET
family only, if I remember correctly).You can find the related code in the library files:
I’m not able to check a
can0
interface but my code detects avcan0
one and should anyway work for any network interface.