Rodolfo Conde
Rodolfo Conde

Reputation: 59

What is the easiest way to get PPP0 interface Tx/Rx bytes in a custom C/C++ program?

I need to show in my C/C++ program Tx/Rx information about three network interfaces. One of them is a ppp interface but my code is not working with ppp0.

I am using the code example from the man page of getifaddrs (see man getifaddrs), which basically checks if the interface has AF_PACKET family and if so, then it retrieves the Tx/Rx information from the ifa->ifa_data member of the ifaddrs struct. But this code fails for the ppp0 interface. Searching the internet, i found the source code of pppstats, but i see the code somewhat cumbersome, because it has many ifdefs for conditional code compilation. I see that ioctl must be used but i do not know exactly how.

What would be the simplest code to get the Tx/Rx bytes information from ppp0 in a linux system ? Is it really needed to use ioctl ?

Thanks in advance

Upvotes: 2

Views: 2071

Answers (1)

bunto1
bunto1

Reputation: 331

I'm currently in the same situation and spent some time researching and coding around the matter today. I too started with a look at the pppstats source code.

What would be the simplest code to get the Tx/Rx bytes information from ppp0 in a linux system ? Is it really needed to use ioctl ?

While I cannot really answer your exact question, here is the (c++) code I ended up with to read the RX/TX bytes on the ppp0 interface:

#include <linux/if_ppp.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <unistd.h>
{
    auto sockfd = ::socket(PF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        std::cout << "couldn't open socket : " << errno << std::endl;
        return;
    }

    ifreq req {};
    ppp_stats stats {};

    req.ifr_data = reinterpret_cast<caddr_t>(&stats);
    ::strncpy(&req.ifr_name[0], "ppp0", sizeof(req.ifr_name));

    auto ret = ::ioctl(sockfd, SIOCGPPPSTATS, &req);
    if (ret < 0) {
        std::cout << "couldn't get PPP statistics : " << errno << std::endl;
    } else {
        std::cout << "received bytes : " << stats.p.ppp_ibytes << std::endl;
        std::cout << "sent bytes : " << stats.p.ppp_obytes << std::endl;
    }

    auto ret = ::close(sockfd);
    if (ret != 0) {
        std::cout << "couldn't close socket : " << errno << std::endl;
    }
}

Upvotes: 3

Related Questions