2003-08-26 05:08:58 +08:00
|
|
|
/* $Id: linux.c,v 1.2 2003/08/25 21:08:58 bwalle Exp $ */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* init_osspecific()
|
|
|
|
*
|
|
|
|
* Init function
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
void init_osspecific(netdata* data)
|
|
|
|
{
|
|
|
|
/* nothing */
|
|
|
|
}
|
|
|
|
|
2003-08-25 04:05:32 +08:00
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* checkinterface()
|
|
|
|
*
|
|
|
|
* check if a given interface exists and is up.
|
|
|
|
* return TRUE if found, FALSE if not
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2003-08-26 05:08:58 +08:00
|
|
|
int checkinterface(netdata* data)
|
2003-08-25 04:05:32 +08:00
|
|
|
{
|
|
|
|
int interfacefound = FALSE;
|
|
|
|
unsigned int i;
|
|
|
|
struct if_nameindex *ifs;
|
|
|
|
|
|
|
|
if ((ifs = if_nameindex()) == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
for (i = 0; ifs[i].if_index; i++)
|
|
|
|
{
|
2003-08-26 05:08:58 +08:00
|
|
|
if (strcmp(ifs[i].if_name, data->ifdata.if_name) == 0)
|
2003-08-25 04:05:32 +08:00
|
|
|
{
|
|
|
|
interfacefound = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return interfacefound;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* get_stat()
|
|
|
|
*
|
|
|
|
* read the network statistics from /proc/net/dev (PATH_NET_DEV)
|
|
|
|
* if the file is not open open it. fseek() to the beginning and parse
|
|
|
|
* each line until we've found the right interface
|
|
|
|
*
|
|
|
|
* returns 0 if successful, 1 in case of error
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2003-08-26 05:08:58 +08:00
|
|
|
int get_stat(netdata* data)
|
2003-08-25 04:05:32 +08:00
|
|
|
{
|
2003-08-26 05:08:58 +08:00
|
|
|
/* bwalle: Instead of the original code we open the file each time new. The
|
|
|
|
* performance difference is _very_ minimal. But I don't think that it's a good
|
|
|
|
* idea to keep the file open for a very long time for _each_ plugin instance.
|
|
|
|
*/
|
2003-08-25 04:05:32 +08:00
|
|
|
char buffer[BUFSIZE];
|
|
|
|
char *ptr;
|
|
|
|
char *devname;
|
|
|
|
int dump;
|
|
|
|
int interfacefound;
|
2003-08-26 05:08:58 +08:00
|
|
|
FILE* proc_net_dev;
|
2003-08-25 04:05:32 +08:00
|
|
|
unsigned long rx_o, tx_o;
|
|
|
|
|
2003-08-26 05:08:58 +08:00
|
|
|
if ((proc_net_dev = fopen(PATH_NET_DEV, "r")) == NULL)
|
2003-08-25 04:05:32 +08:00
|
|
|
{
|
2003-08-26 05:08:58 +08:00
|
|
|
fprintf(stderr, "cannot open %s!\nnot running Linux?\n",
|
|
|
|
PATH_NET_DEV);
|
|
|
|
return 1;
|
2003-08-25 04:05:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* backup old rx/tx values */
|
2003-08-26 05:08:58 +08:00
|
|
|
rx_o = data->stats.rx_bytes; tx_o = data->stats.tx_bytes;
|
2003-08-25 04:05:32 +08:00
|
|
|
|
|
|
|
/* do not parse the first two lines as they only contain static garbage */
|
|
|
|
fseek(proc_net_dev, 0, SEEK_SET);
|
|
|
|
fgets(buffer, BUFSIZ-1, proc_net_dev);
|
|
|
|
fgets(buffer, BUFSIZ-1, proc_net_dev);
|
|
|
|
|
|
|
|
interfacefound = 0;
|
|
|
|
while (fgets(buffer, BUFSIZ-1, proc_net_dev) != NULL)
|
|
|
|
{
|
|
|
|
/* find the device name and substitute ':' with '\0' */
|
|
|
|
ptr = buffer;
|
|
|
|
while (*ptr == ' ')
|
|
|
|
ptr++;
|
|
|
|
devname = ptr;
|
|
|
|
while (*ptr != ':')
|
|
|
|
ptr++;
|
|
|
|
*ptr = '\0';
|
|
|
|
ptr++;
|
2003-08-26 05:08:58 +08:00
|
|
|
if (!strcmp(devname, (char *) data->ifdata.if_name))
|
2003-08-25 04:05:32 +08:00
|
|
|
{
|
|
|
|
/* read stats and fill struct */
|
|
|
|
sscanf(ptr, "%lg %lu %lu %d %d %d %d %d %lg %lu %lu %d %d %d %d %d",
|
2003-08-26 05:08:58 +08:00
|
|
|
&(data->stats.rx_bytes), &(data->stats.rx_packets), &(data->stats.rx_errors),
|
2003-08-25 04:05:32 +08:00
|
|
|
&dump, &dump, &dump, &dump, &dump,
|
2003-08-26 05:08:58 +08:00
|
|
|
&(data->stats.tx_bytes), &(data->stats.tx_packets), &(data->stats.tx_errors),
|
2003-08-25 04:05:32 +08:00
|
|
|
&dump, &dump, &dump, &dump, &dump);
|
|
|
|
interfacefound = 1;
|
|
|
|
continue; /* break, as we won't get any new information */
|
|
|
|
}
|
|
|
|
}
|
2003-08-26 05:08:58 +08:00
|
|
|
fclose( proc_net_dev );
|
2003-08-25 04:05:32 +08:00
|
|
|
if (interfacefound)
|
|
|
|
{
|
2003-08-26 05:08:58 +08:00
|
|
|
if (rx_o > data->stats.rx_bytes)
|
|
|
|
data->stats.rx_over++;
|
|
|
|
if (tx_o > data->stats.tx_bytes)
|
|
|
|
data->stats.tx_over++;
|
2003-08-25 04:05:32 +08:00
|
|
|
}
|
|
|
|
return (interfacefound == 1)? 0 : 1;
|
|
|
|
}
|