1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
#include "linux.h"
/*****************************************************************************
*
* init_osspecific()
*
* Init function
*
****************************************************************************/
void init_osspecific(netdata* data)
{
#ifdef DEBUG
fprintf( stderr, "The netload plugin was initialized for Linux.\n" );
#endif
}
/*****************************************************************************
*
* checkinterface()
*
* check if a given interface exists and is up.
* return TRUE if found, FALSE if not
*
****************************************************************************/
int checkinterface(netdata* data)
{
int interfacefound = FALSE;
unsigned int i;
struct if_nameindex *ifs;
#ifdef DEBUG
fprintf( stderr, "Checking the interface '%s' now ...\n", data->ifdata.if_name );
#endif
if ((ifs = if_nameindex()) == NULL)
return FALSE;
for (i = 0; ifs[i].if_index; i++)
{
if (strcmp(ifs[i].if_name, data->ifdata.if_name) == 0)
{
interfacefound = TRUE;
break;
}
}
/* free the nameindex structure */
if_freenameindex(ifs);
/* check if the /proc/net/dev exists */
if (access(PATH_NET_DEV, R_OK) != 0)
{
data->errorcode = PROC_DEVICE_NOT_FOUND;
return FALSE;
}
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
*
*****************************************************************************/
int get_stat(netdata* data)
{
/* 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.
*/
char buffer[BUFSIZE];
char *ptr;
char *devname;
int dump;
int interfacefound;
FILE* proc_net_dev;
unsigned long rx_o, tx_o;
if ((proc_net_dev = fopen(PATH_NET_DEV, "r")) == NULL)
{
fprintf(stderr, "cannot open %s!\nnot running Linux?\n",
PATH_NET_DEV);
return 1;
}
/* backup old rx/tx values */
rx_o = data->stats.rx_bytes; tx_o = data->stats.tx_bytes;
/* do not parse the first two lines as they only contain static garbage */
fseek(proc_net_dev, 0, SEEK_SET);
fgets(buffer, BUFSIZE-1, proc_net_dev);
fgets(buffer, BUFSIZE-1, proc_net_dev);
interfacefound = 0;
while (fgets(buffer, BUFSIZE-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++;
if (!strcmp(devname, (char *) data->ifdata.if_name))
{
/* read stats and fill struct */
sscanf(ptr, "%lg %lu %lu %d %d %d %d %d %lg %lu %lu %d %d %d %d %d",
&(data->stats.rx_bytes), &(data->stats.rx_packets), &(data->stats.rx_errors),
&dump, &dump, &dump, &dump, &dump,
&(data->stats.tx_bytes), &(data->stats.tx_packets), &(data->stats.tx_errors),
&dump, &dump, &dump, &dump, &dump);
interfacefound = 1;
continue; /* break, as we won't get any new information */
}
}
fclose( proc_net_dev );
if (interfacefound)
{
if (rx_o > data->stats.rx_bytes)
data->stats.rx_over++;
if (tx_o > data->stats.tx_bytes)
data->stats.tx_over++;
}
return (interfacefound == 1)? 0 : 1;
}
|