skip to Main Content

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


  1. 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):

    ...
         address_family
                 Specify the address family which affects interpretation of the remaining parameters.  Since an interface
                 can receive transmissions in differing protocols with different naming schemes, specifying the address
                 family is recommended.  The address or protocol families currently supported are ``inet'', ``inet6'', and
                 ``link''.  The default is ``inet''.  ``ether'' and ``lladdr'' are synonyms for ``link''.
    
    Login or Signup to reply.
  2. 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:

    Inter-|   Receive                                                |  Transmit
     face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    slcan0:       0       0    0    0    0     0          0         0      344      43    0    0    0     0       0          0
    

    Output of ifconfig:

    slcan0: flags=193<UP,RUNNING,NOARP>  mtu 16
            unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 10  (UNSPEC)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 43  bytes 344 (344.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    Login or Signup to reply.
  3. I had a similar problem in my C project nagios-plugins-linux and had to switch from the very easy interface getifaddrs to linux rtnetlink, which is a lot more complex to manage but also more powerfull (getifaddrs provides the network statistics for the AF_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 a vcan0 one and should anyway work for any network interface.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search