Brian Cain
Brian Cain

Reputation: 14619

Determine TCP payload activity/statistics

I'd like to lookup a counter of the TCP payload activity (total bytes received) either for a given file descriptor or a given interface. Preferably the given file descriptor, but for the interface would be sufficient. Ideally I'd really like to know about any bytes that have been ack-ed, even ones which I have not read into userspace (yet?).

I've seen the TCP_INFO feature of getsockopt() but none of the fields appear to store "Total bytes received" or "total bytes transmitted (acked, e.g.)" so far as I can tell.

I've also seen the netlink IFLA_STATS+RTNL_TC_BYTES and the SIOCETHTOOL+ETHTOOL_GSTATS ioctl() (rx_bytes field) for the interfaces, and those are great, but I don't think they'll be able to discriminate between the overhead/headers of the other layers and the actual payload bytes.

procfs has /proc/net/tcp but this doesn't seem to contain what I'm looking for either.

Is there any way to get this particular data?

EDIT: promiscuous mode has an unbearable impact on throughput, so I can't leverage anything that uses it. Not to mention that implementing large parts of the IP stack to determine which packets are appropriate is beyond my intended scope for this solution.

The goal is to have an overarching/no-trust/second-guess of what values I store from recvmsg().

The Right Thing™ to do is to keep track of those values correctly, but it would be valuable to have a simple "Hey OS? How many bytes have I really received on this socket?"

Upvotes: 8

Views: 4311

Answers (4)

Stan
Stan

Reputation: 2599

In case you don't want to just count total RX/TX per interface (which is already available in ifconfig/iproute2 tools)...

If you look into /proc a bit more, you can get somewhat more information. More specifically /proc/<pid>/net/dev.

Sample output:

    Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
  eth0: 12106810846 8527175    0 15842    0     0          0    682866 198923814 1503063    0    0    0     0       0          0
    lo: 270255057 3992930    0    0    0     0          0         0 270255057 3992930    0    0    0     0       0          0
  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0

If you start looking, the information is coming from net/core/net-procfs.c from Linux kernel (procfs just uses this info). All of this of course means you need specific process to track.

You can either peruse information available in /proc or if you need something more stable, then duplicating net-procfs functionality specifically for your application might make sense.

Upvotes: 1

Manoj Pandey
Manoj Pandey

Reputation: 4666

One could also use ioctl call with SIOCINQ to get the amount of queued unread data in the receive buffer. Here is usage from the man page: http://man7.org/linux/man-pages/man7/tcp.7.html

int value;
error = ioctl(tcp_socket_fd, SIOCINQ, &value);

For interface TCP stats, we can use " netstat -i -p tcp" to find stats on a per-interface basis.

Upvotes: 4

David Sainty
David Sainty

Reputation: 1498

Do you want this for diagnosis, or for development?

If diagnosis, tcpdump can tell you exactly what's happening on the network, filtered by the port and host details.

If for development, perhaps a bit more information about what you're trying to achieve would help...

ifconfig gives RX and TX totals.

ifconfig gets these details from /proc/net/dev (as you can see via strace ifconfig).

There are also the Send/Receive-Q values given by netstat -t, if that's closer to what you want.

Upvotes: 2

ash
ash

Reputation: 5165

Perhaps the statistics in /proc/net/dev can help. I am not familiar with counting payload versus full packets including headers, so that makes the question harder to answer.

As for statistics on individual file descriptors, I am not aware of any standard means to get that information.

If it's possible to control startup of the programs for which the statistics are needed, it is possible to use an "interceptor" library which implements its own read(), write(), sendto(), and recvfrom() calls, passthrough the calls to the standard C library (or directly to system call), keep counters of the activity, and find a way to publish those values.

Upvotes: 1

Related Questions