linux上c語言 獲得網路介面的統計值
這個東東,蠻好玩的。其實就是讀取了/proc/net/dev 檔案。
struct netdev_stats {
unsigned long long rx_packets_m; /* total packets received */
unsigned long long tx_packets_m; /* total packets transmitted */
unsigned long long rx_bytes_m; /* total bytes received */
unsigned long long tx_bytes_m; /* total bytes transmitted */
unsigned long rx_errors_m; /* bad packets received */
unsigned long tx_errors_m; /* packet transmit problems */
unsigned long rx_dropped_m; /* no space in linux buffers */
unsigned long tx_dropped_m; /* no space available in linux */
unsigned long rx_multicast_m; /* multicast packets received */
unsigned long rx_compressed_m;
unsigned long tx_compressed_m;
unsigned long collisions_m;
/* detailed rx_errors: */
unsigned long rx_length_errors_m;
unsigned long rx_over_errors_m; /* receiver ring buff overflow */
unsigned long rx_crc_errors_m; /* recved pkt with crc error */
unsigned long rx_frame_errors_m; /* recv'd frame alignment error */
unsigned long rx_fifo_errors_m; /* recv'r fifo overrun */
unsigned long rx_missed_errors_m; /* receiver missed packet */
/* detailed tx_errors */
unsigned long tx_aborted_errors_m;
unsigned long tx_carrier_errors_m;
unsigned long tx_fifo_errors_m;
unsigned long tx_heartbeat_errors_m;
unsigned long tx_window_errors_m;
};
static char * get_name(char * name, char * p)
{
char * t = NULL;
/*interface only contains lowercase letters*/
while((*p<'a') || (*p>'z')) p++;
if ((t = strchr(p, ':')))
{
memcpy(name, p, t-p);
return t+1;
}
else return NULL;
}
#define PROC_NET_DEV_FNAME "/proc/net/dev"
int get_devstats(char * ifname, struct netdev_stats * pstats)
{
FILE * fp;
char name[256] = {0};
char buf[256] = {0};
char * s = NULL;
int found = 0;
if (!ifname || !pstats) return -1;
fp = fopen(PROC_NET_DEV_FNAME, "r");
if (!fp) return -1;
else
{
/*by pass the first 2 lines, they are titles*/
fgets(buf, sizeof(buf), fp );
fgets(buf, sizeof(buf), fp );
memset(buf, 0 ,sizeof(buf));
while (fgets(buf, sizeof(buf), fp ))
{
memset(name, 0, sizeof(name));
s = get_name(name, buf);
if (s)
{
sscanf(s, "%llu%llu%lu%lu%lu%lu%lu%lu%llu%llu%lu%lu%lu%lu%lu%lu",
&pstats->rx_bytes_m, /* missing for 0 */
&pstats->rx_packets_m,
&pstats->rx_errors_m,
&pstats->rx_dropped_m,
&pstats->rx_fifo_errors_m,
&pstats->rx_frame_errors_m,
&pstats->rx_compressed_m, /* missing for <= 1 */
&pstats->rx_multicast_m, /* missing for <= 1 */
&pstats->tx_bytes_m, /* missing for 0 */
&pstats->tx_packets_m,
&pstats->tx_errors_m,
&pstats->tx_dropped_m,
&pstats->tx_fifo_errors_m,
&pstats->collisions_m,
&pstats->tx_carrier_errors_m,
&pstats->tx_compressed_m /* missing for <= 1 */
);
if(!strncmp(name, ifname, strlen(ifname)))
{
found = 1;
break;
debug("name :%s/n", name);
debug("%llu:%llu:%lu:%lu:%lu:%lu:%lu:%lu:%llu:%llu:%lu:%lu:%lu:%lu:%lu:%lu:/n",
pstats->rx_bytes_m, /* missing for 0 */
pstats->rx_packets_m,
pstats->rx_errors_m,
pstats->rx_dropped_m,
pstats->rx_fifo_errors_m,
pstats->rx_frame_errors_m,
pstats->rx_compressed_m, /* missing for <= 1 */
pstats->rx_multicast_m, /* missing for <= 1 */
pstats->tx_bytes_m, /* missing for 0 */
pstats->tx_packets_m,
pstats->tx_errors_m,
pstats->tx_dropped_m,
pstats->tx_fifo_errors_m,
pstats->collisions_m,
pstats->tx_carrier_errors_m,
pstats->tx_compressed_m /* missing for <= 1 */
);
}
}
else continue;
}
fclose(fp);
}
if (!found) return -1;
else return 0;
}
int main()
{
struct netdev_stats wl_pstats;
get_devstats("wl0", &wl_pstats);
return 0;
}